summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pool <mbp@samba.org>2001-08-06 08:07:58 +0000
committerMartin Pool <mbp@samba.org>2001-08-06 08:07:58 +0000
commit507a797c932f795b8df37e24a6d0320cf54d64c8 (patch)
tree2cd13cba0803ecbd29115e8750526f02b6166286
parent25ea348bd19f1b7b69d114fff72a7cb905db4b1b (diff)
downloadrsync-cvs/branch-mbp-merge-rsync+.tar.gz
Merge Jos's rsync+ patch onto 2.4.6 -- it applies cleanly here. I'm goingcvs/branch-mbp-merge-rsync+
to move it across to HEAD (2.4.7pre) next.
-rw-r--r--Makefile.in15
-rw-r--r--batch.c572
-rw-r--r--compat.c10
-rw-r--r--flist.c20
-rw-r--r--main.c143
-rw-r--r--match.c3
-rw-r--r--options.c512
-rw-r--r--rsync.c11
-rw-r--r--sender.c88
-rw-r--r--token.c33
-rw-r--r--util.c64
11 files changed, 1166 insertions, 305 deletions
diff --git a/Makefile.in b/Makefile.in
index 3bf7d492..706259d7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -21,16 +21,14 @@ SHELL=/bin/sh
.SUFFIXES:
.SUFFIXES: .c .o
-LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o
+LIBOBJ=lib/getopt.o lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
zlib/zutil.o zlib/adler32.o
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o
-OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o
+OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
-popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
- popt/popthelp.o popt/poptparse.o
-OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
+OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ)
# note that the -I. is needed to handle config.h when using VPATH
.c.o:
@@ -56,13 +54,6 @@ install-strip:
rsync: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
-Makefile: Makefile.in configure config.status
- echo "WARNING: You need to run ./config.status --recheck"
-
-# don't actually run autoconf, just issue a warning
-configure: configure.in
- echo "WARNING: you need to rerun autoconf"
-
rsync.1: rsync.yo
yodl2man -o rsync.1 rsync.yo
diff --git a/batch.c b/batch.c
new file mode 100644
index 00000000..200ff8bc
--- /dev/null
+++ b/batch.c
@@ -0,0 +1,572 @@
+/*
+ Weiss 1/1999
+ Batch utilities
+
+*/
+
+#include "rsync.h"
+#include <time.h>
+
+char rsync_flist_file[27] = "rsync_flist.";
+char rsync_csums_file[27] = "rsync_csums.";
+char rsync_delta_file[27] = "rsync_delta.";
+char rsync_argvs_file[27] = "rsync_argvs.";
+
+char batch_file_ext[15];
+
+int fdb;
+int fdb_delta;
+int fdb_open;
+int fdb_close;
+
+struct file_list *batch_flist;
+
+void create_batch_file_ext()
+{
+ struct tm *timeptr;
+ time_t elapsed_seconds;
+
+ /* Save run date and time to use for batch file extensions */
+ time(&elapsed_seconds);
+ timeptr = localtime(&elapsed_seconds);
+
+ sprintf(batch_file_ext, "%4d%02d%02d%02d%02d%02d",
+ timeptr->tm_year+1900, timeptr->tm_mon+1, timeptr->tm_mday,
+ timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
+}
+
+void set_batch_file_ext(char *ext)
+{
+ strcpy(batch_file_ext, ext);
+}
+
+void write_batch_flist_file(char *buff, int bytes_to_write)
+{
+
+ if (fdb_open) {
+ /* Set up file extension */
+ strcat(rsync_flist_file, batch_file_ext);
+
+ /* Open batch flist file for writing; create it if it doesn't exist */
+ fdb = do_open(rsync_flist_file, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IREAD|S_IWRITE);
+ if (fdb == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n",
+ rsync_flist_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ fdb_open = 0;
+ }
+
+ /* Write buffer to batch flist file */
+
+ if ( write(fdb, buff, bytes_to_write) == -1 ) {
+ rprintf(FERROR, "Batch file %s write error: %s\n",
+ rsync_flist_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+
+
+ if (fdb_close) {
+ close(fdb);
+ }
+}
+
+void write_batch_flist_info(int flist_count, struct file_struct **fptr)
+{
+ int i;
+ int bytes_to_write;
+
+ /* Write flist info to batch file */
+
+ bytes_to_write = sizeof(unsigned) +
+ sizeof(time_t) +
+ sizeof(OFF_T) +
+ sizeof(mode_t) +
+ sizeof(INO_T) +
+ (2 * sizeof(dev_t)) +
+ sizeof(uid_t) +
+ sizeof(gid_t);
+
+ fdb_open = 1;
+ fdb_close = 0;
+
+ for (i=0; i<flist_count; i++) {
+ write_batch_flist_file( (char *) fptr[i], bytes_to_write);
+ write_char_bufs(fptr[i]->basename);
+ write_char_bufs(fptr[i]->dirname);
+ write_char_bufs(fptr[i]->basedir);
+ write_char_bufs(fptr[i]->link);
+ if (i==flist_count - 1) {
+ fdb_close = 1;
+ }
+ write_char_bufs(fptr[i]->sum);
+ }
+
+}
+
+void write_char_bufs(char *buf)
+{
+ /* Write the size of the string which will follow */
+
+ char b[4];
+ if (buf != NULL)
+ SIVAL(b,0,strlen(buf));
+ else {
+ SIVAL(b,0,0);
+ }
+
+ write_batch_flist_file(b, sizeof(int));
+
+ /* Write the string if there is one */
+
+ if (buf != NULL) {
+ write_batch_flist_file(buf, strlen(buf));
+ }
+}
+
+void write_batch_argvs_file(int orig_argc, int argc, char **argv)
+{
+ int fdb;
+ int i;
+ char buff[256];
+
+ strcat(rsync_argvs_file, batch_file_ext);
+
+
+ /* Open batch argvs file for writing; create it if it doesn't exist */
+ fdb = do_open(rsync_argvs_file, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IREAD|S_IWRITE|S_IEXEC);
+ if (fdb == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n", rsync_argvs_file,
+ strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ buff[0] = '\0';
+ /* Write argvs info to batch file */
+
+ for (i=argc - orig_argc;i<argc;i++) {
+ if ( !strcmp(argv[i],"-F") ){ /* safer to change it here than script*/
+ strncat(buff,"-f ",3); /* chg to -f + ext to get ready for remote */
+ strncat(buff,batch_file_ext,strlen(batch_file_ext));
+ }
+ else {
+ strncat(buff,argv[i],strlen(argv[i]));
+ }
+
+ if (i < (argc - 1)) {
+ strncat(buff," ",1);
+ }
+ }
+ if (!write(fdb, buff, strlen(buff))) {
+ rprintf(FERROR, "Batch file %s write error: %s\n",
+ rsync_argvs_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ close(fdb);
+}
+
+struct file_list *create_flist_from_batch()
+{
+ unsigned char flags;
+
+ fdb_open = 1;
+ fdb_close = 0;
+
+ batch_flist = (struct file_list *)malloc(sizeof(batch_flist[0]));
+ if (!batch_flist) {
+ out_of_memory("create_flist_from_batch");
+ }
+ batch_flist->count=0;
+ batch_flist->malloced=1000;
+ batch_flist->files = (struct file_struct **)malloc(sizeof(batch_flist->files[0])* batch_flist->malloced);
+ if (!batch_flist->files) {
+ out_of_memory("create_flist_from_batch"); /* dw -- will exit */
+ }
+
+ for ( flags=read_batch_flags() ; flags; flags=read_batch_flags() ) {
+
+ int i = batch_flist->count;
+
+ if (i >= batch_flist->malloced) {
+ if (batch_flist->malloced < 1000)
+ batch_flist->malloced += 1000;
+ else
+ batch_flist->malloced *= 2;
+ batch_flist->files =(struct file_struct **)realloc(batch_flist->files,
+ sizeof(batch_flist->files[0])*
+ batch_flist->malloced);
+ if (!batch_flist->files)
+ out_of_memory("create_flist_from_batch");
+ }
+ read_batch_flist_info(&batch_flist->files[i]);
+ batch_flist->files[i]->flags = flags;
+
+ batch_flist->count++;
+ }
+
+ return batch_flist;
+
+}
+
+int read_batch_flist_file(char *buff, int len)
+{
+ int bytes_read;
+
+ if (fdb_open) {
+
+ /* Set up file extension */
+ strcat(rsync_flist_file, batch_file_ext);
+
+ /* Open batch flist file for reading */
+ fdb = do_open(rsync_flist_file, O_RDONLY, 0);
+ if (fdb == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n", rsync_flist_file,
+ strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ fdb_open = 0;
+ }
+
+ /* Read flist batch file */
+
+ bytes_read = read(fdb, buff, len);
+
+ if (bytes_read == -1) {
+ rprintf(FERROR, "Batch file %s read error: %s\n",
+ rsync_flist_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ if (bytes_read == 0) { /* EOF */
+ close(fdb);
+ }
+ return bytes_read;
+}
+
+unsigned char read_batch_flags()
+{
+ int flags;
+
+ if (read_batch_flist_file((char *)&flags, 4) ) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+void read_batch_flist_info(struct file_struct **fptr)
+{
+ int int_str_len;
+ char char_str_len[4];
+ char buff[256];
+ struct file_struct *file;
+
+ file = (struct file_struct *)malloc(sizeof(*file));
+ if (!file) out_of_memory("read_batch_flist_info");
+ memset((char *)file, 0, sizeof(*file));
+
+ (*fptr) = file;
+
+ read_batch_flist_file((char *)&file->modtime, sizeof(time_t));
+ read_batch_flist_file((char *)&file->length, sizeof(OFF_T));
+ read_batch_flist_file((char *)&file->mode, sizeof(mode_t));
+ read_batch_flist_file((char *)&file->inode, sizeof(INO_T));
+ read_batch_flist_file((char *)&file->dev, sizeof(dev_t));
+ read_batch_flist_file((char *)&file->rdev, sizeof(dev_t));
+ read_batch_flist_file((char *)&file->uid, sizeof(uid_t));
+ read_batch_flist_file((char *)&file->gid, sizeof(gid_t));
+ read_batch_flist_file(char_str_len, sizeof(char_str_len));
+ int_str_len = IVAL(char_str_len,0);
+ if (int_str_len > 0) {
+ read_batch_flist_file(buff, int_str_len);
+ buff[int_str_len] = '\0';
+ file->basename = strdup(buff);
+ }
+ else {
+ file->basename = NULL;
+ }
+
+ read_batch_flist_file(char_str_len, sizeof(char_str_len));
+ int_str_len = IVAL(char_str_len,0);
+ if (int_str_len > 0) {
+ read_batch_flist_file(buff, int_str_len);
+ buff[int_str_len] = '\0';
+ file[0].dirname = strdup(buff);
+ }
+ else {
+ file[0].dirname = NULL;
+ }
+
+ read_batch_flist_file(char_str_len, sizeof(char_str_len));
+ int_str_len = IVAL(char_str_len,0);
+ if (int_str_len > 0) {
+ read_batch_flist_file(buff, int_str_len);
+ buff[int_str_len] = '\0';
+ file[0].basedir = strdup(buff);
+ }
+ else {
+ file[0].basedir = NULL;
+ }
+
+ read_batch_flist_file(char_str_len, sizeof(char_str_len));
+ int_str_len = IVAL(char_str_len,0);
+ if (int_str_len > 0) {
+ read_batch_flist_file(buff, int_str_len);
+ buff[int_str_len] = '\0';
+ file[0].link = strdup(buff);
+ }
+ else {
+ file[0].link = NULL;
+ }
+
+ read_batch_flist_file(char_str_len, sizeof(char_str_len));
+ int_str_len = IVAL(char_str_len,0);
+ if (int_str_len > 0) {
+ read_batch_flist_file(buff, int_str_len);
+ buff[int_str_len] = '\0';
+ file[0].sum = strdup(buff);
+ }
+ else {
+ file[0].sum = NULL;
+ }
+}
+
+void write_batch_csums_file(char *buff, int bytes_to_write)
+{
+
+ static int fdb_open = 1;
+
+ if (fdb_open) {
+ /* Set up file extension */
+ strcat(rsync_csums_file, batch_file_ext);
+
+ /* Open batch csums file for writing; create it if it doesn't exist */
+ fdb = do_open(rsync_csums_file, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IREAD|S_IWRITE);
+ if (fdb == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n",
+ rsync_csums_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ fdb_open = 0;
+ }
+
+ /* Write buffer to batch csums file */
+
+ if ( write(fdb, buff, bytes_to_write) == -1 ) {
+ rprintf(FERROR, "Batch file %s write error: %s\n",
+ rsync_csums_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+}
+
+void close_batch_csums_file()
+{
+ close(fdb);
+
+}
+
+void write_batch_csum_info(int *flist_entry, int flist_count, struct sum_struct *s)
+{
+ int i;
+ int int_zero = 0;
+ extern int block_size;
+ extern int csum_length;
+
+ fdb_open = 1;
+
+ /* Write csum info to batch file */
+
+ write_batch_csums_file ( (char *) flist_entry, sizeof(int) );
+ write_batch_csums_file ( (char *) (s?&s->count:&int_zero), sizeof(int) );
+ if (s) {
+ for (i=0; i < s->count; i++) {
+ write_batch_csums_file( (char *) &s->sums[i].sum1, sizeof(uint32));
+ if ( (*flist_entry == flist_count - 1) && (i == s->count - 1) ) {
+ fdb_close = 1;
+ }
+ write_batch_csums_file( s->sums[i].sum2, csum_length);
+ }
+ }
+}
+
+int read_batch_csums_file(char *buff, int len)
+{
+ static int fdb_open = 1;
+ int bytes_read;
+
+ if (fdb_open) {
+
+ /* Set up file extension */
+ strcat(rsync_csums_file, batch_file_ext);
+
+ /* Open batch flist file for reading */
+ fdb = do_open(rsync_csums_file, O_RDONLY, 0);
+ if (fdb == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n", rsync_csums_file,
+ strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ fdb_open = 0;
+ }
+
+ /* Read csums batch file */
+
+ bytes_read = read(fdb, buff, len);
+
+ if (bytes_read == -1) {
+ rprintf(FERROR, "Batch file %s read error: %s\n",
+ rsync_csums_file, strerror(errno));
+ close(fdb);
+ exit_cleanup(1);
+ }
+ return bytes_read;
+}
+
+
+void read_batch_csum_info(int flist_entry, struct sum_struct *s, int *checksums_match)
+{
+ int i;
+ int file_flist_entry;
+ int file_chunk_ct;
+ uint32 file_sum1;
+ char file_sum2[SUM_LENGTH];
+ extern int csum_length;
+
+
+ read_batch_csums_file((char *)&file_flist_entry, sizeof(int));
+ if (file_flist_entry != flist_entry) {
+ rprintf(FINFO,"file_list_entry NE flist_entry\n");
+ rprintf(FINFO,"file_flist_entry = %d flist_entry = %d\n", file_flist_entry, flist_entry);
+ close(fdb);
+ exit_cleanup(1);
+
+ }
+ else {
+ read_batch_csums_file((char *)&file_chunk_ct, sizeof(int));
+ *checksums_match = 1;
+ for (i = 0;i < file_chunk_ct;i++) {
+
+ read_batch_csums_file((char *)&file_sum1, sizeof(uint32));
+ read_batch_csums_file(file_sum2, csum_length);
+
+ if ( (s->sums[i].sum1 != file_sum1) ||
+ ( memcmp(s->sums[i].sum2,file_sum2, csum_length)!=0) ) {
+ *checksums_match = 0;
+ }
+ } /* end for */
+ }
+
+}
+
+void write_batch_delta_file(char *buff, int bytes_to_write)
+{
+ static int fdb_delta_open = 1;
+
+ if (fdb_delta_open) {
+ /* Set up file extension */
+ strcat(rsync_delta_file, batch_file_ext);
+
+ /* Open batch delta file for writing; create it if it doesn't exist */
+ fdb_delta = do_open(rsync_delta_file, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IREAD|S_IWRITE);
+ if (fdb_delta == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n",
+ rsync_delta_file, strerror(errno));
+ close(fdb_delta);
+ exit_cleanup(1);
+ }
+ fdb_delta_open = 0;
+ }
+
+ /* Write buffer to batch delta file */
+
+ if ( write(fdb_delta, buff, bytes_to_write) == -1 ) {
+ rprintf(FERROR, "Batch file %s write error: %s\n",
+ rsync_delta_file, strerror(errno));
+ close(fdb_delta);
+ exit_cleanup(1);
+ }
+}
+void close_batch_delta_file()
+{
+ close(fdb_delta);
+
+}
+
+int read_batch_delta_file(char *buff, int len)
+{
+ static int fdb_delta_open = 1;
+ int bytes_read;
+
+ if (fdb_delta_open) {
+
+ /* Set up file extension */
+ strcat(rsync_delta_file, batch_file_ext);
+
+ /* Open batch flist file for reading */
+ fdb_delta = do_open(rsync_delta_file, O_RDONLY, 0);
+ if (fdb_delta == -1) {
+ rprintf(FERROR, "Batch file %s open error: %s\n", rsync_delta_file,
+ strerror(errno));
+ close(fdb_delta);
+ exit_cleanup(1);
+ }
+ fdb_delta_open = 0;
+ }
+
+ /* Read delta batch file */
+
+ bytes_read = read(fdb_delta, buff, len);
+
+ if (bytes_read == -1) {
+ rprintf(FERROR, "Batch file %s read error: %s\n",
+ rsync_delta_file, strerror(errno));
+ close(fdb_delta);
+ exit_cleanup(1);
+ }
+ return bytes_read;
+}
+
+
+void show_flist(int index, struct file_struct **fptr)
+{
+ /* for debugging show_flist(flist->count, flist->files **/
+
+ int i;
+ for (i=0;i<index;i++) {
+ rprintf(FINFO,"flist->flags=%x\n",fptr[i]->flags);
+ rprintf(FINFO,"flist->modtime=%x\n",fptr[i]->modtime);
+ rprintf(FINFO,"flist->length=%x\n",fptr[i]->length);
+ rprintf(FINFO,"flist->mode=%x\n",fptr[i]->mode);
+ rprintf(FINFO,"flist->basename=%s\n",fptr[i]->basename);
+ if (fptr[i]->dirname)
+ rprintf(FINFO,"flist->dirname=%s\n",fptr[i]->dirname);
+ if (fptr[i]->basedir)
+ rprintf(FINFO,"flist->basedir=%s\n",fptr[i]->basedir);
+ }
+}
+
+void show_argvs(int argc, char *argv[])
+{
+ /* for debugging **/
+
+ int i;
+ rprintf(FINFO,"BATCH.C:show_argvs,argc=%d\n",argc);
+ for (i=0;i<argc;i++) {
+ /* if (argv[i]) */
+ rprintf(FINFO,"i=%d,argv[i]=%s\n",i,argv[i]);
+
+ }
+}
+
diff --git a/compat.c b/compat.c
index 305c827d..6d51a3a9 100644
--- a/compat.c
+++ b/compat.c
@@ -36,6 +36,9 @@ extern int checksum_seed;
extern int remote_version;
extern int verbose;
+extern int read_batch; /* dw */
+extern int write_batch; /* dw */
+
void setup_protocol(int f_out,int f_in)
{
if (remote_version == 0) {
@@ -55,8 +58,15 @@ void setup_protocol(int f_out,int f_in)
exit_cleanup(RERR_PROTOCOL);
}
+ if (verbose > 2)
+ rprintf(FINFO, "local_version=%d remote_version=%d\n",
+ PROTOCOL_VERSION, remote_version);
+
if (remote_version >= 12) {
if (am_server) {
+ if (read_batch || write_batch) /* dw */
+ checksum_seed = 32761;
+ else
checksum_seed = time(NULL);
write_int(f_out,checksum_seed);
} else {
diff --git a/flist.c b/flist.c
index cda35082..cce6ffce 100644
--- a/flist.c
+++ b/flist.c
@@ -47,6 +47,9 @@ extern int remote_version;
extern int io_error;
extern int sanitize_paths;
+extern int read_batch;
+extern int write_batch;
+
static char topsrcname[MAXPATHLEN];
static struct exclude_struct **local_exclude_list;
@@ -185,6 +188,8 @@ int link_stat(const char *Path, STRUCT_STAT *Buffer)
static int match_file_name(char *fname,STRUCT_STAT *st)
{
if (check_exclude(fname,local_exclude_list,st)) {
+ if (verbose > 2)
+ rprintf(FINFO,"excluding file %s\n",fname);
return 0;
}
return 1;
@@ -203,7 +208,7 @@ static void set_filesystem(char *fname)
static int to_wire_mode(mode_t mode)
{
- if (S_ISLNK(mode) && (_S_IFLNK != 0120000)) {
+ if (S_ISLNK(mode) && (S_IFLNK != 0120000)) {
return (mode & ~(_S_IFMT)) | 0120000;
}
return (int)mode;
@@ -211,8 +216,8 @@ static int to_wire_mode(mode_t mode)
static mode_t from_wire_mode(int mode)
{
- if ((mode & (_S_IFMT)) == 0120000 && (_S_IFLNK != 0120000)) {
- return (mode & ~(_S_IFMT)) | _S_IFLNK;
+ if ((mode & (_S_IFMT)) == 0120000 && (S_IFLNK != 0120000)) {
+ return (mode & ~(_S_IFMT)) | S_IFLNK;
}
return (mode_t)mode;
}
@@ -613,6 +618,9 @@ void send_file_name(int f,struct file_list *flist,char *fname,
out_of_memory("send_file_name");
}
+ if (write_batch) /* dw */
+ file->flags = FLAG_DELETE;
+
if (strcmp(file->basename,"")) {
flist->files[flist->count++] = file;
send_file_entry(file,f,base_flags);
@@ -698,8 +706,6 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
if (verbose && recurse && !am_server && f != -1) {
rprintf(FINFO,"building file list ... ");
- if (verbose > 1)
- rprintf(FINFO, "\n");
rflush(FINFO);
}
@@ -841,6 +847,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
io_end_buffering(f);
stats.flist_size = stats.total_written - start_write;
stats.num_files = flist->count;
+ if (write_batch) /* dw */
+ write_batch_flist_info(flist->count, flist->files);
}
if (verbose > 2)
@@ -918,7 +926,7 @@ struct file_list *recv_file_list(int f)
}
/* if protocol version is >= 17 then recv the io_error flag */
- if (f != -1 && remote_version >= 17) {
+ if (f != -1 && remote_version >= 17 && !read_batch) { /* dw-added readbatch */
extern int module_id;
extern int ignore_errors;
if (lp_ignore_errors(module_id) || ignore_errors) {
diff --git a/main.c b/main.c
index 4ecf46d1..9208f2bd 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,5 @@
-/* -*- c-file-style: "linux" -*-
-
- Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
+/*
+ Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
This program is free software; you can redistribute it and/or modify
@@ -36,12 +35,6 @@ void wait_process(pid_t pid, int *status)
msleep(20);
io_flush();
}
-
- /* TODO: If the child exited on a signal, then log an
- * appropriate error message. Perhaps we should also accept a
- * message describing the purpose of the child. Also indicate
- * this to the caller so that thhey know something went
- * wrong. */
*status = WEXITSTATUS(*status);
}
@@ -125,18 +118,17 @@ static void report(int f)
}
-/* Start the remote shell. cmd may be NULL to use the default. */
-static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_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;
- pid_t ret;
+ int i,argc=0, ret;
char *tok,*dir=NULL;
extern int local_server;
extern char *rsync_path;
extern int blocking_io;
+ extern int read_batch;
- if (!local_server) {
+ if (!read_batch && !local_server) { /* dw -- added read_batch */
if (!cmd)
cmd = getenv(RSYNC_RSH_ENV);
if (!cmd)
@@ -187,6 +179,8 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
}
if (local_server) {
+ if (read_batch)
+ create_flist_from_batch();
ret = local_child(argc, args, f_in, f_out);
} else {
ret = piped_child(args,f_in,f_out);
@@ -398,6 +392,9 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
extern int am_daemon;
extern int module_id;
extern int am_sender;
+ extern int read_batch; /* dw */
+ extern int write_batch; /* dw */
+ extern struct file_list *batch_flist; /* dw */
if (verbose > 2)
rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
@@ -423,7 +420,10 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
if (delete_mode && !delete_excluded)
recv_exclude_list(f_in);
- flist = recv_file_list(f_in);
+ if (read_batch) /* dw */
+ flist = batch_flist;
+ else
+ flist = recv_file_list(f_in);
if (!flist) {
rprintf(FERROR,"server_recv: recv_file_list error\n");
exit_cleanup(RERR_FILESELECT);
@@ -447,6 +447,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
extern int cvs_exclude;
extern int am_sender;
extern int remote_version;
+ extern int read_batch; /* dw */
setup_protocol(f_out, f_in);
@@ -457,9 +458,11 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
io_start_multiplex_out(f_out);
if (am_sender) {
- recv_exclude_list(f_in);
- if (cvs_exclude)
+ if (!read_batch) { /* dw */
+ 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);
@@ -467,21 +470,19 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
exit_cleanup(0);
}
-
-/*
- * This is called once the connection has been negotiated. It is used
- * for rsyncd, remote-shell, and local connections.
- */
-int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
+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;
extern int remote_version;
- extern pid_t cleanup_child_pid;
+ extern int write_batch; /* dw */
+ extern int read_batch; /* dw */
+ extern struct file_list *batch_flist; /* dw */
- cleanup_child_pid = pid;
+ if (read_batch)
+ flist = batch_flist; /* dw */
set_nonblocking(f_in);
set_nonblocking(f_out);
@@ -499,21 +500,22 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
add_cvs_excludes();
if (delete_mode && !delete_excluded)
send_exclude_list(f_out);
- flist = send_file_list(f_out,argc,argv);
+ if (!read_batch) /* dw -- don't write to pipe */
+ flist = send_file_list(f_out,argc,argv);
if (verbose > 3)
rprintf(FINFO,"file list sent\n");
send_files(flist,f_out,f_in);
- if (remote_version >= 24) {
- /* final goodbye message */
- read_int(f_in);
- }
if (pid != -1) {
if (verbose > 3)
rprintf(FINFO,"client_run waiting on %d\n",pid);
io_flush();
wait_process(pid, &status);
}
+ if (remote_version >= 24) {
+ /* final goodbye message */
+ read_int(f_in);
+ }
report(-1);
exit_cleanup(status);
}
@@ -523,13 +525,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
list_only = 1;
}
- send_exclude_list(f_out);
+ if (!write_batch) /* dw */
+ send_exclude_list(f_out);
flist = recv_file_list(f_in);
if (!flist || flist->count == 0) {
- rprintf(FINFO, "client: nothing to do: "
- "perhaps you need to specify some filenames or "
- "the --recursive option?\n");
+ rprintf(FINFO,"client: nothing to do\n");
exit_cleanup(0);
}
@@ -544,7 +545,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
wait_process(pid, &status);
}
- return MAX(status, status2);
+ return status | status2;
}
static char *find_colon(char *s)
@@ -562,32 +563,24 @@ static char *find_colon(char *s)
return p;
}
-
-/*
- * Start a client for either type of remote connection. Work out
- * whether the arguments request a remote shell or rsyncd connection,
- * and call the appropriate connection function, then run_client.
- */
static int start_client(int argc, char *argv[])
{
char *p;
char *shell_machine = NULL;
char *shell_path = NULL;
char *shell_user = NULL;
- int ret;
- pid_t pid;
+ int pid, ret;
int f_in,f_out;
extern int local_server;
extern int am_sender;
extern char *shell_cmd;
extern int rsync_port;
- extern int whole_file;
- char *argv0 = strdup(argv[0]);
+ extern int read_batch;
- if (strncasecmp(URL_PREFIX, argv0, strlen(URL_PREFIX)) == 0) {
+ if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
char *host, *path;
- host = argv0 + strlen(URL_PREFIX);
+ host = argv[0] + strlen(URL_PREFIX);
p = strchr(host,'/');
if (p) {
*p = 0;
@@ -603,12 +596,13 @@ static int start_client(int argc, char *argv[])
return start_socket_client(host, path, argc-1, argv+1);
}
- p = find_colon(argv0);
+ if (!read_batch) { /* dw */
+ p = find_colon(argv[0]);
if (p) {
if (p[1] == ':') {
*p = 0;
- return start_socket_client(argv0, p+2, argc-1, argv+1);
+ return start_socket_client(argv[0], p+2, argc-1, argv+1);
}
if (argc < 1) {
@@ -618,7 +612,7 @@ static int start_client(int argc, char *argv[])
am_sender = 0;
*p = 0;
- shell_machine = argv0;
+ shell_machine = argv[0];
shell_path = p+1;
argc--;
argv++;
@@ -628,8 +622,6 @@ static int start_client(int argc, char *argv[])
p = find_colon(argv[argc-1]);
if (!p) {
local_server = 1;
- /* disable "rsync algorithm" when both sides local */
- whole_file = 1;
} else if (p[1] == ':') {
*p = 0;
return start_socket_client(argv[argc-1], p+2, argc-1, argv);
@@ -650,7 +642,12 @@ static int start_client(int argc, char *argv[])
}
argc--;
}
-
+ } else {
+ am_sender = 1; /* dw */
+ local_server = 1; /* dw */
+ shell_path = argv[argc-1]; /* dw */
+ }
+
if (shell_machine) {
p = strchr(shell_machine,'@');
if (p) {
@@ -694,17 +691,9 @@ static RETSIGTYPE sigusr1_handler(int val) {
}
static RETSIGTYPE sigusr2_handler(int val) {
- extern int log_got_error;
- if (log_got_error) _exit(RERR_PARTIAL);
_exit(0);
}
-static RETSIGTYPE sigchld_handler(int val) {
-#ifdef WNOHANG
- while (waitpid(-1, NULL, WNOHANG) > 0) ;
-#endif
-}
-
int main(int argc,char *argv[])
{
extern int am_root;
@@ -712,11 +701,16 @@ int main(int argc,char *argv[])
extern int dry_run;
extern int am_daemon;
extern int am_server;
- int ret;
+ extern int read_batch; /* dw */
+ extern int write_batch; /* dw */
+ extern char *batch_ext; /* dw */
+ int i; /* dw */
+ int orig_argc; /* dw */
+
+ orig_argc = argc; /* dw */
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
- signal(SIGCHLD, sigchld_handler);
starttime = time(NULL);
am_root = (getuid() == 0);
@@ -732,13 +726,15 @@ int main(int argc,char *argv[])
carried across */
orig_umask = (int)umask(0);
- if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
- /* FIXME: We ought to call the same error-handling
- * code here, rather than relying on getopt. */
- option_error();
+ if (!parse_arguments(argc, argv, 1)) {
exit_cleanup(RERR_SYNTAX);
}
+ 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);
@@ -750,6 +746,15 @@ int main(int argc,char *argv[])
that implement getcwd that way "pwd" can't be found after chroot. */
push_dir(NULL,0);
+ if (write_batch) { /* dw */
+ create_batch_file_ext();
+ write_batch_argvs_file(orig_argc, argc, argv);
+ }
+
+ if (read_batch) { /* dw */
+ set_batch_file_ext(batch_ext);
+ }
+
if (am_daemon) {
return daemon_main();
}
@@ -775,8 +780,6 @@ int main(int argc,char *argv[])
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
}
- ret = start_client(argc, argv);
- exit_cleanup(ret);
- return ret;
+ return start_client(argc, argv);
}
diff --git a/match.c b/match.c
index c0ae38c8..7b0f6017 100644
--- a/match.c
+++ b/match.c
@@ -260,6 +260,7 @@ static void hash_search(int f,struct sum_struct *s,
void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
{
char file_sum[MD4_SUM_LENGTH];
+ extern int write_batch; /* dw */
last_match = 0;
false_alarms = 0;
@@ -295,6 +296,8 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
if (verbose > 2)
rprintf(FINFO,"sending file_sum\n");
write_buf(f,file_sum,MD4_SUM_LENGTH);
+ if (write_batch) /* dw */
+ write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
}
if (targets) {
diff --git a/options.c b/options.c
index 35a6dc64..8417d159 100644
--- a/options.c
+++ b/options.c
@@ -1,7 +1,5 @@
-/* -*- c-file-style: "linux" -*-
-
- Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
- Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
+/*
+ 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
@@ -18,8 +16,10 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/* options parsing code */
+
#include "rsync.h"
-#include "popt.h"
+
int make_backups = 0;
int whole_file = 0;
@@ -74,6 +74,9 @@ int modify_window=0;
#endif
int blocking_io=0;
+int read_batch=0; /* dw */
+int write_batch=0; /* dw */
+
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
char *compare_dest = NULL;
@@ -81,7 +84,7 @@ char *config_file = RSYNCD_CONF;
char *shell_cmd = NULL;
char *log_format = NULL;
char *password_file = NULL;
-char *rsync_path = RSYNC_PATH;
+char *rsync_path = RSYNC_NAME;
char *backup_dir = NULL;
int rsync_port = RSYNC_PORT;
@@ -90,49 +93,17 @@ int quiet = 0;
int always_checksum = 0;
int list_only = 0;
+char *batch_ext = NULL;
+
static int modify_window_set;
struct in_addr socket_address = {INADDR_ANY};
-
-static void print_rsync_version(int f)
-{
- char const *got_socketpair = "no ";
- char const *hardlinks = "no ";
- char const *links = "no ";
-
-#ifdef HAVE_SOCKETPAIR
- got_socketpair = "";
-#endif
-
-#if SUPPORT_HARD_LINKS
- hardlinks = "";
-#endif
-
-#if SUPPORT_LINKS
- links = "";
-#endif
-
- rprintf(f, "%s version %s protocol version %d\n",
- RSYNC_NAME, VERSION, PROTOCOL_VERSION);
- rprintf(f,
- "Copyright (C) 1996-2001 by Andrew Tridgell, Paul Mackerras and others\n");
- rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
- "%shard links, %ssymlinks\n\n",
- sizeof(int64) * 8,
- got_socketpair,
- hardlinks, links);
-
-#ifdef NO_INT64
- rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
-#endif
-}
-
-
void usage(enum logcode F)
{
- print_rsync_version(F);
+ rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
+ VERSION);
rprintf(F,"rsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
@@ -206,15 +177,17 @@ 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");
rprintf(F,"\n");
rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
- rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
+ rprintf(F,"See http://rsync.samba.org/ for updates and bug reports\n");
}
-enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
+enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
OPT_EXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS,
OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
@@ -224,88 +197,89 @@ enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
OPT_MODIFY_WINDOW};
-static struct poptOption long_options[] = {
- /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
- {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION},
- {"suffix", 0, POPT_ARG_STRING, &backup_suffix},
- {"rsync-path", 0, POPT_ARG_STRING, &rsync_path},
- {"password-file", 0, POPT_ARG_STRING, &password_file},
- {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times},
- {"size-only", 0, POPT_ARG_NONE, &size_only},
- {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW},
- {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system},
- {"delete", 0, POPT_ARG_NONE, &delete_mode},
- {"existing", 0, POPT_ARG_NONE, &only_existing},
- {"delete-after", 0, POPT_ARG_NONE, &delete_after},
- {"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED},
- {"force", 0, POPT_ARG_NONE, &force_delete},
- {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids},
- {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE},
- {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE},
- {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM},
- {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM},
- {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks},
- {"help", 'h', POPT_ARG_NONE, 0, 'h'},
- {"backup", 'b', POPT_ARG_NONE, &make_backups},
- {"dry-run", 'n', POPT_ARG_NONE, &dry_run},
- {"sparse", 'S', POPT_ARG_NONE, &sparse_files},
- {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude},
- {"update", 'u', POPT_ARG_NONE, &update_only},
- {"links", 'l', POPT_ARG_NONE, &preserve_links},
- {"copy-links", 'L', POPT_ARG_NONE, &copy_links},
- {"whole", 'W', POPT_ARG_NONE, &whole_file},
- {"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links},
- {"perms", 'p', POPT_ARG_NONE, &preserve_perms},
- {"owner", 'o', POPT_ARG_NONE, &preserve_uid},
- {"group", 'g', POPT_ARG_NONE, &preserve_gid},
- {"devices", 'D', POPT_ARG_NONE, &preserve_devices},
- {"times", 't', POPT_ARG_NONE, &preserve_times},
- {"checksum", 'c', POPT_ARG_NONE, &always_checksum},
- {"verbose", 'v', POPT_ARG_NONE, 0, 'v'},
- {"quiet", 'q', POPT_ARG_NONE, 0, 'q'},
- {"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},
- {"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},
- /* 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},
- {"stats", 0, POPT_ARG_NONE, &do_stats},
- {"progress", 0, POPT_ARG_NONE, &do_progress},
- {"partial", 0, POPT_ARG_NONE, &keep_partial},
- {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors},
- {"blocking-io", 0, POPT_ARG_NONE, &blocking_io},
- {0, 'P', POPT_ARG_NONE, 0, 'P'},
- {"config", 0, POPT_ARG_STRING, &config_file},
- {"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},
- {"backup-dir", 0, POPT_ARG_STRING, &backup_dir},
- {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links},
- {0,0,0,0}
-};
+static char *short_options = "oblLWHpguDCtcahvqrRIxnSFfe:B:T:zP";
+/* added options f: (read batch) and F (write batch) ---dw **/
+
+static struct option long_options[] = {
+ {"version", 0, 0, OPT_VERSION},
+ {"server", 0, 0, OPT_SERVER},
+ {"sender", 0, 0, OPT_SENDER},
+ {"existing", 0, 0, OPT_EXISTING},
+ {"delete", 0, 0, OPT_DELETE},
+ {"delete-excluded", 0, 0, OPT_DELETE_EXCLUDED},
+ {"force", 0, 0, OPT_FORCE},
+ {"numeric-ids", 0, 0, OPT_NUMERIC_IDS},
+ {"exclude", 1, 0, OPT_EXCLUDE},
+ {"exclude-from",1, 0, OPT_EXCLUDE_FROM},
+ {"include", 1, 0, OPT_INCLUDE},
+ {"include-from",1, 0, OPT_INCLUDE_FROM},
+ {"rsync-path", 1, 0, OPT_RSYNC_PATH},
+ {"password-file", 1, 0, OPT_PASSWORD_FILE},
+ {"one-file-system",0, 0, 'x'},
+ {"ignore-times",0, 0, 'I'},
+ {"size-only", 0, 0, OPT_SIZE_ONLY},
+ {"modify-window",1, 0, OPT_MODIFY_WINDOW},
+ {"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'},
+ {"quiet", 0, 0, 'q'},
+ {"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'},
+ {"copy-unsafe-links", 0, 0, OPT_COPY_UNSAFE_LINKS},
+ {"safe-links", 0, 0, OPT_SAFE_LINKS},
+ {"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'},
+ {"compare-dest", 1, 0, OPT_COMPARE_DEST},
+ {"compress", 0, 0, 'z'},
+ {"daemon", 0, 0, OPT_DAEMON},
+ {"stats", 0, 0, OPT_STATS},
+ {"progress", 0, 0, OPT_PROGRESS},
+ {"partial", 0, 0, OPT_PARTIAL},
+ {"delete-after",0, 0, OPT_DELETE_AFTER},
+ {"ignore-errors",0, 0, OPT_IGNORE_ERRORS},
+ {"blocking-io" ,0, 0, OPT_BLOCKING_IO},
+ {"config", 1, 0, OPT_CONFIG},
+ {"port", 1, 0, OPT_PORT},
+ {"log-format", 1, 0, OPT_LOG_FORMAT},
+ {"bwlimit", 1, 0, OPT_BWLIMIT},
+ {"address", 1, 0, OPT_ADDRESS},
+ {"max-delete", 1, 0, OPT_MAX_DELETE},
+ {"backup-dir", 1, 0, OPT_BACKUP_DIR},
+ {"read-batch", 1, 0, 'f'}, /* dw */
+ {"write-batch", 0, 0, 'F'}, /* dw */
+ {0,0,0,0}};
static char err_buf[100];
-
void option_error(void)
{
if (err_buf[0]) {
- rprintf(FLOG, "%s", err_buf);
- rprintf(FERROR, "%s: %s", RSYNC_NAME, err_buf);
+ rprintf(FLOG,"%s", err_buf);
+ rprintf(FERROR,"%s", err_buf);
} else {
rprintf(FLOG,"Error parsing options - unsupported option?\n");
rprintf(FERROR,"Error parsing options - unsupported option?\n");
}
+ exit_cleanup(RERR_UNSUPPORTED);
}
/* check to see if we should refuse this option */
@@ -315,19 +289,19 @@ static int check_refuse_options(char *ref, int opt)
char *p;
const char *name;
- for (i=0; long_options[i].longName; i++) {
+ for (i=0; long_options[i].name; i++) {
if (long_options[i].val == opt) break;
}
- if (!long_options[i].longName) return 0;
+ if (!long_options[i].name) return 0;
- name = long_options[i].longName;
+ name = long_options[i].name;
len = strlen(name);
while ((p = strstr(ref,name))) {
if ((p==ref || p[-1]==' ') &&
(p[len] == ' ' || p[len] == 0)) {
- snprintf(err_buf,sizeof(err_buf),
+ slprintf(err_buf,sizeof(err_buf),
"The '%s' option is not supported by this server\n", name);
return 1;
}
@@ -337,93 +311,173 @@ static int check_refuse_options(char *ref, int opt)
}
-static int count_args(char const **argv)
-{
- int i = 0;
-
- while (argv[i] != NULL)
- i++;
-
- return i;
-}
-
-
-/* Process command line arguments. Called on both local and remote.
- * Returns if all options are OK, otherwise fills in err_buf and
- * returns 0. */
-int parse_arguments(int *argc, const char ***argv, int frommain)
+int parse_arguments(int argc, char *argv[], int frommain)
{
int opt;
+ int option_index;
char *ref = lp_refuse_options(module_id);
- poptContext pc;
- /* TODO: Call poptReadDefaultConfig; handle errors. */
+ while ((opt = getopt_long(argc, argv,
+ short_options, long_options, &option_index))
+ != -1) {
- /* The context leaks in case of an error, but if there's a
- * problem we always exit anyhow. */
- pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
if (ref) {
if (check_refuse_options(ref, opt)) return 0;
}
- /* most options are handled automatically by popt;
- * only special cases are returned and listed here. */
-
switch (opt) {
case OPT_VERSION:
- print_rsync_version(FINFO);
+ rprintf(FINFO,"rsync version %s protocol version %d\n\n",
+ VERSION,PROTOCOL_VERSION);
+ rprintf(FINFO,"Written by Andrew Tridgell and Paul Mackerras\n");
exit_cleanup(0);
+ case OPT_SUFFIX:
+ backup_suffix = optarg;
+ break;
+
+ case OPT_RSYNC_PATH:
+ rsync_path = optarg;
+ break;
+
+ case OPT_PASSWORD_FILE:
+ password_file =optarg;
+ break;
+
+ case 'I':
+ ignore_times = 1;
+ break;
+
+ case OPT_SIZE_ONLY:
+ size_only = 1;
+ break;
+
case OPT_MODIFY_WINDOW:
- /* The value has already been set by popt, but
- * we need to remember that we're using a
- * non-default setting. */
+ modify_window = atoi(optarg);
modify_window_set = 1;
break;
+ case 'x':
+ one_file_system=1;
+ break;
+
+ case OPT_DELETE:
+ delete_mode = 1;
+ break;
+
+ case OPT_EXISTING:
+ only_existing = 1;
+ break;
+
+ case OPT_DELETE_AFTER:
+ delete_after = 1;
+ break;
+
case OPT_DELETE_EXCLUDED:
delete_excluded = 1;
delete_mode = 1;
break;
+ case OPT_FORCE:
+ force_delete = 1;
+ break;
+
+ case OPT_NUMERIC_IDS:
+ numeric_ids = 1;
+ break;
+
case OPT_EXCLUDE:
- add_exclude(poptGetOptArg(pc), 0);
+ add_exclude(optarg, 0);
break;
case OPT_INCLUDE:
- add_exclude(poptGetOptArg(pc), 1);
+ add_exclude(optarg, 1);
break;
case OPT_EXCLUDE_FROM:
- add_exclude_file(poptGetOptArg(pc), 1, 0);
+ add_exclude_file(optarg,1, 0);
break;
case OPT_INCLUDE_FROM:
- add_exclude_file(poptGetOptArg(pc), 1, 1);
+ add_exclude_file(optarg,1, 1);
+ break;
+
+ case OPT_COPY_UNSAFE_LINKS:
+ copy_unsafe_links=1;
+ break;
+
+ case OPT_SAFE_LINKS:
+ safe_symlinks=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
- /* FIXME: Don't say "server" if this is
- * happening on the client. */
- /* FIXME: Why do we have the duplicated
- * rprintf? Everybody who gets this message
- * ought to send it to the client and also to
- * the logs. */
- snprintf(err_buf,sizeof(err_buf),
- "hard links are not supported on this %s\n",
- am_server ? "server" : "client");
+#else
+ slprintf(err_buf,sizeof(err_buf),"hard links are not supported on this server\n");
rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
return 0;
-#endif /* SUPPORT_HARD_LINKS */
+#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':
@@ -446,6 +500,10 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
preserve_devices=1;
break;
+ case OPT_SERVER:
+ am_server = 1;
+ break;
+
case OPT_SENDER:
if (!am_server) {
usage(FERROR);
@@ -454,11 +512,87 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
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_MAX_DELETE:
+ max_delete = atoi(optarg);
+ break;
+
+ case OPT_TIMEOUT:
+ io_timeout = atoi(optarg);
+ break;
+
+ case 'T':
+ tmpdir = optarg;
+ break;
+
+ case OPT_COMPARE_DEST:
+ compare_dest = optarg;
+ break;
+
+ case 'z':
+ do_compression = 1;
+ break;
+
+ case OPT_DAEMON:
+ am_daemon = 1;
+ break;
+
+ case OPT_STATS:
+ do_stats = 1;
+ break;
+
+ case OPT_PROGRESS:
+ do_progress = 1;
+ break;
+
+ case OPT_PARTIAL:
+ keep_partial = 1;
+ break;
+
+ case OPT_IGNORE_ERRORS:
+ ignore_errors = 1;
+ break;
+
+ case OPT_BLOCKING_IO:
+ blocking_io = 1;
+ break;
+
case 'P':
do_progress = 1;
keep_partial = 1;
break;
+ case OPT_CONFIG:
+ config_file = optarg;
+ break;
+
+ case OPT_PORT:
+ rsync_port = atoi(optarg);
+ break;
+
+ case OPT_LOG_FORMAT:
+ log_format = optarg;
+ break;
+
+ case OPT_BWLIMIT:
+ bwlimit = atoi(optarg);
+ break;
+
case OPT_ADDRESS:
{
struct in_addr *ia;
@@ -468,30 +602,30 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
}
break;
+ case OPT_BACKUP_DIR:
+ backup_dir = optarg;
+ break;
+
+ case 'f':
+ batch_ext = optarg;
+ read_batch = 1;
+ break;
+
+ case 'F':
+ write_batch = 1;
+ break;
+
default:
- /* FIXME: If --daemon is specified, then errors for later
- * parameters seem to disappear. */
- snprintf(err_buf, sizeof(err_buf),
- "%s%s: %s\n",
- am_server ? "on remote machine: " : "",
- poptBadOption(pc, POPT_BADOPTION_NOALIAS),
- poptStrerror(opt));
- return 0;
+ slprintf(err_buf,sizeof(err_buf),"unrecognised option\n");
+ return 0;
}
}
-
- *argv = poptGetArgs(pc);
- if (*argv)
- *argc = count_args(*argv);
- else
- *argc = 0;
-
return 1;
}
-/* Construct a filtered list of options to pass through from the
- * client to the server */
+/* need to pass all the valid options from the client to the server */
+
void server_options(char **args,int *argc)
{
int ac = *argc;
@@ -501,6 +635,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 +690,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 +705,27 @@ void server_options(char **args,int *argc)
if (x != 1) args[ac++] = argstr;
if (block_size != BLOCK_SIZE) {
- snprintf(bsize,sizeof(bsize),"-B%d",block_size);
+ slprintf(bsize,sizeof(bsize),"-B%d",block_size);
args[ac++] = bsize;
}
if (max_delete && am_sender) {
- snprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
+ slprintf(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) {
- snprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
+ slprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
args[ac++] = iotime;
}
if (bwlimit) {
- snprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
+ slprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
args[ac++] = bw;
}
@@ -602,7 +744,7 @@ void server_options(char **args,int *argc)
args[ac++] = "--size-only";
if (modify_window_set) {
- snprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
+ slprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
modify_window);
args[ac++] = mwindow;
}
diff --git a/rsync.c b/rsync.c
index 3e50f38d..d9cf6e42 100644
--- a/rsync.c
+++ b/rsync.c
@@ -67,21 +67,21 @@ int delete_file(char *fname)
if (!S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) == 0 || errno == ENOENT) return 0;
- rprintf(FERROR,"delete_file: unlink(%s) : %s\n", fname, strerror(errno));
+ rprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno));
return -1;
}
if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
if (!force_delete || !recurse ||
(errno != ENOTEMPTY && errno != EEXIST)) {
- rprintf(FERROR,"delete_file: rmdir(%s) : %s\n", fname, strerror(errno));
+ rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
return -1;
}
/* now we do a recsursive delete on the directory ... */
d = opendir(fname);
if (!d) {
- rprintf(FERROR,"delete_file: opendir(%s): %s\n",
+ rprintf(FERROR,"opendir(%s): %s\n",
fname,strerror(errno));
return -1;
}
@@ -91,7 +91,7 @@ int delete_file(char *fname)
if (strcmp(dname,".")==0 ||
strcmp(dname,"..")==0)
continue;
- snprintf(buf, sizeof(buf), "%s/%s", fname, dname);
+ slprintf(buf, sizeof(buf), "%s/%s", fname, dname);
if (verbose > 0)
rprintf(FINFO,"deleting %s\n", buf);
if (delete_file(buf) != 0) {
@@ -103,7 +103,7 @@ int delete_file(char *fname)
closedir(d);
if (do_rmdir(fname) != 0) {
- rprintf(FERROR,"delete_file: rmdir(%s) : %s\n", fname, strerror(errno));
+ rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
return -1;
}
@@ -226,6 +226,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
void sig_int(void)
{
+ rprintf(FINFO,"\nrsync.c:sig_int() called.\n");
exit_cleanup(RERR_SIGNAL);
}
diff --git a/sender.c b/sender.c
index d2ab1b34..39bb2797 100644
--- a/sender.c
+++ b/sender.c
@@ -93,6 +93,14 @@ void send_files(struct file_list *flist,int f_out,int f_in)
int phase = 0;
extern struct stats stats;
struct stats initial_stats;
+ extern int write_batch; /* dw */
+ int negative_one; /* dw */
+ extern int read_batch; /* dw */
+ int checksums_match; /* dw */
+ int buff_len; /* dw */
+ char buff[CHUNK_SIZE]; /* dw */
+ int j; /* dw */
+ int done; /* dw */
if (verbose > 2)
rprintf(FINFO,"send_files starting\n");
@@ -152,12 +160,15 @@ void send_files(struct file_list *flist,int f_out,int f_in)
initial_stats = stats;
s = receive_sums(f_in);
+ if (write_batch) /* dw */
+ write_batch_csum_info(&i,flist->count,s);
if (!s) {
io_error = 1;
rprintf(FERROR,"receive_sums failed\n");
return;
}
+ if (!read_batch) {
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
io_error = 1;
@@ -185,28 +196,78 @@ void send_files(struct file_list *flist,int f_out,int f_in)
if (verbose > 2)
rprintf(FINFO,"send_files mapped %s of size %.0f\n",
fname,(double)st.st_size);
+ }
- write_int(f_out,i);
+ if (!read_batch) { /* dw */
+ write_int(f_out,i);
- write_int(f_out,s->count);
- write_int(f_out,s->n);
- write_int(f_out,s->remainder);
+ if (write_batch)
+ write_batch_delta_file((char *)&i,sizeof(i));
+
+ write_int(f_out,s->count);
+ write_int(f_out,s->n);
+ write_int(f_out,s->remainder);
+ }
if (verbose > 2)
- rprintf(FINFO,"calling match_sums %s\n",fname);
+ if (!read_batch)
+ rprintf(FINFO,"calling match_sums %s\n",fname);
if (!am_server) {
log_transfer(file, fname+offset);
}
set_compression(fname);
-
- match_sums(f_out,s,buf,st.st_size);
- log_send(file, &initial_stats);
-
- if (buf) unmap_file(buf);
- close(fd);
+ if (read_batch) { /* dw */
+ /* read checksums originally computed on sender side */
+ read_batch_csum_info(i, s, &checksums_match);
+ if (checksums_match) {
+ read_batch_delta_file( (char *) &j, sizeof(int) );
+ if (j != i) { /* if flist index entries don't match*/
+ rprintf(FINFO,"index mismatch in send_files\n");
+ rprintf(FINFO,"read index = %d flist ndx = %d\n",j,i);
+ close_batch_delta_file();
+ close_batch_csums_file();
+ exit_cleanup(1);
+ }
+ else {
+ write_int(f_out,j);
+ write_int(f_out,s->count);
+ write_int(f_out,s->n);
+ write_int(f_out,s->remainder);
+ done=0;
+ while (!done) {
+ read_batch_delta_file( (char *) &buff_len, sizeof(int) );
+ write_int(f_out,buff_len);
+ if (buff_len == 0) {
+ done = 1;
+ }
+ else {
+ if (buff_len > 0) {
+ read_batch_delta_file(buff, buff_len);
+ write_buf(f_out,buff,buff_len);
+ }
+ }
+ } /* end while */
+ read_batch_delta_file( buff, MD4_SUM_LENGTH);
+ write_buf(f_out, buff, MD4_SUM_LENGTH);
+
+ } /* j=i */
+ } else { /* not checksum match */
+ rprintf(FINFO,"readbatch & checksums don't match\n");
+ rprintf(FINFO,"filename=%s is being skipped\n");
+ continue;
+ }
+ } else {
+ match_sums(f_out,s,buf,st.st_size);
+ log_send(file, &initial_stats);
+ }
+
+ if (!read_batch) { /* dw */
+ if (buf) unmap_file(buf);
+ close(fd);
+ }
free_sums(s);
@@ -220,6 +281,11 @@ void send_files(struct file_list *flist,int f_out,int f_in)
match_report();
write_int(f_out,-1);
+ if (write_batch || read_batch) { /* dw */
+ close_batch_csums_file();
+ close_batch_delta_file();
+ }
+
}
diff --git a/token.c b/token.c
index 2967b44c..174f121a 100644
--- a/token.c
+++ b/token.c
@@ -90,18 +90,29 @@ static int simple_recv_token(int f,char **data)
static void simple_send_token(int f,int token,
struct map_struct *buf,OFF_T offset,int n)
{
+ extern int write_batch; /* dw */
+ int hold_int; /* dw */
+
if (n > 0) {
int l = 0;
while (l < n) {
int n1 = MIN(CHUNK_SIZE,n-l);
write_int(f,n1);
write_buf(f,map_ptr(buf,offset+l,n1),n1);
+ if (write_batch) {
+ write_batch_delta_file( (char *) &n1, sizeof(int) );
+ write_batch_delta_file(map_ptr(buf,offset+l,n1),n1);
+ }
l += n1;
}
}
/* a -2 token means to send data only and no token */
if (token != -2) {
write_int(f,-(token+1));
+ if (write_batch) {
+ hold_int = -(token+1);
+ write_batch_delta_file( (char *) &hold_int, sizeof(int) );
+ }
}
}
@@ -134,6 +145,8 @@ send_deflated_token(int f, int token,
{
int n, r;
static int init_done, flush_pending;
+ extern int write_batch; /* dw */
+ char temp_byte; /* dw */
if (last_token == -1) {
/* initialization */
@@ -166,13 +179,27 @@ send_deflated_token(int f, int token,
n = last_token - run_start;
if (r >= 0 && r <= 63) {
write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
+ if (write_batch) { /* dw */
+ temp_byte = (char)( (n==0? TOKEN_REL: TOKENRUN_REL) + r);
+ write_batch_delta_file(&temp_byte,sizeof(char));
+ }
} else {
write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
write_int(f, run_start);
+ if (write_batch) { /* dw */
+ temp_byte = (char)(n==0? TOKEN_LONG: TOKENRUN_LONG);
+ write_batch_delta_file(&temp_byte,sizeof(temp_byte));
+ write_batch_delta_file((char *)&run_start,sizeof(run_start));
+ }
}
if (n != 0) {
write_byte(f, n);
write_byte(f, n >> 8);
+ if (write_batch) { /* dw */
+ write_batch_delta_file((char *)&n,sizeof(char));
+ temp_byte = (char) n >> 8;
+ write_batch_delta_file(&temp_byte,sizeof(temp_byte));
+ }
}
last_run_end = last_token;
run_start = token;
@@ -231,6 +258,8 @@ send_deflated_token(int f, int token,
obuf[0] = DEFLATED_DATA + (n >> 8);
obuf[1] = n;
write_buf(f, obuf, n+2);
+ if (write_batch) /* dw */
+ write_batch_delta_file(obuf,n+2);
}
}
} while (nb != 0 || tx_strm.avail_out == 0);
@@ -240,6 +269,10 @@ send_deflated_token(int f, int token,
if (token == -1) {
/* end of file - clean up */
write_byte(f, END_FLAG);
+ if (write_batch) { /* dw */
+ temp_byte = END_FLAG;
+ write_batch_delta_file((char *)&temp_byte,sizeof(temp_byte));
+ }
} else if (token != -2) {
/* add the data in the current block to the compressor's
diff --git a/util.c b/util.c
index df2af3e8..a8f0f10c 100644
--- a/util.c
+++ b/util.c
@@ -1,7 +1,6 @@
-/* -*- c-file-style: "linux" -*-
-
- Copyright (C) 1996-2000 by Andrew Tridgell
- Copyright (C) Paul Mackerras 1996
+/*
+ Copyright (C) Andrew Tridgell 1996
+ Copyright (C) Paul Mackerras 1996
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
@@ -93,9 +92,9 @@ int fd_pair(int fd[2])
used to cope with badly broken rsh implementations like the one on
solaris.
*/
-pid_t piped_child(char **command,int *f_in,int *f_out)
+int piped_child(char **command,int *f_in,int *f_out)
{
- pid_t pid;
+ int pid;
int to_child_pipe[2];
int from_child_pipe[2];
extern int blocking_io;
@@ -108,7 +107,7 @@ pid_t piped_child(char **command,int *f_in,int *f_out)
pid = do_fork();
- if (pid == -1) {
+ if (pid < 0) {
rprintf(FERROR,"fork: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
@@ -148,11 +147,12 @@ pid_t piped_child(char **command,int *f_in,int *f_out)
return pid;
}
-pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
+int local_child(int argc, char **argv,int *f_in,int *f_out)
{
- pid_t pid;
+ int pid;
int to_child_pipe[2];
int from_child_pipe[2];
+ extern int read_batch; /* dw */
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
@@ -162,7 +162,7 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
pid = do_fork();
- if (pid == -1) {
+ if (pid < 0) {
rprintf(FERROR,"fork: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
@@ -171,7 +171,10 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
extern int am_sender;
extern int am_server;
- am_sender = !am_sender;
+ if (read_batch)
+ am_sender = 0;
+ else
+ am_sender = !am_sender;
am_server = 1;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
@@ -558,7 +561,10 @@ void glob_expand(char *base1, char **argv, int *argc, int maxargs)
s = strdup(s);
if (!s) out_of_memory("glob_expand");
- if (asprintf(&base," %s/", base1) <= 0) out_of_memory("glob_expand");
+ base = (char *)malloc(strlen(base1)+3);
+ if (!base) out_of_memory("glob_expand");
+
+ sprintf(base," %s/", base1);
q = s;
while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
@@ -585,6 +591,33 @@ void strlower(char *s)
}
}
+/* this is like vsnprintf but it always null terminates, so you
+ can fit at most n-1 chars in */
+int vslprintf(char *str, int n, const char *format, va_list ap)
+{
+ int ret = vsnprintf(str, n, format, ap);
+ if (ret >= n || ret < 0) {
+ str[n-1] = 0;
+ return -1;
+ }
+ str[ret] = 0;
+ return ret;
+}
+
+
+/* like snprintf but always null terminates */
+int slprintf(char *str, int n, char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = vslprintf(str,n,format,ap);
+ va_end(ap);
+ return ret;
+}
+
+
void *Realloc(void *p, int size)
{
if (!p) return (void *)malloc(size);
@@ -934,6 +967,7 @@ void msleep(int t)
*******************************************************************/
int cmp_modtime(time_t file1, time_t file2)
{
+ time_t diff;
extern int modify_window;
if (file2 > file1) {
@@ -957,9 +991,9 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
{
static int (*fn)();
int ret;
- char *cmd;
+ char cmd[1024];
- asprintf(&cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'",
+ sprintf(cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'",
getpid(), getpid(), getpid());
if (!fn) {
@@ -972,8 +1006,6 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
system(cmd);
- free(cmd);
-
return ret;
}
#endif