X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3d913675a145896838aa6ea0f6f8243b9da0ff20..27d3cdbc943a57d64f4f2a35a4f1e1b15d9ca41f:/flist.c diff --git a/flist.c b/flist.c index 406a5f44..86bf4aa0 100644 --- a/flist.c +++ b/flist.c @@ -89,12 +89,29 @@ static void set_filesystem(char *fname) } +static int to_wire_mode(mode_t mode) +{ + if (S_ISLNK(mode) && (S_IFLNK != 0120000)) { + return (mode & ~(_S_IFMT)) | 0120000; + } + return (int)mode; +} + +static mode_t from_wire_mode(int mode) +{ + if ((mode & (_S_IFMT)) == 0120000 && (S_IFLNK != 0120000)) { + return (mode & ~(_S_IFMT)) | S_IFLNK; + } + return (mode_t)mode; +} + + static void send_directory(int f,struct file_list *flist,char *dir); static char *flist_dir; -void send_file_entry(struct file_struct *file,int f,unsigned base_flags) +static void send_file_entry(struct file_struct *file,int f,unsigned base_flags) { unsigned char flags; static time_t last_time; @@ -147,7 +164,7 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags) if (!(flags & SAME_TIME)) write_int(f,(int)file->modtime); if (!(flags & SAME_MODE)) - write_int(f,(int)file->mode); + write_int(f,to_wire_mode(file->mode)); if (preserve_uid && !(flags & SAME_UID)) { add_uid(file->uid); write_int(f,(int)file->uid); @@ -248,7 +265,7 @@ static void receive_file_entry(struct file_struct **fptr, file->flags = flags; file->length = read_longint(f); file->modtime = (flags & SAME_TIME) ? last_time : (time_t)read_int(f); - file->mode = (flags & SAME_MODE) ? last_mode : (mode_t)read_int(f); + file->mode = (flags & SAME_MODE) ? last_mode : from_wire_mode(read_int(f)); if (preserve_uid) file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f); if (preserve_gid) @@ -432,7 +449,7 @@ static struct file_struct *make_file(char *fname) -static void send_file_name(int f,struct file_list *flist,char *fname, +void send_file_name(int f,struct file_list *flist,char *fname, int recursive, unsigned base_flags) { struct file_struct *file; @@ -532,7 +549,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) { int i,l; STRUCT_STAT st; - char *p,*dir; + char *p,*dir,*olddir; char lastpath[MAXPATHLEN]=""; struct file_list *flist; int64 start_write; @@ -580,6 +597,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) } dir = NULL; + olddir = NULL; if (!relative_paths) { p = strrchr(fname,'/'); @@ -615,7 +633,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) fname = "."; if (dir && *dir) { - char *olddir = push_dir(dir, 1); + olddir = push_dir(dir, 1); if (!olddir) { io_error=1; @@ -625,21 +643,22 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) } flist_dir = dir; - if (one_file_system) - set_filesystem(fname); + } + + if (one_file_system) + set_filesystem(fname); + + if (!recurse || !send_included_file_names(f,flist)) send_file_name(f,flist,fname,recurse,FLAG_DELETE); + + if (olddir != NULL) { flist_dir = NULL; if (pop_dir(olddir) != 0) { rprintf(FERROR,"pop_dir %s : %s\n", dir,strerror(errno)); exit_cleanup(1); } - continue; } - - if (one_file_system) - set_filesystem(fname); - send_file_name(f,flist,fname,recurse,FLAG_DELETE); } if (f != -1) {