Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

options.c

Go to the documentation of this file.
00001 /*  -*- c-file-style: "linux" -*-
00002  * 
00003  * Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
00004  * Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
00005  * 
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "rsync.h"
00022 #include "popt.h"
00023 
00024 int make_backups = 0;
00025 
00026 /**
00027  * If True, send the whole file as literal data rather than trying to
00028  * create an incremental diff.
00029  *
00030  * If both are 0, then look at whether we're local or remote and go by
00031  * that.
00032  *
00033  * @sa disable_deltas_p()
00034  **/
00035 int whole_file = 0;
00036 int no_whole_file = 0;
00037 
00038 int copy_links = 0;
00039 int preserve_links = 0;
00040 int preserve_hard_links = 0;
00041 int preserve_perms = 0;
00042 int preserve_devices = 0;
00043 int preserve_uid = 0;
00044 int preserve_gid = 0;
00045 int preserve_times = 0;
00046 int update_only = 0;
00047 int cvs_exclude = 0;
00048 int dry_run=0;
00049 int local_server=0;
00050 int ignore_times=0;
00051 int delete_mode=0;
00052 int delete_excluded=0;
00053 int one_file_system=0;
00054 int remote_version=0;
00055 int sparse_files=0;
00056 int do_compression=0;
00057 int am_root=0;
00058 int orig_umask=0;
00059 int relative_paths=0;
00060 int numeric_ids = 0;
00061 int force_delete = 0;
00062 int io_timeout = 0;
00063 int io_error = 0;
00064 int read_only = 0;
00065 int module_id = -1;
00066 int am_server = 0;
00067 int am_sender = 0;
00068 int recurse = 0;
00069 int am_daemon=0;
00070 int do_stats=0;
00071 int do_progress=0;
00072 int keep_partial=0;
00073 int safe_symlinks=0;
00074 int copy_unsafe_links=0;
00075 int block_size=BLOCK_SIZE;
00076 int size_only=0;
00077 int bwlimit=0;
00078 int delete_after=0;
00079 int only_existing=0;
00080 int opt_ignore_existing=0;
00081 int max_delete=0;
00082 int ignore_errors=0;
00083 #ifdef _WIN32
00084 int modify_window=2;
00085 #else
00086 int modify_window=0;
00087 #endif
00088 int blocking_io=-1;
00089 
00090 
00091 /** Network address family. **/
00092 #ifdef INET6
00093 int default_af_hint = 0;        /* Any protocol */
00094 #else
00095 int default_af_hint = AF_INET;  /* Must use IPv4 */
00096 #endif
00097 
00098 /** Do not go into the background when run as --daemon.  Good
00099  * for debugging and required for running as a service on W32,
00100  * or under Unix process-monitors. **/
00101 int no_detach = 0;
00102 
00103 int write_batch = 0;
00104 int read_batch = 0;
00105 
00106 char *backup_suffix = BACKUP_SUFFIX;
00107 char *tmpdir = NULL;
00108 char *compare_dest = NULL;
00109 char *config_file = RSYNCD_CONF;
00110 char *shell_cmd = NULL;
00111 char *log_format = NULL;
00112 char *password_file = NULL;
00113 char *rsync_path = RSYNC_PATH;
00114 char *backup_dir = NULL;
00115 int rsync_port = RSYNC_PORT;
00116 
00117 int verbose = 0;
00118 int quiet = 0;
00119 int always_checksum = 0;
00120 int list_only = 0;
00121 
00122 char *batch_prefix = NULL;
00123 
00124 static int modify_window_set;
00125 
00126 /** Local address to bind.  As a character string because it's
00127  * interpreted by the IPv6 layer: should be a numeric IP4 or ip6
00128  * address, or a hostname. **/
00129 char *bind_address;
00130 
00131 
00132 static void print_rsync_version(enum logcode f)
00133 {
00134         char const *got_socketpair = "no ";
00135         char const *hardlinks = "no ";
00136         char const *links = "no ";
00137         char const *ipv6 = "no ";
00138         STRUCT_STAT *dumstat;
00139 
00140 #ifdef HAVE_SOCKETPAIR
00141         got_socketpair = "";
00142 #endif
00143 
00144 #if SUPPORT_HARD_LINKS
00145         hardlinks = "";
00146 #endif
00147 
00148 #if SUPPORT_LINKS
00149         links = "";
00150 #endif
00151 
00152 #if INET6
00153         ipv6 = "";
00154 #endif       
00155 
00156         rprintf(f, "%s  version %s  protocol version %d\n",
00157                 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
00158         rprintf(f,
00159                 "Copyright (C) 1996-2002 by Andrew Tridgell and others\n");
00160         rprintf(f, "<http://rsync.samba.org/>\n");
00161         rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
00162                 "%shard links, %ssymlinks, batchfiles, \n",
00163                 (int) (sizeof(OFF_T) * 8),
00164                 got_socketpair, hardlinks, links);
00165 
00166         /* Note that this field may not have type ino_t.  It depends
00167          * on the complicated interaction between largefile feature
00168          * macros. */
00169         rprintf(f, "              %sIPv6, %d-bit system inums, %d-bit internal inums\n",
00170                 ipv6, 
00171                 (int) (sizeof(dumstat->st_ino) * 8),
00172                 (int) (sizeof(INO64_T) * 8));
00173 #ifdef MAINTAINER_MODE
00174         rprintf(f, "              panic action: \"%s\"\n",
00175                 get_panic_action());
00176 #endif
00177 
00178 #ifdef NO_INT64
00179         rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
00180 #endif
00181 
00182         rprintf(f,
00183 "\n"
00184 "rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you\n"
00185 "are welcome to redistribute it under certain conditions.  See the GNU\n"
00186 "General Public Licence for details.\n"
00187                 );
00188 }
00189 
00190 
00191 void usage(enum logcode F)
00192 {
00193   print_rsync_version(F);
00194 
00195   rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
00196 
00197   rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
00198   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST:SRC DEST\n");
00199   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... DEST\n");
00200   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
00201   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
00202   rprintf(F,"  or   rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
00203   rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
00204   rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
00205   rprintf(F,"  sources separated by space as long as they have same top-level\n");
00206   rprintf(F,"\nOptions\n");
00207   rprintf(F," -v, --verbose               increase verbosity\n");
00208   rprintf(F," -q, --quiet                 decrease verbosity\n");
00209   rprintf(F," -c, --checksum              always checksum\n");
00210   rprintf(F," -a, --archive               archive mode\n");
00211   rprintf(F," -r, --recursive             recurse into directories\n");
00212   rprintf(F," -R, --relative              use relative path names\n");
00213   rprintf(F," -b, --backup                make backups (default %s suffix)\n",BACKUP_SUFFIX);
00214   rprintf(F,"     --backup-dir            make backups into this directory\n");
00215   rprintf(F,"     --suffix=SUFFIX         override backup suffix\n");  
00216   rprintf(F," -u, --update                update only (don't overwrite newer files)\n");
00217   rprintf(F," -l, --links                 copy symlinks as symlinks\n");
00218   rprintf(F," -L, --copy-links            copy the referent of symlinks\n");
00219   rprintf(F,"     --copy-unsafe-links     copy links outside the source tree\n");
00220   rprintf(F,"     --safe-links            ignore links outside the destination tree\n");
00221   rprintf(F," -H, --hard-links            preserve hard links\n");
00222   rprintf(F," -p, --perms                 preserve permissions\n");
00223   rprintf(F," -o, --owner                 preserve owner (root only)\n");
00224   rprintf(F," -g, --group                 preserve group\n");
00225   rprintf(F," -D, --devices               preserve devices (root only)\n");
00226   rprintf(F," -t, --times                 preserve times\n");  
00227   rprintf(F," -S, --sparse                handle sparse files efficiently\n");
00228   rprintf(F," -n, --dry-run               show what would have been transferred\n");
00229   rprintf(F," -W, --whole-file            copy whole files, no incremental checks\n");
00230   rprintf(F,"     --no-whole-file         turn off --whole-file\n");
00231   rprintf(F," -x, --one-file-system       don't cross filesystem boundaries\n");
00232   rprintf(F," -B, --block-size=SIZE       checksum blocking size (default %d)\n",BLOCK_SIZE);  
00233   rprintf(F," -e, --rsh=COMMAND           specify rsh replacement\n");
00234   rprintf(F,"     --rsync-path=PATH       specify path to rsync on the remote machine\n");
00235   rprintf(F," -C, --cvs-exclude           auto ignore files in the same way CVS does\n");
00236   rprintf(F,"     --existing              only update files that already exist\n");
00237   rprintf(F,"     --ignore-existing       ignore files that already exist on the receiving side\n");
00238   rprintf(F,"     --delete                delete files that don't exist on the sending side\n");
00239   rprintf(F,"     --delete-excluded       also delete excluded files on the receiving side\n");
00240   rprintf(F,"     --delete-after          delete after transferring, not before\n");
00241   rprintf(F,"     --ignore-errors         delete even if there are IO errors\n");
00242   rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\n");
00243   rprintf(F,"     --partial               keep partially transferred files\n");
00244   rprintf(F,"     --force                 force deletion of directories even if not empty\n");
00245   rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
00246   rprintf(F,"     --timeout=TIME          set IO timeout in seconds\n");
00247   rprintf(F," -I, --ignore-times          don't exclude files that match length and time\n");
00248   rprintf(F,"     --size-only             only use file size when determining if a file should be transferred\n");
00249   rprintf(F,"     --modify-window=NUM     Timestamp window (seconds) for file match (default=%d)\n",modify_window);
00250   rprintf(F," -T  --temp-dir=DIR          create temporary files in directory DIR\n");
00251   rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
00252   rprintf(F," -P                          equivalent to --partial --progress\n");
00253   rprintf(F," -z, --compress              compress file data\n");
00254   rprintf(F,"     --exclude=PATTERN       exclude files matching PATTERN\n");
00255   rprintf(F,"     --exclude-from=FILE     exclude patterns listed in FILE\n");
00256   rprintf(F,"     --include=PATTERN       don't exclude files matching PATTERN\n");
00257   rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
00258   rprintf(F,"     --version               print version number\n");  
00259   rprintf(F,"     --daemon                run as a rsync daemon\n");  
00260   rprintf(F,"     --no-detach             do not detach from the parent\n");  
00261   rprintf(F,"     --address=ADDRESS       bind to the specified address\n");  
00262   rprintf(F,"     --config=FILE           specify alternate rsyncd.conf file\n");  
00263   rprintf(F,"     --port=PORT             specify alternate rsyncd port number\n");
00264   rprintf(F,"     --blocking-io           use blocking IO for the remote shell\n");  
00265   rprintf(F,"     --no-blocking-io        turn off --blocking-io\n");  
00266   rprintf(F,"     --stats                 give some file transfer stats\n");  
00267   rprintf(F,"     --progress              show progress during transfer\n");  
00268   rprintf(F,"     --log-format=FORMAT     log file transfers using specified format\n");  
00269   rprintf(F,"     --password-file=FILE    get password from FILE\n");
00270   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
00271   rprintf(F,"     --write-batch=PREFIX    write batch fileset starting with PREFIX\n");
00272   rprintf(F,"     --read-batch=PREFIX     read batch fileset starting with PREFIX\n");
00273   rprintf(F," -h, --help                  show this help screen\n");
00274 #ifdef INET6
00275   rprintf(F," -4                          prefer IPv4\n");
00276   rprintf(F," -6                          prefer IPv6\n");
00277 #endif
00278 
00279   rprintf(F,"\n");
00280 
00281   rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
00282   rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
00283 }
00284 
00285 enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
00286       OPT_EXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS,
00287       OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT,
00288       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
00289       OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
00290       OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
00291       OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR, 
00292       OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
00293       OPT_NO_BLOCKING_IO, OPT_WHOLE_FILE, OPT_NO_WHOLE_FILE,
00294       OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_IGNORE_EXISTING};
00295 
00296 static struct poptOption long_options[] = {
00297   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
00298   {"version",          0,  POPT_ARG_NONE,   0,             OPT_VERSION, 0, 0},
00299   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix,     0, 0, 0 },
00300   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path,        0, 0, 0 },
00301   {"password-file",    0,  POPT_ARG_STRING, &password_file,     0, 0, 0 },
00302   {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times , 0, 0, 0 },
00303   {"size-only",        0,  POPT_ARG_NONE,   &size_only , 0, 0, 0 },
00304   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
00305   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system , 0, 0, 0 },
00306   {"delete",           0,  POPT_ARG_NONE,   &delete_mode , 0, 0, 0 },
00307   {"existing",         0,  POPT_ARG_NONE,   &only_existing , 0, 0, 0 },
00308   {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing , 0, 0, 0 },
00309   {"delete-after",     0,  POPT_ARG_NONE,   &delete_after , 0, 0, 0 },
00310   {"delete-excluded",  0,  POPT_ARG_NONE,   0,              OPT_DELETE_EXCLUDED, 0, 0 },
00311   {"force",            0,  POPT_ARG_NONE,   &force_delete , 0, 0, 0 },
00312   {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids , 0, 0, 0 },
00313   {"exclude",          0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE, 0, 0 },
00314   {"include",          0,  POPT_ARG_STRING, 0,              OPT_INCLUDE, 0, 0 },
00315   {"exclude-from",     0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE_FROM, 0, 0 },
00316   {"include-from",     0,  POPT_ARG_STRING, 0,              OPT_INCLUDE_FROM, 0, 0 },
00317   {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks , 0, 0, 0 },
00318   {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0 },
00319   {"backup",          'b', POPT_ARG_NONE,   &make_backups , 0, 0, 0 },
00320   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run , 0, 0, 0 },
00321   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files , 0, 0, 0 },
00322   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude , 0, 0, 0 },
00323   {"update",          'u', POPT_ARG_NONE,   &update_only , 0, 0, 0 },
00324   {"links",           'l', POPT_ARG_NONE,   &preserve_links , 0, 0, 0 },
00325   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links , 0, 0, 0 },
00326   {"whole-file",      'W', POPT_ARG_NONE,   0,              OPT_WHOLE_FILE, 0, 0 },
00327   {"no-whole-file",    0,  POPT_ARG_NONE,   0,              OPT_NO_WHOLE_FILE, 0, 0 },
00328   {"copy-unsafe-links", 0, POPT_ARG_NONE,   &copy_unsafe_links , 0, 0, 0 },
00329   {"perms",           'p', POPT_ARG_NONE,   &preserve_perms , 0, 0, 0 },
00330   {"owner",           'o', POPT_ARG_NONE,   &preserve_uid , 0, 0, 0 },
00331   {"group",           'g', POPT_ARG_NONE,   &preserve_gid , 0, 0, 0 },
00332   {"devices",         'D', POPT_ARG_NONE,   &preserve_devices , 0, 0, 0 },
00333   {"times",           't', POPT_ARG_NONE,   &preserve_times , 0, 0, 0 },
00334   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum , 0, 0, 0 },
00335   {"verbose",         'v', POPT_ARG_NONE,   0,               'v', 0, 0 },
00336   {"quiet",           'q', POPT_ARG_NONE,   0,               'q', 0, 0 },
00337   {"archive",         'a', POPT_ARG_NONE,   0,               'a', 0, 0 }, 
00338   {"server",           0,  POPT_ARG_NONE,   &am_server , 0, 0, 0 },
00339   {"sender",           0,  POPT_ARG_NONE,   0,               OPT_SENDER, 0, 0 },
00340   {"recursive",       'r', POPT_ARG_NONE,   &recurse , 0, 0, 0 },
00341   {"relative",        'R', POPT_ARG_NONE,   &relative_paths , 0, 0, 0 },
00342   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd , 0, 0, 0 },
00343   {"block-size",      'B', POPT_ARG_INT,    &block_size , 0, 0, 0 },
00344   {"max-delete",       0,  POPT_ARG_INT,    &max_delete , 0, 0, 0 },
00345   {"timeout",          0,  POPT_ARG_INT,    &io_timeout , 0, 0, 0 },
00346   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir , 0, 0, 0 },
00347   {"compare-dest",     0,  POPT_ARG_STRING, &compare_dest , 0, 0, 0 },
00348   /* TODO: Should this take an optional int giving the compression level? */
00349   {"compress",        'z', POPT_ARG_NONE,   &do_compression , 0, 0, 0 },
00350   {"daemon",           0,  POPT_ARG_NONE,   &am_daemon , 0, 0, 0 },
00351   {"no-detach",        0,  POPT_ARG_NONE,   &no_detach , 0, 0, 0 },
00352   {"stats",            0,  POPT_ARG_NONE,   &do_stats , 0, 0, 0 },
00353   {"progress",         0,  POPT_ARG_NONE,   &do_progress , 0, 0, 0 },
00354   {"partial",          0,  POPT_ARG_NONE,   &keep_partial , 0, 0, 0 },
00355   {"ignore-errors",    0,  POPT_ARG_NONE,   &ignore_errors , 0, 0, 0 },
00356   {"blocking-io",      0,  POPT_ARG_NONE,   &blocking_io , 0, 0, 0 },
00357   {"no-blocking-io",   0,  POPT_ARG_NONE,   0,               OPT_NO_BLOCKING_IO, 0, 0 },
00358   {0,                 'P', POPT_ARG_NONE,   0,               'P', 0, 0 },
00359   {"config",           0,  POPT_ARG_STRING, &config_file , 0, 0, 0 },
00360   {"port",             0,  POPT_ARG_INT,    &rsync_port , 0, 0, 0 },
00361   {"log-format",       0,  POPT_ARG_STRING, &log_format , 0, 0, 0 },
00362   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit , 0, 0, 0 },
00363   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
00364   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir , 0, 0, 0 },
00365   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links , 0, 0, 0 },
00366   {"read-batch",       0,  POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH, 0, 0 },
00367   {"write-batch",      0,  POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH, 0, 0 },
00368 #ifdef INET6
00369   {0,                 '4', POPT_ARG_VAL,    &default_af_hint,   AF_INET , 0, 0 },
00370   {0,                 '6', POPT_ARG_VAL,    &default_af_hint,   AF_INET6 , 0, 0 },
00371 #endif
00372   {0,0,0,0, 0, 0, 0}
00373 };
00374 
00375 
00376 static char err_buf[100];
00377 
00378 
00379 /**
00380  * Store the option error message, if any, so that we can log the
00381  * connection attempt (which requires parsing the options), and then
00382  * show the error later on.
00383  **/
00384 void option_error(void)
00385 {
00386         if (err_buf[0]) {
00387                 rprintf(FLOG, "%s", err_buf);
00388                 rprintf(FERROR, "%s: %s", RSYNC_NAME, err_buf);
00389         } else {
00390                 rprintf (FERROR, "Error parsing options: "
00391                          "option may be supported on client but not on server?\n");
00392                 rprintf (FERROR, RSYNC_NAME ": Error parsing options: "
00393                          "option may be supported on client but not on server?\n");
00394         }
00395 }
00396 
00397 
00398 /**
00399  * Check to see if we should refuse this option
00400  **/
00401 static int check_refuse_options(char *ref, int opt)
00402 {
00403         int i, len;
00404         char *p;
00405         const char *name;
00406 
00407         for (i=0; long_options[i].longName; i++) {
00408                 if (long_options[i].val == opt) break;
00409         }
00410         
00411         if (!long_options[i].longName) return 0;
00412 
00413         name = long_options[i].longName;
00414         len = strlen(name);
00415 
00416         while ((p = strstr(ref,name))) {
00417                 if ((p==ref || p[-1]==' ') &&
00418                     (p[len] == ' ' || p[len] == 0)) {
00419                         snprintf(err_buf,sizeof(err_buf),
00420                                  "The '%s' option is not supported by this server\n", name);
00421                         return 1;
00422                 }
00423                 ref += len;
00424         }
00425         return 0;
00426 }
00427 
00428 
00429 static int count_args(char const **argv)
00430 {
00431         int i = 0;
00432 
00433         while (argv[i] != NULL)
00434                 i++;
00435         
00436         return i;
00437 }
00438 
00439 
00440 /**
00441  * Process command line arguments.  Called on both local and remote.
00442  *
00443  * @retval 1 if all options are OK; with globals set to appropriate
00444  * values
00445  *
00446  * @retval 0 on error, with err_buf containing an explanation
00447  **/
00448 int parse_arguments(int *argc, const char ***argv, int frommain)
00449 {
00450         int opt;
00451         char *ref = lp_refuse_options(module_id);
00452         poptContext pc;
00453 
00454         /* TODO: Call poptReadDefaultConfig; handle errors. */
00455 
00456         /* The context leaks in case of an error, but if there's a
00457          * problem we always exit anyhow. */
00458         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
00459 
00460         while ((opt = poptGetNextOpt(pc)) != -1) {
00461                 if (ref) {
00462                         if (check_refuse_options(ref, opt)) return 0;
00463                 }
00464 
00465                 /* most options are handled automatically by popt;
00466                  * only special cases are returned and listed here. */
00467 
00468                 switch (opt) {
00469                 case OPT_VERSION:
00470                         print_rsync_version(FINFO);
00471                         exit_cleanup(0);
00472                         
00473                 case OPT_MODIFY_WINDOW:
00474                         /* The value has already been set by popt, but
00475                          * we need to remember that we're using a
00476                          * non-default setting. */
00477                         modify_window_set = 1;
00478                         break;
00479                         
00480                 case OPT_DELETE_EXCLUDED:
00481                         delete_excluded = 1;
00482                         delete_mode = 1;
00483                         break;
00484 
00485                 case OPT_EXCLUDE:
00486                         add_exclude(poptGetOptArg(pc), 0);
00487                         break;
00488 
00489                 case OPT_INCLUDE:
00490                         add_exclude(poptGetOptArg(pc), 1);
00491                         break;
00492 
00493                 case OPT_EXCLUDE_FROM:
00494                         add_exclude_file(poptGetOptArg(pc), 1, 0);
00495                         break;
00496 
00497                 case OPT_INCLUDE_FROM:
00498                         add_exclude_file(poptGetOptArg(pc), 1, 1);
00499                         break;
00500 
00501                 case OPT_WHOLE_FILE:
00502                         whole_file = 1;
00503                         no_whole_file = 0;
00504                         break;
00505 
00506                 case OPT_NO_WHOLE_FILE:
00507                         no_whole_file = 1;
00508                         whole_file = 0;
00509                         break;
00510 
00511                 case OPT_NO_BLOCKING_IO:
00512                         blocking_io = 0;
00513                         break;
00514 
00515                 case 'h':
00516                         usage(FINFO);
00517                         exit_cleanup(0);
00518 
00519                 case 'H':
00520 #if SUPPORT_HARD_LINKS
00521                         preserve_hard_links=1;
00522 #else
00523                         /* FIXME: Don't say "server" if this is
00524                          * happening on the client. */
00525                         /* FIXME: Why do we have the duplicated
00526                          * rprintf?  Everybody who gets this message
00527                          * ought to send it to the client and also to
00528                          * the logs. */
00529                         snprintf(err_buf,sizeof(err_buf),
00530                                  "hard links are not supported on this %s\n",
00531                                  am_server ? "server" : "client");
00532                         rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
00533                         return 0;
00534 #endif /* SUPPORT_HARD_LINKS */
00535                         break;
00536 
00537                 case 'v':
00538                         verbose++;
00539                         break;
00540 
00541                 case 'q':
00542                         if (frommain) quiet++;
00543                         break;
00544 
00545                 case 'a':
00546                         recurse=1;
00547 #if SUPPORT_LINKS
00548                         preserve_links=1;
00549 #endif
00550                         preserve_perms=1;
00551                         preserve_times=1;
00552                         preserve_gid=1;
00553                         preserve_uid=1;
00554                         preserve_devices=1;
00555                         break;
00556 
00557                 case OPT_SENDER:
00558                         if (!am_server) {
00559                                 usage(FERROR);
00560                                 exit_cleanup(RERR_SYNTAX);
00561                         }
00562                         am_sender = 1;
00563                         break;
00564 
00565                 case 'P':
00566                         do_progress = 1;
00567                         keep_partial = 1;
00568                         break;
00569 
00570                 case OPT_WRITE_BATCH:
00571                         /* popt stores the filename in batch_prefix for us */
00572                         write_batch = 1;
00573                         break;
00574 
00575                 case OPT_READ_BATCH:
00576                         /* popt stores the filename in batch_prefix for us */
00577                         read_batch = 1;
00578                         break;
00579 
00580                 default:
00581                         /* FIXME: If --daemon is specified, then errors for later
00582                          * parameters seem to disappear. */
00583                         snprintf(err_buf, sizeof(err_buf),
00584                                  "%s%s: %s\n",
00585                                  am_server ? "on remote machine: " : "",
00586                                  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
00587                                  poptStrerror(opt));
00588                         return 0;
00589                 }
00590         }
00591 
00592         if (write_batch && read_batch) {
00593             snprintf(err_buf,sizeof(err_buf),
00594                 "write-batch and read-batch can not be used together\n");
00595             rprintf(FERROR,"ERROR: write-batch and read-batch"
00596                 " can not be used together\n");
00597             return 0;
00598         }
00599 
00600         if (do_compression && (write_batch || read_batch)) {
00601             snprintf(err_buf,sizeof(err_buf),
00602                 "compress can not be used with write-batch or read-batch\n");
00603             rprintf(FERROR,"ERROR: compress can not be used with"
00604                 "  write-batch or read-batch\n");
00605             return 0;
00606         }
00607 
00608         *argv = poptGetArgs(pc);
00609         if (*argv)
00610                 *argc = count_args(*argv);
00611         else
00612                 *argc = 0;
00613 
00614         return 1;
00615 }
00616 
00617 
00618 /**
00619  * Construct a filtered list of options to pass through from the
00620  * client to the server.
00621  *
00622  * This involves setting options that will tell the server how to
00623  * behave, and also filtering out options that are processed only
00624  * locally.
00625  **/
00626 void server_options(char **args,int *argc)
00627 {
00628         int ac = *argc;
00629         static char argstr[50];
00630         static char bsize[30];
00631         static char iotime[30];
00632         static char mdelete[30];
00633         static char mwindow[30];
00634         static char bw[50];
00635         /* Leave room for ``--(write|read)-batch='' */
00636         static char fext[MAXPATHLEN + 15];
00637 
00638         int i, x;
00639 
00640         if (blocking_io == -1)
00641                 blocking_io = 0;
00642 
00643         args[ac++] = "--server";
00644 
00645         if (!am_sender)
00646                 args[ac++] = "--sender";
00647 
00648         x = 1;
00649         argstr[0] = '-';
00650         for (i=0;i<verbose;i++)
00651                 argstr[x++] = 'v';
00652 
00653         /* the -q option is intentionally left out */
00654         if (make_backups)
00655                 argstr[x++] = 'b';
00656         if (update_only)
00657                 argstr[x++] = 'u';
00658         if (dry_run)
00659                 argstr[x++] = 'n';
00660         if (preserve_links)
00661                 argstr[x++] = 'l';
00662         if (copy_links)
00663                 argstr[x++] = 'L';
00664 
00665         assert(whole_file == 0 || whole_file == 1);
00666         if (whole_file)
00667                 argstr[x++] = 'W';
00668         /* We don't need to send --no-whole-file, because it's the
00669          * default for remote transfers, and in any case old versions
00670          * of rsync will not understand it. */
00671         
00672         if (preserve_hard_links)
00673                 argstr[x++] = 'H';
00674         if (preserve_uid)
00675                 argstr[x++] = 'o';
00676         if (preserve_gid)
00677                 argstr[x++] = 'g';
00678         if (preserve_devices)
00679                 argstr[x++] = 'D';
00680         if (preserve_times)
00681                 argstr[x++] = 't';
00682         if (preserve_perms)
00683                 argstr[x++] = 'p';
00684         if (recurse)
00685                 argstr[x++] = 'r';
00686         if (always_checksum)
00687                 argstr[x++] = 'c';
00688         if (cvs_exclude)
00689                 argstr[x++] = 'C';
00690         if (ignore_times)
00691                 argstr[x++] = 'I';
00692         if (relative_paths)
00693                 argstr[x++] = 'R';
00694         if (one_file_system)
00695                 argstr[x++] = 'x';
00696         if (sparse_files)
00697                 argstr[x++] = 'S';
00698         if (do_compression)
00699                 argstr[x++] = 'z';
00700 
00701         /* this is a complete hack - blame Rusty 
00702 
00703            this is a hack to make the list_only (remote file list)
00704            more useful */
00705         if (list_only && !recurse) 
00706                 argstr[x++] = 'r';
00707 
00708         argstr[x] = 0;
00709 
00710         if (x != 1) args[ac++] = argstr;
00711 
00712         if (block_size != BLOCK_SIZE) {
00713                 snprintf(bsize,sizeof(bsize),"-B%d",block_size);
00714                 args[ac++] = bsize;
00715         }    
00716 
00717         if (max_delete && am_sender) {
00718                 snprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
00719                 args[ac++] = mdelete;
00720         }    
00721         
00722         if (batch_prefix != NULL) {
00723                 char *fmt = "";
00724                 if (write_batch)
00725                     fmt = "--write-batch=%s";
00726                 else
00727                 if (read_batch)
00728                     fmt = "--read-batch=%s";
00729                 snprintf(fext,sizeof(fext),fmt,batch_prefix);
00730                 args[ac++] = fext;
00731         }
00732 
00733         if (io_timeout) {
00734                 snprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
00735                 args[ac++] = iotime;
00736         }    
00737 
00738         if (bwlimit) {
00739                 snprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
00740                 args[ac++] = bw;
00741         }
00742 
00743         if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
00744                 args[ac++] = "--suffix";
00745                 args[ac++] = backup_suffix;
00746         }
00747 
00748         if (delete_mode && !delete_excluded)
00749                 args[ac++] = "--delete";
00750 
00751         if (delete_excluded)
00752                 args[ac++] = "--delete-excluded";
00753 
00754         if (size_only)
00755                 args[ac++] = "--size-only";
00756 
00757         if (modify_window_set) {
00758                 snprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
00759                          modify_window);
00760                 args[ac++] = mwindow;
00761         }
00762 
00763         if (keep_partial)
00764                 args[ac++] = "--partial";
00765 
00766         if (force_delete)
00767                 args[ac++] = "--force";
00768 
00769         if (delete_after)
00770                 args[ac++] = "--delete-after";
00771 
00772         if (ignore_errors)
00773                 args[ac++] = "--ignore-errors";
00774 
00775         if (copy_unsafe_links)
00776                 args[ac++] = "--copy-unsafe-links";
00777 
00778         if (safe_symlinks)
00779                 args[ac++] = "--safe-links";
00780 
00781         if (numeric_ids)
00782                 args[ac++] = "--numeric-ids";
00783 
00784         if (only_existing && am_sender)
00785                 args[ac++] = "--existing";
00786 
00787         if (opt_ignore_existing && am_sender) 
00788                 args[ac++] = "--ignore-existing";
00789 
00790         if (tmpdir) {
00791                 args[ac++] = "--temp-dir";
00792                 args[ac++] = tmpdir;
00793         }
00794 
00795         if (backup_dir && am_sender) {
00796                 /* only the receiver needs this option, if we are the sender
00797                  *   then we need to send it to the receiver.
00798                  */
00799                 args[ac++] = "--backup-dir";
00800                 args[ac++] = backup_dir;
00801         }
00802 
00803         if (compare_dest && am_sender) {
00804                 /* the server only needs this option if it is not the sender,
00805                  *   and it may be an older version that doesn't know this
00806                  *   option, so don't send it if client is the sender.
00807                  */
00808                 args[ac++] = "--compare-dest";
00809                 args[ac++] = compare_dest;
00810         }
00811 
00812         *argc = ac;
00813 }
00814 

Generated on Tue Apr 16 12:37:37 2002 for rsync by doxygen1.2.15