]> pd.if.org Git - zpackage/commitdiff
add check for symlink removal in syncfs
authorNathan Wagner <nw@hydaspes.if.org>
Sun, 9 Dec 2018 11:40:40 +0000 (11:40 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Sun, 9 Dec 2018 11:40:40 +0000 (11:40 +0000)
Creating a symlink will error if the file already exists, so we check
for a symlink with a different target and mark it for removal before
creation.  This has a small race condition, and there may be a case
where the old symlink gets deleted but the new one does not get created.

zpm-syncfs.c

index c630963030dd001de7bacf2043964f41bfe2b43d..2360f7c167ee1ee658af6907f2a8a36c4618c5db 100644 (file)
@@ -841,6 +841,14 @@ static int install(struct config *conf, struct nitem *item, unsigned int flags)
 
        source = conf->src ? conf->src : conf->log;
 
+       if (mkleading) {
+               rv = create_leading_dirs(item->dest);
+               if (!rv) {
+                       setsyserr(conf, "can't create leading dirs for %s", item->dest);
+                       return failure;
+               }
+       }
+
        if (unlink_file) {
                rv = remove_existing(conf, item->dest);
        } else if (rm_dir) {
@@ -851,14 +859,6 @@ static int install(struct config *conf, struct nitem *item, unsigned int flags)
                return failure;
        }
 
-       if (mkleading) {
-               rv = create_leading_dirs(item->dest);
-               if (!rv) {
-                       setsyserr(conf, "can't create leading dirs for %s", item->dest);
-                       return failure;
-               }
-       }
-
        errno = 0;
        switch (item->ftype) {
                case 'r': rv = zpm_extract(source, item->hash, item->dest, item->mode);
@@ -1278,13 +1278,14 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                                /* fix md */
                                return set_md(conf, &nitem);
                        }
-                       if (mdsame && !hashsame) {
-                               /* install */
-                               return install(conf, &nitem, 3);
-                       }
-                       if (!mdsame && !hashsame) {
-                               /* install */
-                               return install(conf, &nitem, 3);
+
+                       if (!hashsame) {
+                               /* doesn't matter on the md */
+                               int flags = INS_MD | INS_CLD;
+                               if (nitem.ftype == 'l') {
+                                       flags |= INS_UNLINK;
+                               }
+                               return install(conf, &nitem, flags);
                        }
                }