]> pd.if.org Git - zpackage/commitdiff
add symlink support to pkgfiles
authorNathan Wagner <nw@hydaspes.if.org>
Mon, 24 Sep 2018 12:02:52 +0000 (12:02 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Mon, 24 Sep 2018 12:02:52 +0000 (12:02 +0000)
add checks for zero length paths

zpm-pkgfiles.c

index b096c4b1660709ce231386395e03f3c3d5d99208..7b14e670bb534b5545a7bc0a16b62a3e320c4c1f 100644 (file)
@@ -26,7 +26,7 @@ struct config {
        char *dbfile;
        char *pkgid;
        char *rootdir;
-       int errcontinue, errors, verbose, dryrun;
+       int errabort, errors, verbose, dryrun;
        int setuser, setgroup;
        int reverse, exitonerror;
 };
@@ -118,9 +118,9 @@ char *column(char *col, int ncols, char **vals, char **cols) {
        return val;
 }
 
-#define IERR(x) do { conf->log->errmsg = strdup(x); return !conf->errcontinue; } while (0)
+#define IERR(x) do { conf->errors++; conf->log->errmsg = strdup(x); return conf->errabort; } while (0)
 #define COL(x) column(x, ncols, vals, cols)
-#define SYSERR(x) do { conf->log->error = 2; return conf->errcontinue; } while (0)
+#define SYSERR(x) do { conf->log->error = 2; return conf->errabort; } while (0)
 
 static char *ops[] = { "new", "remove", "update", 0 };
 
@@ -162,6 +162,10 @@ static int check_existing(void *f, int ncols, char **vals, char **cols) {
                return 0;
        }
 
+       if (conf->verbose) {
+               fprintf(stderr, "check for existing %s\n", path);
+       }
+
        if (lstat(path, &st) == 0) {
                fprintf(stderr, "%s exists \n", path);
                conf->errors++;
@@ -271,8 +275,14 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
        /* TODO config to dishonor setuid/setgid */
        path = COL("path");
        if (!path) IERR("no file path");
+       if (strlen(path) == 0) {
+               IERR("zero length path not allowed");
+       }
        dest = COL("dest");
        if (!dest) IERR("no file dest");
+       if (strlen(dest) == 0) {
+               IERR("zero length dest not allowed");
+       }
 
        val = COL("mode");
 
@@ -280,7 +290,7 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
        mode = strtoul(val, NULL, 8);
 
        val = COL("filetype");
-       if (!val) {
+       if (!val || strlen(val) == 0) {
                IERR("can't determine file type");
        }
        ftype = *val;
@@ -290,6 +300,10 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                if (!hash) IERR("can't get hash");
        }
 
+       if (conf->verbose) {
+               fprintf(stderr, "installing '%c' %s\n", ftype, dest);
+       }
+
        uid = getuid();
        gid = getgid();
 
@@ -336,6 +350,26 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                if (!zpm_extract(source, hash, dest, mode)) {
                        IERR("can't extract file");
                }
+       } else if (ftype == 'l') {
+               char *target = COL("target");
+               if (!target) {
+                       fprintf(stderr, "no target for symlink %s\n", path);
+                       conf->errors++;
+                       return conf->errabort;
+               }
+
+               if (strlen(target) == 0) {
+                       IERR("zero length symlink not allowed");
+               }
+
+               if (conf->verbose > 1) {
+                       fprintf(stderr, "symlink %s -> %s\n", path, target);
+               }
+               if (symlink(target, path) == -1) {
+                       IERR("can't symlink");
+               }
+       } else {
+               fprintf(stderr, "unhandled filetype %c\n", ftype);
        }
 
        if (conf->setuser && conf->setgroup) {
@@ -425,7 +459,7 @@ int main(int ac, char **av){
 
        struct config conf;
 
-       conf.errcontinue = 0;
+       conf.errabort = 1;
        conf.errors = 0;
        conf.verbose = 0;
        conf.dryrun = 0;
@@ -467,7 +501,7 @@ int main(int ac, char **av){
                        case 'f': pkgdbfile = optarg; break;
                        case 'n': conf.dryrun = 1; break;
                        case 'v': conf.verbose++; break;
-                       case 'C': conf.errcontinue = 1; break;
+                       case 'C': conf.errabort = 0; break;
                        case 'R': conf.rootdir = optarg; break;
                        case 'N': conf.setuser = 0; conf.setgroup = 0; break;
                        default: