rpm  4.10.0
rpmqv.c
Go to the documentation of this file.
00001 #include "system.h"
00002 const char *__progname;
00003 
00004 #include <rpm/rpmcli.h>
00005 #include <rpm/rpmlib.h>                 /* RPMSIGTAG, rpmReadPackageFile .. */
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 /* the structure describing the options we take and the defaults */
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  /* IAM_RPMEIU */
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     /* Set the major mode based on argv[0] */
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     /* Jumpstart option from argv[0] if necessary. */
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  /* IAM_RPMQV */
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  /* IAM_RPMEIU */
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 & MODES_IE) && (ia->installInterfaceFlags & INSTALL_HASH))
00170         argerror(_("--hash (-h) may only be specified during package "
00171                         "installation and erasure"));
00172 
00173     if (!(bigMode & MODES_IE) && (ia->installInterfaceFlags & INSTALL_PERCENT))
00174         argerror(_("--percent may only be specified during package "
00175                         "installation and erasure"));
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  /* IAM_RPMEIU */
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         /* RPMTRANS_FLAG_KEEPOBSOLETE */
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         /* we've already ensured !(!ia->prefix && !ia->relocations) */
00276         if (ia->prefix) {
00277             ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
00278             ia->relocations[0].oldPath = NULL;   /* special case magic */
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             /* FIX: ia->relocations[0].newPath undefined */
00293             ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
00294         }
00295         break;
00296 
00297 #endif  /* IAM_RPMEIU */
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  /* IAM_RPMQV */
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     rpmtsFree(ts);
00336     if (finishPipe())
00337         ec = EXIT_FAILURE;
00338 
00339 #ifdef  IAM_RPMQV
00340     free(qva->qva_queryFormat);
00341 #endif
00342 
00343 #ifdef  IAM_RPMEIU
00344     if (ia->relocations != NULL) {
00345         for (i = 0; i < ia->numRelocations; i++)
00346             free(ia->relocations[i].oldPath);
00347         free(ia->relocations);
00348     }
00349 #endif
00350 
00351     rpmcliFini(optCon);
00352 
00353     return RETVAL(ec);
00354 }