rpm 5.3.7
|
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 @*/