split the options parsing code into options.c
authorAndrew Tridgell <tridge@samba.org>
Sun, 10 May 1998 07:25:40 +0000 (07:25 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 10 May 1998 07:25:40 +0000 (07:25 +0000)
added the --port and --config options

use strlcpy() instead of strncpy()

some cleanups and formatting changes

Makefile.in
clientserver.c
flist.c
main.c
options.c [new file with mode: 0644]
rsync.c
util.c

index 46fe29e578c3d92285ad28874377f8f92bffcd24..f1e94a6562ea83bf814ddc431538a09d42d40c79 100644 (file)
@@ -22,8 +22,9 @@ SHELL=/bin/sh
 
 LIBOBJ=lib/getopt.o lib/fnmatch.o lib/zlib.o lib/compat.o
 OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o log.o
+OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o 
 DAEMON_OBJ = params.o loadparm.o clientserver.o
-OBJS=$(OBJS1) $(DAEMON_OBJ) flist.o io.o compat.o hlink.o token.o uidlist.o socket.o $(LIBOBJ)
+OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ)
 
 # note that the -I. is needed to handle config.h when using VPATH
 .c.o:
index b07654fa6665181154d2fcd8bd8f5aa4581d816c..38bb171d97973ddf275e87b55e1e39233c27b52f 100644 (file)
@@ -160,6 +160,8 @@ static int rsync_module(int fd, int i)
        return 0;
 }
 
+/* send a list of available modules to the client. Don't list those
+   with "list = False". */
 static void send_listing(int fd)
 {
        int n = lp_numservices();
@@ -175,7 +177,7 @@ static void send_listing(int fd)
    here */
 static int start_daemon(int fd)
 {
-       char line[1024];
+       char line[200];
        char *motd;
        int version;
 
@@ -205,7 +207,6 @@ static int start_daemon(int fd)
                io_printf(fd,"\n");
        }
 
-       /* read a single line indicating the resource that is wanted */
        while (1) {
                int i;
 
@@ -240,7 +241,9 @@ static int start_daemon(int fd)
 
 int daemon_main(void)
 {
-       if (!lp_load(RSYNCD_CONF)) {
+       extern char *config_file;
+
+       if (!lp_load(config_file)) {
                exit_cleanup(1);
        }
 
diff --git a/flist.c b/flist.c
index 494b1088310dc0aaad21d260e0b27729e2e02630..15c56c8ebbd8315a3c62a5aa20866d1359c7d66a 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -218,7 +218,7 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
   last_gid = file->gid;
   last_time = file->modtime;
 
-  strncpy(lastname,fname,MAXPATHLEN-1);
+  strlcpy(lastname,fname,MAXPATHLEN-1);
   lastname[MAXPATHLEN-1] = 0;
 }
 
@@ -253,11 +253,11 @@ static void receive_file_entry(struct file_struct **fptr,
 
   if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
 
-  strncpy(thisname,lastname,l1);
+  strlcpy(thisname,lastname,l1);
   read_sbuf(f,&thisname[l1],l2);
   thisname[l1+l2] = 0;
 
-  strncpy(lastname,thisname,MAXPATHLEN-1);
+  strlcpy(lastname,thisname,MAXPATHLEN-1);
   lastname[MAXPATHLEN-1] = 0;
 
   clean_fname(thisname);
@@ -351,7 +351,7 @@ static struct file_struct *make_file(char *fname)
        char *p;
        char cleaned_name[MAXPATHLEN];
 
-       strncpy(cleaned_name, fname, MAXPATHLEN-1);
+       strlcpy(cleaned_name, fname, MAXPATHLEN-1);
        cleaned_name[MAXPATHLEN-1] = 0;
        clean_fname(cleaned_name);
        fname = cleaned_name;
@@ -512,8 +512,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                return;
        }
 
-       strncpy(fname,dir,MAXPATHLEN-1);
-       fname[MAXPATHLEN-1]=0;
+       strlcpy(fname,dir,MAXPATHLEN-1);
        l = strlen(fname);
        if (fname[l-1] != '/') {
                if (l == MAXPATHLEN-1) {
@@ -542,7 +541,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                if (strcmp(dname,".")==0 ||
                    strcmp(dname,"..")==0)
                        continue;
-               strncpy(p,dname,MAXPATHLEN-(l+1));
+               strlcpy(p,dname,MAXPATHLEN-(l+1));
                send_file_name(f,flist,fname,recurse,FLAG_DELETE);
        }
 
@@ -578,8 +577,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                char fname2[MAXPATHLEN];
                char *fname = fname2;
 
-               strncpy(fname,argv[i],MAXPATHLEN-1);
-               fname[MAXPATHLEN-1] = 0;
+               strlcpy(fname,argv[i],MAXPATHLEN-1);
 
                l = strlen(fname);
                if (l != 1 && fname[l-1] == '/') {
diff --git a/main.c b/main.c
index fc4dc60d420d2cea09935cd66353dfbf39c2f38b..e9a00397efd3f51512ef7d21f874a8e682dc067e 100644 (file)
--- a/main.c
+++ b/main.c
 
 #include "rsync.h"
 
-int verbose = 0;
-int always_checksum = 0;
 time_t starttime = 0;
 int64 total_size = 0;
-int block_size=BLOCK_SIZE;
-
-char *backup_suffix = BACKUP_SUFFIX;
-char *tmpdir = NULL;
-
-static char *rsync_path = RSYNC_NAME;
-
-int make_backups = 0;
-int whole_file = 0;
-int copy_links = 0;
-int preserve_links = 0;
-int preserve_hard_links = 0;
-int preserve_perms = 0;
-int preserve_devices = 0;
-int preserve_uid = 0;
-int preserve_gid = 0;
-int preserve_times = 0;
-int update_only = 0;
-int cvs_exclude = 0;
-int dry_run=0;
-int local_server=0;
-int ignore_times=0;
-int delete_mode=0;
-int one_file_system=0;
-int remote_version=0;
-int sparse_files=0;
-int do_compression=0;
-int am_root=0;
-int orig_umask=0;
-int relative_paths=0;
-int numeric_ids = 0;
-int force_delete = 0;
-int io_timeout = 0;
-int io_error = 0;
-int read_only = 0;
-int module_id = -1;
-
-int rsync_port = RSYNC_PORT;
-
-static char *shell_cmd;
 
 extern int csum_length;
 
-int am_server = 0;
-int am_sender=0;
-int recurse = 0;
-int am_daemon=0;
-
-static void usage(int fd);
+extern int verbose;
 
 static void report(int f)
 {
-  int64 in,out,tsize;
-  time_t t = time(NULL);
-  
-  if (!verbose) return;
-
-  if (am_server && am_sender) {
-    write_longint(f,read_total());
-    write_longint(f,write_total());
-    write_longint(f,total_size);
-    write_flush(f);
-    return;
-  }
+       int64 in,out,tsize;
+       time_t t = time(NULL);
+       extern int am_server;
+       extern int am_sender;
+
+       if (!verbose) return;
+
+       if (am_server && am_sender) {
+               write_longint(f,read_total());
+               write_longint(f,write_total());
+               write_longint(f,total_size);
+               write_flush(f);
+               return;
+       }
     
-  if (am_sender) {
-    in = read_total();
-    out = write_total();
-    tsize = total_size;
-  } else {
-    in = read_longint(f);
-    out = read_longint(f);
-    tsize = read_longint(f);
-  }
-
-  printf("wrote %.0f bytes  read %.0f bytes  %.2f bytes/sec\n",
-        (double)out,(double)in,(in+out)/(0.5 + (t-starttime)));
-  printf("total size is %.0f  speedup is %.2f\n",
-        (double)tsize,(1.0*tsize)/(in+out));
-}
-
-
-void server_options(char **args,int *argc)
-{
-  int ac = *argc;
-  static char argstr[50];
-  static char bsize[30];
-  static char iotime[30];
-  int i, x;
-
-  args[ac++] = "--server";
-
-  if (!am_sender)
-    args[ac++] = "--sender";
-
-  x = 1;
-  argstr[0] = '-';
-  for (i=0;i<verbose;i++)
-    argstr[x++] = 'v';
-  if (make_backups)
-    argstr[x++] = 'b';
-  if (update_only)
-    argstr[x++] = 'u';
-  if (dry_run)
-    argstr[x++] = 'n';
-  if (preserve_links)
-    argstr[x++] = 'l';
-  if (copy_links)
-    argstr[x++] = 'L';
-  if (whole_file)
-    argstr[x++] = 'W';
-  if (preserve_hard_links)
-    argstr[x++] = 'H';
-  if (preserve_uid)
-    argstr[x++] = 'o';
-  if (preserve_gid)
-    argstr[x++] = 'g';
-  if (preserve_devices)
-    argstr[x++] = 'D';
-  if (preserve_times)
-    argstr[x++] = 't';
-  if (preserve_perms)
-    argstr[x++] = 'p';
-  if (recurse)
-    argstr[x++] = 'r';
-  if (always_checksum)
-    argstr[x++] = 'c';
-  if (cvs_exclude)
-    argstr[x++] = 'C';
-  if (ignore_times)
-    argstr[x++] = 'I';
-  if (relative_paths)
-    argstr[x++] = 'R';
-  if (one_file_system)
-    argstr[x++] = 'x';
-  if (sparse_files)
-    argstr[x++] = 'S';
-  if (do_compression)
-    argstr[x++] = 'z';
-  argstr[x] = 0;
-
-  if (x != 1) args[ac++] = argstr;
-
-  if (block_size != BLOCK_SIZE) {
-    sprintf(bsize,"-B%d",block_size);
-    args[ac++] = bsize;
-  }    
-
-  if (io_timeout) {
-    sprintf(iotime,"--timeout=%d",io_timeout);
-    args[ac++] = iotime;
-  }    
-
-  if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
-         args[ac++] = "--suffix";
-         args[ac++] = backup_suffix;
-  }
-
-  if (delete_mode)
-    args[ac++] = "--delete";
-
-  if (force_delete)
-    args[ac++] = "--force";
-
-  if (numeric_ids)
-    args[ac++] = "--numeric-ids";
-
-  if (tmpdir) {
-         args[ac++] = "--temp-dir";
-         args[ac++] = tmpdir;
-  }
-
-  *argc = ac;
+       if (am_sender) {
+               in = read_total();
+               out = write_total();
+               tsize = total_size;
+       } else {
+               in = read_longint(f);
+               out = read_longint(f);
+               tsize = read_longint(f);
+       }
+       
+       printf("wrote %.0f bytes  read %.0f bytes  %.2f bytes/sec\n",
+              (double)out,(double)in,(in+out)/(0.5 + (t-starttime)));
+       printf("total size is %.0f  speedup is %.2f\n",
+              (double)tsize,(1.0*tsize)/(in+out));
 }
 
 
-
 static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
 {
        char *args[100];
        int i,argc=0, ret;
        char *tok,*dir=NULL;
+       extern int local_server;
+       extern char *rsync_path;
 
        if (!local_server) {
                if (!cmd)
@@ -273,7 +135,8 @@ oom:
 
 static char *get_local_name(struct file_list *flist,char *name)
 {
-  STRUCT_STAT st;
+       STRUCT_STAT st;
+       extern int orig_umask;
 
   if (do_stat(name,&st) == 0) {
     if (S_ISDIR(st.st_mode)) {
@@ -316,51 +179,55 @@ static char *get_local_name(struct file_list *flist,char *name)
 
 static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
 {
-  int i;
-  struct file_list *flist;
-  char *dir = argv[0];
+       int i;
+       struct file_list *flist;
+       char *dir = argv[0];
+       extern int relative_paths;
+       extern int am_daemon;
+       extern int recurse;
 
-  if (verbose > 2)
-    rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
+       if (verbose > 2)
+               rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
   
-  if (!relative_paths && chdir(dir) != 0) {
-         rprintf(FERROR,"chdir %s: %s (3)\n",dir,strerror(errno));
-         exit_cleanup(1);
-  }
-  argc--;
-  argv++;
+       if (!relative_paths && chdir(dir) != 0) {
+               rprintf(FERROR,"chdir %s: %s (3)\n",dir,strerror(errno));
+               exit_cleanup(1);
+       }
+       argc--;
+       argv++;
   
-  if (strcmp(dir,".")) {
-         int l = strlen(dir);
-         if (strcmp(dir,"/") == 0) 
-                 l = 0;
-         for (i=0;i<argc;i++)
-                 argv[i] += l+1;
-  }
-
-  if (am_daemon) {
-         char *name = lp_name(module_id);
-         int l = strlen(name);
-         for (i=0;i<argc;i++) {
-                 if (strncmp(argv[i], name, l) == 0) {
-                         argv[i] += l;
-                         if (!*argv[i]) argv[i] = ".";
-                 }
-         }
-  }
-
-  if (argc == 0 && recurse) {
-         argc=1;
-         argv--;
-         argv[0] = ".";
-  }
-
-  rprintf(FINFO,"sending file list\n");
+       if (strcmp(dir,".")) {
+               int l = strlen(dir);
+               if (strcmp(dir,"/") == 0) 
+                       l = 0;
+               for (i=0;i<argc;i++)
+                       argv[i] += l+1;
+       }
 
-  flist = send_file_list(f_out,argc,argv);
-  send_files(flist,f_out,f_in);
-  report(f_out);
-  exit_cleanup(0);
+       if (am_daemon) {
+               extern int module_id;
+               char *name = lp_name(module_id);
+               int l = strlen(name);
+               for (i=0;i<argc;i++) {
+                       if (strncmp(argv[i], name, l) == 0) {
+                               argv[i] += l;
+                               if (!*argv[i]) argv[i] = ".";
+                       }
+               }
+       }
+       
+       if (argc == 0 && recurse) {
+               argc=1;
+               argv--;
+               argv[0] = ".";
+       }
+       
+       rprintf(FINFO,"sending file list\n");
+       
+       flist = send_file_list(f_out,argc,argv);
+       send_files(flist,f_out,f_in);
+       report(f_out);
+       exit_cleanup(0);
 }
 
 
@@ -369,6 +236,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
   int pid;
   int status=0;
   int recv_pipe[2];
+  extern int preserve_hard_links;
 
   if (preserve_hard_links)
     init_hard_links(flist);
@@ -396,72 +264,77 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
 
 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
 {
-  int status;
-  struct file_list *flist;
-  char *local_name=NULL;
-  char *dir = NULL;
-  
-  if (verbose > 2)
-    rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
-
-  if (am_daemon) {
-         char *name = lp_name(module_id);
-         int i, l = strlen(name);
-         for (i=0;i<argc;i++) {
-                 if (strncmp(argv[i], name, l) == 0) {
-                         argv[i] += l;
-                         if (!*argv[i]) argv[i] = ".";
-                 }
-                 rprintf(FINFO,"argv[%d]=%s\n", i, argv[i]);
-         }
-  }
+       int status;
+       struct file_list *flist;
+       char *local_name=NULL;
+       char *dir = NULL;
+       extern int delete_mode;
+       extern int am_daemon;
 
-  if (argc > 0) {
-         dir = argv[0];
-         argc--;
-         argv++;
-         if (!am_daemon && chdir(dir) != 0) {
-                 rprintf(FERROR,"chdir %s : %s (4)\n",
-                         dir,strerror(errno));
-                 exit_cleanup(1);
-         }    
-  }
+       if (verbose > 2)
+               rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
+       
+       if (am_daemon) {
+               extern int module_id;
+               char *name = lp_name(module_id);
+               int i, l = strlen(name);
+               for (i=0;i<argc;i++) {
+                       if (strncmp(argv[i], name, l) == 0) {
+                               argv[i] += l;
+                               if (!*argv[i]) argv[i] = ".";
+                       }
+               }
+       }
 
-  if (delete_mode)
-    recv_exclude_list(f_in);
+       if (argc > 0) {
+               dir = argv[0];
+               argc--;
+               argv++;
+               if (!am_daemon && chdir(dir) != 0) {
+                       rprintf(FERROR,"chdir %s : %s (4)\n",
+                               dir,strerror(errno));
+                       exit_cleanup(1);
+               }    
+       }
 
-  flist = recv_file_list(f_in);
-  if (!flist || flist->count == 0) {
-    rprintf(FERROR,"nothing to do\n");
-    exit_cleanup(1);
-  }
+       if (delete_mode)
+               recv_exclude_list(f_in);
 
-  if (argc > 0) {    
-         if (strcmp(dir,".")) {
-                 argv[0] += strlen(dir);
-                 if (argv[0][0] == '/') argv[0]++;
-         }
-         local_name = get_local_name(flist,argv[0]);
-  }
+       flist = recv_file_list(f_in);
+       if (!flist || flist->count == 0) {
+               rprintf(FERROR,"nothing to do\n");
+               exit_cleanup(1);
+       }
+       
+       if (argc > 0) {    
+               if (strcmp(dir,".")) {
+                       argv[0] += strlen(dir);
+                       if (argv[0][0] == '/') argv[0]++;
+               }
+               local_name = get_local_name(flist,argv[0]);
+       }
 
-  status = do_recv(f_in,f_out,flist,local_name);
-  exit_cleanup(status);
+       status = do_recv(f_in,f_out,flist,local_name);
+       exit_cleanup(status);
 }
 
 
 void start_server(int f_in, int f_out, int argc, char *argv[])
 {
-      setup_protocol(f_out, f_in);
+       extern int cvs_exclude;
+       extern int am_sender;
+
+       setup_protocol(f_out, f_in);
        
-      if (am_sender) {
-             recv_exclude_list(f_in);
-             if (cvs_exclude)
-                     add_cvs_excludes();
-             do_server_sender(f_in, f_out, argc, argv);
-      } else {
-             do_server_recv(f_in, f_out, argc, argv);
-      }
-      exit_cleanup(0);
+       if (am_sender) {
+               recv_exclude_list(f_in);
+               if (cvs_exclude)
+                       add_cvs_excludes();
+               do_server_sender(f_in, f_out, argc, argv);
+       } else {
+               do_server_recv(f_in, f_out, argc, argv);
+       }
+       exit_cleanup(0);
 }
 
 int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
@@ -469,10 +342,13 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
        struct file_list *flist;
        int status = 0, status2 = 0;
        char *local_name = NULL;
+       extern int am_sender;
 
        setup_protocol(f_out,f_in);
        
        if (am_sender) {
+               extern int cvs_exclude;
+               extern int delete_mode;
                if (cvs_exclude)
                        add_cvs_excludes();
                if (delete_mode) 
@@ -520,6 +396,9 @@ int start_client(int argc, char *argv[])
        char *shell_user = NULL;
        int pid;
        int f_in,f_out;
+       extern int local_server;
+       extern int am_sender;
+       extern char *shell_cmd;
 
        p = strchr(argv[0],':');
 
@@ -600,335 +479,56 @@ int start_client(int argc, char *argv[])
 }
 
 
-static void usage(int F)
-{
-  rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
-         VERSION);
-  rprintf(F,"Usage:\t%s [options] src user@host:dest\nOR",RSYNC_NAME);
-  rprintf(F,"\t%s [options] user@host:src dest\n\n",RSYNC_NAME);
-  rprintf(F,"Options:\n");
-  rprintf(F,"-v, --verbose            increase verbosity\n");
-  rprintf(F,"-c, --checksum           always checksum\n");
-  rprintf(F,"-a, --archive            archive mode (same as -rlptDog)\n");
-  rprintf(F,"-r, --recursive          recurse into directories\n");
-  rprintf(F,"-R, --relative           use relative path names\n");
-  rprintf(F,"-b, --backup             make backups (default ~ extension)\n");
-  rprintf(F,"-u, --update             update only (don't overwrite newer files)\n");
-  rprintf(F,"-l, --links              preserve soft links\n");
-  rprintf(F,"-L, --copy-links         treat soft links like regular files\n");
-  rprintf(F,"-H, --hard-links         preserve hard links\n");
-  rprintf(F,"-p, --perms              preserve permissions\n");
-  rprintf(F,"-o, --owner              preserve owner (root only)\n");
-  rprintf(F,"-g, --group              preserve group\n");
-  rprintf(F,"-D, --devices            preserve devices (root only)\n");
-  rprintf(F,"-t, --times              preserve times\n");  
-  rprintf(F,"-S, --sparse             handle sparse files efficiently\n");
-  rprintf(F,"-n, --dry-run            show what would have been transferred\n");
-  rprintf(F,"-W, --whole-file         copy whole files, no incremental checks\n");
-  rprintf(F,"-x, --one-file-system    don't cross filesystem boundaries\n");
-  rprintf(F,"-B, --block-size SIZE    checksum blocking size\n");  
-  rprintf(F,"-e, --rsh COMMAND        specify rsh replacement\n");
-  rprintf(F,"    --rsync-path PATH    specify path to rsync on the remote machine\n");
-  rprintf(F,"-C, --cvs-exclude        auto ignore files in the same way CVS does\n");
-  rprintf(F,"    --delete             delete files that don't exist on the sending side\n");
-  rprintf(F,"    --force              force deletion of directories even if not empty\n");
-  rprintf(F,"    --numeric-ids        don't map uid/gid values by user/group name\n");
-  rprintf(F,"    --timeout TIME       set IO timeout in seconds\n");
-  rprintf(F,"-I, --ignore-times       don't exclude files that match length and time\n");
-  rprintf(F,"-T  --temp-dir DIR       create temporary files in directory DIR\n");
-  rprintf(F,"-z, --compress           compress file data\n");
-  rprintf(F,"    --exclude FILE       exclude file FILE\n");
-  rprintf(F,"    --exclude-from FILE  exclude files listed in FILE\n");
-  rprintf(F,"    --suffix SUFFIX      override backup suffix\n");  
-  rprintf(F,"    --version            print version number\n");  
-
-  rprintf(F,"\n");
-  rprintf(F,"the backup suffix defaults to %s\n",BACKUP_SUFFIX);
-  rprintf(F,"the block size defaults to %d\n",BLOCK_SIZE);  
-}
-
-enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
-      OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
-      OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON};
-
-static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
-
-static struct option long_options[] = {
-  {"version",     0,     0,    OPT_VERSION},
-  {"server",      0,     0,    OPT_SERVER},
-  {"sender",      0,     0,    OPT_SENDER},
-  {"delete",      0,     0,    OPT_DELETE},
-  {"force",       0,     0,    OPT_FORCE},
-  {"numeric-ids", 0,     0,    OPT_NUMERIC_IDS},
-  {"exclude",     1,     0,    OPT_EXCLUDE},
-  {"exclude-from",1,     0,    OPT_EXCLUDE_FROM},
-  {"rsync-path",  1,     0,    OPT_RSYNC_PATH},
-  {"one-file-system",0,  0,    'x'},
-  {"ignore-times",0,     0,    'I'},
-  {"help",        0,     0,    'h'},
-  {"dry-run",     0,     0,    'n'},
-  {"sparse",      0,     0,    'S'},
-  {"cvs-exclude", 0,     0,    'C'},
-  {"archive",     0,     0,    'a'},
-  {"checksum",    0,     0,    'c'},
-  {"backup",      0,     0,    'b'},
-  {"update",      0,     0,    'u'},
-  {"verbose",     0,     0,    'v'},
-  {"recursive",   0,     0,    'r'},
-  {"relative",    0,     0,    'R'},
-  {"devices",     0,     0,    'D'},
-  {"perms",       0,     0,    'p'},
-  {"links",       0,     0,    'l'},
-  {"copy-links",  0,     0,    'L'},
-  {"whole-file",  0,     0,    'W'},
-  {"hard-links",  0,     0,    'H'},
-  {"owner",       0,     0,    'o'},
-  {"group",       0,     0,    'g'},
-  {"times",       0,     0,    't'},
-  {"rsh",         1,     0,    'e'},
-  {"suffix",      1,     0,    OPT_SUFFIX},
-  {"block-size",  1,     0,    'B'},
-  {"timeout",     1,     0,    OPT_TIMEOUT},
-  {"temp-dir",    1,     0,    'T'},
-  {"compress",   0,     0,    'z'},
-  {"daemon",      0,     0,    OPT_DAEMON},
-  {0,0,0,0}};
-
 RETSIGTYPE sigusr1_handler(int val) {
        exit_cleanup(1);
 }
 
-
-void parse_arguments(int argc, char *argv[])
-{
-    int opt;
-    int option_index;
-
-    while ((opt = getopt_long(argc, argv, 
-                             short_options, long_options, &option_index)) 
-          != -1) {
-      switch (opt) 
-       {
-       case OPT_VERSION:
-         printf("rsync version %s  protocol version %d\n",
-                VERSION,PROTOCOL_VERSION);
-         exit_cleanup(0);
-
-       case OPT_SUFFIX:
-         backup_suffix = optarg;
-         break;
-
-       case OPT_RSYNC_PATH:
-         rsync_path = optarg;
-         break;
-
-       case 'I':
-         ignore_times = 1;
-         break;
-
-       case 'x':
-         one_file_system=1;
-         break;
-
-       case OPT_DELETE:
-         delete_mode = 1;
-         break;
-
-       case OPT_FORCE:
-         force_delete = 1;
-         break;
-
-       case OPT_NUMERIC_IDS:
-         numeric_ids = 1;
-         break;
-
-       case OPT_EXCLUDE:
-         add_exclude(optarg);
-         break;
-
-       case OPT_EXCLUDE_FROM:
-         add_exclude_file(optarg,1);
-         break;
-
-       case 'h':
-         usage(FINFO);
-         exit_cleanup(0);
-
-       case 'b':
-         make_backups=1;
-         break;
-
-       case 'n':
-         dry_run=1;
-         break;
-
-       case 'S':
-         sparse_files=1;
-         break;
-
-       case 'C':
-         cvs_exclude=1;
-         break;
-
-       case 'u':
-         update_only=1;
-         break;
-
-       case 'l':
-         preserve_links=1;
-         break;
-
-       case 'L':
-         copy_links=1;
-         break;
-
-       case 'W':
-         whole_file=1;
-         break;
-
-       case 'H':
-#if SUPPORT_HARD_LINKS
-         preserve_hard_links=1;
-#else 
-         rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
-         exit_cleanup(1);
-#endif
-         break;
-
-       case 'p':
-         preserve_perms=1;
-         break;
-
-       case 'o':
-         preserve_uid=1;
-         break;
-
-       case 'g':
-         preserve_gid=1;
-         break;
-
-       case 'D':
-         preserve_devices=1;
-         break;
-
-       case 't':
-         preserve_times=1;
-         break;
-
-       case 'c':
-         always_checksum=1;
-         break;
-
-       case 'v':
-         verbose++;
-         break;
-
-       case 'a':
-         recurse=1;
-#if SUPPORT_LINKS
-         preserve_links=1;
-#endif
-         preserve_perms=1;
-         preserve_times=1;
-         preserve_gid=1;
-         if (am_root) {
-           preserve_devices=1;
-           preserve_uid=1;
-         }
-         break;
-
-       case OPT_SERVER:
-         am_server = 1;
-         break;
-
-       case OPT_SENDER:
-         if (!am_server) {
-           usage(FERROR);
-           exit_cleanup(1);
-         }
-         am_sender = 1;
-         break;
-
-       case 'r':
-         recurse = 1;
-         break;
-
-       case 'R':
-         relative_paths = 1;
-         break;
-
-       case 'e':
-         shell_cmd = optarg;
-         break;
-
-       case 'B':
-         block_size = atoi(optarg);
-         break;
-
-       case OPT_TIMEOUT:
-         io_timeout = atoi(optarg);
-         break;
-
-       case 'T':
-               tmpdir = optarg;
-               break;
-
-        case 'z':
-         do_compression = 1;
-         break;
-
-       case OPT_DAEMON:
-               am_daemon = 1;
-               break;
-
-       default:
-         /* rprintf(FERROR,"bad option -%c\n",opt); */
-         exit_cleanup(1);
-       }
-    }
-}
-
 int main(int argc,char *argv[])
-{
+{       
+       extern int am_root;
+       extern int orig_umask;
+       extern int dry_run;
+       extern int am_daemon;
+       extern int am_server;
 
-    signal(SIGUSR1, sigusr1_handler);
+       signal(SIGUSR1, sigusr1_handler);
 
-    starttime = time(NULL);
-    am_root = (getuid() == 0);
+       starttime = time(NULL);
+       am_root = (getuid() == 0);
 
-    /* we set a 0 umask so that correct file permissions can be
-       carried across */
-    orig_umask = (int)umask(0);
+       /* we set a 0 umask so that correct file permissions can be
+          carried across */
+       orig_umask = (int)umask(0);
 
-    parse_arguments(argc, argv);
+       parse_arguments(argc, argv);
 
-    argc -= optind;
-    argv += optind;
-    optind = 0;
+       argc -= optind;
+       argv += optind;
+       optind = 0;
 
-    signal(SIGCHLD,SIG_IGN);
-    signal(SIGINT,SIGNAL_CAST sig_int);
-    signal(SIGPIPE,SIGNAL_CAST sig_int);
-    signal(SIGHUP,SIGNAL_CAST sig_int);
+       signal(SIGCHLD,SIG_IGN);
+       signal(SIGINT,SIGNAL_CAST sig_int);
+       signal(SIGPIPE,SIGNAL_CAST sig_int);
+       signal(SIGHUP,SIGNAL_CAST sig_int);
 
-    if (am_daemon) {
-           return daemon_main();
-    }
+       if (am_daemon) {
+               return daemon_main();
+       }
 
-    if (dry_run)
-      verbose = MAX(verbose,1);
+       if (dry_run)
+               verbose = MAX(verbose,1);
 
 #ifndef SUPPORT_LINKS
-    if (!am_server && preserve_links) {
-           rprintf(FERROR,"ERROR: symbolic links not supported\n");
-           exit_cleanup(1);
-    }
+       if (!am_server && preserve_links) {
+               rprintf(FERROR,"ERROR: symbolic links not supported\n");
+               exit_cleanup(1);
+       }
 #endif
 
-    if (am_server) {
-           start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
-    }
+       if (am_server) {
+               start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
+       }
 
-    return start_client(argc, argv);
+       return start_client(argc, argv);
 }
 
diff --git a/options.c b/options.c
new file mode 100644 (file)
index 0000000..3e2b714
--- /dev/null
+++ b/options.c
@@ -0,0 +1,461 @@
+/* 
+   Copyright (C) Andrew Tridgell 1998
+   
+   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
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* options parsing code */
+
+#include "rsync.h"
+
+
+int make_backups = 0;
+int whole_file = 0;
+int copy_links = 0;
+int preserve_links = 0;
+int preserve_hard_links = 0;
+int preserve_perms = 0;
+int preserve_devices = 0;
+int preserve_uid = 0;
+int preserve_gid = 0;
+int preserve_times = 0;
+int update_only = 0;
+int cvs_exclude = 0;
+int dry_run=0;
+int local_server=0;
+int ignore_times=0;
+int delete_mode=0;
+int one_file_system=0;
+int remote_version=0;
+int sparse_files=0;
+int do_compression=0;
+int am_root=0;
+int orig_umask=0;
+int relative_paths=0;
+int numeric_ids = 0;
+int force_delete = 0;
+int io_timeout = 0;
+int io_error = 0;
+int read_only = 0;
+int module_id = -1;
+int am_server = 0;
+int am_sender=0;
+int recurse = 0;
+int am_daemon=0;
+
+int block_size=BLOCK_SIZE;
+
+char *backup_suffix = BACKUP_SUFFIX;
+char *tmpdir = NULL;
+char *config_file = RSYNCD_CONF;
+char *shell_cmd = NULL;
+
+char *rsync_path = RSYNC_NAME;
+int rsync_port = RSYNC_PORT;
+
+int verbose = 0;
+int always_checksum = 0;
+
+
+void usage(int F)
+{
+  rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
+         VERSION);
+  rprintf(F,"Usage:\t%s [options] src user@host:dest\nOR",RSYNC_NAME);
+  rprintf(F,"\t%s [options] user@host:src dest\n\n",RSYNC_NAME);
+  rprintf(F,"Options:\n");
+  rprintf(F,"-v, --verbose            increase verbosity\n");
+  rprintf(F,"-c, --checksum           always checksum\n");
+  rprintf(F,"-a, --archive            archive mode (same as -rlptDog)\n");
+  rprintf(F,"-r, --recursive          recurse into directories\n");
+  rprintf(F,"-R, --relative           use relative path names\n");
+  rprintf(F,"-b, --backup             make backups (default ~ extension)\n");
+  rprintf(F,"-u, --update             update only (don't overwrite newer files)\n");
+  rprintf(F,"-l, --links              preserve soft links\n");
+  rprintf(F,"-L, --copy-links         treat soft links like regular files\n");
+  rprintf(F,"-H, --hard-links         preserve hard links\n");
+  rprintf(F,"-p, --perms              preserve permissions\n");
+  rprintf(F,"-o, --owner              preserve owner (root only)\n");
+  rprintf(F,"-g, --group              preserve group\n");
+  rprintf(F,"-D, --devices            preserve devices (root only)\n");
+  rprintf(F,"-t, --times              preserve times\n");  
+  rprintf(F,"-S, --sparse             handle sparse files efficiently\n");
+  rprintf(F,"-n, --dry-run            show what would have been transferred\n");
+  rprintf(F,"-W, --whole-file         copy whole files, no incremental checks\n");
+  rprintf(F,"-x, --one-file-system    don't cross filesystem boundaries\n");
+  rprintf(F,"-B, --block-size SIZE    checksum blocking size\n");  
+  rprintf(F,"-e, --rsh COMMAND        specify rsh replacement\n");
+  rprintf(F,"    --rsync-path PATH    specify path to rsync on the remote machine\n");
+  rprintf(F,"-C, --cvs-exclude        auto ignore files in the same way CVS does\n");
+  rprintf(F,"    --delete             delete files that don't exist on the sending side\n");
+  rprintf(F,"    --force              force deletion of directories even if not empty\n");
+  rprintf(F,"    --numeric-ids        don't map uid/gid values by user/group name\n");
+  rprintf(F,"    --timeout TIME       set IO timeout in seconds\n");
+  rprintf(F,"-I, --ignore-times       don't exclude files that match length and time\n");
+  rprintf(F,"-T  --temp-dir DIR       create temporary files in directory DIR\n");
+  rprintf(F,"-z, --compress           compress file data\n");
+  rprintf(F,"    --exclude FILE       exclude file FILE\n");
+  rprintf(F,"    --exclude-from FILE  exclude files listed in FILE\n");
+  rprintf(F,"    --suffix SUFFIX      override backup suffix\n");  
+  rprintf(F,"    --version            print version number\n");  
+  rprintf(F,"    --daemon             run as a rsync daemon\n");  
+  rprintf(F,"    --config FILE        specify alternate rsyncd.conf file\n");  
+  rprintf(F,"    --port PORT          specify alternate rsyncd port number\n");  
+
+  rprintf(F,"\n");
+  rprintf(F,"the backup suffix defaults to %s\n",BACKUP_SUFFIX);
+  rprintf(F,"the block size defaults to %d\n",BLOCK_SIZE);  
+}
+
+enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
+      OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
+      OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT};
+
+static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
+
+static struct option long_options[] = {
+  {"version",     0,     0,    OPT_VERSION},
+  {"server",      0,     0,    OPT_SERVER},
+  {"sender",      0,     0,    OPT_SENDER},
+  {"delete",      0,     0,    OPT_DELETE},
+  {"force",       0,     0,    OPT_FORCE},
+  {"numeric-ids", 0,     0,    OPT_NUMERIC_IDS},
+  {"exclude",     1,     0,    OPT_EXCLUDE},
+  {"exclude-from",1,     0,    OPT_EXCLUDE_FROM},
+  {"rsync-path",  1,     0,    OPT_RSYNC_PATH},
+  {"one-file-system",0,  0,    'x'},
+  {"ignore-times",0,     0,    'I'},
+  {"help",        0,     0,    'h'},
+  {"dry-run",     0,     0,    'n'},
+  {"sparse",      0,     0,    'S'},
+  {"cvs-exclude", 0,     0,    'C'},
+  {"archive",     0,     0,    'a'},
+  {"checksum",    0,     0,    'c'},
+  {"backup",      0,     0,    'b'},
+  {"update",      0,     0,    'u'},
+  {"verbose",     0,     0,    'v'},
+  {"recursive",   0,     0,    'r'},
+  {"relative",    0,     0,    'R'},
+  {"devices",     0,     0,    'D'},
+  {"perms",       0,     0,    'p'},
+  {"links",       0,     0,    'l'},
+  {"copy-links",  0,     0,    'L'},
+  {"whole-file",  0,     0,    'W'},
+  {"hard-links",  0,     0,    'H'},
+  {"owner",       0,     0,    'o'},
+  {"group",       0,     0,    'g'},
+  {"times",       0,     0,    't'},
+  {"rsh",         1,     0,    'e'},
+  {"suffix",      1,     0,    OPT_SUFFIX},
+  {"block-size",  1,     0,    'B'},
+  {"timeout",     1,     0,    OPT_TIMEOUT},
+  {"temp-dir",    1,     0,    'T'},
+  {"compress",   0,     0,    'z'},
+  {"daemon",      0,     0,    OPT_DAEMON},
+  {"config",      1,     0,    OPT_CONFIG},
+  {"port",        1,     0,    OPT_PORT},
+  {0,0,0,0}};
+
+void parse_arguments(int argc, char *argv[])
+{
+    int opt;
+    int option_index;
+
+    while ((opt = getopt_long(argc, argv, 
+                             short_options, long_options, &option_index)) 
+          != -1) {
+      switch (opt) 
+       {
+       case OPT_VERSION:
+         printf("rsync version %s  protocol version %d\n",
+                VERSION,PROTOCOL_VERSION);
+         exit_cleanup(0);
+
+       case OPT_SUFFIX:
+         backup_suffix = optarg;
+         break;
+
+       case OPT_RSYNC_PATH:
+         rsync_path = optarg;
+         break;
+
+       case 'I':
+         ignore_times = 1;
+         break;
+
+       case 'x':
+         one_file_system=1;
+         break;
+
+       case OPT_DELETE:
+         delete_mode = 1;
+         break;
+
+       case OPT_FORCE:
+         force_delete = 1;
+         break;
+
+       case OPT_NUMERIC_IDS:
+         numeric_ids = 1;
+         break;
+
+       case OPT_EXCLUDE:
+         add_exclude(optarg);
+         break;
+
+       case OPT_EXCLUDE_FROM:
+         add_exclude_file(optarg,1);
+         break;
+
+       case 'h':
+         usage(FINFO);
+         exit_cleanup(0);
+
+       case 'b':
+         make_backups=1;
+         break;
+
+       case 'n':
+         dry_run=1;
+         break;
+
+       case 'S':
+         sparse_files=1;
+         break;
+
+       case 'C':
+         cvs_exclude=1;
+         break;
+
+       case 'u':
+         update_only=1;
+         break;
+
+       case 'l':
+         preserve_links=1;
+         break;
+
+       case 'L':
+         copy_links=1;
+         break;
+
+       case 'W':
+         whole_file=1;
+         break;
+
+       case 'H':
+#if SUPPORT_HARD_LINKS
+         preserve_hard_links=1;
+#else 
+         rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
+         exit_cleanup(1);
+#endif
+         break;
+
+       case 'p':
+         preserve_perms=1;
+         break;
+
+       case 'o':
+         preserve_uid=1;
+         break;
+
+       case 'g':
+         preserve_gid=1;
+         break;
+
+       case 'D':
+         preserve_devices=1;
+         break;
+
+       case 't':
+         preserve_times=1;
+         break;
+
+       case 'c':
+         always_checksum=1;
+         break;
+
+       case 'v':
+         verbose++;
+         break;
+
+       case 'a':
+         recurse=1;
+#if SUPPORT_LINKS
+         preserve_links=1;
+#endif
+         preserve_perms=1;
+         preserve_times=1;
+         preserve_gid=1;
+         if (am_root) {
+           preserve_devices=1;
+           preserve_uid=1;
+         }
+         break;
+
+       case OPT_SERVER:
+         am_server = 1;
+         break;
+
+       case OPT_SENDER:
+         if (!am_server) {
+           usage(FERROR);
+           exit_cleanup(1);
+         }
+         am_sender = 1;
+         break;
+
+       case 'r':
+         recurse = 1;
+         break;
+
+       case 'R':
+         relative_paths = 1;
+         break;
+
+       case 'e':
+         shell_cmd = optarg;
+         break;
+
+       case 'B':
+         block_size = atoi(optarg);
+         break;
+
+       case OPT_TIMEOUT:
+         io_timeout = atoi(optarg);
+         break;
+
+       case 'T':
+               tmpdir = optarg;
+               break;
+
+        case 'z':
+         do_compression = 1;
+         break;
+
+       case OPT_DAEMON:
+               am_daemon = 1;
+               break;
+
+       case OPT_CONFIG:
+               config_file = optarg;
+               break;
+
+       case OPT_PORT:
+               rsync_port = atoi(optarg);
+               break;
+
+       default:
+         /* rprintf(FERROR,"bad option -%c\n",opt); */
+         exit_cleanup(1);
+       }
+    }
+}
+
+
+void server_options(char **args,int *argc)
+{
+  int ac = *argc;
+  static char argstr[50];
+  static char bsize[30];
+  static char iotime[30];
+  int i, x;
+
+  args[ac++] = "--server";
+
+  if (!am_sender)
+    args[ac++] = "--sender";
+
+  x = 1;
+  argstr[0] = '-';
+  for (i=0;i<verbose;i++)
+    argstr[x++] = 'v';
+  if (make_backups)
+    argstr[x++] = 'b';
+  if (update_only)
+    argstr[x++] = 'u';
+  if (dry_run)
+    argstr[x++] = 'n';
+  if (preserve_links)
+    argstr[x++] = 'l';
+  if (copy_links)
+    argstr[x++] = 'L';
+  if (whole_file)
+    argstr[x++] = 'W';
+  if (preserve_hard_links)
+    argstr[x++] = 'H';
+  if (preserve_uid)
+    argstr[x++] = 'o';
+  if (preserve_gid)
+    argstr[x++] = 'g';
+  if (preserve_devices)
+    argstr[x++] = 'D';
+  if (preserve_times)
+    argstr[x++] = 't';
+  if (preserve_perms)
+    argstr[x++] = 'p';
+  if (recurse)
+    argstr[x++] = 'r';
+  if (always_checksum)
+    argstr[x++] = 'c';
+  if (cvs_exclude)
+    argstr[x++] = 'C';
+  if (ignore_times)
+    argstr[x++] = 'I';
+  if (relative_paths)
+    argstr[x++] = 'R';
+  if (one_file_system)
+    argstr[x++] = 'x';
+  if (sparse_files)
+    argstr[x++] = 'S';
+  if (do_compression)
+    argstr[x++] = 'z';
+  argstr[x] = 0;
+
+  if (x != 1) args[ac++] = argstr;
+
+  if (block_size != BLOCK_SIZE) {
+    sprintf(bsize,"-B%d",block_size);
+    args[ac++] = bsize;
+  }    
+
+  if (io_timeout) {
+    sprintf(iotime,"--timeout=%d",io_timeout);
+    args[ac++] = iotime;
+  }    
+
+  if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
+         args[ac++] = "--suffix";
+         args[ac++] = backup_suffix;
+  }
+
+  if (delete_mode)
+    args[ac++] = "--delete";
+
+  if (force_delete)
+    args[ac++] = "--force";
+
+  if (numeric_ids)
+    args[ac++] = "--numeric-ids";
+
+  if (tmpdir) {
+         args[ac++] = "--temp-dir";
+         args[ac++] = tmpdir;
+  }
+
+  *argc = ac;
+}
+
diff --git a/rsync.c b/rsync.c
index 9d3b1c563389e2b5bbb49d0677071a01fd0ff879..950d575f40a7d0b0313d179cb5aee348db392bce 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -111,7 +111,7 @@ static int delete_file(char *fname)
                if (strcmp(dname,".")==0 ||
                    strcmp(dname,"..")==0)
                        continue;
-               strncpy(buf, fname, (MAXPATHLEN-strlen(dname))-2);
+               strlcpy(buf, fname, (MAXPATHLEN-strlen(dname))-2);
                strcat(buf, "/");
                strcat(buf, dname);
                buf[MAXPATHLEN-1] = 0;
@@ -976,8 +976,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
 
          fname[0] = 0;
          if (file->basedir) {
-                 strncpy(fname,file->basedir,MAXPATHLEN-1);
-                 fname[MAXPATHLEN-1] = 0;
+                 strlcpy(fname,file->basedir,MAXPATHLEN-1);
                  if (strlen(fname) == MAXPATHLEN-1) {
                          io_error = 1;
                          rprintf(FERROR, "send_files failed on long-named directory %s\n",
diff --git a/util.c b/util.c
index f74228ef83ca1dfee21de3955d7f0515df60e0db..9b28cb03d353f7e5dc3ff9f5dc184cc353d8202a 100644 (file)
--- a/util.c
+++ b/util.c
@@ -446,3 +446,12 @@ void kill_all(int sig)
        }
 }
 
+/* like strncpy but does not 0 fill the buffer and always null 
+   terminates (thus it can use maxlen+1 space in d) */
+void strlcpy(char *d, char *s, int maxlen)
+{
+       int len = strlen(s);
+       if (len > maxlen) len = maxlen;
+       memcpy(d, s, len);
+       d[len] = 0;
+}