rpm  5.2.1
poptIO.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <poptIO.h>
9 
10 #define _RPMPGP_INTERNAL
11 #if defined(WITH_BEECRYPT)
12 #define _RPMBC_INTERNAL
13 #include <rpmbc.h>
14 #endif
15 #if defined(WITH_GCRYPT)
16 #define _RPMGC_INTERNAL
17 #include <rpmgc.h>
18 #endif
19 #if defined(WITH_NSS)
20 #define _RPMNSS_INTERNAL
21 #include <rpmnss.h>
22 #endif
23 #if defined(WITH_SSL)
24 #define _RPMSSL_INTERNAL
25 #include <rpmssl.h>
26 #endif
27 
28 #include <rpmficl.h>
29 #include <rpmjs.h>
30 #include <rpmperl.h>
31 #include <rpmpython.h>
32 #include <rpmruby.h>
33 #include <rpmtcl.h>
34 
35 #include "debug.h"
36 
37 const char *__progname;
38 
39 #if !defined(POPT_ARGFLAG_TOGGLE) /* XXX compat with popt < 1.15 */
40 #define POPT_ARGFLAG_TOGGLE 0
41 #endif
42 #define POPT_SHOWVERSION -999
43 #define POPT_UNDEFINE -994
44 #define POPT_CRYPTO -993
45 
46 /*@unchecked@*/
47 int __debug = 0;
48 
49 /*@-exportheadervar@*/
50 /*@-redecl@*/
51 /*@unchecked@*/
52 extern int _ar_debug;
53 /*@unchecked@*/
54 extern int _av_debug;
55 /*@unchecked@*/
56 extern int _cpio_debug;
57 /*@unchecked@*/
58 extern int _dav_debug;
59 /*@unchecked@*/
60 extern int _ftp_debug;
61 /*@unchecked@*/
62 extern int _fts_debug;
63 /*@unchecked@*/
64 extern int _ht_debug;
65 /*@unchecked@*/
66 extern int _iosm_debug;
67 /*@unchecked@*/
68 extern int noLibio;
69 /*@unchecked@*/
70 extern int _pgp_debug;
71 /*@unchecked@*/
72 extern int _rpmio_debug;
73 /*@unchecked@*/
74 extern int _rpmiob_debug;
75 /*@unchecked@*/
76 extern int _rpmlua_debug;
77 /*@unchecked@*/
78 extern int _rpmsq_debug;
79 /*@unchecked@*/
80 extern int _rpmzq_debug;
81 /*@unchecked@*/
82 extern int _tar_debug;
83 /*@unchecked@*/
84 extern int _xar_debug;
85 /*@=redecl@*/
86 /*@=exportheadervar@*/
87 
88 /*@unchecked@*/ /*@null@*/
89 const char * rpmioPipeOutput = NULL;
90 
91 /*@unchecked@*/
92 const char * rpmioRootDir = "/";
93 
94 /*@observer@*/ /*@unchecked@*/
95 const char *rpmioEVR = VERSION;
96 
97 /*@unchecked@*/
98 static int rpmioInitialized = -1;
99 
100 #ifdef NOTYET
101 #ifdef WITH_LUA
102 /*@unchecked@*/
103 extern const char *rpmluaFiles;
104 #endif
105 
106 /*@unchecked@*/
107 static char *rpmpoptfiles = RPMPOPTFILES;
108 #endif
109 
111 
115 struct poptOption rpmioDigestPoptTable[] = {
116  { "md2", '\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_MD2,
117  N_("MD2 digest (RFC-1319)"), NULL },
118  { "md4", '\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_MD4,
119  N_("MD4 digest"), NULL },
120  { "md5", '\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_MD5,
121  N_("MD5 digest (RFC-1321)"), NULL },
122  { "sha1",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA1,
123  N_("SHA-1 digest (FIPS-180-1)"), NULL },
124  { "sha224",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA224,
125  N_("SHA-224 digest (FIPS-180-2)"), NULL },
126  { "sha256",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA256,
127  N_("SHA-256 digest (FIPS-180-2)"), NULL },
128  { "sha384",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA384,
129  N_("SHA-384 digest (FIPS-180-2)"), NULL },
130  { "sha512",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_SHA512,
131  N_("SHA-512 digest (FIPS-180-2)"), NULL },
132  { "salsa10",'\0', POPT_ARG_VAL,&rpmioDigestHashAlgo, PGPHASHALGO_SALSA10,
133  N_("SALSA-10 hash"), NULL },
134  { "salsa20",'\0', POPT_ARG_VAL,&rpmioDigestHashAlgo, PGPHASHALGO_SALSA20,
135  N_("SALSA-20 hash"), NULL },
136  { "rmd128",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD128,
137  N_("RIPEMD-128 digest"), NULL },
138  { "rmd160",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD160,
139  N_("RIPEMD-160 digest"), NULL },
140  { "rmd256",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD256,
141  N_("RIPEMD-256 digest"), NULL },
142  { "rmd320",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_RIPEMD320,
143  N_("RIPEMD-320 digest"), NULL },
144  { "tiger",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_TIGER192,
145  N_("TIGER digest"), NULL },
146  { "crc32",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_CRC32,
147  N_("CRC-32 checksum"), NULL },
148  { "crc64",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_CRC64,
149  N_("CRC-64 checksum"), NULL },
150  { "adler32",'\0', POPT_ARG_VAL,&rpmioDigestHashAlgo, PGPHASHALGO_ADLER32,
151  N_("ADLER-32 checksum"), NULL },
152  { "jlu32",'\0', POPT_ARG_VAL, &rpmioDigestHashAlgo, PGPHASHALGO_JLU32,
153  N_("Lookup3 hash"), NULL },
154  { "nodigest",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmioDigestHashAlgo, PGPHASHALGO_NONE,
155  N_("No hash algorithm"), NULL },
156  { "alldigests",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmioDigestHashAlgo, 256,
157  N_("All hash algorithm(s)"), NULL },
158  POPT_TABLEEND
159 };
160 
164 static void printVersion(FILE * fp)
165  /*@globals rpmioEVR, fileSystem @*/
166  /*@modifies *fp, fileSystem @*/
167 {
168  fprintf(fp, _("%s (" RPM_NAME ") %s\n"), __progname, rpmioEVR);
169 }
170 
171 void rpmioConfigured(void)
172  /*@globals rpmioInitialized @*/
173  /*@modifies rpmioInitialized @*/
174 {
175 
176  if (rpmioInitialized < 0) {
177  /* XXX TODO: add initialization side-effects. */
178  rpmioInitialized = 0;
179  }
180  if (rpmioInitialized)
181  exit(EXIT_FAILURE);
182 }
183 
186 static void rpmioAllArgCallback(poptContext con,
187  /*@unused@*/ enum poptCallbackReason reason,
188  const struct poptOption * opt, const char * arg,
189  /*@unused@*/ const void * data)
190  /*@globals pgpImplVecs,
191  rpmGlobalMacroContext,
192  fileSystem, internalState @*/
193  /*@modifies con, pgpImplVecs,
194  rpmGlobalMacroContext,
195  fileSystem, internalState @*/
196 {
197 
198  /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
199  if (opt->arg == NULL)
200  switch (opt->val) {
201  case 'q':
203  break;
204  case 'v':
206  break;
207 #ifdef NOTYET
208  case 'D':
209  { char *s, *t;
210  /* XXX Convert '-' in macro name to underscore, skip leading %. */
211  s = t = xstrdup(arg);
212  while (*t && !xisspace((int)*t)) {
213  if (*t == '-') *t = '_';
214  t++;
215  }
216  t = s;
217  if (*t == '%') t++;
218  rpmioConfigured();
219 /*@-type@*/
220  /* XXX adding macro to global context isn't Right Thing Todo. */
221  (void) rpmDefineMacro(NULL, t, RMIL_CMDLINE);
223 /*@=type@*/
224  s = _free(s);
225  } break;
226  case POPT_UNDEFINE:
227  { char *s, *t;
228  /* XXX Convert '-' in macro name to underscore, skip leading %. */
229  s = t = xstrdup(arg);
230  while (*t && !xisspace((int)*t)) {
231  if (*t == '-') *t = '_';
232  t++;
233  }
234  t = s;
235  if (*t == '%') t++;
236 /*@-type@*/
237  rpmioConfigured();
238  (void) rpmUndefineMacro(NULL, t);
240 /*@=type@*/
241  s = _free(s);
242  } break;
243  case 'E':
244  rpmioConfigured();
245  { const char *val = rpmExpand(arg, NULL);
246  size_t val_len;
247  val_len = strlen(val);
248  if (val[val_len - 1] == '\n')
249  fwrite(val, val_len, 1, stdout);
250  else
251  fprintf(stdout, "%s\n", val);
252  val = _free(val);
253  }
254  break;
255 #endif /* NOTYET */
256  case POPT_CRYPTO:
257  { const char *val;
258 #ifdef NOTYET
259  rpmioConfigured();
260  val = rpmExpand(arg, NULL);
261 #else
262  val = xstrdup(arg);
263 #endif /* NOTYET */
264  if (!xstrcasecmp(val, "beecrypt") || !xstrcasecmp(val, "bc")) {
265 #if defined(WITH_BEECRYPT)
267 #else
268  rpmlog(RPMLOG_ERR, "BeeCrypt (\"beecrypt\") based cryptography implementation not available\n");
269  exit(EXIT_FAILURE);
270 #endif
271  }
272  else if (!xstrcasecmp(val, "gcrypt") || !xstrcasecmp(val, "gc")) {
273 #if defined(WITH_GCRYPT)
275 #else
276  rpmlog(RPMLOG_ERR, "GCrypt (\"gcrypt\") based cryptography implementation not available\n");
277  exit(EXIT_FAILURE);
278 #endif
279  }
280  else if (!xstrcasecmp(val, "NSS")) {
281 #if defined(WITH_NSS)
283 #else
284  rpmlog(RPMLOG_ERR, "Mozilla NSS (\"nss\") based cryptography implementation not available\n");
285  exit(EXIT_FAILURE);
286 #endif
287  }
288  else if (!xstrcasecmp(val, "OpenSSL") || !xstrcasecmp(val, "ssl")) {
289 #if defined(WITH_SSL)
291 #else
292  rpmlog(RPMLOG_ERR, "OpenSSL (\"openssl\") based cryptography implementation not available\n");
293  exit(EXIT_FAILURE);
294 #endif
295  }
296  else {
297  rpmlog(RPMLOG_ERR, "cryptography implementation \"%s\" not known\n", val);
298  exit(EXIT_FAILURE);
299  }
300  val = _free(val);
301  }
302  break;
303  case POPT_SHOWVERSION:
304  printVersion(stdout);
305 /*@i@*/ con = rpmioFini(con);
306  exit(EXIT_SUCCESS);
307  /*@notreached@*/ break;
308  }
309 }
310 
311 /*@unchecked@*/
312 int rpmioFtsOpts = 0;
313 
314 /*@unchecked@*/
315 struct poptOption rpmioFtsPoptTable[] = {
316  { "comfollow", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_COMFOLLOW,
317  N_("FTS_COMFOLLOW: follow command line symlinks"), NULL },
318  { "logical", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_LOGICAL,
319  N_("FTS_LOGICAL: logical walk"), NULL },
320  { "nochdir", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_NOCHDIR,
321  N_("FTS_NOCHDIR: don't change directories"), NULL },
322  { "nostat", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_NOSTAT,
323  N_("FTS_NOSTAT: don't get stat info"), NULL },
324  { "physical", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_PHYSICAL,
325  N_("FTS_PHYSICAL: physical walk"), NULL },
326  { "seedot", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_SEEDOT,
327  N_("FTS_SEEDOT: return dot and dot-dot"), NULL },
328  { "xdev", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_XDEV,
329  N_("FTS_XDEV: don't cross devices"), NULL },
330  { "whiteout", '\0', POPT_BIT_SET, &rpmioFtsOpts, FTS_WHITEOUT,
331  N_("FTS_WHITEOUT: return whiteout information"), NULL },
332  POPT_TABLEEND
333 };
334 
335 /*@-bitwisesigned -compmempass @*/
336 /*@unchecked@*/
337 struct poptOption rpmioAllPoptTable[] = {
338 /*@-type@*/ /* FIX: cast? */
339  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
340  rpmioAllArgCallback, 0, NULL, NULL },
341 /*@=type@*/
342 
343  { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &__debug, -1,
344  N_("Debug generic operations"), NULL },
345 
346 #ifdef NOTYET
347  { "define", 'D', POPT_ARG_STRING, NULL, (int)'D',
348  N_("Define MACRO with value EXPR"),
349  N_("'MACRO EXPR'") },
350  { "undefine", '\0', POPT_ARG_STRING, NULL, POPT_UNDEFINE,
351  N_("Undefine MACRO"),
352  N_("'MACRO'") },
353  { "eval", 'E', POPT_ARG_STRING, NULL, (int)'E',
354  N_("Print macro expansion of EXPR"),
355  N_("'EXPR'") },
356 
357  { "macros", '\0', POPT_ARG_STRING, &rpmMacrofiles, 0,
358  N_("Read <FILE:...> instead of default file(s)"),
359  N_("<FILE:...>") },
360 #ifdef WITH_LUA
361  { "rpmlua", '\0', POPT_ARG_STRING, &rpmluaFiles, 0,
362  N_("Read <FILE:...> instead of default RPM Lua file(s)"),
363  N_("<FILE:...>") },
364 #endif
365  { "rpmpopt", '\0', POPT_ARG_STRING, NULL, 0,
366  N_("Read <FILE:...> instead of default POPT file(s)"),
367  N_("<FILE:...>") },
368 #endif /* NOTYET */
369 
370  { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &rpmioPipeOutput, 0,
371  N_("Send stdout to CMD"),
372  N_("CMD") },
373  { "root", 'r', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmioRootDir, 0,
374  N_("Use ROOT as top level directory"),
375  N_("ROOT") },
376 
377  { "quiet", '\0', 0, NULL, (int)'q',
378  N_("Provide less detailed output"), NULL},
379  { "verbose", 'v', 0, NULL, (int)'v',
380  N_("Provide more detailed output"), NULL},
381  { "version", '\0', 0, NULL, POPT_SHOWVERSION,
382  N_("Print the version"), NULL },
383 
384 #if defined(HAVE_LIBIO_H) && defined(_G_IO_IO_FILE_VERSION)
385  { "nolibio", '\0', POPT_ARG_VAL|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN, &noLibio, -1,
386  N_("Disable use of libio(3) API"), NULL},
387 #endif
388 
389  { "usecrypto",'\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_CRYPTO,
390  N_("Select cryptography implementation"),
391  N_("CRYPTO") },
392 
393  { "ardebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ar_debug, -1,
394  N_("Debug ar archives"), NULL},
395  { "avdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_av_debug, -1,
396  N_("Debug argv collections"), NULL},
397  { "cpiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_cpio_debug, -1,
398  N_("Debug cpio archives"), NULL},
399  { "davdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_dav_debug, -1,
400  N_("Debug WebDAV data stream"), NULL},
401  { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
402  N_("Debug FTP/HTTP data stream"), NULL},
403  { "ftsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fts_debug, -1,
404  N_("Debug Fts(3) traverse"), NULL},
405  { "htdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ht_debug, -1,
406  N_("Debug hash tables"), NULL},
407  { "iosmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_iosm_debug, -1,
408  N_("Debug I/O state machine"), NULL},
409  { "miredebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_mire_debug, -1,
410  N_("Debug miRE patterns"), NULL},
411  { "pgpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_pgp_debug, -1,
412  N_("Debug PGP usage"), NULL},
413  { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
414  N_("Debug rpmio I/O"), NULL},
415  { "rpmiobdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmiob_debug, -1,
416  N_("Debug rpmio I/O buffers"), NULL},
417  { "rpmficldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmficl_debug, -1,
418  N_("Debug embedded FICL interpreter"), NULL},
419  { "rpmjsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmjs_debug, -1,
420  N_("Debug embedded JavaScript interpreter"), NULL},
421 #ifdef WITH_LUA
422  { "rpmluadebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmlua_debug, -1,
423  N_("Debug embedded Lua interpreter"), NULL},
424 #endif
425  { "rpmmgdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmmg_debug, -1,
426  N_("Debug rpmmg magic"), NULL},
427  { "rpmperldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmperl_debug, -1,
428  N_("Debug embedded Perl interpreter"), NULL},
429  { "rpmpythondebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmpython_debug, -1,
430  N_("Debug embedded Python interpreter"), NULL},
431  { "rpmrubydebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmruby_debug, -1,
432  N_("Debug embedded Ruby interpreter"), NULL},
433  { "rpmsqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsq_debug, -1,
434  N_("Debug rpmsq Signal Queue"), NULL},
435  { "rpmtcldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmtcl_debug, -1,
436  N_("Debug embedded TCL interpreter"), NULL},
437 #ifdef WITH_BZIP2
438  { "rpmzqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmzq_debug, -1,
439  N_("Debug rpmzq Job Queuing"), NULL},
440 #endif
441  { "xardebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_xar_debug, -1,
442  N_("Debug xar archives"), NULL},
443  { "tardebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_tar_debug, -1,
444  N_("Debug tar archives"), NULL},
445  { "stats", '\0', POPT_ARG_VAL, &_rpmsw_stats, -1,
446  N_("Display operation statistics"), NULL},
447  { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
448  N_("Debug URL cache handling"), NULL},
449 
450  POPT_TABLEEND
451 };
452 /*@=bitwisesigned =compmempass @*/
453 
454 poptContext
455 rpmioFini(poptContext optCon)
456 {
457  /* XXX this should be done in the rpmioClean() wrapper. */
458  /* keeps memory leak checkers quiet */
459  rpmFreeMacros(NULL);
461 
462  rpmioClean();
463 
464  optCon = poptFreeContext(optCon);
465 
466 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
467  /*@-noeffect@*/
468  muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
469  /*@=noeffect@*/
470 #endif
471 
472  return NULL;
473 }
474 
475 static inline int checkfd(const char * devnull, int fdno, int flags)
476  /*@*/
477 {
478  struct stat sb;
479  int ret = 0;
480 
481  if (fstat(fdno, &sb) == -1 && errno == EBADF)
482  ret = (open(devnull, flags) == fdno) ? 1 : 2;
483  return ret;
484 }
485 
486 /*@-globstate@*/
487 poptContext
488 rpmioInit(int argc, char *const argv[], struct poptOption * optionsTable)
489 {
490  poptContext optCon;
491  int rc;
492 #ifdef NOTYET
493  int i;
494 #endif
495 
496 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
497  /*@-noeffect@*/
498  mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
499  /*@=noeffect@*/
500 #endif
501 /*@-globs -mods@*/
502  setprogname(argv[0]); /* Retrofit glibc __progname */
503 
504  /* XXX glibc churn sanity */
505  if (__progname == NULL) {
506  if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
507  else __progname = argv[0];
508  }
509 /*@=globs =mods@*/
510 
511  /* Insure that stdin/stdout/stderr are open, lest stderr end up in rpmdb. */
512  { static const char _devnull[] = "/dev/null";
513 #if defined(STDIN_FILENO)
514  (void) checkfd(_devnull, STDIN_FILENO, O_RDONLY);
515 #endif
516 #if defined(STDOUT_FILENO)
517  (void) checkfd(_devnull, STDOUT_FILENO, O_WRONLY);
518 #endif
519 #if defined(STDERR_FILENO)
520  (void) checkfd(_devnull, STDERR_FILENO, O_WRONLY);
521 #endif
522  }
523 
524 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
525  (void) setlocale(LC_ALL, "" );
527  (void) textdomain(PACKAGE);
528 #endif
529 
531 
532  if (optionsTable == NULL) {
533  /* Read rpm configuration (if not already read). */
534  rpmioConfigured();
535  return NULL;
536  }
537 
538 #ifdef NOTYET
539  /* read all RPM POPT configuration files */
540  for (i = 1; i < argc; i++) {
541  if (strcmp(argv[i], "--rpmpopt") == 0 && i+1 < argc) {
542  rpmpoptfiles = argv[i+1];
543  break;
544  }
545  else if (strncmp(argv[i], "--rpmpopt=", 10) == 0) {
546  rpmpoptfiles = argv[i]+10;
547  break;
548  }
549  }
550 #endif /* NOTYET */
551 
552 /*@-nullpass -temptrans@*/
553  optCon = poptGetContext(__progname, argc, (const char **)argv, optionsTable, 0);
554 /*@=nullpass =temptrans@*/
555 
556 #ifdef NOTYET
557 #if defined(RPM_VENDOR_OPENPKG) /* stick-with-rpm-file-sanity-checking */ || \
558  !defined(POPT_ERROR_BADCONFIG) /* XXX POPT 1.15 retrofit */
559  { char * path_buf = xstrdup(rpmpoptfiles);
560  char *path;
561  char *path_next;
562 
563  for (path = path_buf; path != NULL && *path != '\0'; path = path_next) {
564  const char **av;
565  int ac, i;
566 
567  /* locate start of next path element */
568  path_next = strchr(path, ':');
569  if (path_next != NULL && *path_next == ':')
570  *path_next++ = '\0';
571  else
572  path_next = path + strlen(path);
573 
574  /* glob-expand the path element */
575  ac = 0;
576  av = NULL;
577  if ((i = rpmGlob(path, &ac, &av)) != 0)
578  continue;
579 
580  /* work-off each resulting file from the path element */
581  for (i = 0; i < ac; i++) {
582  const char *fn = av[i];
583  if (fn[0] == '@' /* attention */) {
584  fn++;
585  if (!rpmSecuritySaneFile(fn)) {
586  rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", fn);
587  continue;
588  }
589  }
590  (void)poptReadConfigFile(optCon, fn);
591  av[i] = _free(av[i]);
592  }
593  av = _free(av);
594  }
595  path_buf = _free(path_buf);
596  }
597 #else
598  /* XXX FIXME: better error message is needed. */
599  if ((xx = poptReadConfigFiles(optCon, rpmpoptfiles)) != 0)
600  rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", rpmpoptfiles);
601 #endif
602 
603  /* read standard POPT configuration files */
604  /* XXX FIXME: the 2nd arg useEnv flag is UNUSED. */
605  (void) poptReadDefaultConfig(optCon, 1);
606 
607  poptSetExecPath(optCon, USRLIBRPM, 1);
608 #endif /* NOTYET */
609 
610  /* Process all options, whine if unknown. */
611  while ((rc = poptGetNextOpt(optCon)) > 0) {
612  const char * optArg = poptGetOptArg(optCon);
613 /*@-dependenttrans -modobserver -observertrans @*/
614  optArg = _free(optArg);
615 /*@=dependenttrans =modobserver =observertrans @*/
616  switch (rc) {
617  default:
618 /*@-nullpass@*/
619  fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
620  __progname, rc);
621 /*@=nullpass@*/
622  exit(EXIT_FAILURE);
623 
624  /*@notreached@*/ /*@switchbreak@*/ break;
625  }
626  }
627 
628  if (rc < -1) {
629 /*@-nullpass@*/
630  fprintf(stderr, "%s: %s: %s\n", __progname,
631  poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
632  poptStrerror(rc));
633 /*@=nullpass@*/
634  exit(EXIT_FAILURE);
635  }
636 
637  /* Read rpm configuration (if not already read). */
638  rpmioConfigured();
639 
640  if (__debug) {
643  }
644 
645  return optCon;
646 }
647 /*@=globstate@*/