static int rpm_debug(lua_State *L) /*@globals internalState @*/ /*@modifies L, internalState @*/ { lua_pushboolean(L, rpmIsDebug()); return 1; }
static int xzdClose( /*@only@*/ void * cookie) /*@globals fileSystem, internalState @*/ /*@modifies fileSystem, internalState @*/ { FD_t fd = c2f(cookie); XZFILE *xzfile; const char * errcookie; int rc; xzfile = xzdFileno(fd); if (xzfile == NULL) return -2; errcookie = strerror(ferror(xzfile->fp)); fdstat_enter(fd, FDSTAT_CLOSE); /*@-dependenttrans@*/ rc = xzclose(xzfile); /*@=dependenttrans@*/ fdstat_exit(fd, FDSTAT_CLOSE, rc); if (fd && rc == -1) fd->errcookie = errcookie; DBGIO(fd, (stderr, "==>\txzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd))); if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "XZDIO", stderr); /*@-branchstate@*/ if (rc == 0) fd = fdFree(fd, "open (xzdClose)"); /*@=branchstate@*/ return rc; }
static int bzdClose(FD_t fd) { BZFILE *bzfile; int rc; bzfile = bzdFileno(fd); if (bzfile == NULL) return -2; /* FIX: check rc */ BZ2_bzclose(bzfile); rc = 0; /* XXX FIXME */ /* XXX TODO: preserve fd if errors */ if (fd) { if (rc == -1) { int zerror = 0; fd->errcookie = BZ2_bzerror(bzfile, &zerror); } } if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "BZDIO", stderr); if (rc == 0) fdFree(fd); return rc; }
static int gzdClose(FD_t fd) { gzFile gzfile; int rc; gzfile = gzdFileno(fd); if (gzfile == NULL) return -2; /* XXX can't happen */ rc = gzclose(gzfile); /* XXX TODO: preserve fd if errors */ if (fd) { if (rc < 0) { fd->errcookie = "gzclose error"; if (rc == Z_ERRNO) { fd->syserrno = errno; fd->errcookie = strerror(fd->syserrno); } } } if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "GZDIO", stderr); if (rc == 0) fdFree(fd); return rc; }
static int lzdClose(FD_t fd) { LZFILE *lzfile; int rc; lzfile = lzdFileno(fd); if (lzfile == NULL) return -2; rc = lzclose(lzfile); /* XXX TODO: preserve fd if errors */ if (fd) { if (rc == -1) { fd->errcookie = "lzclose error"; fd->syserrno = errno; fd->errcookie = strerror(fd->syserrno); } } if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "XZDIO", stderr); if (rc == 0) fdFree(fd); return rc; }
static void printDir(struct dirent * dp, off_t offset, int nentry) { if (rpmIsDebug()) { unsigned d_off = 0; #if !(defined(hpux) || defined(__hpux) || defined(sun) || defined(RPM_OS_AIX)) && \ !defined(__APPLE__) && !defined(__FreeBSD_kernel__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) d_off = (unsigned) dp->d_off, #endif fprintf(stderr, "0x%08x %5d (0x%08x,0x%08x) 0x%04x ", (unsigned)offset, nentry, (unsigned) dp->d_ino, d_off, (unsigned) dp->d_reclen); } if (rpmIsVerbose()) { size_t nb = strlen(dp->d_name); if (!rpmIsDebug()) fprintf(stderr, "\t"); fprintf(stderr, "%s%s\n", dp->d_name, (dp->d_type == DT_DIR && dp->d_name[nb-1] != '/' ? "/" : "")); } }
/* Parse the parameters from the OpenPGP packets that will be needed. */ static rpmRC parsePGP(rpmtd sigtd, const char *type, pgpDig dig) { rpmRC rc = RPMRC_FAIL; int debug = (_print_pkts & rpmIsDebug()); if ((pgpPrtPkts(sigtd->data, sigtd->count, dig, debug) == 0) && (dig->signature.version == 3 || dig->signature.version == 4)) { rc = RPMRC_OK; } else { rpmlog(RPMLOG_ERR, _("skipping %s with unverifiable V%u signature\n"), type, dig->signature.version); } return rc; }
void rpmdsNotify(rpmds ds, const char * where, int rc) { const char *DNEVR; if (!rpmIsDebug()) return; if (!(ds != NULL && ds->i >= 0 && ds->i < ds->Count)) return; if (!(ds->Type != NULL && (DNEVR = rpmdsDNEVR(ds)) != NULL)) return; rpmlog(RPMLOG_DEBUG, "%9s: %-45s %-s %s\n", ds->Type, (rstreq(DNEVR, "cached") ? DNEVR : DNEVR+2), (rc ? _("NO ") : _("YES")), (where != NULL ? where : "")); }
static char * writeScript(const char *cmd, const char *script) { char *fn = NULL; size_t slen = strlen(script); int ok = 0; FD_t fd = rpmMkTempFile("/", &fn); if (Ferror(fd)) goto exit; if (rpmIsDebug() && (rstreq(cmd, "/bin/sh") || rstreq(cmd, "/bin/bash"))) { static const char set_x[] = "set -x\n"; /* Assume failures will be caught by the write below */ Fwrite(set_x, sizeof(set_x[0]), sizeof(set_x)-1, fd); } ok = (Fwrite(script, sizeof(script[0]), slen, fd) == slen); exit: if (!ok) fn = _free(fn); Fclose(fd); return fn; }
void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations, rpmfs fs, Header h) { char ** baseNames; char ** dirNames; uint32_t * dirIndexes; rpm_count_t fileCount, dirCount; int nrelocated = 0; int fileAlloced = 0; char * fn = NULL; int haveRelocatedBase = 0; size_t maxlen = 0; int i, j; struct rpmtd_s bnames, dnames, dindexes, fmodes; if (!addPrefixes(h, relocations, numRelocations)) return; if (rpmIsDebug()) { rpmlog(RPMLOG_DEBUG, "========== relocations\n"); for (i = 0; i < numRelocations; i++) { if (relocations[i].oldPath == NULL) continue; /* XXX can't happen */ if (relocations[i].newPath == NULL) rpmlog(RPMLOG_DEBUG, "%5d exclude %s\n", i, relocations[i].oldPath); else rpmlog(RPMLOG_DEBUG, "%5d relocate %s -> %s\n", i, relocations[i].oldPath, relocations[i].newPath); } } for (i = 0; i < numRelocations; i++) { if (relocations[i].newPath == NULL) continue; size_t len = strlen(relocations[i].newPath); if (len > maxlen) maxlen = len; } headerGet(h, RPMTAG_BASENAMES, &bnames, HEADERGET_MINMEM); headerGet(h, RPMTAG_DIRINDEXES, &dindexes, HEADERGET_ALLOC); headerGet(h, RPMTAG_DIRNAMES, &dnames, HEADERGET_MINMEM); headerGet(h, RPMTAG_FILEMODES, &fmodes, HEADERGET_MINMEM); /* TODO XXX ugh.. use rpmtd iterators & friends instead */ baseNames = bnames.data; dirIndexes = dindexes.data; fileCount = rpmtdCount(&bnames); dirCount = rpmtdCount(&dnames); /* XXX TODO: use rpmtdDup() instead */ dirNames = dnames.data = duparray(dnames.data, dirCount); dnames.flags |= RPMTD_PTR_ALLOCED; /* * For all relocations, we go through sorted file/relocation lists * backwards so that /usr/local relocations take precedence over /usr * ones. */ /* Relocate individual paths. */ for (i = fileCount - 1; i >= 0; i--) { rpmFileTypes ft; int fnlen; size_t len = maxlen + strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1; if (len >= fileAlloced) { fileAlloced = len * 2; fn = xrealloc(fn, fileAlloced); } assert(fn != NULL); /* XXX can't happen */ *fn = '\0'; fnlen = stpcpy( stpcpy(fn, dirNames[dirIndexes[i]]), baseNames[i]) - fn; /* * See if this file path needs relocating. */ /* * XXX FIXME: Would a bsearch of the (already sorted) * relocation list be a good idea? */ for (j = numRelocations - 1; j >= 0; j--) { if (relocations[j].oldPath == NULL) /* XXX can't happen */ continue; len = !rstreq(relocations[j].oldPath, "/") ? strlen(relocations[j].oldPath) : 0; if (fnlen < len) continue; /* * Only subdirectories or complete file paths may be relocated. We * don't check for '\0' as our directory names all end in '/'. */ if (!(fn[len] == '/' || fnlen == len)) continue; if (!rstreqn(relocations[j].oldPath, fn, len)) continue; break; } if (j < 0) continue; rpmtdSetIndex(&fmodes, i); ft = rpmfiWhatis(rpmtdGetNumber(&fmodes)); /* On install, a relocate to NULL means skip the path. */ if (relocations[j].newPath == NULL) { if (ft == XDIR) { /* Start with the parent, looking for directory to exclude. */ for (j = dirIndexes[i]; j < dirCount; j++) { len = strlen(dirNames[j]) - 1; while (len > 0 && dirNames[j][len-1] == '/') len--; if (fnlen != len) continue; if (!rstreqn(fn, dirNames[j], fnlen)) continue; break; } } rpmfsSetAction(fs, i, FA_SKIPNSTATE); rpmlog(RPMLOG_DEBUG, "excluding %s %s\n", ftstring(ft), fn); continue; } /* Relocation on full paths only, please. */ if (fnlen != len) continue; rpmlog(RPMLOG_DEBUG, "relocating %s to %s\n", fn, relocations[j].newPath); nrelocated++; strcpy(fn, relocations[j].newPath); { char * te = strrchr(fn, '/'); if (te) { if (te > fn) te++; /* root is special */ fnlen = te - fn; } else te = fn + strlen(fn); if (!rstreq(baseNames[i], te)) { /* basename changed too? */ if (!haveRelocatedBase) { /* XXX TODO: use rpmtdDup() instead */ bnames.data = baseNames = duparray(baseNames, fileCount); bnames.flags |= RPMTD_PTR_ALLOCED; haveRelocatedBase = 1; } free(baseNames[i]); baseNames[i] = xstrdup(te); } *te = '\0'; /* terminate new directory name */ } /* Does this directory already exist in the directory list? */ for (j = 0; j < dirCount; j++) { if (fnlen != strlen(dirNames[j])) continue; if (!rstreqn(fn, dirNames[j], fnlen)) continue; break; } if (j < dirCount) { dirIndexes[i] = j; continue; } /* Creating new paths is a pita */ dirNames = dnames.data = xrealloc(dnames.data, sizeof(*dirNames) * (dirCount + 1)); dirNames[dirCount] = xstrdup(fn); dirIndexes[i] = dirCount; dirCount++; dnames.count++; } /* Finish off by relocating directories. */ for (i = dirCount - 1; i >= 0; i--) { for (j = numRelocations - 1; j >= 0; j--) { if (relocations[j].oldPath == NULL) /* XXX can't happen */ continue; size_t len = !rstreq(relocations[j].oldPath, "/") ? strlen(relocations[j].oldPath) : 0; if (len && !rstreqn(relocations[j].oldPath, dirNames[i], len)) continue; /* * Only subdirectories or complete file paths may be relocated. We * don't check for '\0' as our directory names all end in '/'. */ if (dirNames[i][len] != '/') continue; if (relocations[j].newPath) { /* Relocate the path */ char *t = NULL; rstrscat(&t, relocations[j].newPath, (dirNames[i] + len), NULL); /* Unfortunately rpmCleanPath strips the trailing slash.. */ (void) rpmCleanPath(t); rstrcat(&t, "/"); rpmlog(RPMLOG_DEBUG, "relocating directory %s to %s\n", dirNames[i], t); free(dirNames[i]); dirNames[i] = t; nrelocated++; } } } /* Save original filenames in header and replace (relocated) filenames. */ if (nrelocated) { saveOrig(h); headerMod(h, &bnames); headerMod(h, &dnames); headerMod(h, &dindexes); } rpmtdFreeData(&bnames); rpmtdFreeData(&dnames); rpmtdFreeData(&dindexes); rpmtdFreeData(&fmodes); free(fn); }
/** * Run an external script. */ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes, const char *sname, rpmlogLvl lvl, FD_t scriptFd, ARGV_t * argvp, const char *script, int arg1, int arg2) { FD_t out = NULL; char * fn = NULL; pid_t pid, reaped; int status; rpmRC rc = RPMRC_FAIL; rpmlog(RPMLOG_DEBUG, "%s: scriptlet start\n", sname); if (script) { fn = writeScript(*argvp[0], script); if (fn == NULL) { rpmlog(RPMLOG_ERR, _("Couldn't create temporary file for %s: %s\n"), sname, strerror(errno)); goto exit; } argvAdd(argvp, fn); if (arg1 >= 0) { argvAddNum(argvp, arg1); } if (arg2 >= 0) { argvAddNum(argvp, arg2); } } if (scriptFd != NULL) { if (rpmIsVerbose()) { out = fdDup(Fileno(scriptFd)); } else { out = Fopen("/dev/null", "w.fdio"); if (Ferror(out)) { out = fdDup(Fileno(scriptFd)); } } } else { out = fdDup(STDOUT_FILENO); } if (out == NULL) { rpmlog(RPMLOG_ERR, _("Couldn't duplicate file descriptor: %s: %s\n"), sname, strerror(errno)); goto exit; } pid = fork(); if (pid == (pid_t) -1) { rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"), sname, strerror(errno)); goto exit; } else if (pid == 0) {/* Child */ rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n", sname, *argvp[0], (unsigned)getpid()); /* Run scriptlet post fork hook for all plugins */ if (rpmpluginsCallScriptletForkPost(plugins, *argvp[0], RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC) != RPMRC_FAIL) { doScriptExec(*argvp, prefixes, scriptFd, out); } else { _exit(126); /* exit 126 for compatibility with bash(1) */ } } do { reaped = waitpid(pid, &status, 0); } while (reaped == -1 && errno == EINTR); rpmlog(RPMLOG_DEBUG, "%s: waitpid(%d) rc %d status %x\n", sname, (unsigned)pid, (unsigned)reaped, status); if (reaped < 0) { rpmlog(lvl, _("%s scriptlet failed, waitpid(%d) rc %d: %s\n"), sname, pid, reaped, strerror(errno)); } else if (!WIFEXITED(status) || WEXITSTATUS(status)) { if (WIFSIGNALED(status)) { rpmlog(lvl, _("%s scriptlet failed, signal %d\n"), sname, WTERMSIG(status)); } else { rpmlog(lvl, _("%s scriptlet failed, exit status %d\n"), sname, WEXITSTATUS(status)); } } else { /* if we get this far we're clear */ rc = RPMRC_OK; } exit: if (out) Fclose(out); /* XXX dup'd STDOUT_FILENO */ if (fn) { if (!rpmIsDebug()) unlink(fn); free(fn); } return rc; }