file.c revision 285612
1193323Sed 2193323Sed/** 3193323Sed * \file file.c 4193323Sed * 5193323Sed * Handle options that have file names for arguments. 6193323Sed * 7193323Sed * @addtogroup autoopts 8193323Sed * @{ 9193323Sed */ 10193323Sed/* 11193323Sed * This file is part of AutoOpts, a companion to AutoGen. 12193323Sed * AutoOpts is free software. 13193323Sed * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 14193323Sed * 15193323Sed * AutoOpts is available under any one of two licenses. The license 16193323Sed * in use must be one of these two and the choice is under the control 17193323Sed * of the user of the license. 18193323Sed * 19193323Sed * The GNU Lesser General Public License, version 3 or later 20193323Sed * See the files "COPYING.lgplv3" and "COPYING.gplv3" 21193323Sed * 22193323Sed * The Modified Berkeley Software Distribution License 23193323Sed * See the file "COPYING.mbsd" 24193323Sed * 25193323Sed * These files have the following sha256 sums: 26193323Sed * 27193323Sed * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 28193323Sed * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 29193323Sed * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 30195340Sed */ 31193323Sed 32193323Sed/** 33193323Sed * Make sure the directory containing the subject file exists and that 34193323Sed * the file exists or does not exist, per the option requirements. 35193323Sed * 36193323Sed * @param ftype file existence type flags 37198090Srdivacky * @param pOpts program option descriptor 38193323Sed * @param pOD the option descriptor 39193323Sed */ 40193323Sedstatic void 41198090Srdivackycheck_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD) 42193323Sed{ 43193323Sed char const * fname = pOD->optArg.argString; 44193323Sed struct stat sb; 45193323Sed 46193323Sed errno = 0; 47193323Sed 48193323Sed switch (ftype & FTYPE_MODE_EXIST_MASK) { 49193323Sed case FTYPE_MODE_MUST_NOT_EXIST: 50193323Sed if ((stat(fname, &sb) == 0) || (errno != ENOENT)) { 51193323Sed if (errno == 0) 52198090Srdivacky errno = EINVAL; 53193323Sed fserr_exit(pOpts->pzProgName, "stat", fname); 54193323Sed /* NOTREACHED */ 55193323Sed } 56193323Sed /* FALLTHROUGH */ 57193323Sed 58193323Sed default: 59193323Sed case FTYPE_MODE_MAY_EXIST: 60193323Sed { 61193323Sed char * p = strrchr(fname, DIRCH); 62193323Sed size_t l; 63193323Sed 64193323Sed if (p == NULL) 65193323Sed /* 66193323Sed * The file may or may not exist and its directory is ".". 67193323Sed * Assume that "." exists. 68193323Sed */ 69193323Sed break; 70193323Sed 71193323Sed l = (size_t)(p - fname); 72193323Sed p = AGALOC(l + 1, "fname"); 73193323Sed memcpy(p, fname, l); 74193323Sed p[l] = NUL; 75193323Sed 76193323Sed if ((stat(p, &sb) != 0) || (errno = EINVAL, ! S_ISDIR(sb.st_mode))) 77201360Srdivacky fserr_exit(pOpts->pzProgName, "stat", p); 78201360Srdivacky /* NOTREACHED */ 79201360Srdivacky 80201360Srdivacky AGFREE(p); 81193323Sed break; 82193323Sed } 83193323Sed 84193323Sed case FTYPE_MODE_MUST_EXIST: 85193323Sed if ( (stat(fname, &sb) != 0) 86193323Sed || (errno = EINVAL, ! S_ISREG(sb.st_mode)) ) 87193323Sed fserr_exit(pOpts->pzProgName, "stat", fname); 88193323Sed /* NOTREACHED */ 89193323Sed 90193323Sed break; 91193323Sed } 92193323Sed} 93193323Sed 94193323Sed/** 95193323Sed * Open the specified file with open(2) and save the FD. 96193323Sed * 97193323Sed * @param pOpts program option descriptor 98193323Sed * @param pOD the option descriptor 99193323Sed * @param mode the open mode (uses int flags value) 100193323Sed */ 101193323Sedstatic void 102193323Sedopen_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) 103193323Sed{ 104193323Sed int fd = open(pOD->optArg.argString, mode.file_flags); 105193323Sed if (fd < 0) 106193323Sed fserr_exit(pOpts->pzProgName, "open", pOD->optArg.argString); 107198892Srdivacky /* NOTREACHED */ 108193323Sed 109201360Srdivacky if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) 110201360Srdivacky pOD->optCookie = VOIDP(pOD->optArg.argString); 111201360Srdivacky else 112201360Srdivacky AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); 113201360Srdivacky 114201360Srdivacky pOD->optArg.argFd = fd; 115201360Srdivacky pOD->fOptState &= ~OPTST_ALLOC_ARG; 116201360Srdivacky} 117201360Srdivacky 118193323Sed/** 119198892Srdivacky * Open the specified file with open(2) and save the FD. 120198892Srdivacky * 121201360Srdivacky * @param pOpts program option descriptor 122201360Srdivacky * @param pOD the option descriptor 123198892Srdivacky * @param mode the open mode (uses "char *" mode value) 124193323Sed */ 125201360Srdivackystatic void 126201360Srdivackyfopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) 127201360Srdivacky{ 128201360Srdivacky FILE * fp = fopen(pOD->optArg.argString, mode.file_mode); 129201360Srdivacky if (fp == NULL) 130201360Srdivacky fserr_exit(pOpts->pzProgName, "fopen", pOD->optArg.argString); 131201360Srdivacky /* NOTREACHED */ 132198892Srdivacky 133193323Sed if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) 134198892Srdivacky pOD->optCookie = VOIDP(pOD->optArg.argString); 135193323Sed else 136198892Srdivacky AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); 137193323Sed 138193323Sed pOD->optArg.argFp = fp; 139193323Sed pOD->fOptState &= ~OPTST_ALLOC_ARG; 140193323Sed} 141193323Sed 142193323Sed/*=export_func optionFileCheck 143193323Sed * private: 144193323Sed * 145193323Sed * what: Decipher a boolean value 146198892Srdivacky * arg: + tOptions * + pOpts + program options descriptor + 147193323Sed * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + 148193323Sed * arg: + teOptFileType + ftype + File handling type + 149193323Sed * arg: + tuFileMode + mode + file open mode (if needed) + 150193323Sed * 151193323Sed * doc: 152193323Sed * Make sure the named file conforms with the file type mode. 153193323Sed * The mode specifies if the file must exist, must not exist or may 154193323Sed * (or may not) exist. The mode may also specify opening the 155193323Sed * file: don't, open just the descriptor (fd), or open as a stream 156193323Sed * (FILE * pointer). 157193323Sed=*/ 158193323Sedvoid 159193323SedoptionFileCheck(tOptions * pOpts, tOptDesc * pOD, 160198090Srdivacky teOptFileType ftype, tuFileMode mode) 161198090Srdivacky{ 162193323Sed if (pOpts <= OPTPROC_EMIT_LIMIT) { 163198090Srdivacky if (pOpts != OPTPROC_EMIT_USAGE) 164198090Srdivacky return; 165198090Srdivacky 166198090Srdivacky switch (ftype & FTYPE_MODE_EXIST_MASK) { 167198090Srdivacky case FTYPE_MODE_MUST_NOT_EXIST: 168198090Srdivacky fputs(zFileCannotExist + tab_skip_ct, option_usage_fp); 169198090Srdivacky break; 170193323Sed 171193323Sed case FTYPE_MODE_MUST_EXIST: 172193323Sed fputs(zFileMustExist + tab_skip_ct, option_usage_fp); 173193323Sed break; 174193323Sed } 175193323Sed return; 176193323Sed } 177193323Sed 178193323Sed if ((pOD->fOptState & OPTST_RESET) != 0) { 179193323Sed if (pOD->optCookie != NULL) 180193323Sed AGFREE(pOD->optCookie); 181193323Sed return; 182193323Sed } 183193323Sed 184193323Sed check_existence(ftype, pOpts, pOD); 185193323Sed 186193323Sed switch (ftype & FTYPE_MODE_OPEN_MASK) { 187193323Sed default: 188193323Sed case FTYPE_MODE_NO_OPEN: break; 189193323Sed case FTYPE_MODE_OPEN_FD: open_file_fd( pOpts, pOD, mode); break; 190193323Sed case FTYPE_MODE_FOPEN_FP: fopen_file_fp(pOpts, pOD, mode); break; 191193323Sed } 192193323Sed} 193193323Sed 194193323Sed/** @} 195193323Sed * 196193323Sed * Local Variables: 197193323Sed * mode: C 198193323Sed * c-file-style: "stroustrup" 199193323Sed * indent-tabs-mode: nil 200193323Sed * End: 201193323Sed * end of autoopts/file.c */ 202193323Sed