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