static FD_t urlOpen(const char * url, int flags, mode_t mode) { FD_t fd; char *dest = NULL; int rc = 1; /* assume failure */ fd = rpmMkTempFile(NULL, &dest); if (fd == NULL) { return NULL; } Fclose(fd); rc = urlGetFile(url, dest); if (rc == 0) { fd = fdOpen(dest, flags, mode); unlink(dest); } else { fd = NULL; } dest = _free(dest); return fd; }
/** @todo Generalize --freshen policies. */ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) { struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu)); rpmRelocation * relocations; char * fileURL = NULL; rpmVSFlags vsflags, ovsflags; int rc; int i; vsflags = setvsFlags(ia); ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD)); if (fileArgv == NULL) goto exit; (void) rpmtsSetFlags(ts, ia->transFlags); relocations = ia->relocations; setNotifyFlag(ia, ts); if ((eiu->relocations = relocations) != NULL) { while (eiu->relocations->oldPath) eiu->relocations++; if (eiu->relocations->newPath == NULL) eiu->relocations = NULL; } /* Build fully globbed list of arguments in argv[argc]. */ for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) { ARGV_t av = NULL; int ac = 0; if (giFlags & RPMGI_NOGLOB) { rc = rpmNoGlob(*eiu->fnp, &ac, &av); } else { char * fn = rpmEscapeSpaces(*eiu->fnp); rc = rpmGlob(fn, &ac, &av); fn = _free(fn); } if (rc || ac == 0) { if (giFlags & RPMGI_NOGLOB) { rpmlog(RPMLOG_ERR, _("File not found: %s\n"), *eiu->fnp); } else { rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp); } eiu->numFailed++; continue; } argvAppend(&(eiu->argv), av); argvFree(av); eiu->argc += ac; } restart: /* Allocate sufficient storage for next set of args. */ if (eiu->pkgx >= eiu->numPkgs) { eiu->numPkgs = eiu->pkgx + eiu->argc; eiu->pkgURL = xrealloc(eiu->pkgURL, (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL)); memset(eiu->pkgURL + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgURL))); eiu->pkgState = xrealloc(eiu->pkgState, (eiu->numPkgs + 1) * sizeof(*eiu->pkgState)); memset(eiu->pkgState + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgState))); } /* Retrieve next set of args, cache on local storage. */ for (i = 0; i < eiu->argc; i++) { fileURL = _free(fileURL); fileURL = eiu->argv[i]; eiu->argv[i] = NULL; switch (urlIsURL(fileURL)) { case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: { char *tfn = NULL; FD_t tfd; if (rpmIsVerbose()) fprintf(stdout, _("Retrieving %s\n"), fileURL); tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn); if (tfd && tfn) { Fclose(tfd); rc = urlGetFile(fileURL, tfn); } else { rc = -1; } if (rc != 0) { rpmlog(RPMLOG_ERR, _("skipping %s - transfer failed\n"), fileURL); eiu->numFailed++; eiu->pkgURL[eiu->pkgx] = NULL; tfn = _free(tfn); break; } eiu->pkgState[eiu->pkgx] = 1; eiu->pkgURL[eiu->pkgx] = tfn; eiu->pkgx++; } break; case URL_IS_PATH: case URL_IS_DASH: /* WRONG WRONG WRONG */ case URL_IS_HKP: /* WRONG WRONG WRONG */ default: eiu->pkgURL[eiu->pkgx] = fileURL; fileURL = NULL; eiu->pkgx++; break; } } fileURL = _free(fileURL); if (eiu->numFailed) goto exit; /* Continue processing file arguments, building transaction set. */ for (eiu->fnp = eiu->pkgURL+eiu->prevx; *eiu->fnp != NULL; eiu->fnp++, eiu->prevx++) { Header h = NULL; const char * fileName; rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp); (void) urlPath(*eiu->fnp, &fileName); if (tryReadHeader(ts, eiu, &h) == RPMRC_FAIL) continue; if (eiu->rpmrc == RPMRC_NOTFOUND) { rc = tryReadManifest(eiu); if (rc == RPMRC_OK) { eiu->prevx++; goto restart; } } if (headerIsSource(h)) { if (ia->installInterfaceFlags & INSTALL_FRESHEN) { headerFree(h); continue; } rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n", eiu->numSRPMS); eiu->sourceURL = xrealloc(eiu->sourceURL, (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL)); eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp; *eiu->fnp = NULL; eiu->numSRPMS++; eiu->sourceURL[eiu->numSRPMS] = NULL; continue; } if (eiu->relocations) { struct rpmtd_s prefixes; headerGet(h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT); if (rpmtdCount(&prefixes) == 1) { eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes)); rpmtdFreeData(&prefixes); } else { rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"), headerGetString(h, RPMTAG_NAME)); eiu->numFailed++; goto exit; } } if (ia->installInterfaceFlags & INSTALL_FRESHEN) if (checkFreshenStatus(ts, h) != 1) { headerFree(h); continue; } if (ia->installInterfaceFlags & INSTALL_REINSTALL) rc = rpmtsAddReinstallElement(ts, h, (fnpyKey)fileName); else rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0, relocations); headerFree(h); if (eiu->relocations) eiu->relocations->oldPath = _free(eiu->relocations->oldPath); switch (rc) { case 0: rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n", eiu->numRPMS); break; case 1: rpmlog(RPMLOG_ERR, _("error reading from file %s\n"), *eiu->fnp); eiu->numFailed++; goto exit; break; default: eiu->numFailed++; goto exit; break; } eiu->numRPMS++; } rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n", eiu->numSRPMS, eiu->numRPMS); if (eiu->numFailed) goto exit; if (eiu->numRPMS) { int rc = rpmcliTransaction(ts, ia, eiu->numPkgs); if (rc < 0) eiu->numFailed += eiu->numRPMS; else if (rc > 0) eiu->numFailed += rc; } if (eiu->numSRPMS && (eiu->sourceURL != NULL)) { rpmcliProgressState = 0; rpmcliProgressTotal = 0; rpmcliProgressCurrent = 0; for (i = 0; i < eiu->numSRPMS; i++) { rpmsqPoll(); if (eiu->sourceURL[i] != NULL) { rc = RPMRC_OK; if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) rc = rpmInstallSource(ts, eiu->sourceURL[i], NULL, NULL); if (rc != 0) eiu->numFailed++; } } } exit: if (eiu->pkgURL != NULL) { for (i = 0; i < eiu->numPkgs; i++) { if (eiu->pkgURL[i] == NULL) continue; if (eiu->pkgState[i] == 1) (void) unlink(eiu->pkgURL[i]); eiu->pkgURL[i] = _free(eiu->pkgURL[i]); } } eiu->pkgState = _free(eiu->pkgState); eiu->pkgURL = _free(eiu->pkgURL); eiu->argv = _free(eiu->argv); rc = eiu->numFailed; free(eiu); rpmtsEmpty(ts); rpmtsSetVSFlags(ts, ovsflags); return rc; }
/** @todo Generalize --freshen policies. */ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) { struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu)); rpmps ps; rpmprobFilterFlags probFilter; rpmRelocation * relocations; char * fileURL = NULL; int stopInstall = 0; rpmVSFlags vsflags, ovsflags, tvsflags; int rc; int xx; int i; if (fileArgv == NULL) goto exit; rpmcliPackagesTotal = 0; (void) rpmtsSetFlags(ts, ia->transFlags); probFilter = ia->probFilter; relocations = ia->relocations; if (ia->installInterfaceFlags & INSTALL_UPGRADE) vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); else vsflags = rpmExpandNumeric("%{?_vsflags_install}"); if (ia->qva_flags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (ia->qva_flags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (ia->qva_flags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD)); { int notifyFlags; notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); xx = rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *) ((long)notifyFlags)); } if ((eiu->relocations = relocations) != NULL) { while (eiu->relocations->oldPath) eiu->relocations++; if (eiu->relocations->newPath == NULL) eiu->relocations = NULL; } /* Build fully globbed list of arguments in argv[argc]. */ for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) { ARGV_t av = NULL; int ac = 0; char * fn; fn = rpmEscapeSpaces(*eiu->fnp); rc = rpmGlob(fn, &ac, &av); fn = _free(fn); if (rc || ac == 0) { rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp); eiu->numFailed++; continue; } argvAppend(&(eiu->argv), av); argvFree(av); eiu->argc += ac; } restart: /* Allocate sufficient storage for next set of args. */ if (eiu->pkgx >= eiu->numPkgs) { eiu->numPkgs = eiu->pkgx + eiu->argc; eiu->pkgURL = xrealloc(eiu->pkgURL, (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL)); memset(eiu->pkgURL + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgURL))); eiu->pkgState = xrealloc(eiu->pkgState, (eiu->numPkgs + 1) * sizeof(*eiu->pkgState)); memset(eiu->pkgState + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgState))); } /* Retrieve next set of args, cache on local storage. */ for (i = 0; i < eiu->argc; i++) { fileURL = _free(fileURL); fileURL = eiu->argv[i]; eiu->argv[i] = NULL; switch (urlIsURL(fileURL)) { case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: { char *tfn; FD_t tfd; if (rpmIsVerbose()) fprintf(stdout, _("Retrieving %s\n"), fileURL); tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn); if (tfd && tfn) { Fclose(tfd); rc = urlGetFile(fileURL, tfn); } else { rc = -1; } if (rc != 0) { rpmlog(RPMLOG_ERR, _("skipping %s - transfer failed\n"), fileURL); eiu->numFailed++; eiu->pkgURL[eiu->pkgx] = NULL; tfn = _free(tfn); break; } eiu->pkgState[eiu->pkgx] = 1; eiu->pkgURL[eiu->pkgx] = tfn; eiu->pkgx++; } break; case URL_IS_PATH: case URL_IS_DASH: /* WRONG WRONG WRONG */ case URL_IS_HKP: /* WRONG WRONG WRONG */ default: eiu->pkgURL[eiu->pkgx] = fileURL; fileURL = NULL; eiu->pkgx++; break; } } fileURL = _free(fileURL); if (eiu->numFailed) goto exit; /* Continue processing file arguments, building transaction set. */ for (eiu->fnp = eiu->pkgURL+eiu->prevx; *eiu->fnp != NULL; eiu->fnp++, eiu->prevx++) { const char * fileName; rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp); (void) urlPath(*eiu->fnp, &fileName); /* Try to read the header from a package file. */ eiu->fd = Fopen(*eiu->fnp, "r.ufdio"); if (eiu->fd == NULL || Ferror(eiu->fd)) { rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, Fstrerror(eiu->fd)); if (eiu->fd != NULL) { xx = Fclose(eiu->fd); eiu->fd = NULL; } eiu->numFailed++; *eiu->fnp = NULL; continue; } /* Read the header, verifying signatures (if present). */ tvsflags = rpmtsSetVSFlags(ts, vsflags); eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h); tvsflags = rpmtsSetVSFlags(ts, tvsflags); xx = Fclose(eiu->fd); eiu->fd = NULL; switch (eiu->rpmrc) { case RPMRC_FAIL: rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp); eiu->numFailed++; *eiu->fnp = NULL; continue; break; case RPMRC_NOTFOUND: goto maybe_manifest; break; case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: default: break; } eiu->isSource = headerIsSource(eiu->h); if (eiu->isSource) { rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n", eiu->numSRPMS); eiu->sourceURL = xrealloc(eiu->sourceURL, (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL)); eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp; *eiu->fnp = NULL; eiu->numSRPMS++; eiu->sourceURL[eiu->numSRPMS] = NULL; continue; } if (eiu->relocations) { struct rpmtd_s prefixes; headerGet(eiu->h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT); if (rpmtdCount(&prefixes) == 1) { eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes)); rpmtdFreeData(&prefixes); } else { const char * name; xx = headerNVR(eiu->h, &name, NULL, NULL); rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"), name); eiu->numFailed++; goto exit; } } /* On --freshen, verify package is installed and newer */ if (ia->installInterfaceFlags & INSTALL_FRESHEN) { rpmdbMatchIterator mi; const char * name; Header oldH; int count; xx = headerNVR(eiu->h, &name, NULL, NULL); mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0); count = rpmdbGetIteratorCount(mi); while ((oldH = rpmdbNextIterator(mi)) != NULL) { if (rpmVersionCompare(oldH, eiu->h) < 0) continue; /* same or newer package already installed */ count = 0; break; } mi = rpmdbFreeIterator(mi); if (count == 0) { eiu->h = headerFree(eiu->h); continue; } /* Package is newer than those currently installed. */ } rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName, (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0, relocations); /* XXX reference held by transaction set */ eiu->h = headerFree(eiu->h); if (eiu->relocations) eiu->relocations->oldPath = _free(eiu->relocations->oldPath); switch(rc) { case 0: rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n", eiu->numRPMS); break; case 1: rpmlog(RPMLOG_ERR, _("error reading from file %s\n"), *eiu->fnp); eiu->numFailed++; goto exit; break; case 2: rpmlog(RPMLOG_ERR, _("file %s requires a newer version of RPM\n"), *eiu->fnp); eiu->numFailed++; goto exit; break; default: eiu->numFailed++; goto exit; break; } eiu->numRPMS++; continue; maybe_manifest: /* Try to read a package manifest. */ eiu->fd = Fopen(*eiu->fnp, "r.fpio"); if (eiu->fd == NULL || Ferror(eiu->fd)) { rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, Fstrerror(eiu->fd)); if (eiu->fd != NULL) { xx = Fclose(eiu->fd); eiu->fd = NULL; } eiu->numFailed++; *eiu->fnp = NULL; break; } /* Read list of packages from manifest. */ /* FIX: *eiu->argv can be NULL */ rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv); if (rc != RPMRC_OK) rpmlog(RPMLOG_ERR, _("%s: not an rpm package (or package manifest): %s\n"), *eiu->fnp, Fstrerror(eiu->fd)); xx = Fclose(eiu->fd); eiu->fd = NULL; /* If successful, restart the query loop. */ if (rc == RPMRC_OK) { eiu->prevx++; goto restart; } eiu->numFailed++; *eiu->fnp = NULL; break; } rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n", eiu->numSRPMS, eiu->numRPMS); if (eiu->numFailed) goto exit; if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) { if (rpmtsCheck(ts)) { eiu->numFailed = eiu->numPkgs; stopInstall = 1; } ps = rpmtsProblems(ts); if (!stopInstall && rpmpsNumProblems(ps) > 0) { rpmlog(RPMLOG_ERR, _("Failed dependencies:\n")); rpmpsPrint(NULL, ps); eiu->numFailed = eiu->numPkgs; stopInstall = 1; } ps = rpmpsFree(ps); } if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { if (rpmtsOrder(ts)) { eiu->numFailed = eiu->numPkgs; stopInstall = 1; } } if (eiu->numRPMS && !stopInstall) { rpmcliPackagesTotal += eiu->numSRPMS; rpmlog(RPMLOG_DEBUG, "installing binary packages\n"); /* Drop added/available package indices and dependency sets. */ rpmtsClean(ts); rc = rpmtsRun(ts, NULL, probFilter); ps = rpmtsProblems(ts); if (rc < 0) { eiu->numFailed += eiu->numRPMS; } else if (rc > 0) { eiu->numFailed += rc; if (rpmpsNumProblems(ps) > 0) rpmpsPrint(stderr, ps); } ps = rpmpsFree(ps); } if (eiu->numSRPMS && !stopInstall) { if (eiu->sourceURL != NULL) for (i = 0; i < eiu->numSRPMS; i++) { rpmdbCheckSignals(); if (eiu->sourceURL[i] == NULL) continue; eiu->fd = Fopen(eiu->sourceURL[i], "r.ufdio"); if (eiu->fd == NULL || Ferror(eiu->fd)) { rpmlog(RPMLOG_ERR, _("cannot open file %s: %s\n"), eiu->sourceURL[i], Fstrerror(eiu->fd)); if (eiu->fd != NULL) { xx = Fclose(eiu->fd); eiu->fd = NULL; } continue; } if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL); if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++; } xx = Fclose(eiu->fd); eiu->fd = NULL; } } exit: if (eiu->pkgURL != NULL) for (i = 0; i < eiu->numPkgs; i++) { if (eiu->pkgURL[i] == NULL) continue; if (eiu->pkgState[i] == 1) (void) unlink(eiu->pkgURL[i]); eiu->pkgURL[i] = _free(eiu->pkgURL[i]); } eiu->pkgState = _free(eiu->pkgState); eiu->pkgURL = _free(eiu->pkgURL); eiu->argv = _free(eiu->argv); rc = eiu->numFailed; free(eiu); rpmtsEmpty(ts); return rc; }
/** * Check that all sources/patches/icons exist locally, fetching if necessary. */ static int prepFetch(Spec spec) /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/ { #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ const char *Smacro; #endif const char *Lmacro, *Lurlfn = NULL; const char *Rmacro, *Rurlfn = NULL; struct Source *sp; struct stat st; rpmRC rpmrc; int ec, rc; char *cp; /* XXX insure that %{_sourcedir} exists */ rpmrc = RPMRC_OK; Lurlfn = rpmGenPath(NULL, "%{?_sourcedir}", NULL); if (Lurlfn != NULL && *Lurlfn != '\0') rpmrc = rpmMkdirPath(Lurlfn, "_sourcedir"); Lurlfn = _free(Lurlfn); if (rpmrc != RPMRC_OK) return -1; /* XXX insure that %{_patchdir} exists */ rpmrc = RPMRC_OK; Lurlfn = rpmGenPath(NULL, "%{?_patchdir}", NULL); if (Lurlfn != NULL && *Lurlfn != '\0') rpmrc = rpmMkdirPath(Lurlfn, "_patchdir"); Lurlfn = _free(Lurlfn); if (rpmrc != RPMRC_OK) return -1; /* XXX insure that %{_icondir} exists */ rpmrc = RPMRC_OK; Lurlfn = rpmGenPath(NULL, "%{?_icondir}", NULL); if (Lurlfn != NULL && *Lurlfn != '\0') rpmrc = rpmMkdirPath(Lurlfn, "_icondir"); Lurlfn = _free(Lurlfn); if (rpmrc != RPMRC_OK) return -1; if (rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE)) rpmlog(RPMLOG_NOTICE, "Checking source and patch file(s):\n"); ec = 0; for (sp = spec->sources; sp != NULL; sp = sp->next) { #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ Smacro = "%{?_specdir}/"; #endif #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ if (! (Lmacro = getSourceDir(sp->flags, sp->source))) #else if (! (Lmacro = getSourceDir(sp->flags))) #endif continue; if (sp->flags & RPMFILE_SOURCE) { Rmacro = "%{?_Rsourcedir}/"; } else if (sp->flags & RPMFILE_PATCH) { Rmacro = "%{?_Rpatchdir}/"; } else if (sp->flags & RPMFILE_ICON) { Rmacro = "%{?_Ricondir}/"; } else continue; #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ /* support splitted source directories, i.e., source files which are alternatively placed into the .spec directory and picked up from there, too. */ Lurlfn = rpmGenPath(NULL, Smacro, sp->source); rc = Lstat(Lurlfn, &st); if (rc == 0) { prepFetchVerbose(sp, &st); goto bottom; } #endif Lurlfn = rpmGenPath(NULL, Lmacro, sp->source); rc = Lstat(Lurlfn, &st); if (rc == 0) { /*@-noeffect@*/ prepFetchVerbose(sp, &st); /*@=noeffect@*/ goto bottom; } /*@-noeffect@*/ prepFetchVerbose(sp, NULL); /*@=noeffect@*/ if (errno != ENOENT) { ec++; rpmlog(RPMLOG_ERR, _("Missing %s%d %s: %s\n"), ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"), sp->num, sp->source, strerror(ENOENT)); goto bottom; } /* try to fetch via macro-controlled remote locations */ cp = rpmExpand(Rmacro, NULL); if (cp != NULL && strcmp(cp, "/") != 0) { cp = _free(cp); Rurlfn = rpmGenPath(NULL, Rmacro, sp->source); if (!(Rurlfn == NULL || Rurlfn[0] == '\0' || !strcmp(Rurlfn, "/") || !strcmp(Lurlfn, Rurlfn))) { rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"), (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, Rurlfn); rc = urlGetFile(Rurlfn, Lurlfn); if (rc == 0) goto bottom; else { rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"), (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc)); ec++; } } } cp = _free(cp); /* try to fetch from original location */ rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"), (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, sp->fullSource); rc = urlGetFile(sp->fullSource, Lurlfn); if (rc == 0) goto bottom; else { rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"), (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc)); ec++; } rpmlog(RPMLOG_ERR, _("Missing %s%d: %s: %s\n"), ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"), sp->num, sp->source, strerror(ENOENT)); ec++; bottom: Lurlfn = _free(Lurlfn); Rurlfn = _free(Rurlfn); } return ec; }
/** * Expand %setup macro into %prep scriptlet. * @param spec build info * @param c source index * @param quietly should -vv be omitted from tar? * @return expanded %setup macro (NULL on error) */ static char *doUntar(rpmSpec spec, uint32_t c, int quietly) { char *fn; char *buf = NULL; char *tar, *taropts; struct Source *sp; rpmCompressedMagic compressed = COMPRESSED_NOT; for (sp = spec->sources; sp != NULL; sp = sp->next) { if ((sp->flags & RPMBUILD_ISSOURCE) && (sp->num == c)) { break; } } if (sp == NULL) { if (c) { rpmlog(RPMLOG_ERR, _("No source number %u\n"), c); } else { rpmlog(RPMLOG_ERR, _("No \"Source:\" tag in the spec file\n")); } return NULL; } fn = rpmGetPath("%{_sourcedir}/", sp->source, NULL); /* FIX: shrug */ taropts = ((rpmIsVerbose() && !quietly) ? "-xvvf" : "-xf"); #ifdef AUTOFETCH_NOT /* XXX don't expect this code to be enabled */ /* XXX * XXX If nosource file doesn't exist, try to fetch from url. * XXX TODO: add a "--fetch" enabler. */ if (sp->flags & RPMTAG_NOSOURCE && autofetchnosource) { struct stat st; int rc; if (lstat(fn, &st) != 0 && errno == ENOENT && urlIsUrl(sp->fullSource) != URL_IS_UNKNOWN) { if ((rc = urlGetFile(sp->fullSource, fn)) != 0) { rpmlog(RPMLOG_ERR, _("Couldn't download nosource %s: %s\n"), sp->fullSource); return NULL; } } } #endif /* XXX On non-build parse's, file cannot be stat'd or read */ if (!spec->force && (rpmFileIsCompressed(fn, &compressed) || checkOwners(fn))) { fn = _free(fn); return NULL; } tar = rpmGetPath("%{__tar}", NULL); if (compressed != COMPRESSED_NOT) { char *zipper, *t = NULL; int needtar = 1; switch (compressed) { case COMPRESSED_NOT: /* XXX can't happen */ case COMPRESSED_OTHER: t = "%{__gzip} -dc"; break; case COMPRESSED_BZIP2: t = "%{__bzip2} -dc"; break; case COMPRESSED_ZIP: if (rpmIsVerbose() && !quietly) t = "%{__unzip}"; else t = "%{__unzip} -qq"; needtar = 0; break; case COMPRESSED_LZMA: case COMPRESSED_XZ: t = "%{__xz} -dc"; break; } zipper = rpmGetPath(t, NULL); if (needtar) { rasprintf(&buf, "%s '%s' | %s %s - \n" "STATUS=$?\n" "if [ $STATUS -ne 0 ]; then\n" " exit $STATUS\n" "fi", zipper, fn, tar, taropts); } else { rasprintf(&buf, "%s '%s'\n" "STATUS=$?\n" "if [ $STATUS -ne 0 ]; then\n" " exit $STATUS\n" "fi", zipper, fn); } zipper = _free(zipper); } else { rasprintf(&buf, "%s %s %s", tar, taropts, fn); } fn = _free(fn); tar = _free(tar); return buf; }
static int addSource(rpmSpec spec, Package pkg, const char *field, rpmTagVal tag) { struct Source *p; int flag = 0; const char *name = NULL; char *nump; char *fieldp = NULL; char *buf = NULL; uint32_t num = 0; switch (tag) { case RPMTAG_SOURCE: flag = RPMBUILD_ISSOURCE; name = "source"; fieldp = spec->line + 6; break; case RPMTAG_PATCH: flag = RPMBUILD_ISPATCH; name = "patch"; fieldp = spec->line + 5; break; case RPMTAG_ICON: flag = RPMBUILD_ISICON; fieldp = NULL; break; default: return -1; break; } /* Get the number */ if (tag != RPMTAG_ICON) { /* We already know that a ':' exists, and that there */ /* are no spaces before it. */ /* This also now allows for spaces and tabs between */ /* the number and the ':' */ char ch; char *fieldp_backup = fieldp; while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) { fieldp++; } ch = *fieldp; *fieldp = '\0'; nump = fieldp_backup; SKIPSPACE(nump); if (nump == NULL || *nump == '\0') { num = flag == RPMBUILD_ISSOURCE ? 0 : INT_MAX; } else { if (parseUnsignedNum(fieldp_backup, &num)) { rpmlog(RPMLOG_ERR, _("line %d: Bad %s number: %s\n"), spec->lineNum, name, spec->line); *fieldp = ch; return RPMRC_FAIL; } } *fieldp = ch; } /* Check whether tags of the same number haven't already been defined */ for (p = spec->sources; p != NULL; p = p->next) { if ( p->num != num ) continue; if ((tag == RPMTAG_SOURCE && p->flags == RPMBUILD_ISSOURCE) || (tag == RPMTAG_PATCH && p->flags == RPMBUILD_ISPATCH)) { rpmlog(RPMLOG_ERR, _("%s %d defined multiple times\n"), name, num); return RPMRC_FAIL; } } /* Create the entry and link it in */ p = xmalloc(sizeof(*p)); p->num = num; p->fullSource = xstrdup(field); p->flags = flag; p->source = strrchr(p->fullSource, '/'); if (p->source) { if ((buf = strrchr(p->source,'='))) p->source = buf; p->source++; } else { p->source = p->fullSource; } if (tag != RPMTAG_ICON) { p->next = spec->sources; spec->sources = p; } else { p->next = pkg->icon; pkg->icon = p; } spec->numSources++; if (tag != RPMTAG_ICON) { char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL); struct stat st; int nofetch = (spec->flags & RPMSPEC_FORCE) || rpmExpandNumeric("%{_disable_source_fetch}"); /* try to download source/patch if it's missing */ if (lstat(body, &st) != 0 && errno == ENOENT && !nofetch) { char *url = NULL; if (urlIsURL(p->fullSource) != URL_IS_UNKNOWN) { url = rstrdup(p->fullSource); } else { url = rpmExpand("%{_default_source_url}", NULL); rstrcat(&url, p->source); if (*url == '%') url = _free(url); } if (url) { rpmlog(RPMLOG_WARNING, _("Downloading %s to %s\n"), url, body); if (urlGetFile(url, body) != 0) { free(url); rpmlog(RPMLOG_ERR, _("Couldn't download %s\n"), p->fullSource); return RPMRC_FAIL; } free(url); } } rasprintf(&buf, "%s%d", (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num); rpmPushMacro(spec->macros, buf, NULL, body, RMIL_SPEC); free(buf); rasprintf(&buf, "%sURL%d", (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num); rpmPushMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC); free(buf); #ifdef WITH_LUA { rpmlua lua = NULL; /* global state */ const char * what = (flag & RPMBUILD_ISPATCH) ? "patches" : "sources"; rpmluaPushTable(lua, what); rpmluav var = rpmluavNew(); rpmluavSetListMode(var, 1); rpmluavSetValue(var, RPMLUAV_STRING, body); rpmluaSetVar(lua, var); rpmluavFree(var); rpmluaPop(lua); } #endif free(body); } return 0; }