1 /** \ingroup rpmcli
2  * \file lib/manifest.c
3  */
4 
5 #include "system.h"
6 
7 #include <rpm/rpmlog.h>
8 #include <rpm/rpmfileutil.h>
9 #include <rpm/argv.h>
10 
11 #include "lib/manifest.h"
12 
13 #include "debug.h"
14 
15 
rpmPermsString(int mode)16 char * rpmPermsString(int mode)
17 {
18     char *perms = xstrdup("----------");
19 
20     if (S_ISREG(mode))
21 	perms[0] = '-';
22     else if (S_ISDIR(mode))
23 	perms[0] = 'd';
24     else if (S_ISLNK(mode))
25 	perms[0] = 'l';
26     else if (S_ISFIFO(mode))
27 	perms[0] = 'p';
28     else if (S_ISSOCK(mode))
29 	perms[0] = 's';
30     else if (S_ISCHR(mode))
31 	perms[0] = 'c';
32     else if (S_ISBLK(mode))
33 	perms[0] = 'b';
34     else
35 	perms[0] = '?';
36 
37     if (mode & S_IRUSR) perms[1] = 'r';
38     if (mode & S_IWUSR) perms[2] = 'w';
39     if (mode & S_IXUSR) perms[3] = 'x';
40 
41     if (mode & S_IRGRP) perms[4] = 'r';
42     if (mode & S_IWGRP) perms[5] = 'w';
43     if (mode & S_IXGRP) perms[6] = 'x';
44 
45     if (mode & S_IROTH) perms[7] = 'r';
46     if (mode & S_IWOTH) perms[8] = 'w';
47     if (mode & S_IXOTH) perms[9] = 'x';
48 
49     if (mode & S_ISUID)
50 	perms[3] = ((mode & S_IXUSR) ? 's' : 'S');
51 
52     if (mode & S_ISGID)
53 	perms[6] = ((mode & S_IXGRP) ? 's' : 'S');
54 
55     if (mode & S_ISVTX)
56 	perms[9] = ((mode & S_IXOTH) ? 't' : 'T');
57 
58     return perms;
59 }
60 
61 /**@todo Infinite loops through manifest files exist, operator error for now. */
rpmReadPackageManifest(FD_t fd,int * argcPtr,char *** argvPtr)62 rpmRC rpmReadPackageManifest(FD_t fd, int * argcPtr, char *** argvPtr)
63 {
64     ARGV_t sb = NULL;
65     char * s = NULL;
66     char * se;
67     int ac = 0;
68     char ** av = NULL;
69     int argc = (argcPtr ? *argcPtr : 0);
70     char ** argv = (argvPtr ? *argvPtr : NULL);
71     FILE * f = fdopen(Fileno(fd), "r");
72     rpmRC rpmrc = RPMRC_OK;
73     int i, j, next, npre;
74 
75     if (f != NULL)
76     while (1) {
77 	char line[BUFSIZ];
78 
79 	/* Read next line. */
80 	s = fgets(line, sizeof(line) - 1, f);
81 	if (s == NULL) {
82 	    /* XXX Ferror check needed */
83 	    break;
84 	}
85 
86 	/* Skip comments. */
87 	if (*s == '#')
88 	    continue;
89 
90 	/* Trim white space. */
91 	se = s + strlen(s);
92 	while (se > s && (se[-1] == '\n' || se[-1] == '\r'))
93 	    *(--se) = '\0';
94 	while (*s && strchr(" \f\n\r\t\v", *s) != NULL)
95 	    s++;
96 	if (*s == '\0') continue;
97 
98 	/* Sanity checks: skip obviously binary lines */
99 	if (*s < 32) {
100 	    s = NULL;
101 	    rpmrc = RPMRC_NOTFOUND;
102 	    goto exit;
103 	}
104 
105 	/* Concatenate next line in buffer. */
106 	*se = '\0';
107 	argvAdd(&sb, s);
108     }
109 
110     s = argvJoin(sb, " ");
111 
112     if (!(s && *s)) {
113 	rpmrc = RPMRC_NOTFOUND;
114 	goto exit;
115     }
116 
117     /* Glob manifest items. */
118     rpmrc = (rpmGlob(s, &ac, &av) == 0 ? RPMRC_OK : RPMRC_FAIL);
119     if (rpmrc != RPMRC_OK) goto exit;
120 
121     /* Sanity check: skip dash (for stdin) */
122     for (i = 0; i < ac; i++) {
123 	if (rstreq(av[i], "-")) {
124 	    rpmrc = RPMRC_NOTFOUND;
125 	    goto exit;
126 	}
127     }
128 
129     rpmlog(RPMLOG_DEBUG, "adding %d args from manifest.\n", ac);
130 
131     /* Count non-NULL args, keeping track of 1st arg after last NULL. */
132     npre = 0;
133     next = 0;
134     if (argv != NULL)
135     for (i = 0; i < argc; i++) {
136 	if (argv[i] != NULL)
137 	    npre++;
138 	else if (i >= next)
139 	    next = i + 1;
140     }
141 
142     /* Copy old arg list, inserting manifest before argv[next]. */
143     if (argv != NULL) {
144 	int nac = npre + ac;
145 	char ** nav = xcalloc((nac + 1), sizeof(*nav));
146 
147 	for (i = 0, j = 0; i < next; i++) {
148 	    if (argv[i] != NULL)
149 		nav[j++] = argv[i];
150 	}
151 
152 	if (ac)
153 	    memcpy(nav + j, av, ac * sizeof(*nav));
154 	if ((argc - next) > 0)
155 	    memcpy(nav + j + ac, argv + next, (argc - next) * sizeof(*nav));
156 	nav[nac] = NULL;
157 
158 	if (argvPtr)
159 	    *argvPtr = argv = _free(argv);
160 	av = _free(av);
161 	av = nav;
162 	ac = nac;
163     }
164 
165     /* Save new argc/argv list. */
166     if (argvPtr) {
167 	*argvPtr = _free(*argvPtr);
168 	*argvPtr = av;
169     }
170     if (argcPtr)
171 	*argcPtr = ac;
172 
173 exit:
174     if (f)
175 	fclose(f);
176     if (argvPtr == NULL || (rpmrc != RPMRC_OK && av)) {
177 	if (av)
178 	for (i = 0; i < ac; i++)
179 	   av[i] = _free(av[i]);
180 	av = _free(av);
181     }
182     argvFree(sb);
183     free(s);
184     /* FIX: *argvPtr may be NULL. */
185     return rpmrc;
186 }
187