Diff for /embedaddon/rsync/backup.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2016/11/01 09:54:32 version 1.1.1.4, 2021/03/17 00:32:36
Line 2 Line 2
  * Backup handling code.   * Backup handling code.
  *   *
  * Copyright (C) 1999 Andrew Tridgell   * Copyright (C) 1999 Andrew Tridgell
 * Copyright (C) 2003-2015 Wayne Davison * Copyright (C) 2003-2020 Wayne Davison
  *   *
  * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
Line 29  extern int preserve_specials; Line 29  extern int preserve_specials;
 extern int preserve_links;  extern int preserve_links;
 extern int safe_symlinks;  extern int safe_symlinks;
 extern int backup_dir_len;  extern int backup_dir_len;
   extern int backup_dir_dels_len;
 extern unsigned int backup_dir_remainder;  extern unsigned int backup_dir_remainder;
   extern unsigned int backup_dir_dels_remainder;
 extern char backup_dir_buf[MAXPATHLEN];  extern char backup_dir_buf[MAXPATHLEN];
   extern char backup_dir_dels_buf[MAXPATHLEN];
 extern char *backup_suffix;  extern char *backup_suffix;
   extern char *backup_suffix_dels;
 extern char *backup_dir;  extern char *backup_dir;
   extern char *backup_dir_dels;
   
   static BOOL deleting;
   
 /* Returns -1 on error, 0 on missing dir, and 1 on present dir. */  /* Returns -1 on error, 0 on missing dir, and 1 on present dir. */
static int validate_backup_dir(void)static int validate_backup_dir(char *buf)
 {  {
         STRUCT_STAT st;          STRUCT_STAT st;
   
        if (do_lstat(backup_dir_buf, &st) < 0) {        if (do_lstat(buf, &st) < 0) {
                 if (errno == ENOENT)                  if (errno == ENOENT)
                         return 0;                          return 0;
                rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);                rsyserr(FERROR, errno, "backup lstat %s failed", buf);
                 return -1;                  return -1;
         }          }
         if (!S_ISDIR(st.st_mode)) {          if (!S_ISDIR(st.st_mode)) {
                 int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;                  int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
                if (delete_item(backup_dir_buf, st.st_mode, flags) == 0)                if (delete_item(buf, st.st_mode, flags) == 0)
                         return 0;                          return 0;
                 return -1;                  return -1;
         }          }
Line 58  static int validate_backup_dir(void) Line 65  static int validate_backup_dir(void)
  * backup_dir_buf.  Any new directories (compared to the prior backup   * backup_dir_buf.  Any new directories (compared to the prior backup
  * path) are ensured to exist as directories, replacing anything else   * path) are ensured to exist as directories, replacing anything else
  * that may be in the way (e.g. a symlink). */   * that may be in the way (e.g. a symlink). */
static BOOL copy_valid_path(const char *fname)static BOOL copy_valid_path(const char *fname, char *buf, int prefix_len, unsigned int remainder, const char *suffix)
 {  {
         const char *f;          const char *f;
         int val;          int val;
         BOOL ret = True;          BOOL ret = True;
         stat_x sx;          stat_x sx;
        char *b, *rel = backup_dir_buf + backup_dir_len, *name = rel;        char *b, *rel = buf + prefix_len, *name = rel;
   
         for (f = fname, b = rel; *f && *f == *b; f++, b++) {          for (f = fname, b = rel; *f && *f == *b; f++, b++) {
                 if (*b == '/')                  if (*b == '/')
                         name = b + 1;                          name = b + 1;
         }          }
   
        if (stringjoin(rel, backup_dir_remainder, fname, backup_suffix, NULL) >= backup_dir_remainder) {        if (stringjoin(rel, remainder, fname, suffix, NULL) >= remainder) {
                 rprintf(FERROR, "backup filename too long\n");                  rprintf(FERROR, "backup filename too long\n");
                 *name = '\0';                  *name = '\0';
                 return False;                  return False;
Line 82  static BOOL copy_valid_path(const char *fname) Line 89  static BOOL copy_valid_path(const char *fname)
                         return True;                          return True;
                 *b = '\0';                  *b = '\0';
   
                val = validate_backup_dir();                val = validate_backup_dir(buf);
                 if (val == 0)                  if (val == 0)
                         break;                          break;
                 if (val < 0) {                  if (val < 0) {
Line 98  static BOOL copy_valid_path(const char *fname) Line 105  static BOOL copy_valid_path(const char *fname)
         for ( ; b; name = b + 1, b = strchr(name, '/')) {          for ( ; b; name = b + 1, b = strchr(name, '/')) {
                 *b = '\0';                  *b = '\0';
   
                while (do_mkdir(backup_dir_buf, ACCESSPERMS) < 0) {                while (do_mkdir(buf, ACCESSPERMS) < 0) {
                         if (errno == EEXIST) {                          if (errno == EEXIST) {
                                val = validate_backup_dir();                                val = validate_backup_dir(buf);
                                 if (val > 0)                                  if (val > 0)
                                         break;                                          break;
                                 if (val == 0)                                  if (val == 0)
Line 134  static BOOL copy_valid_path(const char *fname) Line 141  static BOOL copy_valid_path(const char *fname)
                                 free_xattr(&sx);                                  free_xattr(&sx);
                         }                          }
 #endif  #endif
                        set_file_attrs(backup_dir_buf, file, NULL, NULL, 0);                        set_file_attrs(buf, file, NULL, NULL, 0);
                         unmake_file(file);                          unmake_file(file);
                 }                  }
   
Line 156  static BOOL copy_valid_path(const char *fname) Line 163  static BOOL copy_valid_path(const char *fname)
 /* Make a complete pathname for backup file and verify any new path elements. */  /* Make a complete pathname for backup file and verify any new path elements. */
 char *get_backup_name(const char *fname)  char *get_backup_name(const char *fname)
 {  {
           char *buf = deleting ? backup_dir_dels_buf : backup_dir_buf;
           char *suffix = deleting ? backup_suffix_dels : backup_suffix;
   
         if (backup_dir) {          if (backup_dir) {
                   int prefix_len = deleting ? backup_dir_dels_len : backup_dir_len;
                   unsigned int remainder = deleting ? backup_dir_dels_remainder : backup_dir_remainder;
                 static int initialized = 0;                  static int initialized = 0;
                 if (!initialized) {                  if (!initialized) {
                         int ret;                          int ret;
                         if (backup_dir_len > 1)                          if (backup_dir_len > 1)
                                 backup_dir_buf[backup_dir_len-1] = '\0';                                  backup_dir_buf[backup_dir_len-1] = '\0';
                        ret = make_path(backup_dir_buf, 0);                        ret = make_path(backup_dir_buf, ACCESSPERMS, 0);
                         if (backup_dir_len > 1)                          if (backup_dir_len > 1)
                                 backup_dir_buf[backup_dir_len-1] = '/';                                  backup_dir_buf[backup_dir_len-1] = '/';
                         if (ret < 0)                          if (ret < 0)
Line 170  char *get_backup_name(const char *fname) Line 182  char *get_backup_name(const char *fname)
                         initialized = 1;                          initialized = 1;
                 }                  }
                 /* copy fname into backup_dir_buf while validating the dirs. */                  /* copy fname into backup_dir_buf while validating the dirs. */
                if (copy_valid_path(fname))                if (copy_valid_path(fname, buf, prefix_len, remainder, suffix))
                        return backup_dir_buf;                        return buf;
                 /* copy_valid_path() has printed an error message. */                  /* copy_valid_path() has printed an error message. */
                 return NULL;                  return NULL;
         }          }
   
        if (stringjoin(backup_dir_buf, MAXPATHLEN, fname, backup_suffix, NULL) < MAXPATHLEN)        if (stringjoin(backup_dir_buf, MAXPATHLEN, fname, suffix, NULL) < MAXPATHLEN)
                return backup_dir_buf;                return buf;
   
         rprintf(FERROR, "backup filename too long\n");          rprintf(FERROR, "backup filename too long\n");
         return NULL;          return NULL;
Line 336  int make_backup(const char *fname, BOOL prefer_rename) Line 348  int make_backup(const char *fname, BOOL prefer_rename)
   
         save_preserve_xattrs = preserve_xattrs;          save_preserve_xattrs = preserve_xattrs;
         preserve_xattrs = 0;          preserve_xattrs = 0;
        set_file_attrs(buf, file, NULL, fname, 0);        set_file_attrs(buf, file, NULL, fname, ATTRS_ACCURATE_TIME);
         preserve_xattrs = save_preserve_xattrs;          preserve_xattrs = save_preserve_xattrs;
   
         unmake_file(file);          unmake_file(file);
Line 350  int make_backup(const char *fname, BOOL prefer_rename) Line 362  int make_backup(const char *fname, BOOL prefer_rename)
   success:    success:
         if (INFO_GTE(BACKUP, 1))          if (INFO_GTE(BACKUP, 1))
                 rprintf(FINFO, "backed up %s to %s\n", fname, buf);                  rprintf(FINFO, "backed up %s to %s\n", fname, buf);
           return ret;
   }
   
   /* backup switch routine called only when backing-up removed file */
   int safe_delete(const char *fname)
   {
           int ret;
           deleting = 1;
           ret = make_backup(fname, True);
           deleting = 0;
         return ret;          return ret;
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>