diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-01-01 13:25:55 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-01-01 13:33:04 +0200 |
commit | 24e6dfa7cffceea0cac0f3cc349192788f040939 (patch) | |
tree | c2bd53e9bc58873c8187e6bd622ae152b35d1d51 /src/diskio.c | |
parent | 2bdd70d698c63d32f25b4f1142e09f5eaef4812a (diff) | |
download | wydawca-24e6dfa7cffceea0cac0f3cc349192788f040939.tar.gz wydawca-24e6dfa7cffceea0cac0f3cc349192788f040939.tar.bz2 |
Update copyright years. Switch to a familiar style.
Diffstat (limited to 'src/diskio.c')
-rw-r--r-- | src/diskio.c | 1155 |
1 files changed, 557 insertions, 598 deletions
diff --git a/src/diskio.c b/src/diskio.c index 751d684..209d387 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -1,5 +1,5 @@ /* wydawca - automatic release submission daemon - Copyright (C) 2007-2012 Sergey Poznyakoff + Copyright (C) 2007-2013 Sergey Poznyakoff Wydawca is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -18,268 +18,245 @@ /* Return true if ARG is NULL or is a sub-directory of DIR */ int -sub_dir_p (const char *arg, const char *dir) +sub_dir_p(const char *arg, const char *dir) { - int dlen; + int dlen; - if (!arg) - return 0; + if (!arg) + return 0; - dlen = strlen (dir); + dlen = strlen(dir); - return strlen (arg) > dlen - && memcmp (dir, arg, dlen) == 0 - && arg[dlen] == '/'; + return strlen(arg) > dlen + && memcmp(dir, arg, dlen) == 0 && arg[dlen] == '/'; } /* Concatenate BASE directory name, a single directory separator (/) and NAME. Return in PBASELEN the length of BASE, not counting eventual trailing slash. */ char * -concat_dir (const char *base, const char *name, size_t *pbaselen) +concat_dir(const char *base, const char *name, size_t * pbaselen) { - size_t len = strlen (base); - size_t size; - char *dir; - - while (len > 0 && base[len-1] == '/') - len--; - - size = len + 1 + strlen (name); - dir = grecs_malloc (size + 1); - memcpy (dir, base, len); - dir[len++] = '/'; - strcpy (dir + len, name); - - if (pbaselen) - *pbaselen = len; - return dir; + size_t len = strlen(base); + size_t size; + char *dir; + + while (len > 0 && base[len - 1] == '/') + len--; + + size = len + 1 + strlen(name); + dir = grecs_malloc(size + 1); + memcpy(dir, base, len); + dir[len++] = '/'; + strcpy(dir + len, name); + + if (pbaselen) + *pbaselen = len; + return dir; } /* Create the directory DIR, eventually creating all intermediate directories starting from DIR + BASELEN. */ int -create_hierarchy (char *dir, size_t baselen) +create_hierarchy(char *dir, size_t baselen) { - int rc; - struct stat st; - char *p; - - if (stat (dir, &st) == 0) - { - if (!S_ISDIR (st.st_mode)) - { - logmsg (LOG_ERR, _("component %s is not a directory"), dir); - return 1; + int rc; + struct stat st; + char *p; + + if (stat(dir, &st) == 0) { + if (!S_ISDIR(st.st_mode)) { + logmsg(LOG_ERR, _("component %s is not a directory"), + dir); + return 1; + } + return 0; + } else if (errno != ENOENT) { + logmsg(LOG_ERR, _("cannot stat file %s: %s"), dir, + strerror(errno)); + return 1; } - return 0; - } - else if (errno != ENOENT) - { - logmsg (LOG_ERR, _("cannot stat file %s: %s"), dir, strerror (errno)); - return 1; - } - - p = strrchr (dir, '/'); - if (p) - { - if (p - dir + 1 < baselen) - { - logmsg (LOG_ERR, _("base directory %s does not exist"), dir); - return 1; + + p = strrchr(dir, '/'); + if (p) { + if (p - dir + 1 < baselen) { + logmsg(LOG_ERR, _("base directory %s does not exist"), + dir); + return 1; + } + *p = 0; } - *p = 0; - } - - rc = create_hierarchy (dir, baselen); - if (rc == 0) - { - if (p) - *p = '/'; - if (mkdir (dir, MKDIR_PERMISSIONS)) - { - logmsg (LOG_ERR, _("cannot create directory %s: %s"), - dir, strerror (errno)); - rc = 1; + + rc = create_hierarchy(dir, baselen); + if (rc == 0) { + if (p) + *p = '/'; + if (mkdir(dir, MKDIR_PERMISSIONS)) { + logmsg(LOG_ERR, _("cannot create directory %s: %s"), + dir, strerror(errno)); + rc = 1; + } } - } - return rc; + return rc; } /* Create a directory BASE/NAME (with eventual intermediate directories in NAME). Do nothing if dry_run_mode is set. */ char * -create_directory (const char *base, const char *name) +create_directory(const char *base, const char *name) { - size_t baselen; - char *dir = concat_dir (base, name, &baselen); - - if (!dry_run_mode) - { - if (create_hierarchy (dir, baselen)) - { - free (dir); - dir = NULL; + size_t baselen; + char *dir = concat_dir(base, name, &baselen); + + if (!dry_run_mode) { + if (create_hierarchy(dir, baselen)) { + free(dir); + dir = NULL; + } } - } - return dir; + return dir; } - /* Copy FILE to DST_FILE. */ int -copy_file (const char *file, const char *dst_file) +copy_file(const char *file, const char *dst_file) { - int in_fd, out_fd; - struct stat st; - int rc; - char *buf; - size_t bufsize; - size_t fsize; - - in_fd = open (file, O_RDONLY); - - if (in_fd == -1) - { - logmsg (LOG_ERR, _("cannot open source file %s for reading: %s"), - file, strerror (errno)); - return 1; - } - - if (fstat (in_fd, &st)) - { - logmsg (LOG_ERR, _("cannot stat source file %s: %s"), - file, strerror (errno)); - close (in_fd); - return 1; - } - - out_fd = creat (dst_file, CREAT_PERMISSIONS); - if (out_fd == -1) - { - logmsg (LOG_ERR, _("cannot create destination file %s: %s"), - dst_file, strerror (errno)); - close (in_fd); - return 1; - } - - buf = NULL; - fsize = st.st_size; - - for (bufsize = fsize; bufsize > 0 && (buf = malloc (bufsize)) == NULL; - bufsize /= 2) - ; - if (bufsize == 0) - grecs_alloc_die (); - - rc = 0; - while (fsize > 0) - { - size_t rest; - size_t rdbytes; - - rest = fsize > bufsize ? bufsize : fsize; - rdbytes = read (in_fd, buf, rest); - if (rdbytes == -1) - { - logmsg (LOG_ERR, _("unexpected error reading %s: %s"), - file, strerror (errno)); - rc = 1; - break; + int in_fd, out_fd; + struct stat st; + int rc; + char *buf; + size_t bufsize; + size_t fsize; + + in_fd = open(file, O_RDONLY); + + if (in_fd == -1) { + logmsg(LOG_ERR, + _("cannot open source file %s for reading: %s"), + file, strerror(errno)); + return 1; + } + + if (fstat(in_fd, &st)) { + logmsg(LOG_ERR, + _("cannot stat source file %s: %s"), + file, strerror(errno)); + close(in_fd); + return 1; } - rest = write (out_fd, buf, rdbytes); - if (rest == -1) - { - logmsg (LOG_ERR, _("unexpected error writing to %s: %s"), - dst_file, strerror (errno)); - rc = 1; - break; + + out_fd = creat(dst_file, CREAT_PERMISSIONS); + if (out_fd == -1) { + logmsg(LOG_ERR, + _("cannot create destination file %s: %s"), + dst_file, strerror(errno)); + close(in_fd); + return 1; } - else if (rest != rdbytes) - { - logmsg (LOG_ERR, _("short write on %s"), dst_file); - rc = 1; + + buf = NULL; + fsize = st.st_size; + + for (bufsize = fsize; bufsize > 0 && (buf = malloc(bufsize)) == NULL; + bufsize /= 2) ; + if (bufsize == 0) + grecs_alloc_die(); + + rc = 0; + while (fsize > 0) { + size_t rest; + size_t rdbytes; + + rest = fsize > bufsize ? bufsize : fsize; + rdbytes = read(in_fd, buf, rest); + if (rdbytes == -1) { + logmsg(LOG_ERR, _("unexpected error reading %s: %s"), + file, strerror(errno)); + rc = 1; + break; + } + rest = write(out_fd, buf, rdbytes); + if (rest == -1) { + logmsg(LOG_ERR, + _("unexpected error writing to %s: %s"), + dst_file, strerror(errno)); + rc = 1; + break; + } else if (rest != rdbytes) { + logmsg(LOG_ERR, _("short write on %s"), dst_file); + rc = 1; + } + fsize -= rdbytes; } - fsize -= rdbytes; - } - free (buf); - - close (in_fd); - close (out_fd); - if (rc) - unlink (dst_file); - return rc; + free(buf); + + close(in_fd); + close(out_fd); + if (rc) + unlink(dst_file); + return rc; } /* Move FILE to DST_FILE. If they reside on different devices, use copy_file + unlink. */ int -do_move_file (const char *file, const char *dst_file) +do_move_file(const char *file, const char *dst_file) { - int rc = 0; - - if (rename (file, dst_file)) - { - if (errno == EXDEV) - { - if (copy_file (file, dst_file)) - { - logmsg (LOG_CRIT, _("cannot copy %s to %s: %s"), - file, dst_file, strerror (errno)); - rc = 1; - } - else if (unlink (file)) - { - logmsg (LOG_ERR, _("cannot unlink %s: %s"), - file, strerror (errno)); - } - } - else - { - logmsg (LOG_CRIT, _("cannot move %s to %s: %s"), - file, dst_file, strerror (errno)); - rc = 1; + int rc = 0; + + if (rename(file, dst_file)) { + if (errno == EXDEV) { + if (copy_file(file, dst_file)) { + logmsg(LOG_CRIT, _("cannot copy %s to %s: %s"), + file, dst_file, strerror(errno)); + rc = 1; + } else if (unlink(file)) { + logmsg(LOG_ERR, _("cannot unlink %s: %s"), + file, strerror(errno)); + } + } else { + logmsg(LOG_CRIT, _("cannot move %s to %s: %s"), + file, dst_file, strerror(errno)); + rc = 1; + } } - } - return rc; + return rc; } /* Append the FILE to the tar ARCHIVE. Do nothing if dry_run_mode is set. */ int -tar_append_file (const char *archive, const char *file) +tar_append_file(const char *archive, const char *file) { - const char *argv[6]; - - if (debug_level) - logmsg (LOG_DEBUG, _("tarring %s to %s"), file, archive); - if (dry_run_mode) - { - UPDATE_STATS (STAT_ARCHIVES); - return 0; - } - - argv[0] = tar_command_name; - argv[1] = "-f"; - argv[2] = archive; - argv[3] = "-r"; - argv[4] = file; - argv[5] = NULL; - - switch (wydawca_exec (6, argv, NULL)) - { - case exec_success: - UPDATE_STATS (STAT_ARCHIVES); - return 0; - - case exec_fail: - case exec_error: - logmsg (LOG_ERR, _("cannot archive %s"), file); - break; - } - - return 1; + const char *argv[6]; + + if (debug_level) + logmsg(LOG_DEBUG, _("tarring %s to %s"), file, archive); + if (dry_run_mode) { + UPDATE_STATS(STAT_ARCHIVES); + return 0; + } + + argv[0] = tar_command_name; + argv[1] = "-f"; + argv[2] = archive; + argv[3] = "-r"; + argv[4] = file; + argv[5] = NULL; + + switch (wydawca_exec(6, argv, NULL)) { + case exec_success: + UPDATE_STATS(STAT_ARCHIVES); + return 0; + + case exec_fail: + case exec_error: + logmsg(LOG_ERR, _("cannot archive %s"), file); + break; + } + + return 1; } /* Backup a file to a directory. @@ -292,129 +269,126 @@ tar_append_file (const char *archive, const char *file) Do nothing if dry_run_mode is set. */ int -backup_file (const char *dst_file, const char *dst_dir, const char *file, - const struct archive_descr *archive, - const char *reldir) +backup_file(const char *dst_file, const char *dst_dir, const char *file, + const struct archive_descr *archive, const char *reldir) { - int rc = 0; - char *adir; - char *file_name; - - if (archive->name[0] == '/') - adir = create_directory (archive->name, reldir); - else - adir = create_directory (dst_dir, archive->name); - if (!adir) - return 1; - - file_name = concat_dir (adir, file, NULL); - if (access (file_name, F_OK) == 0) - { - if (archive->backup_type == no_backups) - { - if (debug_level) - logmsg (LOG_DEBUG, _("removing previous archive file `%s'"), - file_name); - if (!dry_run_mode && unlink (file_name)) - { - logmsg (LOG_ERR, - _("cannot unlink previous archive file `%s': %s"), - file_name, strerror (errno)); - free (file_name); - free (adir); - return 1; - } - } - else - { - char *archive_file_name = - find_backup_file_name (file_name, archive->backup_type); - if (debug_level) - logmsg (LOG_DEBUG, - _("backing up previous archive file `%s' to `%s'"), - file_name, archive_file_name); - if (!dry_run_mode) - { - rc = do_move_file (file_name, archive_file_name); - if (rc) - { - logmsg (LOG_ERR, _("backing `%s' up as `%s' failed: %s"), - file_name, archive_file_name, strerror (errno)); - free (archive_file_name); - free (file_name); - free (adir); - return 1; + int rc = 0; + char *adir; + char *file_name; + + if (archive->name[0] == '/') + adir = create_directory(archive->name, reldir); + else + adir = create_directory(dst_dir, archive->name); + if (!adir) + return 1; + + file_name = concat_dir(adir, file, NULL); + if (access(file_name, F_OK) == 0) { + if (archive->backup_type == no_backups) { + if (debug_level) + logmsg(LOG_DEBUG, + _("removing previous archive " + "file `%s'"), + file_name); + if (!dry_run_mode && unlink(file_name)) { + logmsg(LOG_ERR, + _("cannot unlink previous archive " + "file `%s': %s"), + file_name, strerror(errno)); + free(file_name); + free(adir); + return 1; + } + } else { + char *archive_file_name = + find_backup_file_name(file_name, + archive->backup_type); + if (debug_level) + logmsg(LOG_DEBUG, + _("backing up previous archive " + "file `%s' to `%s'"), + file_name, archive_file_name); + if (!dry_run_mode) { + rc = do_move_file(file_name, + archive_file_name); + if (rc) { + logmsg(LOG_ERR, + _("backing `%s' up as `%s' failed: %s"), + file_name, archive_file_name, + strerror(errno)); + free(archive_file_name); + free(file_name); + free(adir); + return 1; + } + } + free(archive_file_name); } - } - free (archive_file_name); } - } - - if (debug_level) - logmsg (LOG_DEBUG, _("archiving `%s' to `%s'"), dst_file, file_name); - if (!dry_run_mode) - { - rc = do_move_file (dst_file, file_name); - if (rc) - logmsg (LOG_ERR, _("archiving `%s' as `%s' failed: %s"), - dst_file, file_name, strerror (errno)); - } - free (file_name); - free (adir); - return rc; + + if (debug_level) + logmsg(LOG_DEBUG, _("archiving `%s' to `%s'"), dst_file, + file_name); + if (!dry_run_mode) { + rc = do_move_file(dst_file, file_name); + if (rc) + logmsg(LOG_ERR, _("archiving `%s' as `%s' failed: %s"), + dst_file, file_name, strerror(errno)); + } + free(file_name); + free(adir); + return rc; } /* Select the appropriate backup type and backup a file. See backup_file for the argument description. */ int -do_archive_file (const char *dst_file, const char *dst_dir, const char *file, - const struct archive_descr *archive, - const char *reldir) +do_archive_file(const char *dst_file, const char *dst_dir, const char *file, + const struct archive_descr *archive, const char *reldir) { - switch (archive->type) - { - case archive_none: - break; - - case archive_directory: - if (backup_file (dst_file, dst_dir, file, archive, reldir)) - return 1; - UPDATE_STATS (STAT_ARCHIVES); - break; + switch (archive->type) { + case archive_none: + break; + + case archive_directory: + if (backup_file(dst_file, dst_dir, file, archive, reldir)) + return 1; + UPDATE_STATS(STAT_ARCHIVES); + break; + + case archive_tar: + if (tar_append_file(archive->name, dst_file)) + return 1; + UPDATE_STATS(STAT_ARCHIVES); + break; + } - case archive_tar: - if (tar_append_file (archive->name, dst_file)) - return 1; - UPDATE_STATS (STAT_ARCHIVES); - break; - } - - if (!dry_run_mode && unlink (dst_file) && errno != ENOENT) - { - logmsg (LOG_ERR, _("canot unlink file `%s': %s"), - dst_file, strerror (errno)); - return 1; - } - return 0; + if (!dry_run_mode && unlink(dst_file) && errno != ENOENT) { + logmsg(LOG_ERR, _("canot unlink file `%s': %s"), + dst_file, strerror(errno)); + return 1; + } + return 0; } static int -replace_allowed_p (struct file_triplet *trp) +replace_allowed_p(struct file_triplet *trp) { - const char *val; - - if (trp->version < 102) - return 1; - - if (directive_get_value (trp, "replace", &val)) - return 1; - return strcmp (val, "true") == 0; + const char *val; + + if (trp->version < 102) + return 1; + + if (directive_get_value(trp, "replace", &val)) + return 1; + return strcmp(val, "true") == 0; } const char * -dir_get_path (struct spool *sp) +dir_get_path(struct spool *sp) { - return sp->source_dir; + return sp->source_dir; } /* Move the part FILE_ID of the triplet TRP between the directories in @@ -423,46 +397,46 @@ dir_get_path (struct spool *sp) Do nothing if dry_run_mode is set. */ int -dir_move_file (struct file_triplet *trp, enum file_type file_id) +dir_move_file(struct file_triplet *trp, enum file_type file_id) { - char *dst_file; - int rc = 0; - const struct spool *spool = trp->spool; - char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); - - if (!dst_dir) - return 1; - dst_file = concat_dir (dst_dir, trp->file[file_id].name, NULL); - - if (debug_level) - logmsg (LOG_DEBUG, _("installing %s to %s"), trp->file[file_id].name, - dst_dir); - - if (access (dst_file, F_OK) == 0) - { - if (replace_allowed_p (trp)) - rc = do_archive_file (dst_file, dst_dir, trp->file[file_id].name, - &spool->archive, trp->relative_dir); - else - { - logmsg (LOG_ERR, - _("refusing to upload %s because it already exists " - "and replace is not allowed"), - trp->file[file_id].name); - free (dst_file); - free (dst_dir); - return 1; + char *dst_file; + int rc = 0; + const struct spool *spool = trp->spool; + char *dst_dir = create_directory(spool->dest_dir, trp->relative_dir); + + if (!dst_dir) + return 1; + dst_file = concat_dir(dst_dir, trp->file[file_id].name, NULL); + + if (debug_level) + logmsg(LOG_DEBUG, _("installing %s to %s"), + trp->file[file_id].name, dst_dir); + + if (access(dst_file, F_OK) == 0) { + if (replace_allowed_p(trp)) + rc = do_archive_file(dst_file, dst_dir, + trp->file[file_id].name, + &spool->archive, + trp->relative_dir); + else { + logmsg(LOG_ERR, + _("refusing to upload %s because it already " + "exists and replace is not allowed"), + trp->file[file_id].name); + free(dst_file); + free(dst_dir); + return 1; + } } - } - if (!dry_run_mode && rc == 0) - rc = do_move_file (trp->file[file_id].name, dst_file); + if (!dry_run_mode && rc == 0) + rc = do_move_file(trp->file[file_id].name, dst_file); - free (dst_file); - free (dst_dir); - if (rc == 0) - UPDATE_STATS (STAT_UPLOADS); - return rc; + free(dst_file); + free(dst_dir); + if (rc == 0) + UPDATE_STATS(STAT_UPLOADS); + return rc; } /* Archive the file FILE_NAME, located in DPAIR->dest_dir, and remove the @@ -470,65 +444,61 @@ dir_move_file (struct file_triplet *trp, enum file_type file_id) Do nothing if dry_run_mode is set. */ int -archive_single_file (struct file_triplet *trp, const char *file_name, - int noentok) +archive_single_file(struct file_triplet *trp, const char *file_name, + int noentok) { - char *dst_file; - int rc = 0; - const struct spool *spool = trp->spool; - char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); - - if (!dst_dir) - return 1; - - dst_file = safe_file_name (concat_dir (dst_dir, file_name, NULL)); - if (!sub_dir_p (dst_file, spool->dest_dir)) - { - logmsg (LOG_ERR, _("file to be archived `%s' does not lie under `%s'"), - dst_file, spool->dest_dir); - free (dst_file); - free (dst_dir); - return 1; - } - - if (access (dst_file, F_OK) == 0) - { - if (debug_level) - logmsg (LOG_DEBUG, _("archiving file `%s'"), dst_file); - rc = do_archive_file (dst_file, dst_dir, file_name, &spool->archive, - trp->relative_dir); - } - else if (errno == ENOENT) - { - if (!noentok) - logmsg (LOG_NOTICE, _("nothing to archive: file `%s' does not exist"), - dst_file); - } - else - { - logmsg (LOG_ERR, _("canot access file `%s': %s"), - dst_file, strerror (errno)); - rc = 1; - } - - free (dst_file); - free (dst_dir); - return rc; + char *dst_file; + int rc = 0; + const struct spool *spool = trp->spool; + char *dst_dir = create_directory(spool->dest_dir, trp->relative_dir); + + if (!dst_dir) + return 1; + + dst_file = safe_file_name(concat_dir(dst_dir, file_name, NULL)); + if (!sub_dir_p(dst_file, spool->dest_dir)) { + logmsg(LOG_ERR, + _("file to be archived `%s' does not lie under `%s'"), + dst_file, spool->dest_dir); + free(dst_file); + free(dst_dir); + return 1; + } + + if (access(dst_file, F_OK) == 0) { + if (debug_level) + logmsg(LOG_DEBUG, _("archiving file `%s'"), dst_file); + rc = do_archive_file(dst_file, dst_dir, file_name, + &spool->archive, trp->relative_dir); + } else if (errno == ENOENT) { + if (!noentok) + logmsg(LOG_NOTICE, + _("nothing to archive: " + "file `%s' does not exist"), + dst_file); + } else { + logmsg(LOG_ERR, _("canot access file `%s': %s"), + dst_file, strerror(errno)); + rc = 1; + } + + free(dst_file); + free(dst_dir); + return rc; } static char * -make_signame (const char *file_name) +make_signame(const char *file_name) { - size_t len; - - if (((len = strlen (file_name)) > SUF_SIG_LEN - && memcmp (file_name + len - SUF_SIG_LEN, SUF_SIG, SUF_SIG_LEN))) - { - char *signame = grecs_malloc (len + SUF_SIG_LEN + 1); - strcpy (signame, file_name); - return strcat (signame, SUF_SIG); - } - return NULL; + size_t len; + + if (((len = strlen(file_name)) > SUF_SIG_LEN + && memcmp(file_name + len - SUF_SIG_LEN, SUF_SIG, SUF_SIG_LEN))) { + char *signame = grecs_malloc(len + SUF_SIG_LEN + 1); + strcpy(signame, file_name); + return strcat(signame, SUF_SIG); + } + return NULL; } /* Archive the file FILE_NAME, located in DPAIR->dest_dir, and remove the @@ -537,18 +507,18 @@ make_signame (const char *file_name) Do nothing if dry_run_mode is set. */ int -dir_archive_file (struct file_triplet *trp, const char *file_name) +dir_archive_file(struct file_triplet *trp, const char *file_name) { - int rc; - char *signame; - - rc = archive_single_file (trp, file_name, 0); - if (rc == 0 && archive_signatures && (signame = make_signame (file_name))) - { - rc = archive_single_file (trp, signame, 1); - free (signame); - } - return rc; + int rc; + char *signame; + + rc = archive_single_file(trp, file_name, 0); + if (rc == 0 && archive_signatures + && (signame = make_signame(file_name))) { + rc = archive_single_file(trp, signame, 1); + free(signame); + } + return rc; } /* Create a symbolic link from WANTED_SRC to WANTED_DST in the subdirectory @@ -556,207 +526,196 @@ dir_archive_file (struct file_triplet *trp, const char *file_name) Do nothing if dry_run_mode is set. */ int -dir_symlink_file (struct file_triplet *trp, - const char *wanted_src, const char *wanted_dst) +dir_symlink_file(struct file_triplet *trp, + const char *wanted_src, const char *wanted_dst) { - int rc = 0; - const struct spool *spool = trp->spool; - char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); - char *src, *dst; - - if (!dst_dir) - return 1; - - src = safe_file_name_alloc (wanted_src); - if (!src || src[0] == '/') - { - logmsg (LOG_ERR, _("symlink source `%s' does not lie under `%s'"), - wanted_src, spool->dest_dir); - free (src); - return 1; - } - - dst = safe_file_name_alloc (wanted_dst); - if (!dst || dst[0] == '/') - { - logmsg (LOG_ERR, _("symlink destination `%s' does not lie under `%s'"), - wanted_dst, spool->dest_dir); - free (src); - free (dst); - return 1; - } - - if (debug_level) - logmsg (LOG_DEBUG, _("symlinking %s to %s in directory %s"), - src, dst, dst_dir); - - if (!dry_run_mode) - { - char *p = strrchr (dst, '/'); - if (p > dst) - { - char *dir; - - *p = 0; - dir = create_directory (spool->dest_dir, dst); - if (!dir) - rc = 1; - else - free (dir); - *p = '/'; + int rc = 0; + const struct spool *spool = trp->spool; + char *dst_dir = create_directory(spool->dest_dir, trp->relative_dir); + char *src, *dst; + + if (!dst_dir) + return 1; + + src = safe_file_name_alloc(wanted_src); + if (!src || src[0] == '/') { + logmsg(LOG_ERR, + _("symlink source `%s' does not lie under `%s'"), + wanted_src, spool->dest_dir); + free(src); + return 1; } - if (rc == 0) - { - if (push_dir (dst_dir)) - logmsg (LOG_ERR, _("cannot change to %s: %s"), - dst_dir, strerror (errno)); - else - { - struct stat st; - - if (lstat (dst, &st) == 0) - { - if (!S_ISLNK (st.st_mode)) - { - logmsg (LOG_ERR, - _("file %s exists and is not a symbolic link"), - dst); - rc = 1; - } - else if (unlink (dst)) - { - logmsg (LOG_ERR, - _("cannot unlink %s: %s"), - dst, strerror (errno)); - rc = 1; - } - } - else if (errno != ENOENT) - { - logmsg (LOG_ERR, - _("cannot stat file %s: %s"), - dst, strerror (errno)); - rc = 1; - } + dst = safe_file_name_alloc(wanted_dst); + if (!dst || dst[0] == '/') { + logmsg(LOG_ERR, + _("symlink destination `%s' does not lie under `%s'"), + wanted_dst, spool->dest_dir); + free(src); + free(dst); + return 1; + } - if (rc == 0) - { - rc = symlink (src, dst); - if (rc) - logmsg (LOG_ERR, - _("symlinking %s to %s in directory %s failed: %s"), - src, dst, dst_dir, strerror (errno)); + if (debug_level) + logmsg(LOG_DEBUG, _("symlinking %s to %s in directory %s"), + src, dst, dst_dir); + + if (!dry_run_mode) { + char *p = strrchr(dst, '/'); + if (p > dst) { + char *dir; + + *p = 0; + dir = create_directory(spool->dest_dir, dst); + if (!dir) + rc = 1; + else + free(dir); + *p = '/'; } - if (pop_dir ()) - { - logmsg (LOG_EMERG, _("cannot restore current directory: %s"), - strerror (errno)); - exit (EX_SOFTWARE); + + if (rc == 0) { + if (push_dir(dst_dir)) + logmsg(LOG_ERR, _("cannot change to %s: %s"), + dst_dir, strerror(errno)); + else { + struct stat st; + + if (lstat(dst, &st) == 0) { + if (!S_ISLNK(st.st_mode)) { + logmsg(LOG_ERR, + _("file %s exists and is not a symbolic link"), + dst); + rc = 1; + } else if (unlink(dst)) { + logmsg(LOG_ERR, + _("cannot unlink %s: %s"), + dst, strerror(errno)); + rc = 1; + } + } else if (errno != ENOENT) { + logmsg(LOG_ERR, + _("cannot stat file %s: %s"), + dst, strerror(errno)); + rc = 1; + } + + if (rc == 0) { + rc = symlink(src, dst); + if (rc) + logmsg(LOG_ERR, + _("symlinking %s to %s in directory %s failed: %s"), + src, dst, dst_dir, + strerror(errno)); + } + if (pop_dir()) { + logmsg(LOG_EMERG, + _("cannot restore current directory: %s"), + strerror(errno)); + exit(EX_SOFTWARE); + } + } } - } } - } - - free (src); - free (dst); - free (dst_dir); - if (rc == 0) - UPDATE_STATS (STAT_SYMLINKS); - return rc; + + free(src); + free(dst); + free(dst_dir); + if (rc == 0) + UPDATE_STATS(STAT_SYMLINKS); + return rc; } /* Auxiliary function for rmsymlink_file (see below) */ static int -do_rmsymlink_file (const char *dst_file, int noentok) +do_rmsymlink_file(const char *dst_file, int noentok) { - struct stat st; - - if (debug_level) - logmsg (LOG_DEBUG, _("removing symbolic link %s"), dst_file); - - if (stat (dst_file, &st)) - { - if (errno == ENOENT) - { - if (!noentok) - logmsg (LOG_NOTICE, _("symlink `%s' does not exist"), dst_file); - return 0; + struct stat st; + + if (debug_level) + logmsg(LOG_DEBUG, _("removing symbolic link %s"), dst_file); + + if (stat(dst_file, &st)) { + if (errno == ENOENT) { + if (!noentok) + logmsg(LOG_NOTICE, + _("symlink `%s' does not exist"), + dst_file); + return 0; + } + if (!S_ISLNK(st.st_mode)) { + logmsg(LOG_ERR, + _("refusing to unlink %s: is not a symlink"), + dst_file); + return 1; + } } - if (!S_ISLNK (st.st_mode)) - { - logmsg (LOG_ERR, _("refusing to unlink %s: is not a symlink"), - dst_file); - return 1; + if (!dry_run_mode && unlink(dst_file)) { + logmsg(LOG_ERR, _("cannot unlink %s: %s"), dst_file, + strerror(errno)); + return 1; } - } - if (!dry_run_mode && unlink (dst_file)) - { - logmsg (LOG_ERR, _("cannot unlink %s: %s"), dst_file, strerror (errno)); - return 1; - } - UPDATE_STATS (STAT_RMSYMLINKS); - return 0; + UPDATE_STATS(STAT_RMSYMLINKS); + return 0; } /* Remove the symbolic link TRP->spool->dest_dir/TRP->relative_dir/FILE_NAME Do nothing if dry_run_mode is set. */ int -dir_rmsymlink_file (struct file_triplet *trp, const char *file_name) +dir_rmsymlink_file(struct file_triplet *trp, const char *file_name) { - char *dst_file; - int rc = 0; - char *signame; - const struct spool *spool = trp->spool; - char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); - - if (!dst_dir) - return 1; - - dst_file = safe_file_name (concat_dir (dst_dir, file_name, NULL)); - if (!sub_dir_p (dst_file, spool->dest_dir)) - { - logmsg (LOG_ERR, _("refusing to remove a symlink `%s' that is not " - "located under `%s'"), - dst_file, spool->dest_dir); - free (dst_file); - free (dst_dir); - return 1; - } - - rc = do_rmsymlink_file (dst_file, 0); - if (rc == 0 && archive_signatures && (signame = make_signame (dst_file))) - { - rc = do_rmsymlink_file (signame, 1); - free (signame); - } - - free (dst_file); - free (dst_dir); - return rc; + char *dst_file; + int rc = 0; + char *signame; + const struct spool *spool = trp->spool; + char *dst_dir = create_directory(spool->dest_dir, trp->relative_dir); + + if (!dst_dir) + return 1; + + dst_file = safe_file_name(concat_dir(dst_dir, file_name, NULL)); + if (!sub_dir_p(dst_file, spool->dest_dir)) { + logmsg(LOG_ERR, + _("refusing to remove a symlink `%s' that is not " + "located under `%s'"), dst_file, spool->dest_dir); + free(dst_file); + free(dst_dir); + return 1; + } + + rc = do_rmsymlink_file(dst_file, 0); + if (rc == 0 && archive_signatures && (signame = make_signame(dst_file))) { + rc = do_rmsymlink_file(signame, 1); + free(signame); + } + + free(dst_file); + free(dst_dir); + return rc; |