00001 #include "system.h"
00002 const char *__progname;
00003
00004 #include <rpm/rpmcli.h>
00005 #include <rpm/rpmlib.h>
00006 #include <rpm/rpmlog.h>
00007 #include <rpm/rpmps.h>
00008 #include <rpm/rpmts.h>
00009
00010 #include "cliutils.h"
00011
00012 #include "debug.h"
00013
00014 #if defined(IAM_RPMQ) || defined(IAM_RPMV)
00015 #define IAM_RPMQV
00016 #endif
00017
00018 enum modes {
00019
00020 MODE_QUERY = (1 << 0),
00021 MODE_VERIFY = (1 << 3),
00022 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
00023
00024 MODE_INSTALL = (1 << 1),
00025 MODE_ERASE = (1 << 2),
00026 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
00027
00028 MODE_UNKNOWN = 0
00029 };
00030
00031 #define MODES_FOR_NODEPS (MODES_IE | MODE_VERIFY)
00032 #define MODES_FOR_TEST (MODES_IE)
00033
00034 static int quiet;
00035
00036
00037 static struct poptOption optionsTable[] = {
00038
00039 #ifdef IAM_RPMQV
00040 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
00041 N_("Query/Verify package selection options:"),
00042 NULL },
00043 #endif
00044 #ifdef IAM_RPMQ
00045 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
00046 N_("Query options (with -q or --query):"),
00047 NULL },
00048 #endif
00049 #ifdef IAM_RPMV
00050 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
00051 N_("Verify options (with -V or --verify):"),
00052 NULL },
00053 #endif
00054
00055 #ifdef IAM_RPMEIU
00056 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
00057 N_("Install/Upgrade/Erase options:"),
00058 NULL },
00059 #endif
00060
00061 { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
00062
00063 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
00064 N_("Common options for all rpm modes and executables:"),
00065 NULL },
00066
00067 POPT_AUTOALIAS
00068 POPT_AUTOHELP
00069 POPT_TABLEEND
00070 };
00071
00072 int main(int argc, char *argv[])
00073 {
00074 rpmts ts = NULL;
00075 enum modes bigMode = MODE_UNKNOWN;
00076
00077 #if defined(IAM_RPMQV)
00078 QVA_t qva = &rpmQVKArgs;
00079 #endif
00080
00081 #ifdef IAM_RPMEIU
00082 struct rpmInstallArguments_s * ia = &rpmIArgs;
00083 #endif
00084
00085 poptContext optCon;
00086 int ec = 0;
00087 #ifdef IAM_RPMEIU
00088 int i;
00089 #endif
00090
00091 for (int ac = 1; ac < argc; ac++) {
00092 const char *arg = argv[ac];
00093 if (rstreqn(arg, "-q", 2) || rstreq(arg, "--query")) {
00094 __progname = argv[0] = "rpmquery";
00095 break;
00096 } else if (rstreqn(arg, "-V", 2) || rstreq(arg, "--verify")) {
00097 __progname = argv[0] = "rpmverify";
00098 break;
00099 }
00100 }
00101
00102 optCon = rpmcliInit(argc, argv, optionsTable);
00103
00104
00105 #ifdef IAM_RPMQV
00106 if (rstreq(__progname, "rpmquery")) bigMode = MODE_QUERY;
00107 if (rstreq(__progname, "rpmverify")) bigMode = MODE_VERIFY;
00108 #endif
00109
00110 #if defined(IAM_RPMQV)
00111
00112 switch (bigMode) {
00113 case MODE_QUERY: qva->qva_mode = 'q'; break;
00114 case MODE_VERIFY: qva->qva_mode = 'V'; break;
00115 case MODE_INSTALL:
00116 case MODE_ERASE:
00117 case MODE_UNKNOWN:
00118 default:
00119 break;
00120 }
00121 #endif
00122
00123 #ifdef IAM_RPMQV
00124 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
00125 switch (qva->qva_mode) {
00126 case 'q': bigMode = MODE_QUERY; break;
00127 case 'V': bigMode = MODE_VERIFY; break;
00128 }
00129
00130 if (qva->qva_sourceCount) {
00131 if (qva->qva_sourceCount > 2)
00132 argerror(_("one type of query/verify may be performed at a "
00133 "time"));
00134 }
00135 if (qva->qva_flags && (bigMode & ~MODES_QV))
00136 argerror(_("unexpected query flags"));
00137
00138 if (qva->qva_queryFormat && (bigMode & ~MODES_QV))
00139 argerror(_("unexpected query format"));
00140
00141 if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV))
00142 argerror(_("unexpected query source"));
00143 }
00144 #endif
00145
00146 #ifdef IAM_RPMEIU
00147 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
00148 { int iflags = (ia->installInterfaceFlags &
00149 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
00150 int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
00151
00152 if (iflags & eflags)
00153 argerror(_("only one major mode may be specified"));
00154 else if (iflags)
00155 bigMode = MODE_INSTALL;
00156 else if (eflags)
00157 bigMode = MODE_ERASE;
00158 }
00159 #endif
00160
00161 #if defined(IAM_RPMEIU)
00162 if (!( bigMode == MODE_INSTALL ) &&
00163 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
00164 argerror(_("only installation and upgrading may be forced"));
00165 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
00166 argerror(_("files may only be relocated during package installation"));
00167
00168 if (ia->relocations && ia->prefix)
00169 argerror(_("cannot use --prefix with --relocate or --excludepath"));
00170
00171 if (bigMode != MODE_INSTALL && ia->relocations)
00172 argerror(_("--relocate and --excludepath may only be used when installing new packages"));
00173
00174 if (bigMode != MODE_INSTALL && ia->prefix)
00175 argerror(_("--prefix may only be used when installing new packages"));
00176
00177 if (ia->prefix && ia->prefix[0] != '/')
00178 argerror(_("arguments to --prefix must begin with a /"));
00179
00180 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
00181 argerror(_("--hash (-h) may only be specified during package "
00182 "installation"));
00183
00184 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
00185 argerror(_("--percent may only be specified during package "
00186 "installation"));
00187
00188 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
00189 argerror(_("--replacepkgs may only be specified during package "
00190 "installation"));
00191
00192 if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
00193 argerror(_("--excludedocs may only be specified during package "
00194 "installation"));
00195
00196 if (bigMode != MODE_INSTALL && ia->incldocs)
00197 argerror(_("--includedocs may only be specified during package "
00198 "installation"));
00199
00200 if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
00201 argerror(_("only one of --excludedocs and --includedocs may be "
00202 "specified"));
00203
00204 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
00205 argerror(_("--ignorearch may only be specified during package "
00206 "installation"));
00207
00208 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
00209 argerror(_("--ignoreos may only be specified during package "
00210 "installation"));
00211
00212 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
00213 (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
00214 argerror(_("--ignoresize may only be specified during package "
00215 "installation"));
00216
00217 if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
00218 argerror(_("--allmatches may only be specified during package "
00219 "erasure"));
00220
00221 if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
00222 argerror(_("--allfiles may only be specified during package "
00223 "installation"));
00224
00225 if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
00226 bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
00227 argerror(_("--justdb may only be specified during package "
00228 "installation and erasure"));
00229
00230 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
00231 (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
00232 argerror(_("script disabling options may only be specified during "
00233 "package installation and erasure"));
00234
00235 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
00236 (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
00237 argerror(_("trigger disabling options may only be specified during "
00238 "package installation and erasure"));
00239
00240 if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
00241 argerror(_("--nodeps may only be specified during package "
00242 "installation, erasure, and verification"));
00243
00244 if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
00245 argerror(_("--test may only be specified during package installation "
00246 "and erasure"));
00247 #endif
00248
00249 if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
00250 argerror(_("arguments to --root (-r) must begin with a /"));
00251 }
00252
00253 if (quiet)
00254 rpmSetVerbosity(RPMLOG_WARNING);
00255
00256 if (rpmcliPipeOutput && initPipe())
00257 exit(EXIT_FAILURE);
00258
00259 ts = rpmtsCreate();
00260 (void) rpmtsSetRootDir(ts, rpmcliRootDir);
00261 switch (bigMode) {
00262 #ifdef IAM_RPMEIU
00263 case MODE_ERASE:
00264 if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
00265
00266 if (!poptPeekArg(optCon)) {
00267 argerror(_("no packages given for erase"));
00268 } else {
00269 ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
00270 }
00271 break;
00272
00273 case MODE_INSTALL:
00274
00275
00276
00277 if (!ia->incldocs) {
00278 if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
00279 ;
00280 } else if (rpmExpandNumeric("%{_excludedocs}"))
00281 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
00282 }
00283
00284 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
00285
00286
00287 if (ia->prefix) {
00288 ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
00289 ia->relocations[0].oldPath = NULL;
00290 ia->relocations[0].newPath = ia->prefix;
00291 ia->relocations[1].oldPath = NULL;
00292 ia->relocations[1].newPath = NULL;
00293 } else if (ia->relocations) {
00294 ia->relocations = xrealloc(ia->relocations,
00295 sizeof(*ia->relocations) * (ia->numRelocations + 1));
00296 ia->relocations[ia->numRelocations].oldPath = NULL;
00297 ia->relocations[ia->numRelocations].newPath = NULL;
00298 }
00299
00300 if (!poptPeekArg(optCon)) {
00301 argerror(_("no packages given for install"));
00302 } else {
00303
00304 ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
00305 }
00306 break;
00307
00308 #endif
00309
00310 #ifdef IAM_RPMQV
00311 case MODE_QUERY:
00312 if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
00313 argerror(_("no arguments given for query"));
00314
00315 ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
00316 break;
00317
00318 case MODE_VERIFY:
00319 { rpmVerifyFlags verifyFlags = VERIFY_ALL;
00320
00321 verifyFlags &= ~qva->qva_flags;
00322 qva->qva_flags = (rpmQueryFlags) verifyFlags;
00323
00324 if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
00325 argerror(_("no arguments given for verify"));
00326 ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
00327 } break;
00328 #endif
00329
00330 #if !defined(IAM_RPMQV)
00331 case MODE_QUERY:
00332 case MODE_VERIFY:
00333 #endif
00334 #if !defined(IAM_RPMEIU)
00335 case MODE_INSTALL:
00336 case MODE_ERASE:
00337 #endif
00338 case MODE_UNKNOWN:
00339 if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
00340 printUsage(optCon, stderr, 0);
00341 ec = argc;
00342 }
00343 break;
00344 }
00345
00346 ts = rpmtsFree(ts);
00347 finishPipe();
00348
00349 #ifdef IAM_RPMQV
00350 qva->qva_queryFormat = _free(qva->qva_queryFormat);
00351 #endif
00352
00353 #ifdef IAM_RPMEIU
00354 if (ia->relocations != NULL)
00355 for (i = 0; i < ia->numRelocations; i++)
00356 ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
00357 ia->relocations = _free(ia->relocations);
00358 #endif
00359
00360 rpmcliFini(optCon);
00361
00362 return RETVAL(ec);
00363 }