FD_t Fopen(const char *path, const char *fmode) { char stdio[20], other[20]; const char *end = NULL; mode_t perms = 0666; int flags = 0; FD_t fd; if (path == NULL || fmode == NULL) return NULL; stdio[0] = '\0'; cvtfmode(fmode, stdio, sizeof(stdio), other, sizeof(other), &end, &flags); if (stdio[0] == '\0') return NULL; if (end == NULL || rstreq(end, "fdio")) { if (_rpmio_debug) fprintf(stderr, "*** Fopen fdio path %s fmode %s\n", path, fmode); fd = fdOpen(path, flags, perms); if (fdFileno(fd) < 0) { if (fd) (void) fdClose(fd); return NULL; } } else { /* XXX gzdio and bzdio here too */ switch (urlIsURL(path)) { case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_HKP: case URL_IS_PATH: case URL_IS_DASH: case URL_IS_FTP: case URL_IS_UNKNOWN: if (_rpmio_debug) fprintf(stderr, "*** Fopen ufdio path %s fmode %s\n", path, fmode); fd = ufdOpen(path, flags, perms); if (fd == NULL || !(fdFileno(fd) >= 0)) return fd; break; default: if (_rpmio_debug) fprintf(stderr, "*** Fopen WTFO path %s fmode %s\n", path, fmode); return NULL; break; } } if (fd) fd = Fdopen(fd, fmode); DBGIO(fd, (stderr, "==>\tFopen(\"%s\",%x,0%o) %s\n", path, (unsigned)flags, (unsigned)perms, fdbg(fd))); return fd; }
/* Return path portion of url (or pointer to NUL if url == NULL) */ urltype urlPath(const char * url, const char ** pathp) { const char *path; urltype type; path = url; type = urlIsURL(url); switch (type) { case URL_IS_FTP: url += sizeof("ftp://") - 1; path = strchr(url, '/'); if (path == NULL) path = url + strlen(url); break; case URL_IS_PATH: url += sizeof("file://") - 1; path = strchr(url, '/'); if (path == NULL) path = url + strlen(url); break; case URL_IS_HKP: url += sizeof("hkp://") - 1; path = strchr(url, '/'); if (path == NULL) path = url + strlen(url); break; case URL_IS_HTTP: url += sizeof("http://") - 1; path = strchr(url, '/'); if (path == NULL) path = url + strlen(url); break; case URL_IS_HTTPS: url += sizeof("https://") - 1; path = strchr(url, '/'); if (path == NULL) path = url + strlen(url); break; case URL_IS_UNKNOWN: if (path == NULL) path = ""; break; case URL_IS_DASH: path = ""; break; } if (pathp) *pathp = path; return type; }
/** @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; }
FTS * Fts_open(char * const * argv, int options, int (*compar) (const FTSENT **, const FTSENT **)) { register FTS *sp; register FTSENT *p, *root; register int nitems; FTSENT *parent = NULL; FTSENT *tmp = NULL; size_t len; /*@-formattype -modfilesys@*/ if (_fts_debug) fprintf(stderr, "--> Fts_open(%p, 0x%x, %p) av[0] %s\n", argv, options, compar, argv[0]); /*@=formattype =modfilesys@*/ /* Options check. */ if (options & ~FTS_OPTIONMASK) { /*@-sysunrecog@*/ __set_errno (EINVAL); /*@=sysunrecog@*/ return (NULL); } /* Allocate/initialize the stream */ if ((sp = malloc((u_int)sizeof(*sp))) == NULL) return (NULL); memset(sp, 0, sizeof(*sp)); sp->fts_compar = (int (*) (const void *, const void *)) compar; sp->fts_opendir = Opendir; sp->fts_readdir = Readdir; sp->fts_closedir = Closedir; sp->fts_stat = Stat; sp->fts_lstat = Lstat; sp->fts_options = options; /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ if (ISSET(FTS_LOGICAL)) SET(FTS_NOCHDIR); /* * Start out with 1K of path space, and enough, in any case, * to hold the user's paths. */ #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif len = fts_maxarglen(argv); if (len < MAXPATHLEN) len = MAXPATHLEN; if (fts_palloc(sp, len)) goto mem1; /* Allocate/initialize root's parent. */ if (*argv != NULL) { if ((parent = fts_alloc(sp, "", 0)) == NULL) goto mem2; parent->fts_level = FTS_ROOTPARENTLEVEL; } /* Allocate/initialize root(s). */ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { /* Don't allow zero-length paths. */ if ((len = strlen(*argv)) == 0) { __set_errno (ENOENT); goto mem3; } /* Use fchdir(2) speedup only if local DASDI. */ switch (urlIsURL(*argv)) { case URL_IS_DASH: case URL_IS_HKP: case URL_IS_MONGO: /* XXX FIXME */ __set_errno (ENOENT); goto mem3; /*@notreached@*/ /*@switchbreak@*/ break; case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: SET(FTS_NOCHDIR); /*@switchbreak@*/ break; case URL_IS_UNKNOWN: case URL_IS_PATH: /*@switchbreak@*/ break; } p = fts_alloc(sp, *argv, (int)len); if (p == NULL) goto mem3; p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) p->fts_info = FTS_D; /* * If comparison routine supplied, traverse in sorted * order; otherwise traverse in the order specified. */ if (compar) { p->fts_link = root; root = p; } else { p->fts_link = NULL; if (root == NULL) tmp = root = p; else { if (tmp != NULL) /* XXX can't happen */ tmp->fts_link = p; tmp = p; } } } if (compar && nitems > 1) root = fts_sort(sp, root, nitems); /* * Allocate a dummy pointer and make fts_read think that we've just * finished the node before the root(s); set p->fts_info to FTS_INIT * so that everything about the "current" node is ignored. */ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) goto mem3; sp->fts_cur->fts_link = root; sp->fts_cur->fts_info = FTS_INIT; /* * If using chdir(2), grab a file descriptor pointing to dot to ensure * that we can get back here; this could be avoided for some paths, * but almost certainly not worth the effort. Slashes, symbolic links, * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = __open(".", O_RDONLY, 0)) < 0) SET(FTS_NOCHDIR); return (sp); mem3: fts_lfree(root); free(parent); mem2: free(sp->fts_path); mem1: free(sp); return (NULL); }
int main(int argc, const char ** argv) #endif /*@globals rpmEVR, RPMVERSION, rpmGlobalMacroContext, rpmCLIMacroContext, h_errno, fileSystem, internalState@*/ /*@modifies fileSystem, internalState@*/ { poptContext optCon = rpmcliInit(argc, (char *const *)argv, optionsTable); rpmts ts = NULL; enum modes bigMode = MODE_UNKNOWN; #if defined(IAM_RPMQV) QVA_t qva = &rpmQVKArgs; #endif #ifdef IAM_RPMBT BTA_t ba = &rpmBTArgs; #endif #ifdef IAM_RPMEIU QVA_t ia = &rpmIArgs; #endif #if defined(IAM_RPMDB) QVA_t da = &rpmDBArgs; #endif #if defined(IAM_RPMK) QVA_t ka = &rpmQVKArgs; #endif #if defined(IAM_RPMBT) || defined(IAM_RPMK) char * passPhrase = ""; #endif pid_t pipeChild = 0; int ec = 0; int status; int p[2]; #ifdef IAM_RPMEIU int xx; #endif #if !defined(__GLIBC__) && !defined(__LCLINT__) environ = envp; #else /* XXX limit the fiddle up to linux for now. */ #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) (void) initproctitle(argc, (char **)argv, environ); #endif #endif /* Set the major mode based on argv[0] */ /*@-nullpass@*/ #ifdef IAM_RPMBT if (!strcmp(__progname, "rpmb")) bigMode = MODE_BUILD; if (!strcmp(__progname, "lt-rpmb")) bigMode = MODE_BUILD; if (!strcmp(__progname, "rpmt")) bigMode = MODE_TARBUILD; if (!strcmp(__progname, "rpmbuild")) bigMode = MODE_BUILD; #endif #ifdef IAM_RPMQV if (!strcmp(__progname, "rpmq")) bigMode = MODE_QUERY; if (!strcmp(__progname, "lt-rpmq")) bigMode = MODE_QUERY; if (!strcmp(__progname, "rpmv")) bigMode = MODE_VERIFY; if (!strcmp(__progname, "rpmquery")) bigMode = MODE_QUERY; if (!strcmp(__progname, "rpmverify")) bigMode = MODE_VERIFY; #endif #ifdef RPMEIU if (!strcmp(__progname, "rpme")) bigMode = MODE_ERASE; if (!strcmp(__progname, "rpmi")) bigMode = MODE_INSTALL; if (!strcmp(__progname, "lt-rpmi")) bigMode = MODE_INSTALL; if (!strcmp(__progname, "rpmu")) bigMode = MODE_INSTALL; #endif /*@=nullpass@*/ #if defined(IAM_RPMQV) /* Jumpstart option from argv[0] if necessary. */ switch (bigMode) { case MODE_QUERY: qva->qva_mode = 'q'; break; case MODE_VERIFY: qva->qva_mode = 'V'; break; case MODE_CHECKSIG: qva->qva_mode = 'K'; break; case MODE_RESIGN: qva->qva_mode = 'R'; break; case MODE_INSTALL: case MODE_ERASE: case MODE_BUILD: case MODE_REBUILD: case MODE_RECOMPILE: case MODE_TARBUILD: case MODE_REBUILDDB: case MODE_UNKNOWN: default: break; } #endif rpmcliConfigured(); #ifdef IAM_RPMBT switch (ba->buildMode) { case 'b': bigMode = MODE_BUILD; break; case 't': bigMode = MODE_TARBUILD; break; case 'B': bigMode = MODE_REBUILD; break; case 'C': bigMode = MODE_RECOMPILE; break; } if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN) bigMode = MODE_BUILD; if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN) bigMode = MODE_BUILD; #endif /* IAM_RPMBT */ #ifdef IAM_RPMDB if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) { if (da->rebuild) { if (bigMode != MODE_UNKNOWN) argerror(_("only one major mode may be specified")); else bigMode = MODE_REBUILDDB; } } #endif /* IAM_RPMDB */ #ifdef IAM_RPMQV if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) { switch (qva->qva_mode) { case 'q': bigMode = MODE_QUERY; break; case 'V': bigMode = MODE_VERIFY; break; } if (qva->qva_sourceCount) { if (qva->qva_sourceCount > 2) argerror(_("one type of query/verify may be performed at a " "time")); } if (qva->qva_flags && (bigMode & ~MODES_QV)) argerror(_("unexpected query flags")); if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) argerror(_("unexpected query format")); if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) argerror(_("unexpected query source")); } #endif /* IAM_RPMQV */ #ifdef IAM_RPMEIU if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE)) { int iflags = (ia->installInterfaceFlags & (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL)); int eflags = (ia->installInterfaceFlags & INSTALL_ERASE); if (iflags & eflags) argerror(_("only one major mode may be specified")); else if (iflags) bigMode = MODE_INSTALL; else if (eflags) bigMode = MODE_ERASE; } #endif /* IAM_RPMEIU */ #ifdef IAM_RPMK if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) { switch (ka->qva_mode) { case RPMSIGN_NONE: ka->sign = 0; break; case RPMSIGN_IMPORT_PUBKEY: case RPMSIGN_CHK_SIGNATURE: bigMode = MODE_CHECKSIG; ka->sign = 0; break; case RPMSIGN_ADD_SIGNATURE: case RPMSIGN_NEW_SIGNATURE: case RPMSIGN_DEL_SIGNATURE: bigMode = MODE_RESIGN; ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE); break; } } #endif /* IAM_RPMK */ #if defined(IAM_RPMEIU) if (!( bigMode == MODE_INSTALL ) && (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE))) argerror(_("only installation, upgrading, rmsource and rmspec may be forced")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE)) argerror(_("files may only be relocated during package installation")); if (ia->relocations && ia->qva_prefix) argerror(_("cannot use --prefix with --relocate or --excludepath")); if (bigMode != MODE_INSTALL && ia->relocations) argerror(_("--relocate and --excludepath may only be used when installing new packages")); if (bigMode != MODE_INSTALL && ia->qva_prefix) argerror(_("--prefix may only be used when installing new packages")); if (ia->qva_prefix && ia->qva_prefix[0] != '/') argerror(_("arguments to --prefix must begin with a /")); if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH)) argerror(_("--hash (-h) may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT)) argerror(_("--percent may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG)) argerror(_("--replacepkgs may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS)) argerror(_("--excludedocs may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && ia->incldocs) argerror(_("--includedocs may only be specified during package " "installation")); if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS)) argerror(_("only one of --excludedocs and --includedocs may be " "specified")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH)) argerror(_("--ignorearch may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS)) argerror(_("--ignoreos may only be specified during package " "installation")); if ((ia->installInterfaceFlags & INSTALL_ALLMATCHES) && bigMode != MODE_ERASE) argerror(_("--allmatches may only be specified during package " "erasure")); if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL) argerror(_("--allfiles may only be specified during package " "installation")); if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) && bigMode != MODE_INSTALL && bigMode != MODE_ERASE) argerror(_("--justdb may only be specified during package " "installation and erasure")); if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers))) argerror(_("script disabling options may only be specified during " "package installation and erasure")); if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers))) argerror(_("trigger disabling options may only be specified during " "package installation and erasure")); if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS)) argerror(_("--nodeps may only be specified during package " "building, rebuilding, recompilation, installation, " "erasure, and verification")); if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST)) argerror(_("--test may only be specified during package installation, " "erasure, and building")); #endif /* IAM_RPMEIU */ if (rpmioRootDir && rpmioRootDir[1] && (bigMode & ~MODES_FOR_ROOT)) argerror(_("--root (-r) may only be specified during " "installation, erasure, querying, and " "database rebuilds")); if (rpmioRootDir) { switch (urlIsURL(rpmioRootDir)) { default: if (bigMode & MODES_FOR_ROOT) break; /*@fallthrough@*/ case URL_IS_UNKNOWN: if (rpmioRootDir[0] != '/') argerror(_("arguments to --root (-r) must begin with a /")); break; } } #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */ integrity_check(__progname, bigMode); #endif #if defined(IAM_RPMBT) || defined(IAM_RPMK) if (0 #if defined(IAM_RPMBT) || ba->sign #endif #if defined(IAM_RPMK) || ka->sign #endif ) /*@-branchstate@*/ { if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD || bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD) { const char ** av; struct stat sb; int errors = 0; if ((av = poptGetArgs(optCon)) == NULL) { fprintf(stderr, _("no files to sign\n")); errors++; } else while (*av) { if (Stat(*av, &sb)) { fprintf(stderr, _("cannot access file %s\n"), *av); errors++; } av++; } if (errors) { ec = errors; goto exit; } if (poptPeekArg(optCon) #if defined(IAM_RPMBT) && !ba->nopassword #endif #if defined(IAM_RPMK) && !ka->nopassword #endif ) { passPhrase = Getpass(_("Enter pass phrase: ")); if (rpmCheckPassPhrase(passPhrase)) { fprintf(stderr, _("Pass phrase check failed\n")); ec = EXIT_FAILURE; goto exit; } fprintf(stderr, _("Pass phrase is good.\n")); /* XXX Getpass() should realloc instead. */ passPhrase = xstrdup(passPhrase); } } } /*@=branchstate@*/ #endif /* IAM_RPMBT || IAM_RPMK */ if (rpmioPipeOutput) { if (pipe(p) < 0) { fprintf(stderr, _("creating a pipe for --pipe failed: %m\n")); goto exit; } if (!(pipeChild = fork())) { (void) close(p[1]); (void) dup2(p[0], STDIN_FILENO); (void) close(p[0]); (void) execl("/bin/sh", "/bin/sh", "-c", rpmioPipeOutput, NULL); fprintf(stderr, _("exec failed\n")); } (void) close(p[0]); (void) dup2(p[1], STDOUT_FILENO); (void) close(p[1]); } ts = rpmtsCreate(); (void) rpmtsSetRootDir(ts, rpmioRootDir); switch (bigMode) { #ifdef IAM_RPMDB case MODE_REBUILDDB: { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}"); rpmVSFlags ovsflags; if (rpmcliQueryFlags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (rpmcliQueryFlags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; ovsflags = rpmtsSetVSFlags(ts, vsflags); ec = rpmtsRebuildDB(ts); vsflags = rpmtsSetVSFlags(ts, ovsflags); } break; #endif /* IAM_RPMDB */ #ifdef IAM_RPMBT case MODE_REBUILD: case MODE_RECOMPILE: { const char * pkg; int nbuilds = 0; while (!rpmIsVerbose()) rpmIncreaseVerbosity(); if (!poptPeekArg(optCon)) argerror(_("no packages files given for rebuild")); ba->buildAmount = RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK; if (bigMode == MODE_REBUILD) { ba->buildAmount |= RPMBUILD_PACKAGEBINARY; ba->buildAmount |= RPMBUILD_RMSOURCE; ba->buildAmount |= RPMBUILD_RMSPEC; ba->buildAmount |= RPMBUILD_CLEAN; ba->buildAmount |= RPMBUILD_RMBUILD; } while ((pkg = poptGetArg(optCon))) { if (nbuilds++ > 0) { rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(NULL, NULL); } ba->specFile = NULL; ba->cookie = NULL; ec = rpmInstallSource(ts, pkg, &ba->specFile, &ba->cookie); if (ec == 0) { ba->rootdir = rpmioRootDir; ba->passPhrase = passPhrase; ec = build(ts, ba, NULL); } ba->cookie = _free(ba->cookie); ba->specFile = _free(ba->specFile); if (ec) /*@loopbreak@*/ break; } } break; case MODE_BUILD: case MODE_TARBUILD: { int nbuilds = 0; #if defined(RPM_VENDOR_OPENPKG) /* no-auto-verbose-increase-for-track-and-fetch */ if (ba->buildChar != 't' && ba->buildChar != 'f') #endif while (!rpmIsVerbose()) rpmIncreaseVerbosity(); switch (ba->buildChar) { case 'a': ba->buildAmount |= RPMBUILD_PACKAGESOURCE; /*@fallthrough@*/ case 'b': ba->buildAmount |= RPMBUILD_PACKAGEBINARY; ba->buildAmount |= RPMBUILD_CLEAN; #if defined(RPM_VENDOR_MANDRIVA) if ((ba->buildChar == 'a' || ba->buildChar == 'b') && ba->shortCircuit) #else if ((ba->buildChar == 'b') && ba->shortCircuit) #endif /*@innerbreak@*/ break; /*@fallthrough@*/ case 'i': ba->buildAmount |= RPMBUILD_INSTALL; ba->buildAmount |= RPMBUILD_CHECK; if ((ba->buildChar == 'i') && ba->shortCircuit) /*@innerbreak@*/ break; /*@fallthrough@*/ case 'c': ba->buildAmount |= RPMBUILD_BUILD; if ((ba->buildChar == 'c') && ba->shortCircuit) /*@innerbreak@*/ break; /*@fallthrough@*/ case 'p': ba->buildAmount |= RPMBUILD_PREP; /*@innerbreak@*/ break; case 'l': ba->buildAmount |= RPMBUILD_FILECHECK; /*@innerbreak@*/ break; case 's': ba->buildAmount |= RPMBUILD_PACKAGESOURCE; #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* no-deps-on-building-srpms */ /* enforce no dependency checking when rolling a source RPM */ ba->noDeps = 1; #endif /*@innerbreak@*/ break; case 't': /* support extracting the "%track" script/section */ ba->buildAmount |= RPMBUILD_TRACK; /* enforce no dependency checking and expansion of %setup, %patch and %prep macros */ ba->noDeps = 1; rpmDefineMacro(NULL, "setup #", RMIL_CMDLINE); rpmDefineMacro(NULL, "patch #", RMIL_CMDLINE); rpmDefineMacro(NULL, "prep %%prep", RMIL_CMDLINE); /*@innerbreak@*/ break; case 'f': ba->buildAmount |= RPMBUILD_FETCHSOURCE; ba->noDeps = 1; /*@innerbreak@*/ break; } if (!poptPeekArg(optCon)) { if (bigMode == MODE_BUILD) argerror(_("no spec files given for build")); else argerror(_("no tar files given for build")); } while ((ba->specFile = poptGetArg(optCon))) { if (nbuilds++ > 0) { rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(NULL, NULL); } ba->rootdir = rpmioRootDir; ba->passPhrase = passPhrase; ba->cookie = NULL; ec = build(ts, ba, NULL); if (ec) /*@loopbreak@*/ break; } } break; #endif /* IAM_RPMBT */ #ifdef IAM_RPMEIU case MODE_ERASE: ia->depFlags = global_depFlags; if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS; if (!poptPeekArg(optCon)) { if (ia->rbtid == 0) argerror(_("no packages given for erase")); ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; ia->rbCheck = rpmcliInstallCheck; ia->rbOrder = rpmcliInstallOrder; ia->rbRun = rpmcliInstallRun; ec += rpmRollback(ts, ia, NULL); } else { ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon)); } break; case MODE_INSTALL: /* RPMTRANS_FLAG_KEEPOBSOLETE */ ia->depFlags = global_depFlags; if (!ia->incldocs) { if (ia->transFlags & RPMTRANS_FLAG_NODOCS) { ; } else if (rpmExpandNumeric("%{_excludedocs}")) ia->transFlags |= RPMTRANS_FLAG_NODOCS; } if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS; /* we've already ensured !(!ia->prefix && !ia->relocations) */ /*@-branchstate@*/ if (ia->qva_prefix) { xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, NULL, ia->qva_prefix); xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, NULL, NULL); } else if (ia->relocations) { xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, NULL, NULL); } /*@=branchstate@*/ if (!poptPeekArg(optCon)) { if (ia->rbtid == 0) argerror(_("no packages given for install")); ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; ia->rbCheck = rpmcliInstallCheck; ia->rbOrder = rpmcliInstallOrder; ia->rbRun = rpmcliInstallRun; /*@i@*/ ec += rpmRollback(ts, ia, NULL); } else { /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */ ec += rpmcliInstall(ts, ia, (const char **)poptGetArgs(optCon)); /*@=compdef =compmempass@*/ } break; #endif /* IAM_RPMEIU */ #ifdef IAM_RPMQV case MODE_QUERY: if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST)) argerror(_("no arguments given for query")); qva->depFlags = global_depFlags; qva->qva_specQuery = rpmspecQuery; ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon)); qva->qva_specQuery = NULL; break; case MODE_VERIFY: { rpmVerifyFlags verifyFlags = VERIFY_ALL; qva->depFlags = global_depFlags; verifyFlags &= ~qva->qva_flags; qva->qva_flags = (rpmQueryFlags) verifyFlags; if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST)) argerror(_("no arguments given for verify")); ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon)); } break; #endif /* IAM_RPMQV */ #ifdef IAM_RPMK case MODE_CHECKSIG: { rpmVerifyFlags verifyFlags = (VERIFY_FDIGEST|VERIFY_HDRCHK|VERIFY_DIGEST|VERIFY_SIGNATURE); verifyFlags &= ~ka->qva_flags; ka->qva_flags = (rpmQueryFlags) verifyFlags; } /*@fallthrough@*/ case MODE_RESIGN: if (!poptPeekArg(optCon)) argerror(_("no arguments given")); ka->passPhrase = passPhrase; ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon)); break; #endif /* IAM_RPMK */ #if !defined(IAM_RPMQV) case MODE_QUERY: case MODE_VERIFY: #endif #if !defined(IAM_RPMK) case MODE_CHECKSIG: case MODE_RESIGN: #endif #if !defined(IAM_RPMDB) case MODE_REBUILDDB: #endif #if !defined(IAM_RPMBT) case MODE_BUILD: case MODE_REBUILD: case MODE_RECOMPILE: case MODE_TARBUILD: #endif #if !defined(IAM_RPMEIU) case MODE_INSTALL: case MODE_ERASE: #endif case MODE_UNKNOWN: #ifdef DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */ if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) { printUsage(optCon, stderr, 0); ec = argc; } #endif break; } #if defined(IAM_RPMBT) || defined(IAM_RPMK) exit: #endif /* IAM_RPMBT || IAM_RPMK */ (void)rpmtsFree(ts); ts = NULL; if (pipeChild) { (void) fclose(stdout); (void) waitpid(pipeChild, &status, 0); } #ifdef IAM_RPMQV qva->qva_queryFormat = _free(qva->qva_queryFormat); #endif #ifdef IAM_RPMBT freeNames(); /* XXX _specPool/_pkgPool teardown should be done somewhere else. */ { extern rpmioPool _pkgPool; extern rpmioPool _specPool; _pkgPool = rpmioFreePool(_pkgPool); _specPool = rpmioFreePool(_specPool); } #endif #ifdef IAM_RPMEIU ia->relocations = rpmfiFreeRelocations(ia->relocations); #endif optCon = rpmcliFini(optCon); /* XXX limit the fiddle up to linux for now. */ #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) (void) finiproctitle(); #endif /* XXX don't overflow single byte exit status */ /* XXX status 255 is special to xargs(1) */ if (ec > 254) ec = 254; rpmlog(RPMLOG_DEBUG, D_("exit code: %d\n"), ec); /*@-globstate@*/ return ec; /*@=globstate@*/ }
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; }