summaryrefslogtreecommitdiff
path: root/lib/manifest.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/manifest.c')
-rw-r--r--lib/manifest.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/manifest.c b/lib/manifest.c
new file mode 100644
index 000000000..30345cfa0
--- /dev/null
+++ b/lib/manifest.c
@@ -0,0 +1,162 @@
+/** \ingroup rpmcli
+ * \file lib/manifest.c
+ */
+
+#include "system.h"
+
+#include <rpmio_internal.h>
+#include "stringbuf.h"
+#include "manifest.h"
+#include "misc.h"
+#include "debug.h"
+
+/*@access StringBuf @*/
+
+/**
+ * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
+ * @param this memory to free
+ * @retval NULL always
+ */
+static /*@null@*/ void * _free(/*@only@*/ /*@null@*/ const void * this) {
+ if (this) free((void *)this);
+ return NULL;
+}
+
+char * rpmPermsString(int mode)
+{
+ char *perms = xstrdup("----------");
+
+ 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';
+
+ /*@-unrecog@*/
+ 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');
+ /*@=unrecog@*/
+
+ return perms;
+}
+
+/**@todo Infinite loops through manifest files exist, operator error for now. */
+int rpmReadPackageManifest(FD_t fd, int * argcPtr, const char *** argvPtr)
+{
+ StringBuf sb = newStringBuf();
+ char * s, *se;
+ int ac = 0;
+ const char ** av = NULL;
+ int argc = (argcPtr ? *argcPtr : 0);
+ const char ** argv = (argvPtr ? *argvPtr : NULL);
+ int rc = 0;
+ int i;
+
+ while (1) {
+ char line[BUFSIZ];
+
+ /* Read next line. */
+ s = fgets(line, sizeof(line) - 1, fdGetFp(fd));
+ 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) {
+ rc = 1;
+ 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)) {
+ rc = 1;
+ goto exit;
+ }
+
+ /* Glob manifest items. */
+ rc = rpmGlob(s, &ac, &av);
+ if (rc) goto exit;
+
+ /* Find 1st existing unprocessed arg. */
+ for (i = 0; i < argc; i++)
+ if (argv && argv[i]) break;
+
+ /* Concatenate existing unprocessed args after manifest contents. */
+ if (argv && i < argc) {
+ int nac = ac + (argc - i);
+ const char ** nav = xcalloc((nac + 1), sizeof(*nav));
+
+ if (ac)
+ memcpy(nav, av, ac * sizeof(*nav));
+ if ((argc - i) > 0)
+ memcpy(nav + ac, argv + i, (argc - i) * sizeof(*nav));
+ nav[nac] = NULL;
+
+ *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 || (rc != 0 && av)) {
+ for (i = 0; i < ac; i++)
+ av[i] = _free(av[i]);
+ av = _free(av);
+ }
+ freeStringBuf(sb);
+ return rc;
+}