/** \ingroup rpmcli * \file lib/manifest.c */ #include "system.h" #include #include #include #include "lib/manifest.h" #include "debug.h" char * rpmPermsString(int mode) { char *perms = xstrdup("----------"); if (S_ISREG(mode)) perms[0] = '-'; else if (S_ISDIR(mode)) perms[0] = 'd'; else if (S_ISLNK(mode)) perms[0] = 'l'; else if (S_ISFIFO(mode)) perms[0] = 'p'; else if (S_ISSOCK(mode)) perms[0] = 's'; else if (S_ISCHR(mode)) perms[0] = 'c'; else if (S_ISBLK(mode)) perms[0] = 'b'; else perms[0] = '?'; if (mode & S_IRUSR) perms[1] = 'r'; if (mode & S_IWUSR) perms[2] = 'w'; if (mode & S_IXUSR) perms[3] = 'x'; if (mode & S_IRGRP) perms[4] = 'r'; if (mode & S_IWGRP) perms[5] = 'w'; if (mode & S_IXGRP) perms[6] = 'x'; if (mode & S_IROTH) perms[7] = 'r'; if (mode & S_IWOTH) perms[8] = 'w'; if (mode & S_IXOTH) perms[9] = 'x'; if (mode & S_ISUID) perms[3] = ((mode & S_IXUSR) ? 's' : 'S'); if (mode & S_ISGID) perms[6] = ((mode & S_IXGRP) ? 's' : 'S'); if (mode & S_ISVTX) perms[9] = ((mode & S_IXOTH) ? 't' : 'T'); return perms; } /**@todo Infinite loops through manifest files exist, operator error for now. */ rpmRC rpmReadPackageManifest(FD_t fd, int * argcPtr, const char *** argvPtr) { StringBuf sb = newStringBuf(); char * s = NULL; char * se; int ac = 0; const char ** av = NULL; int argc = (argcPtr ? *argcPtr : 0); const char ** argv = (argvPtr ? *argvPtr : NULL); FILE * f = fdGetFILE(fd); rpmRC rpmrc = RPMRC_OK; int i, j, next, npre; if (f != NULL) while (1) { char line[BUFSIZ]; /* Read next line. */ s = fgets(line, sizeof(line) - 1, f); if (s == NULL) { /* XXX Ferror check needed */ break; } /* Skip comments. */ if ((se = strchr(s, '#')) != NULL) *se = '\0'; /* Trim white space. */ se = s + strlen(s); while (se > s && (se[-1] == '\n' || se[-1] == '\r')) *(--se) = '\0'; while (*s && strchr(" \f\n\r\t\v", *s) != NULL) s++; if (*s == '\0') continue; /* Insure that file contains only ASCII */ if (*s < 32) { rpmrc = RPMRC_NOTFOUND; goto exit; } /* Concatenate next line in buffer. */ *se++ = ' '; *se = '\0'; appendStringBuf(sb, s); } if (s == NULL) /* XXX always true */ s = getStringBuf(sb); if (!(s && *s)) { rpmrc = RPMRC_NOTFOUND; goto exit; } /* Glob manifest items. */ rpmrc = rpmGlob(s, &ac, &av); if (rpmrc != RPMRC_OK) goto exit; rpmlog(RPMLOG_DEBUG, _("adding %d args from manifest.\n"), ac); /* Count non-NULL args, keeping track of 1st arg after last NULL. */ npre = 0; next = 0; if (argv != NULL) for (i = 0; i < argc; i++) { if (argv[i] != NULL) npre++; else if (i >= next) next = i + 1; } /* Copy old arg list, inserting manifest before argv[next]. */ if (argv != NULL) { int nac = npre + ac; const char ** nav = xcalloc((nac + 1), sizeof(*nav)); for (i = 0, j = 0; i < next; i++) { if (argv[i] != NULL) nav[j++] = argv[i]; } if (ac) memcpy(nav + j, av, ac * sizeof(*nav)); if ((argc - next) > 0) memcpy(nav + j + ac, argv + next, (argc - next) * sizeof(*nav)); nav[nac] = NULL; if (argvPtr) *argvPtr = argv = _free(argv); av = _free(av); av = nav; ac = nac; } /* Save new argc/argv list. */ if (argvPtr) { *argvPtr = _free(*argvPtr); *argvPtr = av; } if (argcPtr) *argcPtr = ac; exit: if (argvPtr == NULL || (rpmrc != RPMRC_OK && av)) { if (av) for (i = 0; i < ac; i++) av[i] = _free(av[i]); av = _free(av); } sb = freeStringBuf(sb); /* FIX: *argvPtr may be NULL. */ return rpmrc; }