rpm 5.3.7

lib/poptI.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <rpmio.h>
00009 #include <rpmiotypes.h>
00010 #include <rpmlog.h>
00011 
00012 #include <rpmtag.h>
00013 #include <rpmcli.h>
00014 
00015 #include "debug.h"
00016 
00017 /*@-redecl@*/
00018 extern time_t get_date(const char * p, void * now);     /* XXX expedient lies */
00019 /*@=redecl@*/
00020 
00021 /*@-fullinitblock@*/
00022 /*@unchecked@*/
00023 struct rpmQVKArguments_s rpmIArgs = {
00024 #if defined(RPM_VENDOR_MANDRIVA) /* dont-filter-install-file-conflicts */
00025     .probFilter = RPMPROB_FILTER_NONE,
00026 #else
00027     .probFilter = (RPMPROB_FILTER_REPLACEOLDFILES | RPMPROB_FILTER_REPLACENEWFILES),
00028 #endif
00029 };
00030 /*@=fullinitblock@*/
00031 
00032 #define POPT_RELOCATE           -1021
00033 #define POPT_EXCLUDEPATH        -1022
00034 #define POPT_ROLLBACK           -1023
00035 #define POPT_ROLLBACK_EXCLUDE   -1024
00036 /* -1025 thrugh -1033 are common in rpmcli.h. */
00037 #define POPT_AUTOROLLBACK_GOAL  -1036
00038 
00039 #define alloca_strdup(_s)       strcpy(alloca(strlen(_s)+1), (_s))
00040 
00046 static void argerror(const char * desc) __attribute__((__noreturn__));
00047 /*@exits@*/
00048 static void argerror(const char * desc)
00049         /*@globals stderr, fileSystem @*/
00050         /*@modifies stderr, fileSystem @*/
00051 {
00052     /*@-modfilesys -globs @*/
00053     fprintf(stderr, _("%s: %s\n"), __progname, desc);
00054     /*@=modfilesys =globs @*/
00055     exit(EXIT_FAILURE);
00056 }
00057 
00060 static void installArgCallback(/*@unused@*/ poptContext con,
00061                 /*@unused@*/ enum poptCallbackReason reason,
00062                 const struct poptOption * opt, const char * arg,
00063                 /*@unused@*/ const void * data)
00064         /*@globals rpmIArgs, stderr @*/
00065         /*@modifies rpmIArgs, stderr @*/
00066 {
00067     QVA_t ia = &rpmIArgs;
00068     int xx;
00069 
00070     /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
00071     if (opt->arg == NULL)
00072     switch (opt->val) {
00073 
00074     case 'i':
00075         ia->installInterfaceFlags |= INSTALL_INSTALL;
00076         break;
00077 
00078     case POPT_EXCLUDEPATH:
00079         if (arg == NULL || *arg != '/') 
00080             argerror(_("exclude paths must begin with a /"));
00081         xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, arg, NULL);
00082         break;
00083     case POPT_RELOCATE:
00084       { char * oldPath = NULL;
00085         char * newPath = NULL;
00086         
00087         if (arg == NULL) 
00088             argerror(_("Option --relocate needs /old/path=/new/path argument"));
00089         if (*arg != '/') 
00090             argerror(_("relocations must begin with a /"));
00091         oldPath = xstrdup(arg);
00092         if (!(newPath = strchr(oldPath, '=')))
00093             argerror(_("relocations must contain a ="));
00094         *newPath++ = '\0';
00095         if (*newPath != '/') 
00096             argerror(_("relocations must have a / following the ="));
00097         xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
00098                         oldPath, newPath);
00099         oldPath = _free(oldPath);
00100       } break;
00101 
00102     case POPT_ROLLBACK_EXCLUDE:
00103     {   rpmuint32_t tid;
00104         char *t, *te;
00105 
00106         /* Make sure we were given the proper number of args */
00107         if (arg == NULL)
00108             argerror(_("Option --rbexclude needs transaction id argument(s)"));
00109 
00110         te = alloca_strdup(arg);
00111         while (*te != '\0' && strchr(" \t\n,", *te) != NULL)
00112             *te++ = '\0';
00113         while ((t = te++) != NULL && *t != '\0') {
00114             /* Find next tid. */
00115             while (*te != '\0' && strchr(" \t\n,", *te) == NULL)
00116                 te++;
00117             while (*te != '\0' && strchr(" \t\n,", *te) != NULL)
00118                 *te++ = '\0';
00119 
00120             /* Convert arg to TID which happens to be time_t */
00121             /* XXX: Need check for arg to be an integer      */
00122             tid = (rpmuint32_t) strtol(t, NULL, 0);
00123 
00124             /* Allocate space for new exclude tid */
00125             ia->rbtidExcludes = xrealloc(ia->rbtidExcludes, 
00126                 sizeof(*ia->rbtidExcludes) * (ia->numrbtidExcludes + 1));
00127 
00128             /* Add it to the list and iterate count*/
00129 /*@-temptrans@*/
00130             ia->rbtidExcludes[ia->numrbtidExcludes] = tid;
00131 /*@=temptrans@*/
00132             ia->numrbtidExcludes++;
00133         }
00134     } break;
00135 
00136     case POPT_ROLLBACK:
00137       { time_t tid;
00138         if (arg == NULL)
00139             argerror(_("Option --rollback needs a time/date stamp argument"));
00140 
00141         /*@-moduncon@*/
00142         tid = get_date(arg, NULL);
00143         rpmlog(RPMLOG_INFO, _("Rollback goal:  %-24.24s (0x%08x)\n"), ctime(&tid), (int)tid);
00144         /*@=moduncon@*/
00145 
00146         if (tid == (time_t)-1 || tid == (time_t)0)
00147             argerror(_("malformed rollback time/date stamp argument"));
00148         ia->rbtid = (rpmuint32_t)tid;
00149       } break;
00150     
00151     case POPT_AUTOROLLBACK_GOAL:
00152       { time_t tid;
00153         if (arg == NULL)
00154             argerror(_("arbgoal takes a time/date stamp argument"));
00155 
00156         /*@-moduncon@*/
00157         tid = get_date(arg, NULL);
00158         /*@=moduncon@*/
00159 
00160         if (tid == (time_t)-1 || tid == (time_t)0)
00161             argerror(_("malformed arbgoal time/date stamp argument"));
00162         ia->arbtid = (rpmuint32_t)tid;
00163       } break;
00164 
00165     case RPMCLI_POPT_NODIGEST:
00166         ia->qva_flags |= VERIFY_DIGEST;
00167         break;
00168 
00169     case RPMCLI_POPT_NOSIGNATURE:
00170         ia->qva_flags |= VERIFY_SIGNATURE;
00171         break;
00172 
00173     case RPMCLI_POPT_NOHDRCHK:
00174         ia->qva_flags |= VERIFY_HDRCHK;
00175         break;
00176 
00177     case RPMCLI_POPT_NODEPS:
00178         ia->noDeps = 1;
00179         break;
00180 
00181     case RPMCLI_POPT_NOCONTEXTS:
00182         ia->transFlags |= RPMTRANS_FLAG_NOCONTEXTS;
00183         break;
00184 
00185     case RPMCLI_POPT_NOSCRIPTS:
00186         ia->transFlags |= (_noTransScripts|_noTransTriggers);
00187         break;
00188 
00189     case RPMCLI_POPT_NOFDIGESTS:
00190         ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
00191         break;
00192 
00193     }
00194 }
00195 
00198 /*@-bitwisesigned -compmempass @*/
00199 /*@unchecked@*/
00200 struct poptOption rpmInstallPoptTable[] = {
00201 /*@-type@*/ /* FIX: cast? */
00202  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
00203         installArgCallback, 0, NULL, NULL },
00204 /*@=type@*/
00205 
00206  { "allfiles", '\0', POPT_BIT_SET,
00207         &rpmIArgs.transFlags, RPMTRANS_FLAG_ALLFILES,
00208   N_("install all files, even configurations which might otherwise be skipped"),
00209         NULL},
00210  { "apply", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &rpmIArgs.transFlags,
00211         (_noTransScripts|_noTransTriggers|
00212                 RPMTRANS_FLAG_APPLYONLY|RPMTRANS_FLAG_PKGCOMMIT),
00213         N_("do not execute package scriptlet(s)"), NULL },
00214  { "dirstash", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00215         &rpmIArgs.transFlags, RPMTRANS_FLAG_DIRSTASH,
00216         N_("save erased package files by renaming into sub-directory"), NULL},
00217  { "excludeconfigs", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00218         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOCONFIGS,
00219         N_("do not install configuration files"), NULL},
00220  { "excludedocs", '\0', POPT_BIT_SET,
00221         &rpmIArgs.transFlags, RPMTRANS_FLAG_NODOCS,
00222         N_("do not install documentation"), NULL},
00223  { "justdb", '\0', POPT_BIT_SET, &rpmIArgs.transFlags, RPMTRANS_FLAG_JUSTDB,
00224         N_("update the database, but do not modify the filesystem"), NULL},
00225  { "noconfigs", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00226         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOCONFIGS,
00227         N_("do not install configuration files"), NULL},
00228  { "nodocs", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00229         &rpmIArgs.transFlags, RPMTRANS_FLAG_NODOCS,
00230         N_("do not install documentation"), NULL},
00231 #ifdef  NOTYET  /* XXX multiple identical options forces popt callback. */
00232  { "nocontexts", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00233         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOCONTEXTS,
00234         N_("don't install file security contexts"), NULL},
00235  { "nofdigests", '\0', POPT_BIT_SET,
00236         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOFDIGESTS,
00237         N_("don't verify file digests"), NULL },
00238 #else
00239   { "nocontexts", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOCONTEXTS,
00240         N_("don't verify file security contexts"), NULL },
00241   { "nofdigests", '\0', 0, NULL, RPMCLI_POPT_NOFDIGESTS,
00242         N_("don't verify file digests"), NULL },
00243 #endif
00244  { "norpmdb", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00245         &rpmIArgs.transFlags, RPMTRANS_FLAG_NORPMDB,
00246         N_("don't register headers in rpmdb"), NULL},
00247 
00248 #ifdef  NOTYET  /* XXX multiple identical options forces popt callback. */
00249  { "noscripts", '\0', POPT_BIT_SET,
00250         &rpmIArgs.transFlags, (_noTransScripts|_noTransTriggers),
00251         N_("do not execute package scriptlet(s)"), NULL },
00252 #else
00253   { "noscripts", '\0', 0, NULL, RPMCLI_POPT_NOSCRIPTS,
00254         N_("do not execute package scriptlet(s)"), NULL },
00255 #endif
00256  { "nopretrans", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00257         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPRETRANS,
00258         N_("do not execute %%pretrans scriptlet (if any)"), NULL },
00259  { "nopre", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00260         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPRE,
00261         N_("do not execute %%pre scriptlet (if any)"), NULL },
00262  { "nopost", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00263         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPOST,
00264         N_("do not execute %%post scriptlet (if any)"), NULL },
00265  { "nopreun", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00266         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPREUN,
00267         N_("do not execute %%preun scriptlet (if any)"), NULL },
00268  { "nopostun", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00269         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPOSTUN,
00270         N_("do not execute %%postun scriptlet (if any)"), NULL },
00271  { "noposttrans", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00272         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPOSTTRANS,
00273         N_("do not execute %%postrans scriptlet (if any)"), NULL },
00274 
00275  { "notriggers", '\0', POPT_BIT_SET, &rpmIArgs.transFlags, _noTransTriggers,
00276         N_("do not execute any scriptlet(s) triggered by this package"), NULL},
00277  { "notriggerprein", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00278         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOTRIGGERPREIN,
00279         N_("do not execute any %%triggerprein scriptlet(s)"), NULL},
00280  { "notriggerin", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00281         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOTRIGGERIN,
00282         N_("do not execute any %%triggerin scriptlet(s)"), NULL},
00283  { "notriggerun", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00284         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOTRIGGERUN,
00285         N_("do not execute any %%triggerun scriptlet(s)"), NULL},
00286  { "notriggerpostun", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00287         &rpmIArgs.transFlags, RPMTRANS_FLAG_NOTRIGGERPOSTUN,
00288         N_("do not execute any %%triggerpostun scriptlet(s)"), NULL},
00289 
00290  { "repackage", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
00291         &rpmIArgs.transFlags, RPMTRANS_FLAG_REPACKAGE,
00292         N_("save erased package files by repackaging"), NULL},
00293  { "test", '\0', POPT_BIT_SET, &rpmIArgs.transFlags, RPMTRANS_FLAG_TEST,
00294         N_("don't install, but tell if it would work or not"), NULL},
00295 
00296  { "allmatches", '\0', POPT_BIT_SET,
00297         &rpmIArgs.installInterfaceFlags, INSTALL_ALLMATCHES,
00298         N_("remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)"),
00299         NULL},
00300 
00301  { "badreloc", '\0', POPT_BIT_SET,
00302         &rpmIArgs.probFilter, RPMPROB_FILTER_FORCERELOCATE,
00303         N_("relocate files in non-relocatable package"), NULL},
00304 
00305  { "erase", 'e', POPT_BIT_SET,
00306         &rpmIArgs.installInterfaceFlags, INSTALL_ERASE,
00307         N_("erase (uninstall) package"), N_("<package>+") },
00308  { "excludepath", '\0', POPT_ARG_STRING, NULL, POPT_EXCLUDEPATH,
00309         N_("skip files with leading component <path> "),
00310         N_("<path>") },
00311 
00312  { "fileconflicts", '\0', POPT_BIT_CLR, &rpmIArgs.probFilter,
00313         (RPMPROB_FILTER_REPLACEOLDFILES | RPMPROB_FILTER_REPLACENEWFILES),
00314         N_("detect file conflicts between packages"), NULL},
00315 
00316  { "freshen", 'F', POPT_BIT_SET, &rpmIArgs.installInterfaceFlags,
00317         (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL),
00318         N_("upgrade package(s) if already installed"),
00319         N_("<packagefile>+") },
00320  { "hash", 'h', POPT_BIT_SET, &rpmIArgs.installInterfaceFlags, INSTALL_HASH,
00321         N_("print hash marks as package installs (good with -v)"), NULL},
00322 #ifndef DIEDIEDIE
00323  { "ignorearch", '\0', POPT_BIT_SET,
00324         &rpmIArgs.probFilter, RPMPROB_FILTER_IGNOREARCH,
00325         N_("don't verify package architecture"), NULL},
00326  { "ignoreos", '\0', POPT_BIT_SET,
00327         &rpmIArgs.probFilter, RPMPROB_FILTER_IGNOREOS,
00328         N_("don't verify package operating system"), NULL},
00329 #endif
00330  { "ignoresize", '\0', POPT_BIT_SET, &rpmIArgs.probFilter,
00331         (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES),
00332         N_("don't check disk space before installing"), NULL},
00333  { "includedocs", '\0', POPT_ARGFLAG_DOC_HIDDEN, &rpmIArgs.incldocs, 0,
00334         N_("install documentation"), NULL},
00335 
00336  { "install", 'i', 0, NULL, 'i',
00337         N_("install package(s)"), N_("<packagefile>+") },
00338 
00339  { "nodeps", '\0', 0, NULL, RPMCLI_POPT_NODEPS,
00340         N_("do not verify package dependencies"), NULL },
00341 
00342  { "noorder", '\0', POPT_BIT_SET,
00343         &rpmIArgs.installInterfaceFlags, INSTALL_NOORDER,
00344         N_("do not reorder package installation to satisfy dependencies"),
00345         NULL},
00346 
00347  { "nodigest", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NODIGEST,
00348         N_("don't verify package digest(s)"), NULL },
00349  { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOHDRCHK,
00350         N_("don't verify database header(s) when retrieved"), NULL },
00351  { "nosignature", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOSIGNATURE,
00352         N_("don't verify package signature(s)"), NULL },
00353 
00354  { "oldpackage", '\0', POPT_BIT_SET,
00355         &rpmIArgs.probFilter, RPMPROB_FILTER_OLDPACKAGE,
00356         N_("upgrade to an old version of the package (--force on upgrades does this automatically)"),
00357         NULL},
00358  { "percent", '\0', POPT_BIT_SET,
00359         &rpmIArgs.installInterfaceFlags, INSTALL_PERCENT,
00360         N_("print percentages as package installs"), NULL},
00361  { "prefix", '\0', POPT_ARG_STRING, &rpmIArgs.qva_prefix, 0,
00362         N_("relocate the package to <dir>, if relocatable"),
00363         N_("<dir>") },
00364  { "relocate", '\0', POPT_ARG_STRING, NULL, POPT_RELOCATE,
00365         N_("relocate files from path <old> to <new>"),
00366         N_("<old>=<new>") },
00367  { "replacefiles", '\0', POPT_BIT_SET, &rpmIArgs.probFilter,
00368         (RPMPROB_FILTER_REPLACEOLDFILES | RPMPROB_FILTER_REPLACENEWFILES),
00369         N_("ignore file conflicts between packages"), NULL},
00370  { "replacepkgs", '\0', POPT_BIT_SET,
00371         &rpmIArgs.probFilter, RPMPROB_FILTER_REPLACEPKG,
00372         N_("reinstall if the package is already present"), NULL},
00373  { "rollback", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_ROLLBACK,
00374         N_("deinstall new, reinstall old, package(s), back to <date>"),
00375         N_("<date>") },
00376  { "arbgoal", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_AUTOROLLBACK_GOAL,
00377         N_("If transaction fails rollback to <date>"),
00378         N_("<date>") },
00379  { "rbexclude", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_ROLLBACK_EXCLUDE,
00380         N_("Exclude Transaction I.D. from rollback"),
00381         N_("<tid>") },
00382  { "upgrade", 'U', POPT_BIT_SET,
00383         &rpmIArgs.installInterfaceFlags, (INSTALL_UPGRADE|INSTALL_INSTALL),
00384         N_("upgrade package(s)"),
00385         N_("<packagefile>+") },
00386 
00387    POPT_TABLEEND
00388 };
00389 /*@=bitwisesigned =compmempass @*/