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