rpm 5.2.1

rpmio/poptIO.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <poptIO.h>
00009 
00010 #define _RPMPGP_INTERNAL
00011 #if defined(WITH_BEECRYPT)
00012 #define _RPMBC_INTERNAL
00013 #include <rpmbc.h>
00014 #endif
00015 #if defined(WITH_GCRYPT)
00016 #define _RPMGC_INTERNAL
00017 #include <rpmgc.h>
00018 #endif
00019 #if defined(WITH_NSS)
00020 #define _RPMNSS_INTERNAL
00021 #include <rpmnss.h>
00022 #endif
00023 #if defined(WITH_SSL)
00024 #define _RPMSSL_INTERNAL
00025 #include <rpmssl.h>
00026 #endif
00027 
00028 #include <rpmficl.h>
00029 #include <rpmjs.h>
00030 #include <rpmperl.h>
00031 #include <rpmpython.h>
00032 #include <rpmruby.h>
00033 #include <rpmtcl.h>
00034 
00035 #include "debug.h"
00036 
00037 const char *__progname;
00038 
00039 #if !defined(POPT_ARGFLAG_TOGGLE)       /* XXX compat with popt < 1.15 */
00040 #define POPT_ARGFLAG_TOGGLE     0
00041 #endif
00042 #define POPT_SHOWVERSION        -999
00043 #define POPT_UNDEFINE           -994
00044 #define POPT_CRYPTO             -993
00045 
00046 /*@unchecked@*/
00047 int __debug = 0;
00048 
00049 /*@-exportheadervar@*/
00050 /*@-redecl@*/
00051 /*@unchecked@*/
00052 extern int _ar_debug;
00053 /*@unchecked@*/
00054 extern int _av_debug;
00055 /*@unchecked@*/
00056 extern int _cpio_debug;
00057 /*@unchecked@*/
00058 extern int _dav_debug;
00059 /*@unchecked@*/
00060 extern int _ftp_debug;
00061 /*@unchecked@*/
00062 extern int _fts_debug;
00063 /*@unchecked@*/
00064 extern int _ht_debug;
00065 /*@unchecked@*/
00066 extern int _iosm_debug;
00067 /*@unchecked@*/
00068 extern int noLibio;
00069 /*@unchecked@*/
00070 extern int _pgp_debug;
00071 /*@unchecked@*/
00072 extern int _rpmio_debug;
00073 /*@unchecked@*/
00074 extern int _rpmiob_debug;
00075 /*@unchecked@*/
00076 extern int _rpmlua_debug;
00077 /*@unchecked@*/
00078 extern int _rpmsq_debug;
00079 /*@unchecked@*/
00080 extern int _rpmzq_debug;
00081 /*@unchecked@*/
00082 extern int _tar_debug;
00083 /*@unchecked@*/
00084 extern int _xar_debug;
00085 /*@=redecl@*/
00086 /*@=exportheadervar@*/
00087 
00088 /*@unchecked@*/ /*@null@*/
00089 const char * rpmioPipeOutput = NULL;
00090 
00091 /*@unchecked@*/
00092 const char * rpmioRootDir = "/";
00093 
00094 /*@observer@*/ /*@unchecked@*/
00095 const char *rpmioEVR = VERSION;
00096 
00097 /*@unchecked@*/
00098 static int rpmioInitialized = -1;
00099 
00100 #ifdef  NOTYET
00101 #ifdef WITH_LUA
00102 /*@unchecked@*/
00103 extern const char *rpmluaFiles;
00104 #endif
00105 
00106 /*@unchecked@*/
00107 static char *rpmpoptfiles = RPMPOPTFILES;
00108 #endif
00109 
00110 pgpHashAlgo rpmioDigestHashAlgo = -1;
00111 
00115 struct poptOption rpmioDigestPoptTable[] = {
00116  { "md2", '\0', POPT_ARG_VAL,   &rpmioDigestHashAlgo, PGPHASHALGO_MD2,
00117         N_("MD2 digest (RFC-1319)"), NULL },
00118  { "md4", '\0', POPT_ARG_VAL,   &rpmioDigestHashAlgo, PGPHASHALGO_MD4,
00119         N_("MD4 digest"), NULL },
00120  { "md5", '\0', POPT_ARG_VAL,   &rpmioDigestHashAlgo, PGPHASHALGO_MD5,
00121         N_("MD5 digest (RFC-1321)"), NULL },
00122  { "sha1",'\0', POPT_ARG_VAL,   &rpmioDigestHashAlgo, PGPHASHALGO_SHA1,
00123         N_("SHA-1 digest (FIPS-180-1)"), NULL },
00124  { "sha224",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA224,
00125         N_("SHA-224 digest (FIPS-180-2)"), NULL },
00126  { "sha256",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA256,
00127         N_("SHA-256 digest (FIPS-180-2)"), NULL },
00128  { "sha384",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA384,
00129         N_("SHA-384 digest (FIPS-180-2)"), NULL },
00130  { "sha512",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA512,
00131         N_("SHA-512 digest (FIPS-180-2)"), NULL },
00132  { "salsa10",'\0', POPT_ARG_VAL,&rpmioDigestHashAlgo, PGPHASHALGO_SALSA10,
00133         N_("SALSA-10 hash"), NULL },
00134  { "salsa20",'\0', POPT_ARG_VAL,&rpmioDigestHashAlgo, PGPHASHALGO_SALSA20,
00135         N_("SALSA-20 hash"), NULL },
00136  { "rmd128",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD128,
00137         N_("RIPEMD-128 digest"), NULL },
00138  { "rmd160",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD160,
00139         N_("RIPEMD-160 digest"), NULL },
00140  { "rmd256",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD256,
00141         N_("RIPEMD-256 digest"), NULL },
00142  { "rmd320",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD320,
00143         N_("RIPEMD-320 digest"), NULL },
00144  { "tiger",'\0', POPT_ARG_VAL,  &rpmioDigestHashAlgo, PGPHASHALGO_TIGER192,
00145         N_("TIGER digest"), NULL },
00146  { "crc32",'\0', POPT_ARG_VAL,  &rpmioDigestHashAlgo, PGPHASHALGO_CRC32,
00147         N_("CRC-32 checksum"), NULL },
00148  { "crc64",'\0', POPT_ARG_VAL,  &rpmioDigestHashAlgo, PGPHASHALGO_CRC64,
00149         N_("CRC-64 checksum"), NULL },
00150  { "adler32",'\0', POPT_ARG_VAL,&rpmioDigestHashAlgo, PGPHASHALGO_ADLER32,
00151         N_("ADLER-32 checksum"), NULL },
00152  { "jlu32",'\0', POPT_ARG_VAL,  &rpmioDigestHashAlgo, PGPHASHALGO_JLU32,
00153         N_("Lookup3 hash"), NULL },
00154  { "nodigest",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmioDigestHashAlgo, PGPHASHALGO_NONE,
00155         N_("No hash algorithm"), NULL },
00156  { "alldigests",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmioDigestHashAlgo, 256,
00157         N_("All hash algorithm(s)"), NULL },
00158     POPT_TABLEEND
00159 };
00160 
00164 static void printVersion(FILE * fp)
00165         /*@globals rpmioEVR, fileSystem @*/
00166         /*@modifies *fp, fileSystem @*/
00167 {
00168     fprintf(fp, _("%s (" RPM_NAME ") %s\n"), __progname, rpmioEVR);
00169 }
00170 
00171 void rpmioConfigured(void)
00172         /*@globals rpmioInitialized @*/
00173         /*@modifies rpmioInitialized @*/
00174 {
00175 
00176     if (rpmioInitialized < 0) {
00177         /* XXX TODO: add initialization side-effects. */
00178         rpmioInitialized = 0;
00179     }
00180     if (rpmioInitialized)
00181         exit(EXIT_FAILURE);
00182 }
00183 
00186 static void rpmioAllArgCallback(poptContext con,
00187                 /*@unused@*/ enum poptCallbackReason reason,
00188                 const struct poptOption * opt, const char * arg,
00189                 /*@unused@*/ const void * data)
00190         /*@globals pgpImplVecs,
00191                 rpmGlobalMacroContext,
00192                 fileSystem, internalState @*/
00193         /*@modifies con, pgpImplVecs,
00194                 rpmGlobalMacroContext,
00195                 fileSystem, internalState @*/
00196 {
00197 
00198     /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
00199     if (opt->arg == NULL)
00200     switch (opt->val) {
00201     case 'q':
00202         rpmSetVerbosity(RPMLOG_WARNING);
00203         break;
00204     case 'v':
00205         rpmIncreaseVerbosity();
00206         break;
00207 #ifdef  NOTYET
00208     case 'D':
00209     {   char *s, *t;
00210         /* XXX Convert '-' in macro name to underscore, skip leading %. */
00211         s = t = xstrdup(arg);
00212         while (*t && !xisspace((int)*t)) {
00213             if (*t == '-') *t = '_';
00214             t++;
00215         }
00216         t = s;
00217         if (*t == '%') t++;
00218         rpmioConfigured();
00219 /*@-type@*/
00220         /* XXX adding macro to global context isn't Right Thing Todo. */
00221         (void) rpmDefineMacro(NULL, t, RMIL_CMDLINE);
00222         (void) rpmDefineMacro(rpmCLIMacroContext, t, RMIL_CMDLINE);
00223 /*@=type@*/
00224         s = _free(s);
00225     }   break;
00226     case POPT_UNDEFINE:
00227     {   char *s, *t;
00228         /* XXX Convert '-' in macro name to underscore, skip leading %. */
00229         s = t = xstrdup(arg);
00230         while (*t && !xisspace((int)*t)) {
00231             if (*t == '-') *t = '_';
00232             t++;
00233         }
00234         t = s;
00235         if (*t == '%') t++;
00236 /*@-type@*/
00237         rpmioConfigured();
00238         (void) rpmUndefineMacro(NULL, t);
00239         (void) rpmUndefineMacro(rpmCLIMacroContext, t);
00240 /*@=type@*/
00241         s = _free(s);
00242     }   break;
00243     case 'E':
00244         rpmioConfigured();
00245         {   const char *val = rpmExpand(arg, NULL);
00246             size_t val_len;
00247             val_len = strlen(val);
00248             if (val[val_len - 1] == '\n')
00249                 fwrite(val, val_len, 1, stdout);
00250             else
00251                 fprintf(stdout, "%s\n", val);
00252             val = _free(val);
00253         }
00254         break;
00255 #endif  /* NOTYET */
00256     case POPT_CRYPTO:
00257         {   const char *val;
00258 #ifdef  NOTYET
00259             rpmioConfigured();
00260             val = rpmExpand(arg, NULL);
00261 #else
00262             val = xstrdup(arg);
00263 #endif  /* NOTYET */
00264             if (!xstrcasecmp(val, "beecrypt") || !xstrcasecmp(val, "bc")) {
00265 #if defined(WITH_BEECRYPT)
00266                 pgpImplVecs = &rpmbcImplVecs;
00267 #else
00268                 rpmlog(RPMLOG_ERR, "BeeCrypt (\"beecrypt\") based cryptography implementation not available\n");
00269                 exit(EXIT_FAILURE);
00270 #endif
00271             }
00272             else if (!xstrcasecmp(val, "gcrypt") || !xstrcasecmp(val, "gc")) {
00273 #if defined(WITH_GCRYPT)
00274                 pgpImplVecs = &rpmgcImplVecs;
00275 #else
00276                 rpmlog(RPMLOG_ERR, "GCrypt (\"gcrypt\") based cryptography implementation not available\n");
00277                 exit(EXIT_FAILURE);
00278 #endif
00279             }
00280             else if (!xstrcasecmp(val, "NSS")) {
00281 #if defined(WITH_NSS)
00282                 pgpImplVecs = &rpmnssImplVecs;
00283 #else
00284                 rpmlog(RPMLOG_ERR, "Mozilla NSS (\"nss\") based cryptography implementation not available\n");
00285                 exit(EXIT_FAILURE);
00286 #endif
00287             }
00288             else if (!xstrcasecmp(val, "OpenSSL") || !xstrcasecmp(val, "ssl")) {
00289 #if defined(WITH_SSL)
00290                 pgpImplVecs = &rpmsslImplVecs;
00291 #else
00292                 rpmlog(RPMLOG_ERR, "OpenSSL (\"openssl\") based cryptography implementation not available\n");
00293                 exit(EXIT_FAILURE);
00294 #endif
00295             }
00296             else {
00297                 rpmlog(RPMLOG_ERR, "cryptography implementation \"%s\" not known\n", val);
00298                 exit(EXIT_FAILURE);
00299             }
00300             val = _free(val);
00301         }
00302         break;
00303     case POPT_SHOWVERSION:
00304         printVersion(stdout);
00305 /*@i@*/ con = rpmioFini(con);
00306         exit(EXIT_SUCCESS);
00307         /*@notreached@*/ break;
00308     }
00309 }
00310 
00311 /*@unchecked@*/
00312 int rpmioFtsOpts = 0;
00313 
00314 /*@unchecked@*/
00315 struct poptOption rpmioFtsPoptTable[] = {
00316  { "comfollow", '\0', POPT_BIT_SET,     &rpmioFtsOpts, FTS_COMFOLLOW,
00317         N_("FTS_COMFOLLOW: follow command line symlinks"), NULL },
00318  { "logical", '\0', POPT_BIT_SET,       &rpmioFtsOpts, FTS_LOGICAL,
00319         N_("FTS_LOGICAL: logical walk"), NULL },
00320  { "nochdir", '\0', POPT_BIT_SET,       &rpmioFtsOpts, FTS_NOCHDIR,
00321         N_("FTS_NOCHDIR: don't change directories"), NULL },
00322  { "nostat", '\0', POPT_BIT_SET,        &rpmioFtsOpts, FTS_NOSTAT,
00323         N_("FTS_NOSTAT: don't get stat info"), NULL },
00324  { "physical", '\0', POPT_BIT_SET,      &rpmioFtsOpts, FTS_PHYSICAL,
00325         N_("FTS_PHYSICAL: physical walk"), NULL },
00326  { "seedot", '\0', POPT_BIT_SET,        &rpmioFtsOpts, FTS_SEEDOT,
00327         N_("FTS_SEEDOT: return dot and dot-dot"), NULL },
00328  { "xdev", '\0', POPT_BIT_SET,          &rpmioFtsOpts, FTS_XDEV,
00329         N_("FTS_XDEV: don't cross devices"), NULL },
00330  { "whiteout", '\0', POPT_BIT_SET,      &rpmioFtsOpts, FTS_WHITEOUT,
00331         N_("FTS_WHITEOUT: return whiteout information"), NULL },
00332    POPT_TABLEEND
00333 };
00334 
00335 /*@-bitwisesigned -compmempass @*/
00336 /*@unchecked@*/
00337 struct poptOption rpmioAllPoptTable[] = {
00338 /*@-type@*/ /* FIX: cast? */
00339  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
00340         rpmioAllArgCallback, 0, NULL, NULL },
00341 /*@=type@*/
00342 
00343  { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &__debug, -1,
00344         N_("Debug generic operations"), NULL },
00345 
00346 #ifdef  NOTYET
00347  { "define", 'D', POPT_ARG_STRING, NULL, (int)'D',
00348         N_("Define MACRO with value EXPR"),
00349         N_("'MACRO EXPR'") },
00350  { "undefine", '\0', POPT_ARG_STRING, NULL, POPT_UNDEFINE,
00351         N_("Undefine MACRO"),
00352         N_("'MACRO'") },
00353  { "eval", 'E', POPT_ARG_STRING, NULL, (int)'E',
00354         N_("Print macro expansion of EXPR"),
00355         N_("'EXPR'") },
00356 
00357  { "macros", '\0', POPT_ARG_STRING, &rpmMacrofiles, 0,
00358         N_("Read <FILE:...> instead of default file(s)"),
00359         N_("<FILE:...>") },
00360 #ifdef WITH_LUA
00361  { "rpmlua", '\0', POPT_ARG_STRING, &rpmluaFiles, 0,
00362         N_("Read <FILE:...> instead of default RPM Lua file(s)"),
00363         N_("<FILE:...>") },
00364 #endif
00365  { "rpmpopt", '\0', POPT_ARG_STRING, NULL, 0,
00366         N_("Read <FILE:...> instead of default POPT file(s)"),
00367         N_("<FILE:...>") },
00368 #endif  /* NOTYET */
00369 
00370  { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &rpmioPipeOutput, 0,
00371         N_("Send stdout to CMD"),
00372         N_("CMD") },
00373  { "root", 'r', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmioRootDir, 0,
00374         N_("Use ROOT as top level directory"),
00375         N_("ROOT") },
00376 
00377  { "quiet", '\0', 0, NULL, (int)'q',
00378         N_("Provide less detailed output"), NULL},
00379  { "verbose", 'v', 0, NULL, (int)'v',
00380         N_("Provide more detailed output"), NULL},
00381  { "version", '\0', 0, NULL, POPT_SHOWVERSION,
00382         N_("Print the version"), NULL },
00383 
00384 #if defined(HAVE_LIBIO_H) && defined(_G_IO_IO_FILE_VERSION)
00385  { "nolibio", '\0', POPT_ARG_VAL|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN, &noLibio, -1,
00386         N_("Disable use of libio(3) API"), NULL},
00387 #endif
00388 
00389  { "usecrypto",'\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_CRYPTO,
00390         N_("Select cryptography implementation"),
00391         N_("CRYPTO") },
00392 
00393  { "ardebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ar_debug, -1,
00394         N_("Debug ar archives"), NULL},
00395  { "avdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_av_debug, -1,
00396         N_("Debug argv collections"), NULL},
00397  { "cpiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_cpio_debug, -1,
00398         N_("Debug cpio archives"), NULL},
00399  { "davdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_dav_debug, -1,
00400         N_("Debug WebDAV data stream"), NULL},
00401  { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
00402         N_("Debug FTP/HTTP data stream"), NULL},
00403  { "ftsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fts_debug, -1,
00404         N_("Debug Fts(3) traverse"), NULL},
00405  { "htdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ht_debug, -1,
00406         N_("Debug hash tables"), NULL},
00407  { "iosmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_iosm_debug, -1,
00408         N_("Debug I/O state machine"), NULL},
00409  { "miredebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_mire_debug, -1,
00410         N_("Debug miRE patterns"), NULL},
00411  { "pgpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_pgp_debug, -1,
00412         N_("Debug PGP usage"), NULL},
00413  { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
00414         N_("Debug rpmio I/O"), NULL},
00415  { "rpmiobdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmiob_debug, -1,
00416         N_("Debug rpmio I/O buffers"), NULL},
00417  { "rpmficldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmficl_debug, -1,
00418         N_("Debug embedded FICL interpreter"), NULL},
00419  { "rpmjsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmjs_debug, -1,
00420         N_("Debug embedded JavaScript interpreter"), NULL},
00421 #ifdef WITH_LUA
00422  { "rpmluadebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmlua_debug, -1,
00423         N_("Debug embedded Lua interpreter"), NULL},
00424 #endif
00425  { "rpmmgdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmmg_debug, -1,
00426         N_("Debug rpmmg magic"), NULL},
00427  { "rpmperldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmperl_debug, -1,
00428         N_("Debug embedded Perl interpreter"), NULL},
00429  { "rpmpythondebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmpython_debug, -1,
00430         N_("Debug embedded Python interpreter"), NULL},
00431  { "rpmrubydebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmruby_debug, -1,
00432         N_("Debug embedded Ruby interpreter"), NULL},
00433  { "rpmsqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsq_debug, -1,
00434         N_("Debug rpmsq Signal Queue"), NULL},
00435  { "rpmtcldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmtcl_debug, -1,
00436         N_("Debug embedded TCL interpreter"), NULL},
00437 #ifdef WITH_BZIP2
00438  { "rpmzqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmzq_debug, -1,
00439         N_("Debug rpmzq Job Queuing"), NULL},
00440 #endif
00441  { "xardebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_xar_debug, -1,
00442         N_("Debug xar archives"), NULL},
00443  { "tardebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_tar_debug, -1,
00444         N_("Debug tar archives"), NULL},
00445  { "stats", '\0', POPT_ARG_VAL,                         &_rpmsw_stats, -1,
00446         N_("Display operation statistics"), NULL},
00447  { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
00448         N_("Debug URL cache handling"), NULL},
00449 
00450    POPT_TABLEEND
00451 };
00452 /*@=bitwisesigned =compmempass @*/
00453 
00454 poptContext
00455 rpmioFini(poptContext optCon)
00456 {
00457     /* XXX this should be done in the rpmioClean() wrapper. */
00458     /* keeps memory leak checkers quiet */
00459     rpmFreeMacros(NULL);
00460 /*@i@*/ rpmFreeMacros(rpmCLIMacroContext);
00461 
00462     rpmioClean();
00463 
00464     optCon = poptFreeContext(optCon);
00465 
00466 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
00467     /*@-noeffect@*/
00468     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00469     /*@=noeffect@*/
00470 #endif
00471 
00472     return NULL;
00473 }
00474 
00475 static inline int checkfd(const char * devnull, int fdno, int flags)
00476         /*@*/
00477 {
00478     struct stat sb;
00479     int ret = 0;
00480 
00481     if (fstat(fdno, &sb) == -1 && errno == EBADF)
00482         ret = (open(devnull, flags) == fdno) ? 1 : 2;
00483     return ret;
00484 }
00485 
00486 /*@-globstate@*/
00487 poptContext
00488 rpmioInit(int argc, char *const argv[], struct poptOption * optionsTable)
00489 {
00490     poptContext optCon;
00491     int rc;
00492 #ifdef  NOTYET
00493     int i;
00494 #endif
00495 
00496 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
00497     /*@-noeffect@*/
00498     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00499     /*@=noeffect@*/
00500 #endif
00501 /*@-globs -mods@*/
00502     setprogname(argv[0]);       /* Retrofit glibc __progname */
00503 
00504     /* XXX glibc churn sanity */
00505     if (__progname == NULL) {
00506         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
00507         else __progname = argv[0];
00508     }
00509 /*@=globs =mods@*/
00510 
00511     /* Insure that stdin/stdout/stderr are open, lest stderr end up in rpmdb. */
00512    {    static const char _devnull[] = "/dev/null";
00513 #if defined(STDIN_FILENO)
00514         (void) checkfd(_devnull, STDIN_FILENO, O_RDONLY);
00515 #endif
00516 #if defined(STDOUT_FILENO)
00517         (void) checkfd(_devnull, STDOUT_FILENO, O_WRONLY);
00518 #endif
00519 #if defined(STDERR_FILENO)
00520         (void) checkfd(_devnull, STDERR_FILENO, O_WRONLY);
00521 #endif
00522    }
00523 
00524 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
00525     (void) setlocale(LC_ALL, "" );
00526     (void) bindtextdomain(PACKAGE, LOCALEDIR);
00527     (void) textdomain(PACKAGE);
00528 #endif
00529 
00530     rpmSetVerbosity(RPMLOG_NOTICE);
00531 
00532     if (optionsTable == NULL) {
00533         /* Read rpm configuration (if not already read). */
00534         rpmioConfigured();
00535         return NULL;
00536     }
00537 
00538 #ifdef  NOTYET
00539     /* read all RPM POPT configuration files */
00540     for (i = 1; i < argc; i++) {
00541         if (strcmp(argv[i], "--rpmpopt") == 0 && i+1 < argc) {
00542             rpmpoptfiles = argv[i+1];
00543             break;
00544         }
00545         else if (strncmp(argv[i], "--rpmpopt=", 10) == 0) {
00546             rpmpoptfiles = argv[i]+10;
00547             break;
00548         }
00549     }
00550 #endif  /* NOTYET */
00551 
00552 /*@-nullpass -temptrans@*/
00553     optCon = poptGetContext(__progname, argc, (const char **)argv, optionsTable, 0);
00554 /*@=nullpass =temptrans@*/
00555 
00556 #ifdef  NOTYET
00557 #if defined(RPM_VENDOR_OPENPKG) /* stick-with-rpm-file-sanity-checking */ || \
00558     !defined(POPT_ERROR_BADCONFIG)      /* XXX POPT 1.15 retrofit */
00559   { char * path_buf = xstrdup(rpmpoptfiles);
00560     char *path;
00561     char *path_next;
00562 
00563     for (path = path_buf; path != NULL && *path != '\0'; path = path_next) {
00564         const char **av;
00565         int ac, i;
00566 
00567         /* locate start of next path element */
00568         path_next = strchr(path, ':');
00569         if (path_next != NULL && *path_next == ':')
00570             *path_next++ = '\0';
00571         else
00572             path_next = path + strlen(path);
00573 
00574         /* glob-expand the path element */
00575         ac = 0;
00576         av = NULL;
00577         if ((i = rpmGlob(path, &ac, &av)) != 0)
00578             continue;
00579 
00580         /* work-off each resulting file from the path element */
00581         for (i = 0; i < ac; i++) {
00582             const char *fn = av[i];
00583             if (fn[0] == '@' /* attention */) {
00584                 fn++;
00585                 if (!rpmSecuritySaneFile(fn)) {
00586                     rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", fn);
00587                     continue;
00588                 }
00589             }
00590             (void)poptReadConfigFile(optCon, fn);
00591             av[i] = _free(av[i]);
00592         }
00593         av = _free(av);
00594     }
00595     path_buf = _free(path_buf);
00596   }
00597 #else
00598     /* XXX FIXME: better error message is needed. */
00599     if ((xx = poptReadConfigFiles(optCon, rpmpoptfiles)) != 0)
00600        rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", rpmpoptfiles);
00601 #endif
00602 
00603     /* read standard POPT configuration files */
00604     /* XXX FIXME: the 2nd arg useEnv flag is UNUSED. */
00605     (void) poptReadDefaultConfig(optCon, 1);
00606 
00607     poptSetExecPath(optCon, USRLIBRPM, 1);
00608 #endif  /* NOTYET */
00609 
00610     /* Process all options, whine if unknown. */
00611     while ((rc = poptGetNextOpt(optCon)) > 0) {
00612         const char * optArg = poptGetOptArg(optCon);
00613 /*@-dependenttrans -modobserver -observertrans @*/
00614         optArg = _free(optArg);
00615 /*@=dependenttrans =modobserver =observertrans @*/
00616         switch (rc) {
00617         default:
00618 /*@-nullpass@*/
00619             fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
00620                 __progname, rc);
00621 /*@=nullpass@*/
00622             exit(EXIT_FAILURE);
00623 
00624             /*@notreached@*/ /*@switchbreak@*/ break;
00625         }
00626     }
00627 
00628     if (rc < -1) {
00629 /*@-nullpass@*/
00630         fprintf(stderr, "%s: %s: %s\n", __progname,
00631                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
00632                 poptStrerror(rc));
00633 /*@=nullpass@*/
00634         exit(EXIT_FAILURE);
00635     }
00636 
00637     /* Read rpm configuration (if not already read). */
00638     rpmioConfigured();
00639 
00640     if (__debug) {
00641         rpmIncreaseVerbosity();
00642         rpmIncreaseVerbosity();
00643     }
00644 
00645     return optCon;
00646 }
00647 /*@=globstate@*/