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 optCon = rpmcliInit(argc, argv, optionsTable);
00092
00093
00094 #ifdef IAM_RPMQV
00095 if (rstreq(__progname, "rpmquery")) bigMode = MODE_QUERY;
00096 if (rstreq(__progname, "rpmverify")) bigMode = MODE_VERIFY;
00097 #endif
00098
00099 #if defined(IAM_RPMQV)
00100
00101 switch (bigMode) {
00102 case MODE_QUERY: qva->qva_mode = 'q'; break;
00103 case MODE_VERIFY: qva->qva_mode = 'V'; break;
00104 case MODE_INSTALL:
00105 case MODE_ERASE:
00106 case MODE_UNKNOWN:
00107 default:
00108 break;
00109 }
00110 #endif
00111
00112 #ifdef IAM_RPMQV
00113 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
00114 switch (qva->qva_mode) {
00115 case 'q': bigMode = MODE_QUERY; break;
00116 case 'V': bigMode = MODE_VERIFY; break;
00117 }
00118
00119 if (qva->qva_sourceCount) {
00120 if (qva->qva_sourceCount > 1)
00121 argerror(_("one type of query/verify may be performed at a "
00122 "time"));
00123 }
00124 if (qva->qva_flags && (bigMode & ~MODES_QV))
00125 argerror(_("unexpected query flags"));
00126
00127 if (qva->qva_queryFormat && (bigMode & ~MODES_QV))
00128 argerror(_("unexpected query format"));
00129
00130 if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV))
00131 argerror(_("unexpected query source"));
00132 }
00133 #endif
00134
00135 #ifdef IAM_RPMEIU
00136 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
00137 { int iflags = (ia->installInterfaceFlags &
00138 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
00139 int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
00140
00141 if (iflags & eflags)
00142 argerror(_("only one major mode may be specified"));
00143 else if (iflags)
00144 bigMode = MODE_INSTALL;
00145 else if (eflags)
00146 bigMode = MODE_ERASE;
00147 }
00148 #endif
00149
00150 #if defined(IAM_RPMEIU)
00151 if (!( bigMode == MODE_INSTALL ) &&
00152 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
00153 argerror(_("only installation and upgrading may be forced"));
00154 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
00155 argerror(_("files may only be relocated during package installation"));
00156
00157 if (ia->relocations && ia->prefix)
00158 argerror(_("cannot use --prefix with --relocate or --excludepath"));
00159
00160 if (bigMode != MODE_INSTALL && ia->relocations)
00161 argerror(_("--relocate and --excludepath may only be used when installing new packages"));
00162
00163 if (bigMode != MODE_INSTALL && ia->prefix)
00164 argerror(_("--prefix may only be used when installing new packages"));
00165
00166 if (ia->prefix && ia->prefix[0] != '/')
00167 argerror(_("arguments to --prefix must begin with a /"));
00168
00169 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
00170 argerror(_("--hash (-h) may only be specified during package "
00171 "installation"));
00172
00173 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
00174 argerror(_("--percent may only be specified during package "
00175 "installation"));
00176
00177 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
00178 argerror(_("--replacepkgs may only be specified during package "
00179 "installation"));
00180
00181 if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
00182 argerror(_("--excludedocs may only be specified during package "
00183 "installation"));
00184
00185 if (bigMode != MODE_INSTALL && ia->incldocs)
00186 argerror(_("--includedocs may only be specified during package "
00187 "installation"));
00188
00189 if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
00190 argerror(_("only one of --excludedocs and --includedocs may be "
00191 "specified"));
00192
00193 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
00194 argerror(_("--ignorearch may only be specified during package "
00195 "installation"));
00196
00197 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
00198 argerror(_("--ignoreos may only be specified during package "
00199 "installation"));
00200
00201 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
00202 (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
00203 argerror(_("--ignoresize may only be specified during package "
00204 "installation"));
00205
00206 if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
00207 argerror(_("--allmatches may only be specified during package "
00208 "erasure"));
00209
00210 if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
00211 argerror(_("--allfiles may only be specified during package "
00212 "installation"));
00213
00214 if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
00215 bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
00216 argerror(_("--justdb may only be specified during package "
00217 "installation and erasure"));
00218
00219 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
00220 (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
00221 argerror(_("script disabling options may only be specified during "
00222 "package installation and erasure"));
00223
00224 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
00225 (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
00226 argerror(_("trigger disabling options may only be specified during "
00227 "package installation and erasure"));
00228
00229 if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
00230 argerror(_("--nodeps may only be specified during package "
00231 "installation, erasure, and verification"));
00232
00233 if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
00234 argerror(_("--test may only be specified during package installation "
00235 "and erasure"));
00236 #endif
00237
00238 if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
00239 argerror(_("arguments to --root (-r) must begin with a /"));
00240 }
00241
00242 if (quiet)
00243 rpmSetVerbosity(RPMLOG_WARNING);
00244
00245 if (rpmcliPipeOutput && initPipe())
00246 exit(EXIT_FAILURE);
00247
00248 ts = rpmtsCreate();
00249 (void) rpmtsSetRootDir(ts, rpmcliRootDir);
00250 switch (bigMode) {
00251 #ifdef IAM_RPMEIU
00252 case MODE_ERASE:
00253 if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
00254
00255 if (!poptPeekArg(optCon)) {
00256 argerror(_("no packages given for erase"));
00257 } else {
00258 ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
00259 }
00260 break;
00261
00262 case MODE_INSTALL:
00263
00264
00265
00266 if (!ia->incldocs) {
00267 if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
00268 ;
00269 } else if (rpmExpandNumeric("%{_excludedocs}"))
00270 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
00271 }
00272
00273 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
00274
00275
00276 if (ia->prefix) {
00277 ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
00278 ia->relocations[0].oldPath = NULL;
00279 ia->relocations[0].newPath = ia->prefix;
00280 ia->relocations[1].oldPath = NULL;
00281 ia->relocations[1].newPath = NULL;
00282 } else if (ia->relocations) {
00283 ia->relocations = xrealloc(ia->relocations,
00284 sizeof(*ia->relocations) * (ia->numRelocations + 1));
00285 ia->relocations[ia->numRelocations].oldPath = NULL;
00286 ia->relocations[ia->numRelocations].newPath = NULL;
00287 }
00288
00289 if (!poptPeekArg(optCon)) {
00290 argerror(_("no packages given for install"));
00291 } else {
00292
00293 ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
00294 }
00295 break;
00296
00297 #endif
00298
00299 #ifdef IAM_RPMQV
00300 case MODE_QUERY:
00301 if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
00302 argerror(_("no arguments given for query"));
00303
00304 ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
00305 break;
00306
00307 case MODE_VERIFY:
00308 { rpmVerifyFlags verifyFlags = VERIFY_ALL;
00309
00310 verifyFlags &= ~qva->qva_flags;
00311 qva->qva_flags = (rpmQueryFlags) verifyFlags;
00312
00313 if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
00314 argerror(_("no arguments given for verify"));
00315 ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
00316 } break;
00317 #endif
00318
00319 #if !defined(IAM_RPMQV)
00320 case MODE_QUERY:
00321 case MODE_VERIFY:
00322 #endif
00323 #if !defined(IAM_RPMEIU)
00324 case MODE_INSTALL:
00325 case MODE_ERASE:
00326 #endif
00327 case MODE_UNKNOWN:
00328 if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
00329 printUsage(optCon, stderr, 0);
00330 ec = argc;
00331 }
00332 break;
00333 }
00334
00335 ts = rpmtsFree(ts);
00336 finishPipe();
00337
00338 #ifdef IAM_RPMQV
00339 qva->qva_queryFormat = _free(qva->qva_queryFormat);
00340 #endif
00341
00342 #ifdef IAM_RPMEIU
00343 if (ia->relocations != NULL)
00344 for (i = 0; i < ia->numRelocations; i++)
00345 ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
00346 ia->relocations = _free(ia->relocations);
00347 #endif
00348
00349 rpmcliFini(optCon);
00350
00351 return RETVAL(ec);
00352 }