home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / rsync221.zip / flist.c < prev    next >
C/C++ Source or Header  |  1999-03-04  |  23KB  |  979 lines

  1. /* 
  2.    Copyright (C) Andrew Tridgell 1996
  3.    Copyright (C) Paul Mackerras 1996
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2 of the License, or
  8.    (at your option) any later version.
  9.    
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.    
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. /* generate and receive file lists */
  21.  
  22. #include "rsync.h"
  23.  
  24. extern struct stats stats;
  25.  
  26. extern int csum_length;
  27.  
  28. extern int verbose;
  29. extern int am_server;
  30. extern int always_checksum;
  31.  
  32. extern int cvs_exclude;
  33.  
  34. extern int recurse;
  35.  
  36. extern int one_file_system;
  37. extern int make_backups;
  38. extern int preserve_links;
  39. extern int preserve_hard_links;
  40. extern int preserve_perms;
  41. extern int preserve_devices;
  42. extern int preserve_uid;
  43. extern int preserve_gid;
  44. extern int preserve_times;
  45. extern int relative_paths;
  46. extern int copy_links;
  47. extern int remote_version;
  48. extern int io_error;
  49.  
  50. static struct exclude_struct **local_exclude_list;
  51.  
  52. static void clean_flist(struct file_list *flist, int strip_root);
  53.  
  54.  
  55. static void list_file_entry(struct file_struct *f)
  56. {
  57.     char perms[11] = "----------";
  58.     char *perm_map = "rwxrwxrwx";
  59.     int i;
  60.  
  61.     if (!f->basename)
  62.         /* this can happen if duplicate names were removed */
  63.         return;
  64.  
  65.     for (i=0;i<9;i++) {
  66.         if (f->mode & (1<<i)) perms[9-i] = perm_map[8-i];
  67.     }
  68.     if (S_ISLNK(f->mode)) perms[0] = 'l';
  69.     if (S_ISDIR(f->mode)) perms[0] = 'd';
  70. #ifndef __EMX__
  71.     if (S_ISBLK(f->mode)) perms[0] = 'b';
  72. #endif
  73.     if (S_ISCHR(f->mode)) perms[0] = 'c';
  74.     if (S_ISSOCK(f->mode)) perms[0] = 's';
  75.     if (S_ISFIFO(f->mode)) perms[0] = 'p';
  76.     
  77.     if (preserve_links && S_ISLNK(f->mode)) {
  78.         rprintf(FINFO,"%s %11.0f %s %s -> %s\n", 
  79.             perms, 
  80.             (double)f->length, timestring(f->modtime), 
  81.             f_name(f), f->link);
  82.     } else {
  83.         rprintf(FINFO,"%s %11.0f %s %s\n", 
  84.             perms, 
  85.             (double)f->length, timestring(f->modtime), f_name(f));
  86.     }
  87. }
  88.  
  89.  
  90. int link_stat(const char *Path, STRUCT_STAT *Buffer) 
  91. {
  92. #if SUPPORT_LINKS
  93.     if (copy_links) {
  94.     return do_stat(Path, Buffer);
  95.     } else {
  96.     return do_lstat(Path, Buffer);
  97.     }
  98. #else
  99.     return do_stat(Path, Buffer);
  100. #endif
  101. }
  102.  
  103. /*
  104.   This function is used to check if a file should be included/excluded
  105.   from the list of files based on its name and type etc
  106.  */
  107. static int match_file_name(char *fname,STRUCT_STAT *st)
  108. {
  109.   if (check_exclude(fname,local_exclude_list,st)) {
  110.     if (verbose > 2)
  111.       rprintf(FINFO,"excluding file %s\n",fname);
  112.     return 0;
  113.   }
  114.   return 1;
  115. }
  116.  
  117. /* used by the one_file_system code */
  118. static dev_t filesystem_dev;
  119.  
  120. static void set_filesystem(char *fname)
  121. {
  122.   STRUCT_STAT st;
  123.   if (link_stat(fname,&st) != 0) return;
  124.   filesystem_dev = st.st_dev;
  125. }
  126.  
  127.  
  128. static int to_wire_mode(mode_t mode)
  129. {
  130. #ifndef __EMX__
  131.     if (S_ISLNK(mode) && (S_IFLNK != 0120000)) {
  132.         return (mode & ~(_S_IFMT)) | 0120000;
  133.     }
  134. #endif
  135.     return (int)mode;
  136. }
  137.  
  138. static mode_t from_wire_mode(int mode)
  139. {
  140. #ifndef __EMX__
  141.     if ((mode & (_S_IFMT)) == 0120000 && (S_IFLNK != 0120000)) {
  142.         return (mode & ~(_S_IFMT)) | S_IFLNK;
  143.     }
  144. #endif
  145.     return (mode_t)mode;
  146. }
  147.  
  148.  
  149. static void send_directory(int f,struct file_list *flist,char *dir);
  150.  
  151. static char *flist_dir;
  152.  
  153.  
  154. static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
  155. {
  156.     unsigned char flags;
  157.     static time_t last_time;
  158.     static mode_t last_mode;
  159.     static dev_t last_rdev;
  160.     static uid_t last_uid;
  161.     static gid_t last_gid;
  162.     static char lastname[MAXPATHLEN];
  163.     char *fname;
  164.     int l1,l2;
  165.  
  166.     if (f == -1) return;
  167.  
  168.     if (!file) {
  169.         write_byte(f,0);
  170.         return;
  171.     }
  172.  
  173.     fname = f_name(file);
  174.  
  175.     flags = base_flags;
  176.  
  177.     if (file->mode == last_mode) flags |= SAME_MODE;
  178.     if (file->rdev == last_rdev) flags |= SAME_RDEV;
  179.     if (file->uid == last_uid) flags |= SAME_UID;
  180.     if (file->gid == last_gid) flags |= SAME_GID;
  181.     if (file->modtime == last_time) flags |= SAME_TIME;
  182.  
  183.     for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;  
  184.     l2 = strlen(fname) - l1;
  185.  
  186.     if (l1 > 0) flags |= SAME_NAME;
  187.     if (l2 > 255) flags |= LONG_NAME;
  188.  
  189.     /* we must make sure we don't send a zero flags byte or the other
  190.        end will terminate the flist transfer */
  191.     if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
  192.     if (flags == 0) flags |= LONG_NAME;
  193.  
  194.     write_byte(f,flags);  
  195.     if (flags & SAME_NAME)
  196.         write_byte(f,l1);
  197.     if (flags & LONG_NAME)
  198.         write_int(f,l2);
  199.     else
  200.         write_byte(f,l2);
  201.     write_buf(f,fname+l1,l2);
  202.  
  203.     write_longint(f,file->length);
  204.     if (!(flags & SAME_TIME))
  205.         write_int(f,(int)file->modtime);
  206.     if (!(flags & SAME_MODE))
  207.         write_int(f,to_wire_mode(file->mode));
  208.     if (preserve_uid && !(flags & SAME_UID)) {
  209.         add_uid(file->uid);
  210.         write_int(f,(int)file->uid);
  211.     }
  212.     if (preserve_gid && !(flags & SAME_GID)) {
  213.         add_gid(file->gid);
  214.         write_int(f,(int)file->gid);
  215.     }
  216.     if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
  217.         write_int(f,(int)file->rdev);
  218.  
  219. #if SUPPORT_LINKS
  220.     if (preserve_links && S_ISLNK(file->mode)) {
  221.         write_int(f,strlen(file->link));
  222.         write_buf(f,file->link,strlen(file->link));
  223.     }
  224. #endif
  225.  
  226. #if SUPPORT_HARD_LINKS
  227.     if (preserve_hard_links && S_ISREG(file->mode)) {
  228.         write_int(f,(int)file->dev);
  229.         write_int(f,(int)file->inode);
  230.     }
  231. #endif
  232.  
  233.     if (always_checksum) {
  234.         write_buf(f,file->sum,csum_length);
  235.     }       
  236.  
  237.     last_mode = file->mode;
  238.     last_rdev = file->rdev;
  239.     last_uid = file->uid;
  240.     last_gid = file->gid;
  241.     last_time = file->modtime;
  242.  
  243.     strlcpy(lastname,fname,MAXPATHLEN);
  244.     lastname[MAXPATHLEN-1] = 0;
  245. }
  246.  
  247.  
  248.  
  249. static void receive_file_entry(struct file_struct **fptr,
  250.                    unsigned flags,int f)
  251. {
  252.     static time_t last_time;
  253.     static mode_t last_mode;
  254.     static dev_t last_rdev;
  255.     static uid_t last_uid;
  256.     static gid_t last_gid;
  257.     static char lastname[MAXPATHLEN];
  258.     char thisname[MAXPATHLEN];
  259.     int l1=0,l2=0;
  260.     char *p;
  261.     struct file_struct *file;
  262.  
  263.     if (flags & SAME_NAME)
  264.         l1 = read_byte(f);
  265.   
  266.     if (flags & LONG_NAME)
  267.         l2 = read_int(f);
  268.     else
  269.         l2 = read_byte(f);
  270.  
  271.     file = (struct file_struct *)malloc(sizeof(*file));
  272.     if (!file) out_of_memory("receive_file_entry");
  273.     memset((char *)file, 0, sizeof(*file));
  274.     (*fptr) = file;
  275.  
  276.     if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
  277.  
  278.     strlcpy(thisname,lastname,l1+1);
  279.     read_sbuf(f,&thisname[l1],l2);
  280.     thisname[l1+l2] = 0;
  281.  
  282.     strlcpy(lastname,thisname,MAXPATHLEN);
  283.     lastname[MAXPATHLEN-1] = 0;
  284.  
  285.     clean_fname(thisname);
  286.  
  287.     if ((p = strrchr(thisname,'/'))) {
  288.         static char *lastdir;
  289.         *p = 0;
  290.         if (lastdir && strcmp(thisname, lastdir)==0) {
  291.             file->dirname = lastdir;
  292.         } else {
  293.             file->dirname = strdup(thisname);
  294.             lastdir = file->dirname;
  295.         }
  296.         file->basename = strdup(p+1);
  297.     } else {
  298.         file->dirname = NULL;
  299.         file->basename = strdup(thisname);
  300.     }
  301.  
  302.     if (!file->basename) out_of_memory("receive_file_entry 1");
  303.  
  304.  
  305.     file->flags = flags;
  306.     file->length = read_longint(f);
  307.     file->modtime = (flags & SAME_TIME) ? last_time : (time_t)read_int(f);
  308.     file->mode = (flags & SAME_MODE) ? last_mode : from_wire_mode(read_int(f));
  309.     if (preserve_uid)
  310.         file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
  311.     if (preserve_gid)
  312.         file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
  313.     if (preserve_devices && IS_DEVICE(file->mode))
  314.         file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
  315.  
  316.     if (preserve_links && S_ISLNK(file->mode)) {
  317.         int l = read_int(f);
  318.         file->link = (char *)malloc(l+1);
  319.         if (!file->link) out_of_memory("receive_file_entry 2");
  320.         read_sbuf(f,file->link,l);
  321.     }
  322.  
  323. #if SUPPORT_HARD_LINKS
  324.     if (preserve_hard_links && S_ISREG(file->mode)) {
  325.         file->dev = read_int(f);
  326.         file->inode = read_int(f);
  327.     }
  328. #endif
  329.   
  330.     if (always_checksum) {
  331.         file->sum = (char *)malloc(MD4_SUM_LENGTH);
  332.         if (!file->sum) out_of_memory("md4 sum");
  333.         read_buf(f,file->sum,csum_length);
  334.     }
  335.   
  336.     last_mode = file->mode;
  337.     last_rdev = file->rdev;
  338.     last_uid = file->uid;
  339.     last_gid = file->gid;
  340.     last_time = file->modtime;
  341.  
  342.     if (!preserve_perms) {
  343.         extern int orig_umask;
  344.         /* set an appropriate set of permissions based on original
  345.            permissions and umask. This emulates what GNU cp does */
  346.         file->mode &= ~orig_umask;
  347.     }
  348. }
  349.  
  350.  
  351. /* determine if a file in a different filesstem should be skipped
  352.    when one_file_system is set. We bascally only want to include
  353.    the mount points - but they can be hard to find! */
  354. static int skip_filesystem(char *fname, STRUCT_STAT *st)
  355. {
  356.     STRUCT_STAT st2;
  357.     char *p = strrchr(fname, '/');
  358.  
  359.     /* skip all but directories */
  360.     if (!S_ISDIR(st->st_mode)) return 1;
  361.  
  362.     /* if its not a subdirectory then allow */
  363.     if (!p) return 0;
  364.  
  365.     *p = 0;
  366.     if (link_stat(fname, &st2)) {
  367.         *p = '/';
  368.         return 0;
  369.     }
  370.     *p = '/';
  371.     
  372.     return (st2.st_dev != filesystem_dev);
  373. }
  374.  
  375. static struct file_struct *make_file(char *fname)
  376. {
  377.     struct file_struct *file;
  378.     STRUCT_STAT st;
  379.     char sum[SUM_LENGTH];
  380.     char *p;
  381.     char cleaned_name[MAXPATHLEN];
  382.  
  383.     strlcpy(cleaned_name, fname, MAXPATHLEN);
  384.     cleaned_name[MAXPATHLEN-1] = 0;
  385.     clean_fname(cleaned_name);
  386.     fname = cleaned_name;
  387.  
  388.     memset(sum,0,SUM_LENGTH);
  389.  
  390.     if (link_stat(fname,&st) != 0) {
  391.         io_error = 1;
  392.         rprintf(FERROR,"%s: %s\n",
  393.             fname,strerror(errno));
  394.         return NULL;
  395.     }
  396.  
  397.     if (S_ISDIR(st.st_mode) && !recurse) {
  398.         rprintf(FINFO,"skipping directory %s\n",fname);
  399.         return NULL;
  400.     }
  401.     
  402.     if (one_file_system && st.st_dev != filesystem_dev) {
  403.         if (skip_filesystem(fname, &st))
  404.             return NULL;
  405.     }
  406.     
  407.     if (!match_file_name(fname,&st))
  408.         return NULL;
  409.     
  410.     if (verbose > 2)
  411.         rprintf(FINFO,"make_file(%s)\n",fname);
  412.     
  413.     file = (struct file_struct *)malloc(sizeof(*file));
  414.     if (!file) out_of_memory("make_file");
  415.     memset((char *)file,0,sizeof(*file));
  416.  
  417.     if ((p = strrchr(fname,'/'))) {
  418.         static char *lastdir;
  419.         *p = 0;
  420.         if (lastdir && strcmp(fname, lastdir)==0) {
  421.             file->dirname = lastdir;
  422.         } else {
  423.             file->dirname = strdup(fname);
  424.             lastdir = file->dirname;
  425.         }
  426.         file->basename = strdup(p+1);
  427.         *p = '/';
  428.     } else {
  429.         file->dirname = NULL;
  430.         file->basename = strdup(fname);
  431.     }
  432.  
  433.     file->modtime = st.st_mtime;
  434.     file->length = st.st_size;
  435.     file->mode = st.st_mode;
  436.     file->uid = st.st_uid;
  437.     file->gid = st.st_gid;
  438.     file->dev = st.st_dev;
  439.     file->inode = st.st_ino;
  440. #ifdef HAVE_ST_RDEV
  441.     file->rdev = st.st_rdev;
  442. #endif
  443.  
  444. #if SUPPORT_LINKS
  445.     if (S_ISLNK(st.st_mode)) {
  446.         int l;
  447.         char lnk[MAXPATHLEN];
  448.         if ((l=readlink(fname,lnk,MAXPATHLEN-1)) == -1) {
  449.             io_error=1;
  450.             rprintf(FERROR,"readlink %s : %s\n",
  451.                 fname,strerror(errno));
  452.             return NULL;
  453.         }
  454.         lnk[l] = 0;
  455.         file->link = strdup(lnk);
  456.     }
  457. #endif
  458.  
  459.     if (always_checksum) {
  460.         file->sum = (char *)malloc(MD4_SUM_LENGTH);
  461.         if (!file->sum) out_of_memory("md4 sum");
  462.         /* drat. we have to provide a null checksum for non-regular
  463.            files in order to be compatible with earlier versions
  464.            of rsync */
  465.         if (S_ISREG(st.st_mode)) {
  466.             file_checksum(fname,file->sum,st.st_size);
  467.         } else {
  468.             memset(file->sum, 0, MD4_SUM_LENGTH);
  469.         }
  470.     }       
  471.  
  472.     if (flist_dir) {
  473.         static char *lastdir;
  474.         if (lastdir && strcmp(lastdir, flist_dir)==0) {
  475.             file->basedir = lastdir;
  476.         } else {
  477.             file->basedir = strdup(flist_dir);
  478.             lastdir = file->basedir;
  479.         }
  480.     } else {
  481.         file->basedir = NULL;
  482.     }
  483.  
  484.     if (!S_ISDIR(st.st_mode))
  485.         stats.total_size += st.st_size;
  486.  
  487.     return file;
  488. }
  489.  
  490.  
  491.  
  492. void send_file_name(int f,struct file_list *flist,char *fname,
  493.                int recursive, unsigned base_flags)
  494. {
  495.   struct file_struct *file;
  496.  
  497.   file = make_file(fname);
  498.  
  499.   if (!file) return;  
  500.   
  501.   if (flist->count >= flist->malloced) {
  502.       if (flist->malloced < 1000)
  503.           flist->malloced += 1000;
  504.       else
  505.           flist->malloced *= 2;
  506.       flist->files = (struct file_struct **)realloc(flist->files,
  507.                             sizeof(flist->files[0])*
  508.                             flist->malloced);
  509.       if (!flist->files)
  510.           out_of_memory("send_file_name");
  511.   }
  512.  
  513.   if (strcmp(file->basename,"")) {
  514.     flist->files[flist->count++] = file;
  515.     send_file_entry(file,f,base_flags);
  516.   }
  517.  
  518.   if (S_ISDIR(file->mode) && recursive) {
  519.       struct exclude_struct **last_exclude_list = local_exclude_list;
  520.       send_directory(f,flist,f_name(file));
  521.       local_exclude_list = last_exclude_list;
  522.       return;
  523.   }
  524. }
  525.  
  526.  
  527.  
  528. static void send_directory(int f,struct file_list *flist,char *dir)
  529. {
  530.     DIR *d;
  531.     struct dirent *di;
  532.     char fname[MAXPATHLEN];
  533.     int l;
  534.     char *p;
  535.  
  536.     d = opendir(dir);
  537.     if (!d) {
  538.         io_error = 1;
  539.         rprintf(FERROR,"opendir(%s): %s\n",
  540.             dir,strerror(errno));
  541.         return;
  542.     }
  543.  
  544.     strlcpy(fname,dir,MAXPATHLEN);
  545.     l = strlen(fname);
  546.     if (fname[l-1] != '/') {
  547.         if (l == MAXPATHLEN-1) {
  548.             io_error = 1;
  549.             rprintf(FERROR,"skipping long-named directory %s\n",fname);
  550.             closedir(d);
  551.             return;
  552.         }
  553.         strlcat(fname,"/", MAXPATHLEN);
  554.         l++;
  555.     }
  556.     p = fname + strlen(fname);
  557.  
  558.     local_exclude_list = NULL;
  559.  
  560.     if (cvs_exclude) {
  561.         if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) {
  562.             strcpy(p,".cvsignore");
  563.             local_exclude_list = make_exclude_list(fname,NULL,0,0);
  564.         } else {
  565.             io_error = 1;
  566.             rprintf(FINFO,"cannot cvs-exclude in long-named directory %s\n",fname);
  567.         }
  568.     }  
  569.     
  570.     for (di=readdir(d); di; di=readdir(d)) {
  571.         char *dname = d_name(di);
  572.         if (strcmp(dname,".")==0 ||
  573.             strcmp(dname,"..")==0)
  574.             continue;
  575.         strlcpy(p,dname,MAXPATHLEN-l);
  576.         send_file_name(f,flist,fname,recurse,0);
  577.     }
  578.  
  579.     if (local_exclude_list) {
  580.         add_exclude_list("!", &local_exclude_list, 0);
  581.     }
  582.  
  583.     closedir(d);
  584. }
  585.  
  586.  
  587.  
  588. struct file_list *send_file_list(int f,int argc,char *argv[])
  589. {
  590.     int i,l;
  591.     STRUCT_STAT st;
  592.     char *p,*dir,*olddir;
  593.     char lastpath[MAXPATHLEN]="";
  594.     struct file_list *flist;
  595.     int64 start_write;
  596.  
  597.     if (verbose && recurse && !am_server && f != -1) {
  598.         rprintf(FINFO,"building file list ... ");
  599.         rflush(FINFO);
  600.     }
  601.  
  602.     start_write = stats.total_written;
  603.  
  604.     flist = (struct file_list *)malloc(sizeof(flist[0]));
  605.     if (!flist) out_of_memory("send_file_list");
  606.  
  607.     flist->count=0;
  608.     flist->malloced = 1000;
  609.     flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
  610.                              flist->malloced);
  611.     if (!flist->files) out_of_memory("send_file_list");
  612.  
  613.     if (f != -1) {
  614.         io_start_buffering(f);
  615.     }
  616.  
  617.     for (i=0;i<argc;i++) {
  618.         char fname2[MAXPATHLEN];
  619.         char *fname = fname2;
  620.  
  621.         strlcpy(fname,argv[i],MAXPATHLEN);
  622.  
  623.         l = strlen(fname);
  624.         if (l != 1 && fname[l-1] == '/') {
  625.             strlcat(fname,".",MAXPATHLEN);
  626.         }
  627.  
  628.         if (link_stat(fname,&st) != 0) {
  629.             io_error=1;
  630.             rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
  631.             continue;
  632.         }
  633.  
  634.         if (S_ISDIR(st.st_mode) && !recurse) {
  635.             rprintf(FINFO,"skipping directory %s\n",fname);
  636.             continue;
  637.         }
  638.  
  639.         dir = NULL;
  640.         olddir = NULL;
  641.  
  642.         if (!relative_paths) {
  643.             p = strrchr(fname,'/');
  644.             if (p) {
  645.                 *p = 0;
  646.                 if (p == fname) 
  647.                     dir = "/";
  648.                 else
  649.                     dir = fname;      
  650.                 fname = p+1;      
  651.             }
  652.         } else if (f != -1 && (p=strrchr(fname,'/'))) {
  653.             /* this ensures we send the intermediate directories,
  654.                thus getting their permissions right */
  655.             *p = 0;
  656.             if (strcmp(lastpath,fname)) {
  657.                 strlcpy(lastpath, fname, sizeof(lastpath));
  658.                 *p = '/';
  659.                 for (p=fname+1; (p=strchr(p,'/')); p++) {
  660.                     int copy_links_saved = copy_links;
  661.                     *p = 0;
  662.                     copy_links = 0;
  663.                     send_file_name(f, flist, fname, 0, 0);
  664.                     copy_links = copy_links_saved;
  665.                     *p = '/';
  666.                 }
  667.             } else {
  668.                 *p = '/';
  669.             }
  670.         }
  671.         
  672.         if (!*fname)
  673.             fname = ".";
  674.         
  675.         if (dir && *dir) {
  676.             olddir = push_dir(dir, 1);
  677.  
  678.             if (!olddir) {
  679.                 io_error=1;
  680.                 rprintf(FERROR,"push_dir %s : %s\n",
  681.                     dir,strerror(errno));
  682.                 continue;
  683.             }
  684.  
  685.             flist_dir = dir;
  686.         }
  687.         
  688.         if (one_file_system)
  689.             set_filesystem(fname);
  690.  
  691.         if (!recurse || !send_included_file_names(f,flist))
  692.             send_file_name(f,flist,fname,recurse,FLAG_DELETE);
  693.  
  694.         if (olddir != NULL) {
  695.             flist_dir = NULL;
  696.             if (pop_dir(olddir) != 0) {
  697.                 rprintf(FERROR,"pop_dir %s : %s\n",
  698.                     dir,strerror(errno));
  699.                 exit_cleanup(RERR_FILESELECT);
  700.             }
  701.         }
  702.     }
  703.  
  704.     if (f != -1) {
  705.         send_file_entry(NULL,f,0);
  706.     }
  707.  
  708.     if (verbose && recurse && !am_server && f != -1)
  709.         rprintf(FINFO,"done\n");
  710.     
  711.     clean_flist(flist, 0);
  712.     
  713.     /* now send the uid/gid list. This was introduced in protocol
  714.            version 15 */
  715.     if (f != -1 && remote_version >= 15) {
  716.         send_uid_list(f);
  717.     }
  718.  
  719.     /* if protocol version is >= 17 then send the io_error flag */
  720.     if (f != -1 && remote_version >= 17) {
  721.         write_int(f, io_error);
  722.     }
  723.  
  724.     if (f != -1) {
  725.         io_end_buffering(f);
  726.         stats.flist_size = stats.total_written - start_write;
  727.         stats.num_files = flist->count;
  728.     }
  729.  
  730.     if (verbose > 2)
  731.         rprintf(FINFO,"send_file_list done\n");
  732.  
  733.     return flist;
  734. }
  735.  
  736.  
  737. struct file_list *recv_file_list(int f)
  738. {
  739.   struct file_list *flist;
  740.   unsigned char flags;
  741.   int64 start_read;
  742.   extern int list_only;
  743.  
  744.   if (verbose && recurse && !am_server) {
  745.     rprintf(FINFO,"receiving file list ... ");
  746.     rflush(FINFO);
  747.   }
  748.  
  749.   start_read = stats.total_read;
  750.  
  751.   flist = (struct file_list *)malloc(sizeof(flist[0]));
  752.   if (!flist)
  753.     goto oom;
  754.  
  755.   flist->count=0;
  756.   flist->malloced=1000;
  757.   flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
  758.                            flist->malloced);
  759.   if (!flist->files)
  760.     goto oom;
  761.  
  762.  
  763.   for (flags=read_byte(f); flags; flags=read_byte(f)) {
  764.     int i = flist->count;
  765.  
  766.     if (i >= flist->malloced) {
  767.       if (flist->malloced < 1000)
  768.           flist->malloced += 1000;
  769.       else
  770.           flist->malloced *= 2;
  771.       flist->files =(struct file_struct **)realloc(flist->files,
  772.                                sizeof(flist->files[0])*
  773.                                flist->malloced);
  774.       if (!flist->files)
  775.           goto oom;
  776.     }
  777.  
  778.     receive_file_entry(&flist->files[i],flags,f);
  779.  
  780.     if (S_ISREG(flist->files[i]->mode))
  781.         stats.total_size += flist->files[i]->length;
  782.  
  783.     flist->count++;
  784.  
  785.     if (verbose > 2)
  786.       rprintf(FINFO,"recv_file_name(%s)\n",f_name(flist->files[i]));
  787.   }
  788.  
  789.  
  790.   if (verbose > 2)
  791.     rprintf(FINFO,"received %d names\n",flist->count);
  792.  
  793.   clean_flist(flist, relative_paths);
  794.  
  795.   if (verbose && recurse && !am_server) {
  796.     rprintf(FINFO,"done\n");
  797.   }
  798.  
  799.   /* now recv the uid/gid list. This was introduced in protocol version 15 */
  800.   if (f != -1 && remote_version >= 15) {
  801.       recv_uid_list(f, flist);
  802.   }
  803.  
  804.   /* if protocol version is >= 17 then recv the io_error flag */
  805.   if (f != -1 && remote_version >= 17) {
  806.       io_error |= read_int(f);
  807.   }
  808.  
  809.   if (list_only) {
  810.       int i;
  811.       for (i=0;i<flist->count;i++) {
  812.           list_file_entry(flist->files[i]);
  813.       }
  814.   }
  815.  
  816.  
  817.   if (verbose > 2)
  818.     rprintf(FINFO,"recv_file_list done\n");
  819.  
  820.   stats.flist_size = stats.total_read - start_read;
  821.   stats.num_files = flist->count;
  822.  
  823.   return flist;
  824.  
  825. oom:
  826.     out_of_memory("recv_file_list");
  827.     return NULL; /* not reached */
  828. }
  829.  
  830.  
  831. int file_compare(struct file_struct **f1,struct file_struct **f2)
  832. {
  833.     if (!(*f1)->basename && !(*f2)->basename) return 0;
  834.     if (!(*f1)->basename) return -1;
  835.     if (!(*f2)->basename) return 1;
  836.     if ((*f1)->dirname == (*f2)->dirname)
  837.         return u_strcmp((*f1)->basename, (*f2)->basename);
  838.     return u_strcmp(f_name(*f1),f_name(*f2));
  839. }
  840.  
  841.  
  842. int flist_find(struct file_list *flist,struct file_struct *f)
  843. {
  844.     int low=0,high=flist->count-1;
  845.  
  846.     if (flist->count <= 0) return -1;
  847.  
  848.     while (low != high) {
  849.         int mid = (low+high)/2;
  850.         int ret = file_compare(&flist->files[flist_up(flist, mid)],&f);
  851.         if (ret == 0) return flist_up(flist, mid);
  852.         if (ret > 0) {
  853.             high=mid;
  854.         } else {
  855.             low=mid+1;
  856.         }
  857.     }
  858.  
  859.     if (file_compare(&flist->files[flist_up(flist,low)],&f) == 0)
  860.         return flist_up(flist,low);
  861.     return -1;
  862. }
  863.  
  864.  
  865. /*
  866.  * free up one file
  867.  */
  868. static void free_file(struct file_struct *file)
  869. {
  870.     if (!file) return;
  871.     if (file->basename) free(file->basename);
  872.     if (file->link) free(file->link);
  873.     if (file->sum) free(file->sum);
  874.     memset((char *)file, 0, sizeof(*file));
  875. }
  876.  
  877.  
  878. /*
  879.  * free up all elements in a flist
  880.  */
  881. void flist_free(struct file_list *flist)
  882. {
  883.     int i;
  884.     for (i=1;i<flist->count;i++) {
  885.         free_file(flist->files[i]);
  886.         free(flist->files[i]);
  887.     }    
  888.     memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
  889.     free(flist->files);
  890.     memset((char *)flist, 0, sizeof(*flist));
  891.     free(flist);
  892. }
  893.  
  894.  
  895. /*
  896.  * This routine ensures we don't have any duplicate names in our file list.
  897.  * duplicate names can cause corruption because of the pipelining 
  898.  */
  899. static void clean_flist(struct file_list *flist, int strip_root)
  900. {
  901.     int i;
  902.  
  903.     if (!flist || flist->count == 0) 
  904.         return;
  905.   
  906.     qsort(flist->files,flist->count,
  907.           sizeof(flist->files[0]),
  908.           (int (*)())file_compare);
  909.  
  910.     for (i=1;i<flist->count;i++) {
  911.         if (flist->files[i]->basename &&
  912.             flist->files[i-1]->basename &&
  913.             strcmp(f_name(flist->files[i]),
  914.                f_name(flist->files[i-1])) == 0) {
  915.             if (verbose > 1 && !am_server)
  916.                 rprintf(FINFO,"removing duplicate name %s from file list %d\n",
  917.                     f_name(flist->files[i-1]),i-1);
  918.             free_file(flist->files[i]);
  919.         } 
  920.     }
  921.  
  922.     if (strip_root) {
  923.         /* we need to strip off the root directory in the case
  924.            of relative paths, but this must be done _after_
  925.            the sorting phase */
  926.         for (i=0;i<flist->count;i++) {
  927.             if (flist->files[i]->dirname &&
  928.                 flist->files[i]->dirname[0] == '/') {
  929.                 memmove(&flist->files[i]->dirname[0],
  930.                     &flist->files[i]->dirname[1],
  931.                     strlen(flist->files[i]->dirname));
  932.             }
  933.             
  934.             if (flist->files[i]->dirname && 
  935.                 !flist->files[i]->dirname[0]) {
  936.                 flist->files[i]->dirname = NULL;
  937.             }
  938.         }
  939.     }
  940.  
  941.  
  942.     if (verbose <= 3) return;
  943.  
  944.     for (i=0;i<flist->count;i++) {
  945.         rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%d\n",
  946.             getpid(), i, 
  947.             NS(flist->files[i]->dirname),
  948.             NS(flist->files[i]->basename),
  949.             flist->files[i]->mode,
  950.             (int)flist->files[i]->length);
  951.     }
  952. }
  953.  
  954.  
  955. /*
  956.  * return the full filename of a flist entry
  957.  */
  958. char *f_name(struct file_struct *f)
  959. {
  960.     static char names[10][MAXPATHLEN];
  961.     static int n;
  962.     char *p = names[n];
  963.  
  964.     if (!f || !f->basename) return NULL;
  965.  
  966.     n = (n+1)%10;
  967.  
  968.     if (f->dirname) {
  969.         strlcpy(p, f->dirname, MAXPATHLEN);
  970.         strlcat(p, "/", MAXPATHLEN);
  971.         strlcat(p, f->basename, MAXPATHLEN);
  972.     } else {
  973.         strlcpy(p, f->basename, MAXPATHLEN);
  974.     }
  975.  
  976.     return p;
  977. }
  978.  
  979.