- don't allow chown for the group of a file if running as a daemon and
[rsync/rsync.git] / rsync.c
diff --git a/rsync.c b/rsync.c
index 950d575..2f772ac 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -111,10 +111,7 @@ static int delete_file(char *fname)
                if (strcmp(dname,".")==0 ||
                    strcmp(dname,"..")==0)
                        continue;
-               strlcpy(buf, fname, (MAXPATHLEN-strlen(dname))-2);
-               strcat(buf, "/");
-               strcat(buf, dname);
-               buf[MAXPATHLEN-1] = 0;
+               slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
                if (verbose > 0)
                        rprintf(FINFO,"deleting %s\n", buf);
                if (delete_file(buf) != 0) {
@@ -270,6 +267,7 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
 {
   int updated = 0;
   STRUCT_STAT st2;
+  extern int am_daemon;
 
   if (dry_run) return 0;
 
@@ -303,8 +301,9 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
   }
 #endif
 
-  if ((am_root && preserve_uid && st->st_uid != file->uid) || 
-      (preserve_gid && st->st_gid != file->gid)) {
+  if ((am_root || !am_daemon) &&
+      ((am_root && preserve_uid && st->st_uid != file->uid) || 
+       (preserve_gid && st->st_gid != file->gid))) {
          if (do_lchown(fname,
                        (am_root&&preserve_uid)?file->uid:-1,
                        preserve_gid?file->gid:-1) != 0) {
@@ -726,6 +725,7 @@ static char *cleanup_fname;
 
 void exit_cleanup(int code)
 {
+       io_flush();
        if (cleanup_fname)
                do_unlink(cleanup_fname);
        signal(SIGUSR1, SIG_IGN);
@@ -818,12 +818,6 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
       }
 
       /* open tmp file */
-      if (strlen(fname) > (MAXPATHLEN-8)) {
-       rprintf(FERROR,"filename too long\n");
-       if (buf) unmap_file(buf);
-       close(fd1);
-       continue;
-      }
       if (tmpdir) {
              char *f;
              f = strrchr(fname,'/');
@@ -831,9 +825,30 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                      f = fname;
              else 
                      f++;
-             sprintf(fnametmp,"%s/%s.XXXXXX",tmpdir,f);
+             if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
+                     rprintf(FERROR,"filename too long\n");
+                     if (buf) unmap_file(buf);
+                     close(fd1);
+                     continue;
+             }
+             slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f);
       } else {
-             sprintf(fnametmp,"%s.XXXXXX",fname);
+             char *f = strrchr(fname,'/');
+
+             if (strlen(fname)+9 > MAXPATHLEN) {
+                     rprintf(FERROR,"filename too long\n");
+                     if (buf) unmap_file(buf);
+                     close(fd1);
+                     continue;
+             }
+
+             if (f) {
+                     *f = 0;
+                     slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1);
+                     *f = '/';
+             } else {
+                     slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname);
+             }
       }
       if (NULL == do_mktemp(fnametmp)) {
        rprintf(FERROR,"mktemp %s failed\n",fnametmp);
@@ -878,7 +893,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                rprintf(FERROR,"backup filename too long\n");
                continue;
        }
-       sprintf(fnamebak,"%s%s",fname,backup_suffix);
+       slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
        if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
          rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
          continue;
@@ -927,7 +942,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
   /* now we need to fix any directory permissions that were 
      modified during the transfer */
   for (i = 0; i < flist->count; i++) {
-         struct file_struct *file = flist->files[i];
+         file = flist->files[i];
          if (!file->basename || !S_ISDIR(file->mode)) continue;
          recv_generator(f_name(file),flist,i,-1);
   }
@@ -983,10 +998,10 @@ void send_files(struct file_list *flist,int f_out,int f_in)
                                  fname);
                          return;
                  }
-                 strcat(fname,"/");
+                 strlcat(fname,"/",MAXPATHLEN-1);
                  offset = strlen(file->basedir)+1;
          }
-         strncat(fname,f_name(file),MAXPATHLEN-strlen(fname));
+         strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
          
          if (verbose > 2) 
                  rprintf(FINFO,"send_files(%d,%s)\n",i,fname);