• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

rpminstall.c

Go to the documentation of this file.
00001 #include "system.h"
00002 const char *__progname;
00003 
00004 #define _AUTOHELP
00005 
00006 #include <sys/wait.h>
00007 #if HAVE_MCHECK_H
00008 #include <mcheck.h>
00009 #endif
00010 
00011 #include <rpm/rpmcli.h>
00012 #include <rpm/rpmlib.h>                 /* RPMSIGTAG, rpmReadPackageFile .. */
00013 #include <rpm/rpmlog.h>
00014 #include <rpm/rpmfileutil.h>
00015 #include <rpm/rpmts.h>
00016 
00017 #include "debug.h"
00018 
00019 enum modes {
00020     MODE_INSTALL        = (1 <<  1),
00021     MODE_ERASE          = (1 <<  2),
00022 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
00023 
00024     MODE_UNKNOWN        = 0
00025 };
00026 
00027 #define MODES_FOR_DBPATH        (MODES_IE)
00028 #define MODES_FOR_NODEPS        (MODES_IE)
00029 #define MODES_FOR_TEST          (MODES_IE)
00030 #define MODES_FOR_ROOT          (MODES_IE)
00031 
00032 static int quiet;
00033 
00034 /* the structure describing the options we take and the defaults */
00035 static struct poptOption optionsTable[] = {
00036  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
00037         N_("Install/Upgrade/Erase options:"),
00038         NULL },
00039 
00040  { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
00041 
00042  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
00043         N_("Common options for all rpm modes and executables:"),
00044         NULL },
00045 
00046    POPT_AUTOALIAS
00047    POPT_AUTOHELP
00048    POPT_TABLEEND
00049 };
00050 
00051 RPM_GNUC_NORETURN
00052 static void argerror(const char * desc)
00053 {
00054     fprintf(stderr, _("%s: %s\n"), __progname, desc);
00055     exit(EXIT_FAILURE);
00056 }
00057 
00058 static void printVersion(FILE * fp)
00059 {
00060     fprintf(fp, _("RPM version %s\n"), rpmEVR);
00061 }
00062 
00063 static void printBanner(FILE * fp)
00064 {
00065     fprintf(fp, _("Copyright (C) 1998-2002 - Red Hat, Inc.\n"));
00066     fprintf(fp, _("This program may be freely redistributed under the terms of the GNU GPL\n"));
00067 }
00068 
00069 static void printUsage(poptContext con, FILE * fp, int flags)
00070 {
00071     printVersion(fp);
00072     printBanner(fp);
00073     fprintf(fp, "\n");
00074 
00075     if (rpmIsVerbose())
00076         poptPrintHelp(con, fp, flags);
00077     else
00078         poptPrintUsage(con, fp, flags);
00079 }
00080 
00081 int main(int argc, char *argv[])
00082 {
00083     rpmts ts = NULL;
00084     enum modes bigMode = MODE_UNKNOWN;
00085     struct rpmInstallArguments_s * ia = &rpmIArgs;
00086     int arg;
00087 
00088     const char *optArg;
00089     poptContext optCon;
00090     int ec = 0;
00091     int i;
00092         
00093 #if HAVE_MCHECK_H && HAVE_MTRACE
00094     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00095 #endif
00096     setprogname(argv[0]);       /* Retrofit glibc __progname */
00097 
00098     /* XXX glibc churn sanity */
00099     if (__progname == NULL) {
00100         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
00101         else __progname = argv[0];
00102     }
00103 
00104 #if defined(ENABLE_NLS)
00105     /* set up the correct locale */
00106     (void) setlocale(LC_ALL, "" );
00107 
00108     bindtextdomain(PACKAGE, LOCALEDIR);
00109     textdomain(PACKAGE);
00110 #endif
00111 
00112     rpmSetVerbosity(RPMLOG_NOTICE);     /* XXX silly use by showrc */
00113 
00114     /* Make a first pass through the arguments, looking for --rcfile */
00115     /* We need to handle that before dealing with the rest of the arguments. */
00116     /* XXX popt argv definition should be fixed instead of casting... */
00117     optCon = poptGetContext("rpm", argc, (const char **)argv, optionsTable, 0);
00118     {
00119         char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL);
00120         (void) poptReadConfigFile(optCon, poptfile);
00121         free(poptfile);
00122     }
00123     (void) poptReadDefaultConfig(optCon, 1);
00124     poptSetExecPath(optCon, rpmConfigDir(), 1);
00125 
00126     while ((arg = poptGetNextOpt(optCon)) > 0) {
00127         optArg = poptGetOptArg(optCon);
00128 
00129         switch (arg) {
00130         default:
00131             fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
00132             exit(EXIT_FAILURE);
00133         }
00134     }
00135 
00136     if (arg < -1) {
00137         fprintf(stderr, "%s: %s\n", 
00138                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
00139                 poptStrerror(arg));
00140         exit(EXIT_FAILURE);
00141     }
00142 
00143     rpmcliConfigured();
00144 
00145   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
00146     {   int iflags = (ia->installInterfaceFlags &
00147                 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
00148         int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
00149 
00150         if (iflags & eflags)
00151             argerror(_("only one major mode may be specified"));
00152         else if (iflags)
00153             bigMode = MODE_INSTALL;
00154         else if (eflags)
00155             bigMode = MODE_ERASE;
00156     }
00157 
00158     if (!( bigMode == MODE_INSTALL ) &&
00159 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
00160         argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
00161     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
00162         argerror(_("files may only be relocated during package installation"));
00163 
00164     if (ia->relocations && ia->prefix)
00165         argerror(_("cannot use --prefix with --relocate or --excludepath"));
00166 
00167     if (bigMode != MODE_INSTALL && ia->relocations)
00168         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
00169 
00170     if (bigMode != MODE_INSTALL && ia->prefix)
00171         argerror(_("--prefix may only be used when installing new packages"));
00172 
00173     if (ia->prefix && ia->prefix[0] != '/') 
00174         argerror(_("arguments to --prefix must begin with a /"));
00175 
00176     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
00177         argerror(_("--hash (-h) may only be specified during package "
00178                         "installation"));
00179 
00180     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
00181         argerror(_("--percent may only be specified during package "
00182                         "installation"));
00183 
00184     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
00185         argerror(_("--replacepkgs may only be specified during package "
00186                         "installation"));
00187 
00188     if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
00189         argerror(_("--excludedocs may only be specified during package "
00190                    "installation"));
00191 
00192     if (bigMode != MODE_INSTALL && ia->incldocs)
00193         argerror(_("--includedocs may only be specified during package "
00194                    "installation"));
00195 
00196     if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
00197         argerror(_("only one of --excludedocs and --includedocs may be "
00198                  "specified"));
00199   
00200     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
00201         argerror(_("--ignorearch may only be specified during package "
00202                    "installation"));
00203 
00204     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
00205         argerror(_("--ignoreos may only be specified during package "
00206                    "installation"));
00207 
00208     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
00209         (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
00210         argerror(_("--ignoresize may only be specified during package "
00211                    "installation"));
00212 
00213     if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
00214         argerror(_("--allmatches may only be specified during package "
00215                    "erasure"));
00216 
00217     if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
00218         argerror(_("--allfiles may only be specified during package "
00219                    "installation"));
00220 
00221     if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
00222         bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
00223         argerror(_("--justdb may only be specified during package "
00224                    "installation and erasure"));
00225 
00226     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
00227         (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
00228         argerror(_("script disabling options may only be specified during "
00229                    "package installation and erasure"));
00230 
00231     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
00232         (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
00233         argerror(_("trigger disabling options may only be specified during "
00234                    "package installation and erasure"));
00235 
00236     if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
00237         argerror(_("--nodeps may only be specified during package "
00238                    "installation, erasure, and verification"));
00239 
00240     if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
00241         argerror(_("--test may only be specified during package installation, "
00242                  "erasure"));
00243 
00244     if (rpmcliRootDir) {
00245         switch (urlIsURL(rpmcliRootDir)) {
00246         default:
00247             if (rpmcliRootDir[0] != '/')
00248                 argerror(_("arguments to --root (-r) must begin with a /"));
00249             break;
00250         }
00251     }
00252 
00253     if (quiet)
00254         rpmSetVerbosity(RPMLOG_WARNING);
00255 
00256     ts = rpmtsCreate();
00257     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
00258     switch (bigMode) {
00259     case MODE_ERASE:
00260         if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
00261 
00262         if (!poptPeekArg(optCon)) {
00263             argerror(_("no packages given for erase"));
00264         } else {
00265             ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
00266         }
00267         break;
00268 
00269     case MODE_INSTALL:
00270 
00271         /* RPMTRANS_FLAG_KEEPOBSOLETE */
00272 
00273         if (!ia->incldocs) {
00274             if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
00275                 ;
00276             } else if (rpmExpandNumeric("%{_excludedocs}"))
00277                 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
00278         }
00279 
00280         if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
00281 
00282         /* we've already ensured !(!ia->prefix && !ia->relocations) */
00283         if (ia->prefix) {
00284             ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
00285             ia->relocations[0].oldPath = NULL;   /* special case magic */
00286             ia->relocations[0].newPath = ia->prefix;
00287             ia->relocations[1].oldPath = NULL;
00288             ia->relocations[1].newPath = NULL;
00289         } else if (ia->relocations) {
00290             ia->relocations = xrealloc(ia->relocations, 
00291                         sizeof(*ia->relocations) * (ia->numRelocations + 1));
00292             ia->relocations[ia->numRelocations].oldPath = NULL;
00293             ia->relocations[ia->numRelocations].newPath = NULL;
00294         }
00295 
00296         if (!poptPeekArg(optCon)) {
00297             argerror(_("no packages given for install"));
00298         } else {
00299             /* FIX: ia->relocations[0].newPath undefined */
00300             ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
00301         }
00302         break;
00303     case MODE_UNKNOWN:
00304         if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
00305             printUsage(optCon, stderr, 0);
00306             ec = argc;
00307         }
00308         break;
00309     }
00310 
00311     ts = rpmtsFree(ts);
00312 
00313     optCon = poptFreeContext(optCon);
00314     rpmFreeMacros(NULL);
00315     rpmFreeMacros(rpmCLIMacroContext);
00316     rpmFreeRpmrc();
00317 
00318     /* keeps memory leak checkers quiet */
00319     rpmlogClose();
00320 
00321     if (ia->relocations != NULL)
00322     for (i = 0; i < ia->numRelocations; i++)
00323         ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
00324     ia->relocations = _free(ia->relocations);
00325 
00326 #if HAVE_MCHECK_H && HAVE_MTRACE
00327     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00328 #endif
00329 
00330     /* XXX Avoid exit status overflow. Status 255 is special to xargs(1) */
00331     if (ec > 254) ec = 254;
00332 
00333     return ec;
00334 }

Generated on Thu Aug 19 2010 for rpm by  doxygen 1.7.1