📄 save.c
字号:
/* * save.c $Id: save.c,v 4.18 2007/04/15 19:01:18 bkorb Exp $ * Time-stamp: "2007-04-15 11:11:10 bkorb" * * This module's routines will take the currently set options and * store them into an ".rc" file for re-interpretation the next * time the invoking program is run. *//* * Automated Options copyright 1992-2007 Bruce Korb * * Automated Options is free software. * You may redistribute it and/or modify it under the terms of the * GNU General Public License, as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * Automated Options is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Automated Options. See the file "COPYING". If not, * write to: The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * As a special exception, Bruce Korb gives permission for additional * uses of the text contained in his release of AutoOpts. * * The exception is that, if you link the AutoOpts library with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the AutoOpts library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by Bruce Korb under * the name AutoOpts. If you copy code from other sources under the * General Public License into a copy of AutoOpts, as the General Public * License permits, the exception does not apply to the code that you add * in this way. To avoid misleading anyone as to the status of such * modified files, you must delete this exception notice from them. * * If you write modifications of your own for AutoOpts, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. */tSCC zWarn[] = "%s WARNING: cannot save options - ";/* = = = START-STATIC-FORWARD = = = *//* static forward declarations maintained by :mkfwd */static tCC*findDirName( tOptions* pOpts, int* p_free );static tCC*findFileName( tOptions* pOpts, int* p_free_name );static voidprintEntry( FILE * fp, tOptDesc * p, tCC* pzLA );/* = = = END-STATIC-FORWARD = = = */static tCC*findDirName( tOptions* pOpts, int* p_free ){ tCC* pzDir; if (pOpts->specOptIdx.save_opts == 0) return NULL; pzDir = pOpts->pOptDesc[ pOpts->specOptIdx.save_opts ].optArg.argString; if ((pzDir != NULL) && (*pzDir != NUL)) return pzDir; /* * This function only works if there is a directory where * we can stash the RC (INI) file. */ { tCC* const* papz = pOpts->papzHomeList; if (papz == NULL) return NULL; while (papz[1] != NULL) papz++; pzDir = *papz; } /* * IF it does not require deciphering an env value, then just copy it */ if (*pzDir != '$') return pzDir; { tCC* pzEndDir = strchr( ++pzDir, DIRCH ); char* pzFileName; char* pzEnv; if (pzEndDir != NULL) { char z[ AO_NAME_SIZE ]; if ((pzEndDir - pzDir) > AO_NAME_LIMIT ) return NULL; strncpy( z, pzDir, (size_t)(pzEndDir - pzDir) ); z[ (pzEndDir - pzDir) ] = NUL; pzEnv = getenv( z ); } else { /* * Make sure we can get the env value (after stripping off * any trailing directory or file names) */ pzEnv = getenv( pzDir ); } if (pzEnv == NULL) { fprintf( stderr, zWarn, pOpts->pzProgName ); fprintf( stderr, zNotDef, pzDir ); return NULL; } if (pzEndDir == NULL) return pzEnv; { size_t sz = strlen( pzEnv ) + strlen( pzEndDir ) + 2; pzFileName = (char*)AGALOC( sz, "dir name" ); } if (pzFileName == NULL) return NULL; *p_free = 1; /* * Glue together the full name into the allocated memory. * FIXME: We lose track of this memory. */ sprintf( pzFileName, "%s/%s", pzEnv, pzEndDir ); return pzFileName; }}static tCC*findFileName( tOptions* pOpts, int* p_free_name ){ tCC* pzDir; struct stat stBuf; int free_dir_name = 0; pzDir = findDirName( pOpts, &free_dir_name ); if (pzDir == NULL) return NULL; /* * See if we can find the specified directory. We use a once-only loop * structure so we can bail out early. */ if (stat( pzDir, &stBuf ) != 0) do { /* * IF we could not, check to see if we got a full * path to a file name that has not been created yet. */ if (errno == ENOENT) { char z[AG_PATH_MAX]; /* * Strip off the last component, stat the remaining string and * that string must name a directory */ char* pzDirCh = strrchr( pzDir, DIRCH ); if (pzDirCh == NULL) { stBuf.st_mode = S_IFREG; continue; /* bail out of error condition */ } strncpy( z, pzDir, (size_t)(pzDirCh - pzDir)); z[ pzDirCh - pzDir ] = NUL; if ( (stat( z, &stBuf ) == 0) && S_ISDIR( stBuf.st_mode )) { /* * We found the directory. Restore the file name and * mark the full name as a regular file */ stBuf.st_mode = S_IFREG; continue; /* bail out of error condition */ } } /* * We got a bogus name. */ fprintf( stderr, zWarn, pOpts->pzProgName ); fprintf( stderr, zNoStat, errno, strerror( errno ), pzDir ); if (free_dir_name) AGFREE( (void*)pzDir ); return NULL; } while (0); /* * IF what we found was a directory, * THEN tack on the config file name */ if (S_ISDIR( stBuf.st_mode )) { size_t sz = strlen( pzDir ) + strlen( pOpts->pzRcName ) + 2; { char* pzPath = (char*)AGALOC( sz, "file name" );#ifdef HAVE_SNPRINTF snprintf( pzPath, sz, "%s/%s", pzDir, pOpts->pzRcName );#else sprintf( pzPath, "%s/%s", pzDir, pOpts->pzRcName );#endif if (free_dir_name) AGFREE( (void*)pzDir ); pzDir = pzPath; free_dir_name = 1; } /* * IF we cannot stat the object for any reason other than * it does not exist, then we bail out */ if (stat( pzDir, &stBuf ) != 0) { if (errno != ENOENT) { fprintf( stderr, zWarn, pOpts->pzProgName ); fprintf( stderr, zNoStat, errno, strerror( errno ), pzDir ); AGFREE( (void*)pzDir ); return NULL; } /* * It does not exist yet, but it will be a regular file */ stBuf.st_mode = S_IFREG; } } /* * Make sure that whatever we ultimately found, that it either is * or will soon be a file. */ if (! S_ISREG( stBuf.st_mode )) { fprintf( stderr, zWarn, pOpts->pzProgName ); fprintf( stderr, zNotFile, pzDir ); if (free_dir_name) AGFREE( (void*)pzDir ); return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -