added support for --include, --include-from and the +/- syntax
[rsync/rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index cf40151..7b2c985 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -46,7 +46,7 @@ extern int copy_links;
 extern int remote_version;
 extern int io_error;
 
-static char **local_exclude_list;
+static struct exclude_struct **local_exclude_list;
 
 int link_stat(const char *Path, STRUCT_STAT *Buffer) 
 {
@@ -67,7 +67,7 @@ int link_stat(const char *Path, STRUCT_STAT *Buffer)
  */
 static int match_file_name(char *fname,STRUCT_STAT *st)
 {
-  if (check_exclude(fname,local_exclude_list)) {
+  if (check_exclude(fname,local_exclude_list,st)) {
     if (verbose > 2)
       rprintf(FINFO,"excluding file %s\n",fname);
     return 0;
@@ -163,7 +163,7 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
   if (file->gid == last_gid) flags |= SAME_GID;
   if (file->modtime == last_time) flags |= SAME_TIME;
 
-  for (l1=0;lastname[l1] && fname[l1] == lastname[l1];l1++) ;
+  for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;  
   l2 = strlen(fname) - l1;
 
   if (l1 > 0) flags |= SAME_NAME;
@@ -262,6 +262,12 @@ static void receive_file_entry(struct file_struct **fptr,
 
   clean_fname(thisname);
 
+  if (relative_paths && thisname[0] == '/') {
+         /* strip / off absolute paths in destination */
+         memmove(thisname, thisname+1, strlen(thisname));
+         if (!thisname[0]) strcpy(thisname,".");
+  }
+
   if ((p = strrchr(thisname,'/'))) {
          static char *lastdir;
          *p = 0;
@@ -487,10 +493,10 @@ static void send_file_name(int f,struct file_list *flist,char *fname,
   }
 
   if (S_ISDIR(file->mode) && recursive) {
-    char **last_exclude_list = local_exclude_list;
-    send_directory(f,flist,f_name(file));
-    local_exclude_list = last_exclude_list;
-    return;
+         struct exclude_struct **last_exclude_list = local_exclude_list;
+         send_directory(f,flist,f_name(file));
+         local_exclude_list = last_exclude_list;
+         return;
   }
 }
 
@@ -507,7 +513,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
        d = opendir(dir);
        if (!d) {
                io_error = 1;
-               rprintf(FERROR,"%s: %s\n",
+               rprintf(FERROR,"opendir(%s): %s\n",
                        dir,strerror(errno));
                return;
        }
@@ -529,7 +535,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
        if (cvs_exclude) {
                if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) {
                        strcpy(p,".cvsignore");
-                       local_exclude_list = make_exclude_list(fname,NULL,0);
+                       local_exclude_list = make_exclude_list(fname,NULL,0,0);
                } else {
                        io_error = 1;
                        rprintf(FINFO,"cannot cvs-exclude in long-named directory %s\n",fname);
@@ -542,7 +548,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                    strcmp(dname,"..")==0)
                        continue;
                strlcpy(p,dname,MAXPATHLEN-(l+1));
-               send_file_name(f,flist,fname,recurse,FLAG_DELETE);
+               send_file_name(f,flist,fname,recurse,0);
        }
 
        closedir(d);
@@ -619,8 +625,11 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                                strlcpy(lastpath, fname, sizeof(lastpath)-1);
                                *p = '/';
                                for (p=fname+1; (p=strchr(p,'/')); p++) {
+                                       int copy_links_saved = copy_links;
                                        *p = 0;
+                                       copy_links = 0;
                                        send_file_name(f, flist, fname, 0, 0);
+                                       copy_links = copy_links_saved;
                                        *p = '/';
                                }
                        } else {