rpm
4.5
|
00001 00005 #include "system.h" 00006 00007 #include <rpmcli.h> 00008 00009 #include "rpmdb.h" 00010 #ifdef NOTYET 00011 #include "rpmds.h" /* XXX ts->suggests, +foo -foo =foo args */ 00012 #endif 00013 00014 #include "rpmte.h" /* XXX rpmtsPrint() */ 00015 #define _RPMTS_INTERNAL /* XXX ts->goal, ts->suggests */ 00016 #include "rpmts.h" 00017 00018 #include "manifest.h" 00019 #include "misc.h" /* XXX rpmGlob() */ 00020 #include "rpmgi.h" /* XXX rpmgiEscapeSpaces */ 00021 #include "debug.h" 00022 00023 /*@access rpmts @*/ /* XXX ts->goal */ 00024 00025 /*@unchecked@*/ 00026 int rpmcliPackagesTotal = 0; 00027 /*@unchecked@*/ 00028 int rpmcliHashesCurrent = 0; 00029 /*@unchecked@*/ 00030 int rpmcliHashesTotal = 0; 00031 /*@unchecked@*/ 00032 unsigned long long rpmcliProgressCurrent = 0; 00033 /*@unchecked@*/ 00034 unsigned long long rpmcliProgressTotal = 0; 00035 00042 static void printHash(const unsigned long long amount, const unsigned long long total) 00043 /*@globals rpmcliHashesCurrent, rpmcliHashesTotal, 00044 rpmcliProgressCurrent, fileSystem @*/ 00045 /*@modifies rpmcliHashesCurrent, rpmcliHashesTotal, 00046 rpmcliProgressCurrent, fileSystem @*/ 00047 { 00048 int hashesNeeded; 00049 00050 rpmcliHashesTotal = (isatty (STDOUT_FILENO) ? 44 : 50); 00051 00052 if (rpmcliHashesCurrent != rpmcliHashesTotal) { 00053 /*@+relaxtypes@*/ 00054 float pct = (total ? (((float) amount) / total) : 1.0); 00055 hashesNeeded = (rpmcliHashesTotal * pct) + 0.5; 00056 /*@=relaxtypes@*/ 00057 while (hashesNeeded > rpmcliHashesCurrent) { 00058 if (isatty (STDOUT_FILENO)) { 00059 int i; 00060 for (i = 0; i < rpmcliHashesCurrent; i++) 00061 (void) putchar ('#'); 00062 for (; i < rpmcliHashesTotal; i++) 00063 (void) putchar (' '); 00064 fprintf(stdout, "(%3d%%)", (int)((100 * pct) + 0.5)); 00065 for (i = 0; i < (rpmcliHashesTotal + 6); i++) 00066 (void) putchar ('\b'); 00067 } else 00068 fprintf(stdout, "#"); 00069 00070 rpmcliHashesCurrent++; 00071 } 00072 (void) fflush(stdout); 00073 00074 if (rpmcliHashesCurrent == rpmcliHashesTotal) { 00075 int i; 00076 rpmcliProgressCurrent++; 00077 if (isatty(STDOUT_FILENO)) { 00078 for (i = 1; i < rpmcliHashesCurrent; i++) 00079 (void) putchar ('#'); 00080 /*@+relaxtypes@*/ 00081 pct = (rpmcliProgressTotal 00082 ? (((float) rpmcliProgressCurrent) / rpmcliProgressTotal) 00083 : 1); 00084 /*@=relaxtypes@*/ 00085 fprintf(stdout, " [%3d%%]", (int)((100 * pct) + 0.5)); 00086 } 00087 fprintf(stdout, "\n"); 00088 } 00089 (void) fflush(stdout); 00090 } 00091 } 00092 00093 void * rpmShowProgress(/*@null@*/ const void * arg, 00094 const rpmCallbackType what, 00095 const unsigned long long amount, 00096 const unsigned long long total, 00097 /*@null@*/ fnpyKey key, 00098 /*@null@*/ void * data) 00099 /*@globals rpmcliHashesCurrent, rpmcliProgressCurrent, rpmcliProgressTotal, 00100 fileSystem @*/ 00101 /*@modifies rpmcliHashesCurrent, rpmcliProgressCurrent, rpmcliProgressTotal, 00102 fileSystem @*/ 00103 { 00104 /*@-abstract -castexpose @*/ 00105 Header h = (Header) arg; 00106 /*@=abstract =castexpose @*/ 00107 char * s; 00108 int flags = (int) ((long)data); 00109 void * rc = NULL; 00110 /*@-abstract -assignexpose @*/ 00111 const char * filename = (const char *)key; 00112 /*@=abstract =assignexpose @*/ 00113 static FD_t fd = NULL; 00114 int xx; 00115 00116 switch (what) { 00117 case RPMCALLBACK_INST_OPEN_FILE: 00118 /*@-boundsread@*/ 00119 if (filename == NULL || filename[0] == '\0') 00120 return NULL; 00121 /*@=boundsread@*/ 00122 fd = Fopen(filename, "r"); 00123 /*@-type@*/ /* FIX: still necessary? */ 00124 if (fd == NULL || Ferror(fd)) { 00125 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), filename, 00126 Fstrerror(fd)); 00127 if (fd != NULL) { 00128 xx = Fclose(fd); 00129 fd = NULL; 00130 } 00131 } else { 00132 long oldfl; 00133 fd = fdLink(fd, "persist (showProgress)"); 00134 oldfl=Fcntl(fd, F_GETFD, 0); 00135 if(oldfl >= 0) { 00136 oldfl |= FD_CLOEXEC; /* scripts shouldn't inherit rpm file descriptor */ 00137 Fcntl(fd, F_SETFD, (void*)oldfl); 00138 } 00139 } 00140 /*@=type@*/ 00141 /*@+voidabstract@*/ 00142 return (void *)fd; 00143 /*@=voidabstract@*/ 00144 /*@notreached@*/ break; 00145 00146 case RPMCALLBACK_INST_CLOSE_FILE: 00147 /*@-type@*/ /* FIX: still necessary? */ 00148 fd = fdFree(fd, "persist (showProgress)"); 00149 /*@=type@*/ 00150 if (fd != NULL) { 00151 xx = Fclose(fd); 00152 fd = NULL; 00153 } 00154 break; 00155 00156 case RPMCALLBACK_INST_START: 00157 rpmcliHashesCurrent = 0; 00158 if (h == NULL || !(flags & INSTALL_LABEL)) 00159 break; 00160 /* @todo Remove headerSprintf() on a progress callback. */ 00161 if (flags & INSTALL_HASH) { 00162 s = headerSprintf(h, "%{NAME}", 00163 rpmTagTable, rpmHeaderFormats, NULL); 00164 if (isatty (STDOUT_FILENO)) 00165 fprintf(stdout, "%4d:%-23.23s", (int)rpmcliProgressCurrent + 1, s); 00166 else 00167 fprintf(stdout, "%-28.28s", s); 00168 (void) fflush(stdout); 00169 s = _free(s); 00170 } else { 00171 s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}", 00172 rpmTagTable, rpmHeaderFormats, NULL); 00173 fprintf(stdout, "%s\n", s); 00174 (void) fflush(stdout); 00175 s = _free(s); 00176 } 00177 break; 00178 00179 case RPMCALLBACK_TRANS_PROGRESS: 00180 case RPMCALLBACK_INST_PROGRESS: 00181 /*@+relaxtypes@*/ 00182 if (flags & INSTALL_PERCENT) 00183 fprintf(stdout, "%%%% %f\n", (double) (total 00184 ? ((((float) amount) / total) * 100) 00185 : 100.0)); 00186 else if (flags & INSTALL_HASH) 00187 printHash(amount, total); 00188 /*@=relaxtypes@*/ 00189 (void) fflush(stdout); 00190 break; 00191 00192 case RPMCALLBACK_TRANS_START: 00193 rpmcliHashesCurrent = 0; 00194 rpmcliProgressTotal = 1; 00195 rpmcliProgressCurrent = 0; 00196 if (!(flags & INSTALL_LABEL)) 00197 break; 00198 if (flags & INSTALL_HASH) 00199 fprintf(stdout, "%-28s", _("Preparing...")); 00200 else 00201 fprintf(stdout, "%s\n", _("Preparing packages for installation...")); 00202 (void) fflush(stdout); 00203 break; 00204 00205 case RPMCALLBACK_TRANS_STOP: 00206 if (flags & INSTALL_HASH) 00207 printHash(1, 1); /* Fixes "preparing..." progress bar */ 00208 rpmcliProgressTotal = rpmcliPackagesTotal; 00209 rpmcliProgressCurrent = 0; 00210 break; 00211 00212 case RPMCALLBACK_REPACKAGE_START: 00213 rpmcliHashesCurrent = 0; 00214 rpmcliProgressTotal = total; 00215 rpmcliProgressCurrent = 0; 00216 if (!(flags & INSTALL_LABEL)) 00217 break; 00218 if (flags & INSTALL_HASH) 00219 fprintf(stdout, "%-28s\n", _("Repackaging...")); 00220 else 00221 fprintf(stdout, "%s\n", _("Repackaging erased files...")); 00222 (void) fflush(stdout); 00223 break; 00224 00225 case RPMCALLBACK_REPACKAGE_PROGRESS: 00226 if (amount && (flags & INSTALL_HASH)) 00227 printHash(1, 1); /* Fixes "preparing..." progress bar */ 00228 break; 00229 00230 case RPMCALLBACK_REPACKAGE_STOP: 00231 rpmcliProgressTotal = total; 00232 rpmcliProgressCurrent = total; 00233 if (flags & INSTALL_HASH) 00234 printHash(1, 1); /* Fixes "preparing..." progress bar */ 00235 rpmcliProgressTotal = rpmcliPackagesTotal; 00236 rpmcliProgressCurrent = 0; 00237 if (!(flags & INSTALL_LABEL)) 00238 break; 00239 if (flags & INSTALL_HASH) 00240 fprintf(stdout, "%-28s\n", _("Upgrading...")); 00241 else 00242 fprintf(stdout, "%s\n", _("Upgrading packages...")); 00243 (void) fflush(stdout); 00244 break; 00245 00246 case RPMCALLBACK_UNINST_PROGRESS: 00247 break; 00248 case RPMCALLBACK_UNINST_START: 00249 break; 00250 case RPMCALLBACK_UNINST_STOP: 00251 break; 00252 case RPMCALLBACK_UNPACK_ERROR: 00253 break; 00254 case RPMCALLBACK_CPIO_ERROR: 00255 break; 00256 case RPMCALLBACK_UNKNOWN: 00257 default: 00258 break; 00259 } 00260 00261 return rc; 00262 } 00263 00264 typedef /*@only@*/ /*@null@*/ const char * str_t; 00265 00266 struct rpmEIU { 00267 Header h; 00268 FD_t fd; 00269 int numFailed; 00270 int numPkgs; 00271 /*@only@*/ 00272 str_t * pkgURL; 00273 /*@dependent@*/ /*@null@*/ 00274 str_t * fnp; 00275 /*@only@*/ 00276 char * pkgState; 00277 int prevx; 00278 int pkgx; 00279 int numRPMS; 00280 int numSRPMS; 00281 /*@only@*/ /*@null@*/ 00282 str_t * sourceURL; 00283 int isSource; 00284 int argc; 00285 /*@only@*/ /*@null@*/ 00286 str_t * argv; 00287 /*@dependent@*/ 00288 rpmRelocation relocations; 00289 rpmRC rpmrc; 00290 }; 00291 00293 /*@-bounds@*/ 00294 int rpmInstall(rpmts ts, QVA_t ia, const char ** fileArgv) 00295 { 00296 struct rpmEIU * eiu = memset(alloca(sizeof(*eiu)), 0, sizeof(*eiu)); 00297 rpmps ps; 00298 rpmprobFilterFlags probFilter; 00299 rpmRelocation relocations; 00300 /*@only@*/ /*@null@*/ const char * fileURL = NULL; 00301 int stopInstall = 0; 00302 const char ** av = NULL; 00303 const char *fn; 00304 rpmVSFlags vsflags, ovsflags, tvsflags; 00305 int ac = 0; 00306 int rc; 00307 int xx; 00308 int i; 00309 00310 if (fileArgv == NULL) goto exit; 00311 00312 ts->goal = TSM_INSTALL; 00313 rpmcliPackagesTotal = 0; 00314 00315 if (rpmExpandNumeric("%{?_repackage_all_erasures}")) 00316 ia->transFlags |= RPMTRANS_FLAG_REPACKAGE; 00317 00318 /* Initialize security context patterns (if not already done). */ 00319 if (!(ia->transFlags & RPMTRANS_FLAG_NOCONTEXTS)) { 00320 const char *fn = rpmGetPath("%{?_install_file_context_path}", NULL); 00321 if (fn != NULL && *fn != '\0') 00322 xx = matchpathcon_init(fn); 00323 fn = _free(fn); 00324 } 00325 (void) rpmtsSetFlags(ts, ia->transFlags); 00326 (void) rpmtsSetDFlags(ts, ia->depFlags); 00327 00328 /* Display and set autorollback goal. */ 00329 if (rpmExpandNumeric("%{?_rollback_transaction_on_failure}")) { 00330 if (ia->arbtid) { 00331 time_t ttid = (time_t)ia->arbtid; 00332 rpmMessage(RPMMESS_DEBUG, D_("Autorollback Goal: %-24.24s (0x%08x)\n"), 00333 ctime(&ttid), ia->arbtid); 00334 rpmtsSetARBGoal(ts, ia->arbtid); 00335 } 00336 } 00337 00338 probFilter = ia->probFilter; 00339 relocations = ia->relocations; 00340 00341 if (ia->installInterfaceFlags & INSTALL_UPGRADE) 00342 vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); 00343 else 00344 vsflags = rpmExpandNumeric("%{?_vsflags_install}"); 00345 if (ia->qva_flags & VERIFY_DIGEST) 00346 vsflags |= _RPMVSF_NODIGESTS; 00347 if (ia->qva_flags & VERIFY_SIGNATURE) 00348 vsflags |= _RPMVSF_NOSIGNATURES; 00349 if (ia->qva_flags & VERIFY_HDRCHK) 00350 vsflags |= RPMVSF_NOHDRCHK; 00351 ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD)); 00352 00353 { int notifyFlags; 00354 notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); 00355 xx = rpmtsSetNotifyCallback(ts, 00356 rpmShowProgress, (void *) ((long)notifyFlags)); 00357 } 00358 00359 if ((eiu->relocations = relocations) != NULL) { 00360 while (eiu->relocations->oldPath) 00361 eiu->relocations++; 00362 if (eiu->relocations->newPath == NULL) 00363 eiu->relocations = NULL; 00364 } 00365 00366 /* Build fully globbed list of arguments in argv[argc]. */ 00367 /*@-branchstate@*/ 00368 /*@-temptrans@*/ 00369 for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) { 00370 /*@=temptrans@*/ 00371 av = _free(av); ac = 0; 00372 fn = rpmgiEscapeSpaces(*eiu->fnp); 00373 rc = rpmGlob(fn, &ac, &av); 00374 fn = _free(fn); 00375 if (rc || ac == 0) { 00376 rpmError(RPMERR_OPEN, _("File not found by glob: %s\n"), *eiu->fnp); 00377 continue; 00378 } 00379 00380 eiu->argv = xrealloc(eiu->argv, (eiu->argc+ac+1) * sizeof(*eiu->argv)); 00381 memcpy(eiu->argv+eiu->argc, av, ac * sizeof(*av)); 00382 eiu->argc += ac; 00383 eiu->argv[eiu->argc] = NULL; 00384 } 00385 /*@=branchstate@*/ 00386 av = _free(av); ac = 0; 00387 00388 restart: 00389 /* Allocate sufficient storage for next set of args. */ 00390 if (eiu->pkgx >= eiu->numPkgs) { 00391 eiu->numPkgs = eiu->pkgx + eiu->argc; 00392 eiu->pkgURL = xrealloc(eiu->pkgURL, 00393 (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL)); 00394 memset(eiu->pkgURL + eiu->pkgx, 0, 00395 ((eiu->argc + 1) * sizeof(*eiu->pkgURL))); 00396 eiu->pkgState = xrealloc(eiu->pkgState, 00397 (eiu->numPkgs + 1) * sizeof(*eiu->pkgState)); 00398 memset(eiu->pkgState + eiu->pkgx, 0, 00399 ((eiu->argc + 1) * sizeof(*eiu->pkgState))); 00400 } 00401 00402 /* Retrieve next set of args, cache on local storage. */ 00403 for (i = 0; i < eiu->argc; i++) { 00404 fileURL = _free(fileURL); 00405 fileURL = eiu->argv[i]; 00406 eiu->argv[i] = NULL; 00407 00408 #ifdef NOTYET 00409 if (fileURL[0] == '=') { 00410 rpmds this = rpmdsSingle(RPMTAG_REQUIRENAME, fileURL+1, NULL, 0); 00411 00412 xx = rpmtsSolve(ts, this, NULL); 00413 if (ts->suggests && ts->nsuggests > 0) { 00414 fileURL = _free(fileURL); 00415 fileURL = ts->suggests[0]; 00416 ts->suggests[0] = NULL; 00417 while (ts->nsuggests-- > 0) { 00418 if (ts->suggests[ts->nsuggests] == NULL) 00419 continue; 00420 ts->suggests[ts->nsuggests] = _free(ts->suggests[ts->nsuggests]); 00421 } 00422 ts->suggests = _free(ts->suggests); 00423 rpmMessage(RPMMESS_DEBUG, D_("Adding goal: %s\n"), fileURL); 00424 eiu->pkgURL[eiu->pkgx] = fileURL; 00425 fileURL = NULL; 00426 eiu->pkgx++; 00427 } 00428 this = rpmdsFree(this); 00429 } else 00430 #endif 00431 00432 switch (urlIsURL(fileURL)) { 00433 case URL_IS_HTTPS: 00434 case URL_IS_HTTP: 00435 case URL_IS_FTP: 00436 { const char *tfn; 00437 00438 if (rpmIsVerbose()) 00439 fprintf(stdout, _("Retrieving %s\n"), fileURL); 00440 00441 { char tfnbuf[64]; 00442 const char * rootDir = rpmtsRootDir(ts); 00443 if (!(rootDir && * rootDir)) 00444 rootDir = ""; 00445 strcpy(tfnbuf, "rpm-xfer.XXXXXX"); 00446 (void) mktemp(tfnbuf); 00447 tfn = rpmGenPath(rootDir, "%{_tmppath}/", tfnbuf); 00448 } 00449 00450 /* XXX undefined %{name}/%{version}/%{release} here */ 00451 /* XXX %{_tmpdir} does not exist */ 00452 rpmMessage(RPMMESS_DEBUG, D_(" ... as %s\n"), tfn); 00453 rc = urlGetFile(fileURL, tfn); 00454 if (rc < 0) { 00455 rpmMessage(RPMMESS_ERROR, 00456 _("skipping %s - transfer failed - %s\n"), 00457 fileURL, ftpStrerror(rc)); 00458 eiu->numFailed++; 00459 eiu->pkgURL[eiu->pkgx] = NULL; 00460 tfn = _free(tfn); 00461 /*@switchbreak@*/ break; 00462 } 00463 eiu->pkgState[eiu->pkgx] = 1; 00464 eiu->pkgURL[eiu->pkgx] = tfn; 00465 eiu->pkgx++; 00466 } /*@switchbreak@*/ break; 00467 case URL_IS_PATH: 00468 case URL_IS_DASH: /* WRONG WRONG WRONG */ 00469 case URL_IS_HKP: /* WRONG WRONG WRONG */ 00470 default: 00471 eiu->pkgURL[eiu->pkgx] = fileURL; 00472 fileURL = NULL; 00473 eiu->pkgx++; 00474 /*@switchbreak@*/ break; 00475 } 00476 } 00477 fileURL = _free(fileURL); 00478 00479 if (eiu->numFailed) goto exit; 00480 00481 /* Continue processing file arguments, building transaction set. */ 00482 for (eiu->fnp = eiu->pkgURL+eiu->prevx; 00483 *eiu->fnp != NULL; 00484 eiu->fnp++, eiu->prevx++) 00485 { 00486 const char * fileName; 00487 00488 rpmMessage(RPMMESS_DEBUG, "============== %s\n", *eiu->fnp); 00489 (void) urlPath(*eiu->fnp, &fileName); 00490 00491 /* Try to read the header from a package file. */ 00492 eiu->fd = Fopen(*eiu->fnp, "r"); 00493 if (eiu->fd == NULL || Ferror(eiu->fd)) { 00494 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp, 00495 Fstrerror(eiu->fd)); 00496 if (eiu->fd != NULL) { 00497 xx = Fclose(eiu->fd); 00498 eiu->fd = NULL; 00499 } 00500 eiu->numFailed++; *eiu->fnp = NULL; 00501 continue; 00502 } 00503 00504 /* Read the header, verifying signatures (if present). */ 00505 tvsflags = rpmtsSetVSFlags(ts, vsflags); 00506 eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h); 00507 tvsflags = rpmtsSetVSFlags(ts, tvsflags); 00508 xx = Fclose(eiu->fd); 00509 eiu->fd = NULL; 00510 00511 switch (eiu->rpmrc) { 00512 case RPMRC_FAIL: 00513 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *eiu->fnp); 00514 eiu->numFailed++; *eiu->fnp = NULL; 00515 continue; 00516 /*@notreached@*/ /*@switchbreak@*/ break; 00517 case RPMRC_NOTFOUND: 00518 goto maybe_manifest; 00519 /*@notreached@*/ /*@switchbreak@*/ break; 00520 case RPMRC_NOTTRUSTED: 00521 case RPMRC_NOKEY: 00522 case RPMRC_OK: 00523 default: 00524 /*@switchbreak@*/ break; 00525 } 00526 00527 eiu->isSource = (headerIsEntry(eiu->h, RPMTAG_SOURCERPM) == 0); 00528 00529 if (eiu->isSource) { 00530 rpmMessage(RPMMESS_DEBUG, D_("\tadded source package [%d]\n"), 00531 eiu->numSRPMS); 00532 eiu->sourceURL = xrealloc(eiu->sourceURL, 00533 (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL)); 00534 eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp; 00535 *eiu->fnp = NULL; 00536 eiu->numSRPMS++; 00537 eiu->sourceURL[eiu->numSRPMS] = NULL; 00538 continue; 00539 } 00540 00541 if (eiu->relocations) { 00542 const char ** paths; 00543 int pft; 00544 int c; 00545 00546 if (headerGetEntry(eiu->h, RPMTAG_PREFIXES, &pft, &paths, &c) 00547 && c == 1) 00548 { 00549 eiu->relocations->oldPath = xstrdup(paths[0]); 00550 paths = headerFreeData(paths, pft); 00551 } else { 00552 const char * name; 00553 xx = headerNVR(eiu->h, &name, NULL, NULL); 00554 rpmMessage(RPMMESS_ERROR, 00555 _("package %s is not relocatable\n"), name); 00556 eiu->numFailed++; 00557 goto exit; 00558 /*@notreached@*/ 00559 } 00560 } 00561 00562 /* On --freshen, verify package is installed and newer */ 00563 if (ia->installInterfaceFlags & INSTALL_FRESHEN) { 00564 rpmdbMatchIterator mi; 00565 const char * name; 00566 Header oldH; 00567 int count; 00568 00569 xx = headerNVR(eiu->h, &name, NULL, NULL); 00570 mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0); 00571 count = rpmdbGetIteratorCount(mi); 00572 while ((oldH = rpmdbNextIterator(mi)) != NULL) { 00573 if (rpmVersionCompare(oldH, eiu->h) < 0) 00574 /*@innercontinue@*/ continue; 00575 /* same or newer package already installed */ 00576 count = 0; 00577 /*@innerbreak@*/ break; 00578 } 00579 mi = rpmdbFreeIterator(mi); 00580 if (count == 0) { 00581 eiu->h = headerFree(eiu->h); 00582 continue; 00583 } 00584 /* Package is newer than those currently installed. */ 00585 } 00586 00587 /*@-abstract@*/ 00588 rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName, 00589 (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0, 00590 relocations); 00591 /*@=abstract@*/ 00592 00593 /* XXX reference held by transaction set */ 00594 eiu->h = headerFree(eiu->h); 00595 if (eiu->relocations) 00596 eiu->relocations->oldPath = _free(eiu->relocations->oldPath); 00597 00598 switch(rc) { 00599 case 0: 00600 rpmMessage(RPMMESS_DEBUG, D_("\tadded binary package [%d]\n"), 00601 eiu->numRPMS); 00602 eiu->numRPMS++; 00603 /*@switchbreak@*/ break; 00604 case 1: 00605 rpmMessage(RPMMESS_WARNING, 00606 _("package file %s was skipped\n"), *eiu->fnp); 00607 /*@switchbreak@*/ break; 00608 case 2: 00609 rpmMessage(RPMMESS_ERROR, 00610 _("file %s requires a newer version of RPM\n"), 00611 *eiu->fnp); 00612 eiu->numFailed++; 00613 goto exit; 00614 /*@notreached@*/ /*@switchbreak@*/ break; 00615 } 00616 00617 continue; 00618 00619 maybe_manifest: 00620 /* Try to read a package manifest. */ 00621 eiu->fd = Fopen(*eiu->fnp, "r.fpio"); 00622 if (eiu->fd == NULL || Ferror(eiu->fd)) { 00623 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp, 00624 Fstrerror(eiu->fd)); 00625 if (eiu->fd != NULL) { 00626 xx = Fclose(eiu->fd); 00627 eiu->fd = NULL; 00628 } 00629 eiu->numFailed++; *eiu->fnp = NULL; 00630 break; 00631 } 00632 00633 /* Read list of packages from manifest. */ 00634 /*@-nullstate@*/ /* FIX: *eiu->argv can be NULL */ 00635 rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv); 00636 /*@=nullstate@*/ 00637 if (rc != RPMRC_OK) 00638 rpmError(RPMERR_MANIFEST, _("%s: not an rpm package (or package manifest): %s\n"), 00639 *eiu->fnp, Fstrerror(eiu->fd)); 00640 xx = Fclose(eiu->fd); 00641 eiu->fd = NULL; 00642 00643 /* If successful, restart the query loop. */ 00644 if (rc == RPMRC_OK) { 00645 eiu->prevx++; 00646 goto restart; 00647 } 00648 00649 eiu->numFailed++; *eiu->fnp = NULL; 00650 break; 00651 } 00652 00653 rpmMessage(RPMMESS_DEBUG, D_("found %d source and %d binary packages\n"), 00654 eiu->numSRPMS, eiu->numRPMS); 00655 00656 if (eiu->numFailed) goto exit; 00657 00658 if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) { 00659 00660 if (rpmtsCheck(ts)) { 00661 eiu->numFailed = eiu->numPkgs; 00662 stopInstall = 1; 00663 } 00664 00665 ps = rpmtsProblems(ts); 00666 if (!stopInstall && rpmpsNumProblems(ps) > 0) { 00667 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n")); 00668 rpmpsPrint(NULL, ps); 00669 eiu->numFailed = eiu->numPkgs; 00670 stopInstall = 1; 00671 00672 /*@-branchstate@*/ 00673 if (ts->suggests != NULL && ts->nsuggests > 0) { 00674 rpmMessage(RPMMESS_NORMAL, _(" Suggested resolutions:\n")); 00675 for (i = 0; i < ts->nsuggests; i++) { 00676 const char * str = ts->suggests[i]; 00677 00678 if (str == NULL) 00679 break; 00680 00681 rpmMessage(RPMMESS_NORMAL, "\t%s\n", str); 00682 00683 ts->suggests[i] = NULL; 00684 str = _free(str); 00685 } 00686 ts->suggests = _free(ts->suggests); 00687 } 00688 /*@=branchstate@*/ 00689 } 00690 ps = rpmpsFree(ps); 00691 } 00692 00693 if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { 00694 if (rpmtsOrder(ts)) { 00695 eiu->numFailed = eiu->numPkgs; 00696 stopInstall = 1; 00697 } 00698 } 00699 00700 if (eiu->numRPMS && !stopInstall) { 00701 00702 rpmcliPackagesTotal += eiu->numSRPMS; 00703 00704 rpmMessage(RPMMESS_DEBUG, D_("installing binary packages\n")); 00705 00706 /* Drop added/available package indices and dependency sets. */ 00707 rpmtsClean(ts); 00708 00709 rc = rpmtsRun(ts, NULL, probFilter); 00710 ps = rpmtsProblems(ts); 00711 00712 if (rc < 0) { 00713 eiu->numFailed += eiu->numRPMS; 00714 } else if (rc > 0) { 00715 eiu->numFailed += rc; 00716 if (rpmpsNumProblems(ps) > 0) 00717 rpmpsPrint(stderr, ps); 00718 } 00719 ps = rpmpsFree(ps); 00720 } 00721 00722 if (eiu->numSRPMS && !stopInstall) { 00723 if (eiu->sourceURL != NULL) 00724 for (i = 0; i < eiu->numSRPMS; i++) { 00725 if (eiu->sourceURL[i] == NULL) continue; 00726 eiu->fd = Fopen(eiu->sourceURL[i], "r"); 00727 if (eiu->fd == NULL || Ferror(eiu->fd)) { 00728 rpmMessage(RPMMESS_ERROR, _("cannot open file %s: %s\n"), 00729 eiu->sourceURL[i], Fstrerror(eiu->fd)); 00730 if (eiu->fd != NULL) { 00731 xx = Fclose(eiu->fd); 00732 eiu->fd = NULL; 00733 } 00734 continue; 00735 } 00736 00737 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { 00738 eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL); 00739 if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++; 00740 } 00741 00742 xx = Fclose(eiu->fd); 00743 eiu->fd = NULL; 00744 } 00745 } 00746 00747 exit: 00748 if (eiu->pkgURL != NULL) 00749 for (i = 0; i < eiu->numPkgs; i++) { 00750 if (eiu->pkgURL[i] == NULL) continue; 00751 if (eiu->pkgState[i] == 1) 00752 (void) Unlink(eiu->pkgURL[i]); 00753 eiu->pkgURL[i] = _free(eiu->pkgURL[i]); 00754 } 00755 eiu->pkgState = _free(eiu->pkgState); 00756 eiu->pkgURL = _free(eiu->pkgURL); 00757 eiu->argv = _free(eiu->argv); 00758 00759 rpmtsEmpty(ts); 00760 00761 return eiu->numFailed; 00762 } 00763 /*@=bounds@*/ 00764 00765 int rpmErase(rpmts ts, QVA_t ia, const char ** argv) 00766 { 00767 int count; 00768 const char ** arg; 00769 int numFailed = 0; 00770 int stopUninstall = 0; 00771 int numPackages = 0; 00772 rpmVSFlags vsflags, ovsflags; 00773 rpmps ps; 00774 00775 if (argv == NULL) return 0; 00776 00777 vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); 00778 if (ia->qva_flags & VERIFY_DIGEST) 00779 vsflags |= _RPMVSF_NODIGESTS; 00780 if (ia->qva_flags & VERIFY_SIGNATURE) 00781 vsflags |= _RPMVSF_NOSIGNATURES; 00782 if (ia->qva_flags & VERIFY_HDRCHK) 00783 vsflags |= RPMVSF_NOHDRCHK; 00784 ovsflags = rpmtsSetVSFlags(ts, vsflags); 00785 00786 if (rpmExpandNumeric("%{?_repackage_all_erasures}")) 00787 ia->transFlags |= RPMTRANS_FLAG_REPACKAGE; 00788 00789 (void) rpmtsSetFlags(ts, ia->transFlags); 00790 (void) rpmtsSetDFlags(ts, ia->depFlags); 00791 00792 /* Display and set autorollback goal. */ 00793 if (rpmExpandNumeric("%{?_rollback_transaction_on_failure}")) { 00794 if (ia->arbtid) { 00795 time_t ttid = (time_t)ia->arbtid; 00796 rpmMessage(RPMMESS_DEBUG, D_("Autorollback Goal: %-24.24s (0x%08x)\n"), 00797 ctime(&ttid), ia->arbtid); 00798 rpmtsSetARBGoal(ts, ia->arbtid); 00799 } 00800 } 00801 00802 #ifdef NOTYET /* XXX no callbacks on erase yet */ 00803 { int notifyFlags; 00804 notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); 00805 xx = rpmtsSetNotifyCallback(ts, 00806 rpmShowProgress, (void *) ((long)notifyFlags)); 00807 } 00808 #endif 00809 00810 ts->goal = TSM_ERASE; 00811 00812 for (arg = argv; *arg; arg++) { 00813 rpmdbMatchIterator mi; 00814 00815 /* XXX HACK to get rpmdbFindByLabel out of the API */ 00816 mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0); 00817 if (mi == NULL) { 00818 rpmMessage(RPMMESS_ERROR, _("package %s is not installed\n"), *arg); 00819 numFailed++; 00820 } else { 00821 Header h; /* XXX iterator owns the reference */ 00822 count = 0; 00823 while ((h = rpmdbNextIterator(mi)) != NULL) { 00824 unsigned int recOffset = rpmdbGetIteratorOffset(mi); 00825 00826 if (!(count++ == 0 || (ia->installInterfaceFlags & INSTALL_ALLMATCHES))) { 00827 rpmMessage(RPMMESS_ERROR, _("\"%s\" specifies multiple packages\n"), 00828 *arg); 00829 numFailed++; 00830 /*@innerbreak@*/ break; 00831 } 00832 if (recOffset) { 00833 (void) rpmtsAddEraseElement(ts, h, recOffset); 00834 numPackages++; 00835 } 00836 } 00837 } 00838 mi = rpmdbFreeIterator(mi); 00839 } 00840 00841 if (numFailed) goto exit; 00842 00843 if (!(ia->installInterfaceFlags & INSTALL_NODEPS)) { 00844 00845 if (rpmtsCheck(ts)) { 00846 numFailed = numPackages; 00847 stopUninstall = 1; 00848 } 00849 00850 ps = rpmtsProblems(ts); 00851 if (!stopUninstall && rpmpsNumProblems(ps) > 0) { 00852 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n")); 00853 rpmpsPrint(NULL, ps); 00854 numFailed += numPackages; 00855 stopUninstall = 1; 00856 } 00857 ps = rpmpsFree(ps); 00858 } 00859 00860 if (!stopUninstall && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { 00861 if (rpmtsOrder(ts)) { 00862 numFailed += numPackages; 00863 stopUninstall = 1; 00864 } 00865 } 00866 00867 if (numPackages > 0 && !stopUninstall) { 00868 00869 /* Drop added/available package indices and dependency sets. */ 00870 rpmtsClean(ts); 00871 00872 numPackages = rpmtsRun(ts, NULL, 0); 00873 ps = rpmtsProblems(ts); 00874 if (rpmpsNumProblems(ps) > 0) 00875 rpmpsPrint(NULL, ps); 00876 numFailed += numPackages; 00877 stopUninstall = 1; 00878 ps = rpmpsFree(ps); 00879 } 00880 00881 exit: 00882 rpmtsEmpty(ts); 00883 00884 return numFailed; 00885 } 00886 00887 int rpmInstallSource(rpmts ts, const char * arg, 00888 const char ** specFilePtr, const char ** cookie) 00889 { 00890 FD_t fd; 00891 int rc; 00892 00893 00894 fd = Fopen(arg, "r"); 00895 if (fd == NULL || Ferror(fd)) { 00896 rpmMessage(RPMMESS_ERROR, _("cannot open %s: %s\n"), arg, Fstrerror(fd)); 00897 if (fd != NULL) (void) Fclose(fd); 00898 return 1; 00899 } 00900 00901 if (rpmIsVerbose()) 00902 fprintf(stdout, _("Installing %s\n"), arg); 00903 00904 { 00905 rpmVSFlags ovsflags = 00906 rpmtsSetVSFlags(ts, (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD)); 00907 rpmRC rpmrc = rpmInstallSourcePackage(ts, fd, specFilePtr, cookie); 00908 rc = (rpmrc == RPMRC_OK ? 0 : 1); 00909 ovsflags = rpmtsSetVSFlags(ts, ovsflags); 00910 } 00911 if (rc != 0) { 00912 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), arg); 00913 /*@-unqualifiedtrans@*/ 00914 if (specFilePtr && *specFilePtr) 00915 *specFilePtr = _free(*specFilePtr); 00916 if (cookie && *cookie) 00917 *cookie = _free(*cookie); 00918 /*@=unqualifiedtrans@*/ 00919 } 00920 00921 (void) Fclose(fd); 00922 00923 return rc; 00924 }