rpm  5.2.1
poptALL.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 extern const char *__progname;
8 
9 #if defined(RPM_VENDOR_WINDRIVER)
10 const char *__usrlibrpm = USRLIBRPM;
11 const char *__etcrpm = SYSCONFIGDIR;
12 #endif
13 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
14 const char *__localedir = LOCALEDIR;
15 #endif
16 
17 #define _RPMIOB_INTERNAL
18 #include <rpmio.h>
19 #include <rpmiotypes.h>
20 #include <fts.h>
21 #include <mire.h>
22 #include <poptIO.h>
23 
24 #include <rpmjs.h>
25 #include <rpmruby.h>
26 
27 #include <rpmtag.h>
28 #include <rpmtypes.h>
29 #include <rpmrc.h>
30 #include <rpmversion.h>
31 #include <rpmcli.h>
32 
33 #include <rpmns.h> /* XXX rpmnsClean() */
34 
35 #include <fs.h> /* XXX rpmFreeFilesystems() */
36 
37 #include "debug.h"
38 
39 /*@unchecked@*/ /*@only@*/ /*@null@*/
40 extern unsigned int * keyids;
41 
42 #define POPT_SHOWVERSION -999
43 #define POPT_SHOWRC -998
44 #define POPT_QUERYTAGS -997
45 #define POPT_PREDEFINE -996
46 #define POPT_UNDEFINE -994
47 
48 /*@access headerTagIndices @*/ /* XXX rpmcliFini */
49 /*@access headerTagTableEntry @*/ /* XXX rpmcliFini */
50 
51 /*@unchecked@*/
52 static int _debug = 0;
53 
54 /*@-exportheadervar@*/
55 /*@unchecked@*/
56 extern int _rpmds_nopromote;
57 
58 /*@unchecked@*/
59 extern int _fps_debug;
60 
61 /*@unchecked@*/
62 extern int _fsm_debug;
63 
64 /*@unchecked@*/
65 extern int _fsm_threads;
66 
67 /*@unchecked@*/
68 extern int _hdr_debug;
69 /*@unchecked@*/
70 extern int _hdrqf_debug;
71 
72 /*@unchecked@*/
73 extern int _pkgio_debug;
74 
75 /*@unchecked@*/
76 extern int _print_pkts;
77 
78 /*@unchecked@*/
79 extern int _psm_debug;
80 /*@unchecked@*/
81 extern rpmioPool _psmPool;
82 
83 /*@unchecked@*/
84 extern int _psm_threads;
85 
86 /*@unchecked@*/
87 extern int _rpmal_debug;
88 
89 /*@unchecked@*/
90 extern int _rpmdb_debug;
91 
92 /*@unchecked@*/
93 extern int _rpmds_debug;
94 /*@unchecked@*/
95 extern rpmioPool _rpmdsPool;
96 
97 /*@unchecked@*/
99 /*@unchecked@*/
100 extern rpmioPool _rpmfcPool;
101 
102 /*@unchecked@*/
103 extern int _rpmfi_debug;
104 /*@unchecked@*/
105 extern rpmioPool _rpmfiPool;
106 
107 /*@unchecked@*/
108 extern int _rpmgi_debug;
109 /*@unchecked@*/
110 extern rpmioPool _rpmgiPool;
111 
112 /*@unchecked@*/
113 extern int _rpmmi_debug;
114 
115 /*@unchecked@*/
116 extern int _rpmps_debug;
117 /*@unchecked@*/
118 extern rpmioPool _rpmpsPool;
119 
120 /*@unchecked@*/
121 extern int _rpmsq_debug;
122 
123 /*@unchecked@*/
124 extern int _rpmsx_debug;
125 /*@unchecked@*/
126 extern rpmioPool _rpmsxPool;
127 
128 /*@unchecked@*/
129 extern int _rpmte_debug;
130 /*@unchecked@*/
131 extern rpmioPool _rpmtePool;
132 /*@unchecked@*/
133 extern rpmioPool _rpmtsiPool;
134 
135 /*@unchecked@*/
136 extern int _rpmts_debug;
137 /*@unchecked@*/
138 extern rpmioPool _rpmtsPool;
139 
140 /*@unchecked@*/
141 extern int _rpmwf_debug;
142 
143 /*@unchecked@*/
144 extern int _rpmts_macros;
145 
146 /*@unchecked@*/
147 extern int _rpmts_stats;
148 
149 /*@unchecked@*/
150 extern int _hdr_stats;
151 
152 /*@unchecked@*/
154 
155 /*@unchecked@*/ /*@null@*/
156 const char * rpmcliTargets = NULL;
157 
158 /*@unchecked@*/
159 static int rpmcliInitialized = -1;
160 
161 #ifdef WITH_LUA
162 /*@unchecked@*/
163 extern const char *rpmluaFiles;
164 #endif
165 
166 /*@-readonlytrans@*/ /* argv loading prevents observer, xstrdup needed. */
167 /*@unchecked@*/
168 static char *rpmpoptfiles = RPMPOPTFILES;
169 /*@=readonlytrans@*/
170 
174 static void printVersion(FILE * fp)
175  /*@globals rpmEVR, fileSystem, internalState @*/
176  /*@modifies *fp, fileSystem, internalState @*/
177 {
178  fprintf(fp, _("%s (" RPM_NAME ") %s\n"), __progname, rpmEVR);
179  if (rpmIsVerbose())
180  fprintf(fp, "rpmlib 0x%08x,0x%08x,0x%08x\n", (unsigned)rpmlibVersion(),
181  (unsigned)rpmlibTimestamp(), (unsigned)rpmlibVendor());
182 }
183 
185  /*@globals rpmcliInitialized, rpmCLIMacroContext, rpmGlobalMacroContext,
186  h_errno, fileSystem, internalState @*/
187  /*@modifies rpmcliInitialized, rpmCLIMacroContext, rpmGlobalMacroContext,
188  fileSystem, internalState @*/
189 {
190 
191  if (rpmcliInitialized < 0) {
192  char * t = NULL;
193  if (rpmcliTargets != NULL) {
194  char *te;
195  t = xstrdup(rpmcliTargets);
196  if ((te = strchr(t, ',')) != NULL)
197  *te = '\0';
198  }
200  t = _free(t);
201  }
202  if (rpmcliInitialized)
203  exit(EXIT_FAILURE);
204 }
205 
206 /* ========== all-rpm-modes popt args */
207 
208 static const char * rpmcliEvalSlurp(const char * arg)
209  /*@*/
210 {
211  const char * pre = "";
212  const char * post = "";
213  rpmiob iob = NULL;
214  const char * val = NULL;
215  struct stat sb;
216  int xx;
217 
218  if (!strcmp(arg, "-")) { /* Macros from stdin arg. */
219  xx = rpmiobSlurp(arg, &iob);
220  } else
221  if ((arg[0] == '/' || strchr(arg, ' ') == NULL)
222  && !Stat(arg, &sb)
223  && S_ISREG(sb.st_mode)) { /* Macros from a file arg. */
224  xx = rpmiobSlurp(arg, &iob);
225  } else { /* Macros from string arg. */
226  iob = rpmiobAppend(rpmiobNew(strlen(arg)+1), arg, 0);
227  }
228 
229  val = rpmExpand(pre, iob->b, post, NULL);
230  iob = rpmiobFree(iob);
231  return val;
232 }
233 
236 static void rpmcliAllArgCallback(poptContext con,
237  /*@unused@*/ enum poptCallbackReason reason,
238  const struct poptOption * opt, const char * arg,
239  /*@unused@*/ const void * data)
240  /*@globals pgpDigVSFlags, rpmcliTargets, rpmcliQueryFlags, rpmCLIMacroContext,
241  rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
242  /*@modifies con, pgpDigVSFlags, rpmcliTargets, rpmcliQueryFlags, rpmCLIMacroContext,
243  rpmGlobalMacroContext, fileSystem, internalState @*/
244 {
245 
246  /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
247  if (opt->arg == NULL)
248  switch (opt->val) {
249  case POPT_PREDEFINE:
250  (void) rpmDefineMacro(NULL, arg, RMIL_CMDLINE);
251  break;
252  case 'D':
253  { char *s, *t;
254  /* XXX Convert '-' in macro name to underscore, skip leading %. */
255  s = t = xstrdup(arg);
256  while (*t && !xisspace(*t)) {
257  if (*t == '-') *t = '_';
258  t++;
259  }
260  t = s;
261  if (*t == '%') t++;
263 /*@-type@*/
264  /* XXX adding macro to global context isn't Right Thing Todo. */
265  (void) rpmDefineMacro(NULL, t, RMIL_CMDLINE);
267 /*@=type@*/
268  s = _free(s);
269  } break;
270  case POPT_UNDEFINE:
271  { char *s, *t;
272  /* XXX Convert '-' in macro name to underscore, skip leading %. */
273  s = t = xstrdup(arg);
274  while (*t && !xisspace(*t)) {
275  if (*t == '-') *t = '_';
276  t++;
277  }
278  t = s;
279  if (*t == '%') t++;
280 /*@-type@*/
282  (void) rpmUndefineMacro(NULL, t);
284 /*@=type@*/
285  s = _free(s);
286  } break;
287  case 'E':
288 assert(arg != NULL);
290  { const char * val = rpmcliEvalSlurp(arg);
291  size_t val_len = fwrite(val, strlen(val), 1, stdout);
292  if (val[val_len - 1] != '\n')
293  fprintf(stdout, "\n");
294  val = _free(val);
295  } break;
296  case POPT_SHOWVERSION:
297  printVersion(stdout);
298 /*@i@*/ con = rpmcliFini(con);
299  exit(EXIT_SUCCESS);
300  /*@notreached@*/ break;
301  case POPT_SHOWRC:
303  (void) rpmShowRC(stdout);
304 /*@i@*/ con = rpmcliFini(con);
305  exit(EXIT_SUCCESS);
306  /*@notreached@*/ break;
307  case POPT_QUERYTAGS:
308  rpmDisplayQueryTags(NULL, NULL, NULL);
309 /*@i@*/ con = rpmcliFini(con);
310  exit(EXIT_SUCCESS);
311  /*@notreached@*/ break;
315  break;
316 
320  break;
321 
325  break;
326 
328  if (rpmcliTargets == NULL)
329  rpmcliTargets = xstrdup(arg);
330  else {
331 /*@-modobserver @*/
332  char * t = (char *) rpmcliTargets;
333  size_t nb = strlen(t) + (sizeof(",")-1) + strlen(arg) + 1;
334 /*@i@*/ t = xrealloc(t, nb);
335  (void) stpcpy( stpcpy(t, ","), arg);
336  rpmcliTargets = t;
337 /*@=modobserver @*/
338  }
339  break;
340  }
341 }
342 
343 /*@unchecked@*/
345 
346 /*@unchecked@*/
347 struct poptOption rpmcliDepFlagsPoptTable[] = {
348  { "aid", '\0', POPT_BIT_SET, &global_depFlags, RPMDEPS_FLAG_ADDINDEPS,
349  N_("Add suggested packages to transaction"), NULL },
350  { "anaconda", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
352  N_("Use anaconda \"presentation order\""), NULL},
353  { "deploops", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
355  N_("Print dependency loops as warning"), NULL},
356  { "nosuggest", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
358  N_("Do not suggest missing dependency resolution(s)"), NULL},
359  { "noconflicts", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
361  N_("Do not check added package conflicts"), NULL},
362  { "nolinktos", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
364  N_("Ignore added package requires on symlink targets"), NULL},
365  { "noobsoletes", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
367  N_("Ignore added package obsoletes"), NULL},
368  { "noparentdirs", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
370  N_("Ignore added package requires on file parent directory"), NULL},
371  { "norequires", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
373  N_("Do not check added package requires"), NULL},
374  { "noupgrade", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
376  N_("Ignore added package upgrades"), NULL},
377  POPT_TABLEEND
378 };
379 
380 /*@-bitwisesigned -compmempass @*/
381 /*@unchecked@*/
382 struct poptOption rpmcliAllPoptTable[] = {
383 /*@-type@*/ /* FIX: cast? */
384  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
385  rpmcliAllArgCallback, 0, NULL, NULL },
386 /*@=type@*/
387 
388  { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_debug, -1,
389  N_("Debug generic operations"), NULL},
390 
391  { "predefine", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_PREDEFINE,
392  N_("Predefine MACRO with value EXPR"),
393  N_("'MACRO EXPR'") },
394 
395  { "define", 'D', POPT_ARG_STRING, NULL, 'D',
396  N_("Define MACRO with value EXPR"),
397  N_("'MACRO EXPR'") },
398  { "undefine", '\0', POPT_ARG_STRING, NULL, POPT_UNDEFINE,
399  N_("Undefine MACRO"),
400  N_("'MACRO'") },
401  { "eval", 'E', POPT_ARG_STRING, NULL, 'E',
402  N_("Print macro expansion of EXPR"),
403  N_("'EXPR'") },
404  { "macros", '\0', POPT_ARG_STRING, &rpmMacrofiles, 0,
405  N_("Read <FILE:...> instead of default file(s)"),
406  N_("<FILE:...>") },
407 #ifdef WITH_LUA
408  { "rpmlua", '\0', POPT_ARG_STRING, &rpmluaFiles, 0,
409  N_("Read <FILE:...> instead of default RPM Lua file(s)"),
410  N_("<FILE:...>") },
411 #endif
412  { "rpmpopt", '\0', POPT_ARG_STRING, NULL, 0,
413  N_("Read <FILE:...> instead of default POPT file(s)"),
414  N_("<FILE:...>") },
415 
416  { "target", '\0', POPT_ARG_STRING, NULL, RPMCLI_POPT_TARGETPLATFORM,
417  N_("Specify target platform"), N_("CPU-VENDOR-OS") },
418 
419  { "nodigest", '\0', 0, NULL, RPMCLI_POPT_NODIGEST,
420  N_("Don't verify package digest(s)"), NULL },
421  { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOHDRCHK,
422  N_("Don't verify database header(s) when retrieved"), NULL },
423  { "nosignature", '\0', 0, NULL, RPMCLI_POPT_NOSIGNATURE,
424  N_("Don't verify package signature(s)"), NULL },
425 
426  { "querytags", '\0', 0, NULL, POPT_QUERYTAGS,
427  N_("Display known query tags"), NULL },
428  { "showrc", '\0', 0, NULL, POPT_SHOWRC,
429  N_("Display macro and configuration values"), NULL },
430  { "version", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_SHOWVERSION,
431  N_("Print the version"), NULL },
432 
433  { "promoteepoch", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_nopromote, 0,
434  NULL, NULL},
435 
436  { "fpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fps_debug, -1,
437  N_("Debug file FingerPrintS"), NULL},
438  { "fsmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_debug, -1,
439  N_("Debug payload File State Machine"), NULL},
440  { "fsmthreads", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_threads, -1,
441  N_("Use threads for File State Machine"), NULL},
442  { "hdrdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_hdr_debug, -1,
443  NULL, NULL},
444  { "hdrqfdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_hdrqf_debug, -1,
445  NULL, NULL},
446  { "macrosused", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_macros, -1,
447  N_("Display macros used"), NULL},
448  { "pkgiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_pkgio_debug, -1,
449  NULL, NULL},
450  { "prtpkts", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_print_pkts, -1,
451  N_("Display OpenPGP (RFC 2440/4880) parsing"), NULL},
452  { "psmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_psm_debug, -1,
453  N_("Debug Package State Machine"), NULL},
454  { "psmthreads", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_psm_threads, -1,
455  N_("Use threads for Package State Machine"), NULL},
456  { "rpmdbdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmdb_debug, -1,
457  N_("Debug rpmdb DataBase"), NULL},
458  { "rpmdsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_debug, -1,
459  N_("Debug rpmds Dependency Set"), NULL},
460  { "rpmfcdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfc_debug, -1,
461  N_("Debug rpmfc File Classifier"), NULL},
462  { "rpmfidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfi_debug, -1,
463  N_("Debug rpmfi File Info"), NULL},
464  { "rpmgidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmgi_debug, -1,
465  N_("Debug rpmgi Generalized Iterator"), NULL},
466  { "rpmmidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmmi_debug, -1,
467  N_("Debug rpmmi Match Iterator"), NULL},
468  { "rpmnsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmns_debug, -1,
469  N_("Debug rpmns Name Space"), NULL},
470  { "rpmpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmps_debug, -1,
471  N_("Debug rpmps Problem Set"), NULL},
472  { "rpmsxdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsx_debug, -1,
473  N_("Debug rpmsx SELinux Xattrs"), NULL},
474  { "rpmtedebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmte_debug, -1,
475  N_("Debug rpmte Transaction Element"), NULL},
476  { "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1,
477  N_("Debug rpmts Transaction Set"), NULL},
478  { "rpmwfdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmwf_debug, -1,
479  N_("Debug rpmwf Wrapper Format"), NULL},
480  { "stats", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_stats, -1,
481  N_("Display operation statistics"), NULL},
482 
483  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
484  NULL, NULL},
485 
486  POPT_TABLEEND
487 };
488 /*@=bitwisesigned =compmempass @*/
489 
490 poptContext
491 rpmcliFini(poptContext optCon)
492  /*@globals keyids @*/
493  /*@modifies keyids @*/
494 {
495 /*@-nestedextern@*/
496  extern rpmioPool _rpmjsPool;
497  extern rpmioPool _rpmrubyPool;
498  extern rpmioPool _headerPool;
499  extern rpmioPool _rpmmiPool;
500  extern rpmioPool _rpmdbPool;
501  extern rpmioPool _rpmwfPool;
502  extern const char * evr_tuple_order;
503  extern const char * evr_tuple_match;
504  extern miRE evr_tuple_mire;
505 /*@=nestedextern@*/
506 
507 /*@-mods@*/
508  evr_tuple_order = _free(evr_tuple_order);
509  evr_tuple_match = _free(evr_tuple_match);
510  evr_tuple_mire = mireFree(evr_tuple_mire);
511 
512 /*@-onlyunqglobaltrans@*/
513  /* Realease (and dereference) embedded interpreter global objects first. */
514  _rpmjsI = rpmjsFree(_rpmjsI);
515  _rpmjsPool = rpmioFreePool(_rpmjsPool);
516  _rpmrubyI = rpmrubyFree(_rpmrubyI);
517  _rpmrubyPool = rpmioFreePool(_rpmrubyPool);
518 
519  _rpmgiPool = rpmioFreePool(_rpmgiPool);
520  _rpmmiPool = rpmioFreePool(_rpmmiPool);
521 
522  _psmPool = rpmioFreePool(_psmPool);
523  _rpmtsiPool = rpmioFreePool(_rpmtsiPool);
524 
525  _rpmtsPool = rpmioFreePool(_rpmtsPool);
526  _rpmtePool = rpmioFreePool(_rpmtePool);
527  _rpmpsPool = rpmioFreePool(_rpmpsPool);
528 
529  _rpmfcPool = rpmioFreePool(_rpmfcPool);
530  _rpmsxPool = rpmioFreePool(_rpmsxPool);
531 
532  rpmnsClean();
533 
534  _rpmdsPool = rpmioFreePool(_rpmdsPool);
535  _rpmfiPool = rpmioFreePool(_rpmfiPool);
536 
537  _rpmwfPool = rpmioFreePool(_rpmwfPool);
538  _rpmdbPool = rpmioFreePool(_rpmdbPool);
539  _headerPool = rpmioFreePool(_headerPool);
540 /*@=onlyunqglobaltrans@*/
541 /*@=mods@*/
542 
543  /* XXX this should be done in the rpmioClean() wrapper. */
544  /* keeps memory leak checkers quiet */
545  rpmFreeMacros(NULL);
547 
548  rpmFreeRpmrc(); /* XXX mireFreeAll(platpat) before rpmioFreePool. */
549 
552 
553  keyids = _free(keyids);
554 
555  tagClean(NULL); /* Free header tag indices. */
556 
557  rpmioClean(); /* XXX rpmioFreePool()'s after everything else. */
558 
559  optCon = poptFreeContext(optCon);
560 
561 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
562  /*@-noeffect@*/
563  muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
564  /*@=noeffect@*/
565 #endif
566 
567 /*@-globstate@*/
568  return NULL;
569 /*@=globstate@*/
570 }
571 
572 static inline int checkfd(const char * devnull, int fdno, int flags)
573  /*@*/
574 {
575  struct stat sb;
576  int ret = 0;
577 
578  if (fstat(fdno, &sb) == -1 && errno == EBADF)
579  ret = (open(devnull, flags) == fdno) ? 1 : 2;
580  return ret;
581 }
582 
583 #if defined(RPM_VENDOR_WINDRIVER)
584 void setRuntimeRelocPaths(void)
585 {
586  /*
587  * This is just an example of setting the values using env
588  * variables.... if they're not set, we make sure they get set
589  * for helper apps... We probably want to escape "%" in the path
590  * to avoid macro expansion.. someone might have a % in a path...
591  */
592 
593  __usrlibrpm = getenv("RPM_USRLIBRPM");
594  __etcrpm = getenv("RPM_ETCRPM");
595 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
596  __localedir = getenv("RPM_LOCALEDIR");
597 #endif
598 
599  if ( __usrlibrpm == NULL ) {
600  __usrlibrpm = USRLIBRPM ;
601  setenv("RPM_USRLIBRPM", USRLIBRPM, 0);
602  }
603 
604  if ( __etcrpm == NULL ) {
605  __etcrpm = SYSCONFIGDIR ;
606  setenv("RPM_ETCRPM", SYSCONFIGDIR, 0);
607  }
608 
609 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
610  if ( __localedir == NULL ) {
611  __localedir = LOCALEDIR ;
612  setenv("RPM_LOCALEDIR", LOCALEDIR, 0);
613  }
614 #endif
615 }
616 #endif
617 
618 /*@-globstate@*/
619 poptContext
620 rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
621  /*@globals rpmpoptfiles @*/
622  /*@modifies rpmpoptfiles @*/
623 {
624  poptContext optCon;
625  int rc;
626  int xx;
627  int i;
628 
629 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
630  /*@-noeffect@*/
631  mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
632  /*@=noeffect@*/
633 #endif
634 /*@-globs -mods@*/
635  setprogname(argv[0]); /* Retrofit glibc __progname */
636 
637  /* XXX glibc churn sanity */
638  if (__progname == NULL) {
639  if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
640  else __progname = argv[0];
641  }
642 /*@=globs =mods@*/
643 
644  /* Insure that stdin/stdout/stderr are open, lest stderr end up in rpmdb. */
645  { static const char _devnull[] = "/dev/null";
646 #if defined(STDIN_FILENO)
647  (void) checkfd(_devnull, STDIN_FILENO, O_RDONLY);
648 #endif
649 #if defined(STDOUT_FILENO)
650  (void) checkfd(_devnull, STDOUT_FILENO, O_WRONLY);
651 #endif
652 #if defined(STDERR_FILENO)
653  (void) checkfd(_devnull, STDERR_FILENO, O_WRONLY);
654 #endif
655  }
656 
657 #if defined(RPM_VENDOR_WINDRIVER)
658  (void) setRuntimeRelocPaths();
659 #endif
660 
661 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
662  (void) setlocale(LC_ALL, "" );
663  (void) bindtextdomain(PACKAGE, __localedir);
664  (void) textdomain(PACKAGE);
665 #endif
666 
668 
669  if (optionsTable == NULL) {
670  /* Read rpm configuration (if not already read). */
672  return NULL;
673  }
674 
675  /* read all RPM POPT configuration files */
676  for (i = 1; i < argc; i++) {
677  if (strcmp(argv[i], "--rpmpopt") == 0 && i+1 < argc) {
678  rpmpoptfiles = argv[i+1];
679  break;
680  }
681  else if (strncmp(argv[i], "--rpmpopt=", 10) == 0) {
682  rpmpoptfiles = argv[i]+10;
683  break;
684  }
685  }
686 
687 /*@-nullpass -temptrans@*/
688  optCon = poptGetContext(__progname, argc, (const char **)argv, optionsTable, 0);
689 /*@=nullpass =temptrans@*/
690 
691 #if defined(RPM_VENDOR_OPENPKG) /* stick-with-rpm-file-sanity-checking */ || \
692  !defined(POPT_ERROR_BADCONFIG) /* XXX POPT 1.15 retrofit */
693  { char * path_buf = xstrdup(rpmpoptfiles);
694  char *path;
695  char *path_next;
696 
697  for (path = path_buf; path != NULL && *path != '\0'; path = path_next) {
698  const char **av;
699  int ac;
700 
701  /* locate start of next path element */
702  path_next = strchr(path, ':');
703  if (path_next != NULL && *path_next == ':')
704  *path_next++ = '\0';
705  else
706  path_next = path + strlen(path);
707 
708  /* glob-expand the path element */
709  ac = 0;
710  av = NULL;
711  if ((xx = rpmGlob(path, &ac, &av)) != 0)
712  continue;
713 
714  /* work-off each resulting file from the path element */
715  for (i = 0; i < ac; i++) {
716  const char *fn = av[i];
717  if (fn[0] == '@' /* attention */) {
718  fn++;
719  if (!rpmSecuritySaneFile(fn)) {
720  rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", fn);
721  /*@innercontinue@*/ continue;
722  }
723  }
724  (void) poptReadConfigFile(optCon, fn);
725  av[i] = _free(av[i]);
726  }
727  av = _free(av);
728  }
729  path_buf = _free(path_buf);
730  }
731 #else
732  /* XXX FIXME: better error message is needed. */
733  if ((xx = poptReadConfigFiles(optCon, rpmpoptfiles)) != 0)
734  rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", rpmpoptfiles);
735 #endif
736 
737 #if defined(RPM_VENDOR_WINDRIVER)
738  { const char * poptAliasFn = rpmGetPath(__usrlibrpm, "/rpmpopt", NULL);
739  (void) poptReadConfigFile(optCon, poptAliasFn);
740  poptAliasFn = _free(poptAliasFn);
741  }
742 #endif
743 
744  /* read standard POPT configuration files */
745  /* XXX FIXME: the 2nd arg useEnv flag is UNUSED. */
746  (void) poptReadDefaultConfig(optCon, 1);
747 
748 #if defined(RPM_VENDOR_WINDRIVER)
749  { const char * poptExecPath = rpmGetPath(__usrlibrpm, NULL);
750  poptSetExecPath(optCon, poptExecPath, 1);
751  poptExecPath = _free(poptExecPath);
752  }
753 #else
754  poptSetExecPath(optCon, USRLIBRPM, 1);
755 #endif
756 
757  /* Process all options, whine if unknown. */
758  while ((rc = poptGetNextOpt(optCon)) > 0) {
759  const char * optArg = poptGetOptArg(optCon);
760 /*@-dependenttrans -observertrans@*/ /* Avoid popt memory leaks. */
761  optArg = _free(optArg);
762 /*@=dependenttrans =observertrans @*/
763  switch (rc) {
764  default:
765 /*@-nullpass@*/
766  fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
767  __progname, rc);
768 /*@=nullpass@*/
769  exit(EXIT_FAILURE);
770 
771  /*@notreached@*/ /*@switchbreak@*/ break;
772  }
773  }
774 
775  if (rc < -1) {
776 /*@-nullpass@*/
777  fprintf(stderr, "%s: %s: %s\n", __progname,
778  poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
779  poptStrerror(rc));
780 /*@=nullpass@*/
781  exit(EXIT_FAILURE);
782  }
783 
784  /* Read rpm configuration (if not already read). */
786 
787  if (_debug) {
790  }
791 
792  /* Initialize header stat collection. */
793 /*@-mods@*/
795 /*@=mods@*/
796 
797  return optCon;
798 }
799 /*@=globstate@*/