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