Split code to generate "rwx-----" strings into lib/permstring.c so it
[rsync/rsync.git] / options.c
index 4c34e4c..cc0533d 100644 (file)
--- a/options.c
+++ b/options.c
@@ -52,7 +52,7 @@ int io_error = 0;
 int read_only = 0;
 int module_id = -1;
 int am_server = 0;
-int am_sender=0;
+int am_sender = 0;
 int recurse = 0;
 int am_daemon=0;
 int do_stats=0;
@@ -74,6 +74,12 @@ int modify_window=0;
 #endif
 int blocking_io=0;
 
+/** Global options set from command line. **/
+struct global_opts global_opts;
+
+int read_batch=0;  /* dw */
+int write_batch=0; /* dw */
+
 char *backup_suffix = BACKUP_SUFFIX;
 char *tmpdir = NULL;
 char *compare_dest = NULL;
@@ -81,7 +87,7 @@ char *config_file = RSYNCD_CONF;
 char *shell_cmd = NULL;
 char *log_format = NULL;
 char *password_file = NULL;
-char *rsync_path = RSYNC_NAME;
+char *rsync_path = RSYNC_PATH;
 char *backup_dir = NULL;
 int rsync_port = RSYNC_PORT;
 
@@ -90,10 +96,14 @@ int quiet = 0;
 int always_checksum = 0;
 int list_only = 0;
 
-static int modify_window_set;
+char *batch_ext = NULL;
 
+static int modify_window_set;
 
-struct in_addr socket_address = {INADDR_ANY};
+/** Local address to bind.  As a character string because it's
+ * interpreted by the IPv6 layer: should be a numeric IP4 or ip6
+ * address, or a hostname. **/
+char *bind_address;
 
 
 static void print_rsync_version(int f)
@@ -101,6 +111,7 @@ static void print_rsync_version(int f)
         char const *got_socketpair = "no ";
         char const *hardlinks = "no ";
         char const *links = "no ";
+       char const *ipv6 = "no ";
 
 #ifdef HAVE_SOCKETPAIR
         got_socketpair = "";
@@ -114,15 +125,19 @@ static void print_rsync_version(int f)
         links = "";
 #endif
 
+#if INET6
+       ipv6 = "";
+#endif       
+
         rprintf(f, "%s  version %s  protocol version %d\n",
-                RSYNC_NAME, VERSION, PROTOCOL_VERSION);
+                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
         rprintf(f,
-                "Copyright (C) 1996-2001 by Andrew Tridgell, Paul Mackerras and others\n");
+                "Copyright (C) 1996-2001 by Andrew Tridgell and others\n");
+       rprintf(f, "<http://rsync.samba.org/>\n");
         rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
-                "%shard links, %ssymlinks\n\n",
-                sizeof(int64) * 8,
-                got_socketpair,
-                hardlinks, links);
+                "%shard links, %ssymlinks, batchfiles, %sIPv6\n\n",
+                (int) (sizeof(OFF_T) * 8),
+                got_socketpair, hardlinks, links, ipv6);
 
 #ifdef NO_INT64
         rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
@@ -206,7 +221,13 @@ void usage(enum logcode F)
   rprintf(F,"     --log-format=FORMAT     log file transfers using specified format\n");  
   rprintf(F,"     --password-file=FILE    get password from FILE\n");
   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
+  rprintf(F," -f  --read-batch=EXT        read batch file\n");
+  rprintf(F," -F  --write-batch           write batch file\n");
   rprintf(F," -h, --help                  show this help screen\n");
+#ifdef INET6
+  rprintf(F," -4                          prefer IPv4\n");
+  rprintf(F," -6                          prefer IPv6\n");
+#endif
 
   rprintf(F,"\n");
 
@@ -266,14 +287,14 @@ static struct poptOption long_options[] = {
   {"archive",         'a', POPT_ARG_NONE,   0,               'a'}, 
   {"server",           0,  POPT_ARG_NONE,   &am_server},
   {"sender",           0,  POPT_ARG_NONE,   0,               OPT_SENDER},
-  {"recurse",         'r', POPT_ARG_NONE,   &recurse},
+  {"recursive",       'r', POPT_ARG_NONE,   &recurse},
   {"relative",        'R', POPT_ARG_NONE,   &relative_paths},
   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd},
   {"block-size",      'B', POPT_ARG_INT,    &block_size},
   {"max-delete",       0,  POPT_ARG_INT,    &max_delete},
   {"timeout",          0,  POPT_ARG_INT,    &io_timeout},
   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir},
-  {"compare-dest",     0,  POPT_ARG_NONE,   &compare_dest},
+  {"compare-dest",     0,  POPT_ARG_STRING, &compare_dest},
   /* TODO: Should this take an optional int giving the compression level? */
   {"compress",        'z', POPT_ARG_NONE,   &do_compression},
   {"daemon",           0,  POPT_ARG_NONE,   &am_daemon},
@@ -287,9 +308,15 @@ static struct poptOption long_options[] = {
   {"port",             0,  POPT_ARG_INT,    &rsync_port},
   {"log-format",       0,  POPT_ARG_STRING, &log_format},
   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit},
-  {"address",          0,  POPT_ARG_STRING, 0,               OPT_ADDRESS},
+  {"address",          0,  POPT_ARG_STRING, &bind_address, 0},
   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir},
   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links},
+  {"read-batch",      'f', POPT_ARG_STRING, &batch_ext, 'f'},
+  {"write-batch",     'F', POPT_ARG_NONE,   &write_batch, 0},
+#ifdef INET6
+  {0,                '4', POPT_ARG_VAL,    &global_opts.af_hint,   AF_INET },
+  {0,                '6', POPT_ARG_VAL,    &global_opts.af_hint,   AF_INET6 },
+#endif
   {0,0,0,0}
 };
 
@@ -297,14 +324,19 @@ static struct poptOption long_options[] = {
 static char err_buf[100];
 
 
+/* We store the option error message, if any, so that we can log the
+   connection attempt (which requires parsing the options), and then
+   show the error later on. */
 void option_error(void)
 {
        if (err_buf[0]) {
                rprintf(FLOG, "%s", err_buf);
                rprintf(FERROR, "%s: %s", RSYNC_NAME, err_buf);
        } else {
-               rprintf(FLOG,"Error parsing options - unsupported option?\n");
-               rprintf(FERROR,"Error parsing options - unsupported option?\n");
+               rprintf (FERROR, "Error parsing options: "
+                        "option may be supported on client but not on server?\n");
+               rprintf (FERROR, RSYNC_NAME ": Error parsing options: "
+                        "option may be supported on client but not on server?\n");
        }
 }
 
@@ -327,7 +359,7 @@ static int check_refuse_options(char *ref, int opt)
        while ((p = strstr(ref,name))) {
                if ((p==ref || p[-1]==' ') &&
                    (p[len] == ' ' || p[len] == 0)) {
-                       slprintf(err_buf,sizeof(err_buf),
+                       snprintf(err_buf,sizeof(err_buf),
                                 "The '%s' option is not supported by this server\n", name);
                        return 1;
                }
@@ -418,7 +450,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                          * rprintf?  Everybody who gets this message
                          * ought to send it to the client and also to
                          * the logs. */
-                       slprintf(err_buf,sizeof(err_buf),
+                       snprintf(err_buf,sizeof(err_buf),
                                  "hard links are not supported on this %s\n",
                                 am_server ? "server" : "client");
                        rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
@@ -459,19 +491,16 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        keep_partial = 1;
                        break;
 
-               case OPT_ADDRESS:
-                       {
-                               struct in_addr *ia;
-                               if ((ia = ip_address(optarg))) {
-                                       socket_address = *ia;
-                               }
-                       }
+
+               case 'f':
+                       /* The filename is stored for us by popt */
+                       read_batch = 1;
                        break;
 
                default:
                         /* FIXME: If --daemon is specified, then errors for later
                          * parameters seem to disappear. */
-                        slprintf(err_buf, sizeof(err_buf),
+                        snprintf(err_buf, sizeof(err_buf),
                                  "%s%s: %s\n",
                                  am_server ? "on remote machine: " : "",
                                  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
@@ -501,6 +530,7 @@ void server_options(char **args,int *argc)
        static char mdelete[30];
        static char mwindow[30];
        static char bw[50];
+       static char fext[20]; /* dw */
 
        int i, x;
 
@@ -555,6 +585,8 @@ void server_options(char **args,int *argc)
                argstr[x++] = 'S';
        if (do_compression)
                argstr[x++] = 'z';
+       if (write_batch)
+           argstr[x++] = 'F'; /* dw */
 
        /* this is a complete hack - blame Rusty 
 
@@ -568,22 +600,27 @@ void server_options(char **args,int *argc)
        if (x != 1) args[ac++] = argstr;
 
        if (block_size != BLOCK_SIZE) {
-               slprintf(bsize,sizeof(bsize),"-B%d",block_size);
+               snprintf(bsize,sizeof(bsize),"-B%d",block_size);
                args[ac++] = bsize;
        }    
 
        if (max_delete && am_sender) {
-               slprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
+               snprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
                args[ac++] = mdelete;
        }    
+       
+       if (batch_ext != NULL) {
+               sprintf(fext,"-f%s",batch_ext);
+               args[ac++] = fext;
+       }
 
        if (io_timeout) {
-               slprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
+               snprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
                args[ac++] = iotime;
        }    
 
        if (bwlimit) {
-               slprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
+               snprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
                args[ac++] = bw;
        }
 
@@ -602,7 +639,7 @@ void server_options(char **args,int *argc)
                args[ac++] = "--size-only";
 
        if (modify_window_set) {
-               slprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
+               snprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
                         modify_window);
                args[ac++] = mwindow;
        }