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>
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
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();
00095 #endif
00096 setprogname(argv[0]);
00097
00098
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
00106 (void) setlocale(LC_ALL, "" );
00107
00108 bindtextdomain(PACKAGE, LOCALEDIR);
00109 textdomain(PACKAGE);
00110 #endif
00111
00112 rpmSetVerbosity(RPMLOG_NOTICE);
00113
00114
00115
00116
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
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
00283 if (ia->prefix) {
00284 ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
00285 ia->relocations[0].oldPath = NULL;
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
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
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();
00328 #endif
00329
00330
00331 if (ec > 254) ec = 254;
00332
00333 return ec;
00334 }