xref: /netbsd-src/external/bsd/ntp/dist/sntp/libopts/file.c (revision 7d3af8c6a2070d16ec6d1aef203d052d6683100d)
1 /*	$NetBSD: file.c,v 1.2 2012/02/03 21:36:40 christos Exp $	*/
2 
3 
4 /**
5  * \file file.c
6  *
7  *  Time-stamp:      "2010-07-10 11:00:59 bkorb"
8  *
9  *  This file is part of AutoOpts, a companion to AutoGen.
10  *  AutoOpts is free software.
11  *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
12  *
13  *  AutoOpts is available under any one of two licenses.  The license
14  *  in use must be one of these two and the choice is under the control
15  *  of the user of the license.
16  *
17  *   The GNU Lesser General Public License, version 3 or later
18  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
19  *
20  *   The Modified Berkeley Software Distribution License
21  *      See the file "COPYING.mbsd"
22  *
23  *  These files have the following md5sums:
24  *
25  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
26  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
27  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
28  */
29 
30 /*=export_func  optionFileCheck
31  * private:
32  *
33  * what:  Decipher a boolean value
34  * arg:   + tOptions*     + pOpts    + program options descriptor  +
35  * arg:   + tOptDesc*     + pOptDesc + the descriptor for this arg +
36  * arg:   + teOptFileType + ftype    + File handling type          +
37  * arg:   + tuFileMode    + mode     + file open mode (if needed)  +
38  *
39  * doc:
40  *   Make sure the named file conforms with the file type mode.
41  *   The mode specifies if the file must exist, must not exist or may
42  *   (or may not) exist.  The mode may also specify opening the
43  *   file: don't, open just the descriptor (fd), or open as a stream
44  *   (FILE* pointer).
45 =*/
46 void
47 optionFileCheck(tOptions* pOpts, tOptDesc* pOD,
48                 teOptFileType ftype, tuFileMode mode)
49 {
50     if (pOpts <= OPTPROC_EMIT_LIMIT) {
51         if (pOpts != OPTPROC_EMIT_USAGE)
52             return;
53 
54         switch (ftype & FTYPE_MODE_EXIST_MASK) {
55         case FTYPE_MODE_MUST_NOT_EXIST:
56             fputs(zFileCannotExist, option_usage_fp);
57             break;
58 
59         case FTYPE_MODE_MUST_EXIST:
60             fputs(zFileMustExist, option_usage_fp);
61             break;
62         }
63         return;
64     }
65 
66     if ((pOD->fOptState & OPTST_RESET) != 0) {
67         if (pOD->optCookie != NULL)
68             AGFREE(pOD->optCookie);
69         return;
70     }
71 
72     {
73         struct stat sb;
74 
75         errno = 0;
76 
77         switch (ftype & FTYPE_MODE_EXIST_MASK) {
78         case FTYPE_MODE_MUST_NOT_EXIST:
79             if (  (stat(pOD->optArg.argString, &sb) == 0)
80                || (errno != ENOENT) ){
81                 if (errno == 0)
82                     errno = EINVAL;
83                 fprintf(stderr, zFSOptError, errno, strerror(errno),
84                         zFSOptErrNoExist, pOD->optArg.argString, pOD->pz_Name);
85                 pOpts->pUsageProc(pOpts, EXIT_FAILURE);
86                 /* NOTREACHED */
87             }
88             /* FALLTHROUGH */
89 
90         default:
91         case FTYPE_MODE_MAY_EXIST:
92         {
93             char * p = strrchr(pOD->optArg.argString, DIRCH);
94             if (p == NULL)
95                 break; /* assume "." always exists. */
96 
97             *p = NUL;
98             if (  (stat(pOD->optArg.argString, &sb) != 0)
99                || (errno = EINVAL, ! S_ISDIR(sb.st_mode)) ){
100                 fprintf(stderr, zFSOptError, errno, strerror(errno),
101                         zFSOptErrMayExist, pOD->optArg.argString, pOD->pz_Name);
102                 pOpts->pUsageProc(pOpts, EXIT_FAILURE);
103                 /* NOTREACHED */
104             }
105             if (p != NULL)
106                 *p = DIRCH;
107             break;
108         }
109 
110         case FTYPE_MODE_MUST_EXIST:
111             if (  (stat(pOD->optArg.argString, &sb) != 0)
112                || (errno = EINVAL, ! S_ISREG(sb.st_mode)) ){
113                 fprintf(stderr, zFSOptError, errno, strerror(errno),
114                         zFSOptErrMustExist, pOD->optArg.argString,
115                         pOD->pz_Name);
116                 pOpts->pUsageProc(pOpts, EXIT_FAILURE);
117                 /* NOTREACHED */
118             }
119             break;
120         }
121     }
122 
123     switch (ftype & FTYPE_MODE_OPEN_MASK) {
124     default:
125     case FTYPE_MODE_NO_OPEN:
126         break;
127 
128     case FTYPE_MODE_OPEN_FD:
129     {
130         int fd = open(pOD->optArg.argString, mode.file_flags);
131         if (fd < 0) {
132             fprintf(stderr, zFSOptError, errno, strerror(errno),
133                     zFSOptErrOpen, pOD->optArg.argString, pOD->pz_Name);
134             pOpts->pUsageProc(pOpts, EXIT_FAILURE);
135             /* NOTREACHED */
136         }
137 
138         if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
139             pOD->optCookie = (void *)(intptr_t)pOD->optArg.argString;
140         else
141             AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name");
142 
143         pOD->optArg.argFd = fd;
144         pOD->fOptState &= ~OPTST_ALLOC_ARG;
145         break;
146     }
147 
148     case FTYPE_MODE_FOPEN_FP:
149     {
150         FILE* fp = fopen(pOD->optArg.argString, mode.file_mode);
151         if (fp == NULL) {
152             fprintf(stderr, zFSOptError, errno, strerror(errno),
153                     zFSOptErrFopen, pOD->optArg.argString, pOD->pz_Name);
154             pOpts->pUsageProc(pOpts, EXIT_FAILURE);
155             /* NOTREACHED */
156         }
157 
158         if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
159             pOD->optCookie = (void *)(intptr_t)pOD->optArg.argString;
160         else
161             AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name");
162 
163         pOD->optArg.argFp = fp;
164         pOD->fOptState &= ~OPTST_ALLOC_ARG;
165         break;
166     }
167     }
168 }
169 /*
170  * Local Variables:
171  * mode: C
172  * c-file-style: "stroustrup"
173  * indent-tabs-mode: nil
174  * End:
175  * end of autoopts/file.c */
176