csomh / source-git / rpm

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