00001 #include "system.h"
00002
00003 #include <rpmcli.h>
00004
00005 #include "rpmdb.h"
00006 #include "rpmps.h"
00007
00008 #include "rpmte.h"
00009
00010 #define _RPMTS_INTERNAL
00011 #include "rpmts.h"
00012
00013 #include "manifest.h"
00014 #include "misc.h"
00015 #include "debug.h"
00016
00017 static int noDeps = 1;
00018 static int noChainsaw = 0;
00019
00020 static rpmVSFlags vsflags = 0;
00021
00022 static inline const char * const identifyDepend(int_32 f)
00023
00024 {
00025 if (isLegacyPreReq(f))
00026 return "PreReq:";
00027 f = _notpre(f);
00028 if (f & RPMSENSE_SCRIPT_PRE)
00029 return "Requires(pre):";
00030 if (f & RPMSENSE_SCRIPT_POST)
00031 return "Requires(post):";
00032 if (f & RPMSENSE_SCRIPT_PREUN)
00033 return "Requires(preun):";
00034 if (f & RPMSENSE_SCRIPT_POSTUN)
00035 return "Requires(postun):";
00036 if (f & RPMSENSE_SCRIPT_VERIFY)
00037 return "Requires(verify):";
00038 if (f & RPMSENSE_FIND_REQUIRES)
00039 return "Requires(auto):";
00040 return "Requires:";
00041 }
00042
00043 static int
00044 rpmGraph(rpmts ts, struct rpmInstallArguments_s * ia, const char ** fileArgv)
00045
00046 {
00047 rpmps ps;
00048 const char ** pkgURL = NULL;
00049 char * pkgState = NULL;
00050 const char ** fnp;
00051 const char * fileURL = NULL;
00052 int numPkgs = 0;
00053 int numFailed = 0;
00054 int prevx = 0;
00055 int pkgx = 0;
00056 const char ** argv = NULL;
00057 int argc = 0;
00058 const char ** av = NULL;
00059 int ac = 0;
00060 int tsflags;
00061 Header h;
00062 rpmRC rpmrc;
00063 int rc = 0;
00064 rpmVSFlags ovsflags;
00065 int i;
00066
00067 if (fileArgv == NULL)
00068 return 0;
00069
00070 tsflags = rpmtsFlags(ts);
00071 if (!noChainsaw)
00072 tsflags |= RPMTRANS_FLAG_CHAINSAW;
00073 (void) rpmtsSetFlags(ts, tsflags);
00074
00075 if (ia->qva_flags & VERIFY_DIGEST)
00076 vsflags |= _RPMVSF_NODIGESTS;
00077 if (ia->qva_flags & VERIFY_SIGNATURE)
00078 vsflags |= _RPMVSF_NOSIGNATURES;
00079 ovsflags = rpmtsSetVSFlags(ts, vsflags);
00080
00081
00082 for (fnp = fileArgv; *fnp; fnp++) {
00083 av = _free(av);
00084 ac = 0;
00085 rc = rpmGlob(*fnp, &ac, &av);
00086 if (rc || ac == 0) continue;
00087
00088 argv = xrealloc(argv, (argc+2) * sizeof(*argv));
00089 memcpy(argv+argc, av, ac * sizeof(*av));
00090 argc += ac;
00091 argv[argc] = NULL;
00092 }
00093 av = _free(av); ac = 0;
00094
00095 restart:
00096
00097 if (pkgx >= numPkgs) {
00098 numPkgs = pkgx + argc;
00099 pkgURL = xrealloc(pkgURL, (numPkgs + 1) * sizeof(*pkgURL));
00100 memset(pkgURL + pkgx, 0, ((argc + 1) * sizeof(*pkgURL)));
00101 pkgState = xrealloc(pkgState, (numPkgs + 1) * sizeof(*pkgState));
00102 memset(pkgState + pkgx, 0, ((argc + 1) * sizeof(*pkgState)));
00103 }
00104
00105
00106 for (i = 0; i < argc; i++) {
00107 fileURL = _free(fileURL);
00108 fileURL = argv[i];
00109 argv[i] = NULL;
00110
00111 pkgURL[pkgx] = fileURL;
00112 fileURL = NULL;
00113 pkgx++;
00114 }
00115 fileURL = _free(fileURL);
00116
00117
00118 for (fnp = pkgURL+prevx; *fnp != NULL; fnp++, prevx++) {
00119 const char * fileName;
00120 FD_t fd;
00121
00122 (void) urlPath(*fnp, &fileName);
00123
00124
00125 fd = Fopen(*fnp, "r.ufdio");
00126 if (fd == NULL || Ferror(fd)) {
00127 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00128 Fstrerror(fd));
00129 if (fd) {
00130 Fclose(fd);
00131 fd = NULL;
00132 }
00133 numFailed++; *fnp = NULL;
00134 continue;
00135 }
00136
00137
00138 ovsflags = rpmtsSetVSFlags(ts, vsflags);
00139 rpmrc = rpmReadPackageFile(ts, fd, *fnp, &h);
00140 ovsflags = rpmtsSetVSFlags(ts, ovsflags);
00141 Fclose(fd);
00142 fd = NULL;
00143
00144 switch (rpmrc) {
00145 case RPMRC_FAIL:
00146 default:
00147 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *fnp);
00148 numFailed++; *fnp = NULL;
00149 break;
00150 case RPMRC_OK:
00151 rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, 0, NULL);
00152 break;
00153 case RPMRC_NOTFOUND:
00154 goto maybe_manifest;
00155 break;
00156 }
00157 h = headerFree(h);
00158 continue;
00159
00160 maybe_manifest:
00161
00162 fd = Fopen(*fnp, "r.fpio");
00163 if (fd == NULL || Ferror(fd)) {
00164 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00165 Fstrerror(fd));
00166 if (fd) {
00167 Fclose(fd);
00168 fd = NULL;
00169 }
00170 numFailed++; *fnp = NULL;
00171 break;
00172 }
00173
00174
00175 rc = rpmReadPackageManifest(fd, &argc, &argv);
00176 if (rc)
00177 rpmError(RPMERR_MANIFEST, _("%s: read manifest failed: %s\n"),
00178 fileURL, Fstrerror(fd));
00179 Fclose(fd);
00180 fd = NULL;
00181
00182
00183 if (rc == 0) {
00184 prevx++;
00185 goto restart;
00186 }
00187
00188 numFailed++; *fnp = NULL;
00189 break;
00190 }
00191
00192 if (numFailed > 0) goto exit;
00193
00194 if (!noDeps) {
00195 rc = rpmtsCheck(ts);
00196 if (rc) {
00197 numFailed += numPkgs;
00198 goto exit;
00199 }
00200 ps = rpmtsProblems(ts);
00201 if (rpmpsNumProblems(ps) > 0) {
00202 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00203 rpmpsPrint(NULL, ps);
00204 numFailed += numPkgs;
00205
00206
00207 if (ts->suggests != NULL && ts->nsuggests > 0) {
00208 rpmMessage(RPMMESS_NORMAL, _(" Suggested resolutions:\n"));
00209 for (i = 0; i < ts->nsuggests; i++) {
00210 const char * str = ts->suggests[i];
00211
00212 if (str == NULL)
00213 break;
00214
00215 rpmMessage(RPMMESS_NORMAL, "\t%s\n", str);
00216 ts->suggests[i] = NULL;
00217 str = _free(str);
00218 }
00219 ts->suggests = _free(ts->suggests);
00220 }
00221
00222 }
00223 ps = rpmpsFree(ps);
00224 }
00225
00226 if (numFailed > 0) goto exit;
00227
00228 rc = rpmtsOrder(ts);
00229 if (rc)
00230 goto exit;
00231
00232 { rpmtsi pi;
00233 rpmte p;
00234 rpmte q;
00235 unsigned char * selected =
00236 alloca(sizeof(*selected) * (rpmtsNElements(ts) + 1));
00237 int oType = TR_ADDED;
00238
00239 fprintf(stdout, "digraph XXX {\n");
00240
00241 fprintf(stdout, " rankdir=LR\n");
00242
00243 fprintf(stdout, "//===== Packages:\n");
00244 pi = rpmtsiInit(ts);
00245 while ((p = rpmtsiNext(pi, oType)) != NULL) {
00246 fprintf(stdout, "//%5d%5d %s\n", rpmteTree(p), rpmteDepth(p), rpmteN(p));
00247 q = rpmteParent(p);
00248 if (q != NULL)
00249 fprintf(stdout, " \"%s\" -> \"%s\"\n", rpmteN(p), rpmteN(q));
00250 else {
00251 fprintf(stdout, " \"%s\"\n", rpmteN(p));
00252 fprintf(stdout, " { rank=max ; \"%s\" }\n", rpmteN(p));
00253 }
00254 }
00255 pi = rpmtsiFree(pi);
00256
00257 fprintf(stdout, "}\n");
00258 }
00259
00260 rc = 0;
00261
00262 exit:
00263 for (i = 0; i < numPkgs; i++)
00264 pkgURL[i] = _free(pkgURL[i]);
00265 pkgState = _free(pkgState);
00266 pkgURL = _free(pkgURL);
00267 argv = _free(argv);
00268
00269 return rc;
00270 }
00271
00272 static struct poptOption optionsTable[] = {
00273 { "check", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noDeps, 0,
00274 N_("don't verify package dependencies"), NULL },
00275 { "nolegacy", '\0', POPT_BIT_SET, &vsflags, RPMVSF_NEEDPAYLOAD,
00276 N_("don't verify header+payload signature"), NULL },
00277
00278 { "nochainsaw", '\0', POPT_ARGFLAG_DOC_HIDDEN, &noChainsaw, 0,
00279 NULL, NULL},
00280
00281 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
00282 N_("Common options for all rpm modes and executables:"),
00283 NULL },
00284
00285 POPT_AUTOALIAS
00286 POPT_AUTOHELP
00287 POPT_TABLEEND
00288 };
00289
00290 int
00291 main(int argc, char *const argv[])
00292 {
00293 rpmts ts = NULL;
00294 struct rpmInstallArguments_s * ia = &rpmIArgs;
00295 poptContext optCon;
00296 int ec = 0;
00297
00298 optCon = rpmcliInit(argc, argv, optionsTable);
00299 if (optCon == NULL)
00300 exit(EXIT_FAILURE);
00301
00302 ts = rpmtsCreate();
00303 if (rpmcliQueryFlags & VERIFY_DIGEST)
00304 vsflags |= _RPMVSF_NODIGESTS;
00305 if (rpmcliQueryFlags & VERIFY_SIGNATURE)
00306 vsflags |= _RPMVSF_NOSIGNATURES;
00307 if (rpmcliQueryFlags & VERIFY_HDRCHK)
00308 vsflags |= RPMVSF_NOHDRCHK;
00309 (void) rpmtsSetVSFlags(ts, vsflags);
00310
00311 ec = rpmGraph(ts, ia, poptGetArgs(optCon));
00312
00313 ts = rpmtsFree(ts);
00314
00315 optCon = rpmcliFini(optCon);
00316
00317 return ec;
00318 }