summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in5
-rw-r--r--configure.in2
-rw-r--r--io.c48
-rw-r--r--main.c249
-rw-r--r--mkproto.awk35
-rw-r--r--rsync.h10
-rw-r--r--socket.c272
-rw-r--r--syscall.c14
-rw-r--r--util.c55
9 files changed, 616 insertions, 74 deletions
diff --git a/Makefile.in b/Makefile.in
index 8d1c173f..f8ed5464 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -21,8 +21,9 @@ SHELL=/bin/sh
.SUFFIXES: .c .o
LIBOBJ=lib/getopt.o lib/fnmatch.o lib/zlib.o lib/compat.o
-OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o
-OBJS=$(OBJS1) flist.o io.o compat.o hlink.o token.o uidlist.o socket.o $(LIBOBJ)
+OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o log.o
+DAEMON_OBJ = params.o loadparm.o
+OBJS=$(OBJS1) $(DAEMON_OBJ) flist.o io.o compat.o hlink.o token.o uidlist.o socket.o $(LIBOBJ)
# note that the -I. is needed to handle config.h when using VPATH
.c.o:
diff --git a/configure.in b/configure.in
index 9749558d..7755272a 100644
--- a/configure.in
+++ b/configure.in
@@ -42,7 +42,7 @@ AC_FUNC_MMAP
AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid strtok pipe getcwd mkdir strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr bcopy bzero readlink link utime utimes)
-AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf vsnprintf)
+AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf vsnprintf setsid)
echo $ac_n "checking for working fnmatch... $ac_c"
AC_TRY_RUN([#include <fnmatch.h>
diff --git a/io.c b/io.c
index f5816ed9..587b3c74 100644
--- a/io.c
+++ b/io.c
@@ -423,10 +423,16 @@ void write_buf(int f,char *buf,int len)
total_written += len;
}
+/* write a string to the connection */
+void write_sbuf(int f,char *buf)
+{
+ write_buf(f, buf, strlen(buf));
+}
+
void write_byte(int f,unsigned char c)
{
- write_buf(f,(char *)&c,1);
+ write_buf(f,(char *)&c,1);
}
void write_flush(int f)
@@ -434,3 +440,43 @@ void write_flush(int f)
}
+int read_line(int f, char *buf, int maxlen)
+{
+ while (maxlen) {
+ read_buf(f, buf, 1);
+ if (buf[0] == '\n') {
+ buf[0] = 0;
+ break;
+ }
+ if (buf[0] != '\r') {
+ buf++;
+ maxlen--;
+ }
+ }
+ if (maxlen == 0) {
+ *buf = 0;
+ return 0;
+ }
+ return 1;
+}
+
+
+void io_printf(int fd, const char *format, ...)
+{
+ va_list ap;
+ char buf[1024];
+ int len;
+
+ va_start(ap, format);
+
+#if HAVE_VSNPRINTF
+ len = vsnprintf(buf, sizeof(buf)-1, format, ap);
+#else
+ len = vsprintf(buf, format, ap);
+#endif
+ va_end(ap);
+
+ if (len < 0) exit_cleanup(1);
+
+ write_sbuf(fd, buf);
+}
diff --git a/main.c b/main.c
index 527daeb6..0bcc7f54 100644
--- a/main.c
+++ b/main.c
@@ -21,7 +21,7 @@
int verbose = 0;
int always_checksum = 0;
-time_t starttime;
+time_t starttime = 0;
int64 total_size = 0;
int block_size=BLOCK_SIZE;
@@ -57,6 +57,9 @@ int numeric_ids = 0;
int force_delete = 0;
int io_timeout = 0;
int io_error = 0;
+int read_only = 0;
+static int module_id;
+
static int port = RSYNC_PORT;
static char *shell_cmd;
@@ -64,9 +67,9 @@ static char *shell_cmd;
extern int csum_length;
int am_server = 0;
-int am_sender;
+int am_sender=0;
int recurse = 0;
-int am_daemon;
+int am_daemon=0;
static void usage(int fd);
@@ -335,12 +338,24 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
argv[i] += l+1;
}
+ if (am_daemon) {
+ char *name = lp_name(module_id);
+ int l = strlen(name);
+ for (i=0;i<argc;i++) {
+ if (strncmp(argv[i], name, l) == 0) {
+ argv[i] += l;
+ if (!*argv[i]) argv[i] = ".";
+ }
+ }
+ }
+
if (argc == 0 && recurse) {
argc=1;
argv--;
argv[0] = ".";
}
-
+
+ rprintf(FINFO,"sending file list\n");
flist = send_file_list(f_out,argc,argv);
send_files(flist,f_out,f_in);
@@ -389,11 +404,23 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
if (verbose > 2)
rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
+ if (am_daemon) {
+ char *name = lp_name(module_id);
+ int i, l = strlen(name);
+ for (i=0;i<argc;i++) {
+ if (strncmp(argv[i], name, l) == 0) {
+ argv[i] += l;
+ if (!*argv[i]) argv[i] = ".";
+ }
+ rprintf(FINFO,"argv[%d]=%s\n", i, argv[i]);
+ }
+ }
+
if (argc > 0) {
dir = argv[0];
argc--;
argv++;
- if (chdir(dir) != 0) {
+ if (!am_daemon && chdir(dir) != 0) {
rprintf(FERROR,"chdir %s : %s (4)\n",
dir,strerror(errno));
exit_cleanup(1);
@@ -487,13 +514,15 @@ static int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
int start_socket_client(char *host, char *path, int argc, char *argv[])
{
- int fd;
- char *sargs[100];
+ int fd, i;
+ char *sargs[MAX_ARGS];
int sargc=0;
-
+ char line[1024];
+ char *p;
+ int version;
+
fd = open_socket_out(host, port);
if (fd == -1) {
- rprintf(FERROR,"failed to connect to %s - %s\n", host, strerror(errno));
exit_cleanup(1);
}
@@ -506,6 +535,41 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
sargs[sargc] = NULL;
+ p = strchr(path,'/');
+ if (p) *p = 0;
+ io_printf(fd,"%s\n",path);
+ if (p) *p = '/';
+
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+
+ if (sscanf(line,"RSYNCD %d", &version) != 1) {
+ return -1;
+ }
+
+ while (1) {
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+ if (strcmp(line,"RSYNCD: OK") == 0) break;
+ rprintf(FINFO,"%s\n", line);
+ }
+
+ for (i=0;i<sargc;i++) {
+ io_printf(fd,"%s\n", sargs[i]);
+ }
+ io_printf(fd,"\n");
+
+#if 0
+ while (1) {
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+ rprintf(FINFO,"%s\n", line);
+ }
+#endif
+
return client_run(fd, fd, -1, argc, argv);
}
@@ -874,6 +938,161 @@ static void parse_arguments(int argc, char *argv[])
}
}
+static int rsync_module(int fd, int i)
+{
+ int argc=0;
+ char *argv[MAX_ARGS];
+ char **argp;
+ char line[1024];
+
+ module_id = i;
+
+ if (lp_read_only(i))
+ read_only = 1;
+
+ rprintf(FERROR,"rsyncd starting\n");
+
+ if (chroot(lp_path(i))) {
+ io_printf(fd,"ERROR: chroot failed\n");
+ return -1;
+ }
+
+ if (chdir("/")) {
+ io_printf(fd,"ERROR: chdir failed\n");
+ return -1;
+ }
+
+ if (setgid(lp_gid(i))) {
+ io_printf(fd,"ERROR: setgid failed\n");
+ return -1;
+ }
+
+ if (setuid(lp_uid(i))) {
+ io_printf(fd,"ERROR: setuid failed\n");
+ return -1;
+ }
+
+ io_printf(fd,"RSYNCD: OK\n");
+
+ argv[argc++] = "rsyncd";
+
+ while (1) {
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+
+ if (!*line) break;
+
+ argv[argc] = strdup(line);
+ if (!argv[argc]) {
+ return -1;
+ }
+
+ argc++;
+ if (argc == MAX_ARGS) {
+ return -1;
+ }
+ }
+
+ parse_arguments(argc, argv);
+
+ /* don't allow the logs to be flooded too fast */
+ if (verbose > 1) verbose = 1;
+
+ argc -= optind;
+ argp = argv + optind;
+ optind = 0;
+
+ start_server(fd, fd, argc, argp);
+
+ return 0;
+}
+
+static void send_listing(int fd)
+{
+ int n = lp_numservices();
+ int i;
+
+ for (i=0;i<n;i++)
+ if (lp_list(i))
+ io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i));
+}
+
+/* this is called when a socket connection is established to a client
+ and we want to start talking. The setup of the system is done from
+ here */
+static int start_daemon(int fd)
+{
+ char line[1024];
+ char *motd;
+
+ set_socket_options(fd,"SO_KEEPALIVE");
+
+ io_printf(fd,"RSYNCD %d\n", PROTOCOL_VERSION);
+
+ motd = lp_motd_file();
+ if (*motd) {
+ FILE *f = fopen(motd,"r");
+ while (f && !feof(f)) {
+ int len = fread(line, 1, sizeof(line)-1, f);
+ if (len > 0) {
+ line[len] = 0;
+ io_printf(fd,"%s", line);
+ }
+ }
+ if (f) fclose(f);
+ io_printf(fd,"\n");
+ }
+
+ /* read a single line indicating the resource that is wanted */
+ while (1) {
+ int i;
+
+ line[0] = 0;
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+
+ if (!*line || strcmp(line,"#list")==0) {
+ send_listing(fd);
+ return -1;
+ }
+
+ if (*line == '#') {
+ /* it's some sort of command that I don't understand */
+ io_printf(fd,"ERROR: Unknown command '%s'\n", line);
+ return -1;
+ }
+
+ i = lp_number(line);
+ if (i == -1) {
+ io_printf(fd,"ERROR: Unknown module '%s'\n", line);
+ return -1;
+ }
+
+ return rsync_module(fd, i);
+ }
+
+ return 0;
+}
+
+
+static int daemon_main(void)
+{
+ if (!lp_load(RSYNCD_CONF)) {
+ exit_cleanup(1);
+ }
+
+ if (is_a_socket(STDIN_FILENO)) {
+ /* we are running via inetd */
+ return start_daemon(STDIN_FILENO);
+ }
+
+ become_daemon();
+
+ return start_accept_loop(port, start_daemon);
+}
+
int main(int argc,char *argv[])
{
@@ -888,17 +1107,19 @@ int main(int argc,char *argv[])
parse_arguments(argc, argv);
- while (optind) {
- argc--;
- argv++;
- optind--;
- }
+ 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);
+ if (am_daemon) {
+ return daemon_main();
+ }
+
if (dry_run)
verbose = MAX(verbose,1);
diff --git a/mkproto.awk b/mkproto.awk
index 0e3f5bf3..a08b1aff 100644
--- a/mkproto.awk
+++ b/mkproto.awk
@@ -19,6 +19,41 @@ BEGIN {
}
}
+/^FN_LOCAL_BOOL/ {
+ split($0,a,"[,()]")
+ printf "BOOL %s(int );\n", a[2]
+}
+
+/^FN_LOCAL_STRING/ {
+ split($0,a,"[,()]")
+ printf "char *%s(int );\n", a[2]
+}
+
+/^FN_LOCAL_INT/ {
+ split($0,a,"[,()]")
+ printf "int %s(int );\n", a[2]
+}
+
+/^FN_LOCAL_CHAR/ {
+ split($0,a,"[,()]")
+ printf "char %s(int );\n", a[2]
+}
+
+/^FN_GLOBAL_BOOL/ {
+ split($0,a,"[,()]")
+ printf "BOOL %s(void);\n", a[2]
+}
+
+/^FN_GLOBAL_STRING/ {
+ split($0,a,"[,()]")
+ printf "char *%s(void);\n", a[2]
+}
+
+/^FN_GLOBAL_INT/ {
+ split($0,a,"[,()]")
+ printf "int %s(void);\n", a[2]
+}
+
/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
next;
}
diff --git a/rsync.h b/rsync.h
index e5206409..e2d77453 100644
--- a/rsync.h
+++ b/rsync.h
@@ -21,6 +21,9 @@
#define RSYNC_RSH_ENV "RSYNC_RSH"
#define RSYNC_NAME "rsync"
+#define RSYNCD_CONF "/etc/rsyncd.conf"
+#define RSYNCD_LOG "/var/adm/rsyncd.log"
+
#define BACKUP_SUFFIX "~"
/* a non-zero CHAR_OFFSET makes the rolling sum stronger, but is
@@ -50,6 +53,8 @@
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (4*1024*1024)
+#define MAX_ARGS 100
+
#define BLOCKING_TIMEOUT 10
#define FERROR 1
@@ -170,6 +175,9 @@
#include <grp.h>
#include <stdarg.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
#ifndef S_IFLNK
#define S_IFLNK 0120000
@@ -179,6 +187,8 @@
#define S_ISLNK(mode) (((mode) & S_IFLNK) == S_IFLNK)
#endif
+#define BOOL int
+
#ifndef uchar
#define uchar unsigned char
#endif
diff --git a/socket.c b/socket.c
index 71aa6c2a..7027338b 100644
--- a/socket.c
+++ b/socket.c
@@ -21,7 +21,277 @@
*/
+#include "rsync.h"
+
+/* open a socket to a tcp remote host with the specified port
+ based on code from Warren */
int open_socket_out(char *host, int port)
{
- return -1;
+ int type = SOCK_STREAM;
+ struct sockaddr_in sock_out;
+ int res;
+ struct hostent *hp;
+
+
+ res = socket(PF_INET, type, 0);
+ if (res == -1) {
+ return -1;
+ }
+
+ hp = gethostbyname(host);
+ if (!hp) {
+ rprintf(FERROR,"unknown host: %s\n", host);
+ return -1;
+ }
+
+ memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
+ sock_out.sin_port = htons(port);
+ sock_out.sin_family = PF_INET;
+
+ if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
+ close(res);
+ rprintf(FERROR,"failed to connect to %s - %s\n", host, strerror(errno));
+ return -1;
+ }
+
+ return res;
+}
+
+
+/****************************************************************************
+open a socket of the specified type, port and address for incoming data
+****************************************************************************/
+static int open_socket_in(int type, int port)
+{
+ struct hostent *hp;
+ struct sockaddr_in sock;
+ char host_name[200];
+ int res;
+ int one=1;
+
+ /* get my host name */
+ if (gethostname(host_name, sizeof(host_name)) == -1) {
+ rprintf(FERROR,"gethostname failed\n");
+ return -1;
+ }
+
+ /* get host info */
+ if ((hp = gethostbyname(host_name)) == 0) {
+ rprintf(FERROR,"gethostbyname: Unknown host %s\n",host_name);
+ return -1;
+ }
+
+ bzero((char *)&sock,sizeof(sock));
+ memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
+ sock.sin_port = htons(port);
+ sock.sin_family = hp->h_addrtype;
+ sock.sin_addr.s_addr = INADDR_ANY;
+ res = socket(hp->h_addrtype, type, 0);
+ if (res == -1) {
+ rprintf(FERROR,"socket failed\n");
+ return -1;
+ }
+
+ setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+
+ /* now we've got a socket - we need to bind it */
+ if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) == -1) {
+ rprintf(FERROR,"bind failed on port %d\n", port);
+ close(res);
+ return -1;
+ }
+
+ return res;
+}
+
+
+/****************************************************************************
+determine if a file descriptor is in fact a socket
+****************************************************************************/
+int is_a_socket(int fd)
+{
+ int v,l;
+ l = sizeof(int);
+ return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
+}
+
+
+int start_accept_loop(int port, int (*fn)(int ))
+{
+ int s;
+
+ signal(SIGCLD, SIG_IGN);
+
+ /* open an incoming socket */
+ s = open_socket_in(SOCK_STREAM, port);
+ if (s == -1)
+ return(-1);
+
+ /* ready to listen */
+ if (listen(s, 5) == -1) {
+ close(s);
+ return -1;
+ }
+
+
+ /* now accept incoming connections - forking a new process
+ for each incoming connection */
+ while (1) {
+ fd_set fds;
+ int fd;
+ struct sockaddr addr;
+ int in_addrlen = sizeof(addr);
+
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+
+ if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
+ continue;
+ }
+
+ if(!FD_ISSET(s, &fds)) continue;
+
+ fd = accept(s,&addr,&in_addrlen);
+
+ if (fd == -1) continue;
+
+ if (fork()==0) {
+ close(s);
+
+ _exit(fn(fd));
+ }
+
+ close(fd);
+ }
+ return 0;
+}
+
+
+enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
+
+struct
+{
+ char *name;
+ int level;
+ int option;
+ int value;
+ int opttype;
+} socket_options[] = {
+ {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
+ {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
+ {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
+#ifdef TCP_NODELAY
+ {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
+#endif
+#ifdef IPTOS_LOWDELAY
+ {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
+#endif
+#ifdef IPTOS_THROUGHPUT
+ {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
+#endif
+#ifdef SO_SNDBUF
+ {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
+#endif
+#ifdef SO_RCVBUF
+ {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
+#endif
+#ifdef SO_SNDLOWAT
+ {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
+#endif
+#ifdef SO_RCVLOWAT
+ {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
+#endif
+#ifdef SO_SNDTIMEO
+ {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
+#endif
+#ifdef SO_RCVTIMEO
+ {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
+#endif
+ {NULL,0,0,0,0}};
+
+
+
+/****************************************************************************
+set user socket options
+****************************************************************************/
+void set_socket_options(int fd, char *options)
+{
+ char *tok;
+ options = strdup(options);
+
+ if (!options) out_of_memory("set_socket_options");
+
+ for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
+ int ret=0,i;
+ int value = 1;
+ char *p;
+ int got_value = 0;
+
+ if ((p = strchr(tok,'='))) {
+ *p = 0;
+ value = atoi(p+1);
+ got_value = 1;
+ }
+
+ for (i=0;socket_options[i].name;i++)
+ if (strcmp(socket_options[i].name,tok)==0)
+ break;
+
+ if (!socket_options[i].name) {
+ rprintf(FERROR,"Unknown socket option %s\n",tok);
+ continue;
+ }
+
+ switch (socket_options[i].opttype) {
+ case OPT_BOOL:
+ case OPT_INT:
+ ret = setsockopt(fd,socket_options[i].level,
+ socket_options[i].option,(char *)&value,sizeof(int));
+ break;
+
+ case OPT_ON:
+ if (got_value)
+ rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
+
+ {
+ int on = socket_options[i].value;
+ ret = setsockopt(fd,socket_options[i].level,
+ socket_options[i].option,(char *)&on,sizeof(int));
+ }
+ break;
+ }
+
+ if (ret != 0)
+ rprintf(FERROR,"Failed to set socket option %s\n",tok);
+ }
+
+ free(options);
+}
+
+/****************************************************************************
+become a daemon, discarding the controlling terminal
+****************************************************************************/
+void become_daemon(void)
+{
+ if (fork())
+ _exit(0);
+
+ /* detach from the terminal */
+#ifdef HAVE_SETSID
+ setsid();
+#else
+#ifdef TIOCNOTTY
+ {
+ int i = open("/dev/tty", O_RDWR);
+ if (i >= 0)
+ {
+ ioctl(i, (int) TIOCNOTTY, (char *)0);
+ close(i);
+ }
+ }
+#endif /* TIOCNOTTY */
+#endif
+ close(0);
+ close(1);
+ close(2);
}
diff --git a/syscall.c b/syscall.c
index c6fd354b..c655969e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -23,16 +23,21 @@
#include "rsync.h"
extern int dry_run;
+extern int read_only;
+
+#define CHECK_RO if (read_only) {errno = EROFS; return -1;}
int do_unlink(char *fname)
{
if (dry_run) return 0;
+ CHECK_RO
return unlink(fname);
}
int do_symlink(char *fname1, char *fname2)
{
if (dry_run) return 0;
+ CHECK_RO
return symlink(fname1, fname2);
}
@@ -40,6 +45,7 @@ int do_symlink(char *fname1, char *fname2)
int do_link(char *fname1, char *fname2)
{
if (dry_run) return 0;
+ CHECK_RO
return link(fname1, fname2);
}
#endif
@@ -47,6 +53,7 @@ int do_link(char *fname1, char *fname2)
int do_lchown(const char *path, uid_t owner, gid_t group)
{
if (dry_run) return 0;
+ CHECK_RO
return lchown(path, owner, group);
}
@@ -54,6 +61,7 @@ int do_lchown(const char *path, uid_t owner, gid_t group)
int do_mknod(char *pathname, mode_t mode, dev_t dev)
{
if (dry_run) return 0;
+ CHECK_RO
return mknod(pathname, mode, dev);
}
#endif
@@ -61,12 +69,14 @@ int do_mknod(char *pathname, mode_t mode, dev_t dev)
int do_rmdir(char *pathname)
{
if (dry_run) return 0;
+ CHECK_RO
return rmdir(pathname);
}
int do_open(char *pathname, int flags, mode_t mode)
{
if (dry_run) return -1;
+ CHECK_RO
return open(pathname, flags, mode);
}
@@ -74,6 +84,7 @@ int do_open(char *pathname, int flags, mode_t mode)
int do_chmod(const char *path, mode_t mode)
{
if (dry_run) return 0;
+ CHECK_RO
return chmod(path, mode);
}
#endif
@@ -81,18 +92,21 @@ int do_chmod(const char *path, mode_t mode)
int do_rename(char *fname1, char *fname2)
{
if (dry_run) return 0;
+ CHECK_RO
return rename(fname1, fname2);
}
int do_mkdir(char *fname, mode_t mode)
{
if (dry_run) return 0;
+ CHECK_RO
return mkdir(fname, mode);
}
char *do_mktemp(char *template)
{
if (dry_run) return NULL;
+ if (read_only) {errno = EROFS; return NULL;}
return mktemp(template);
}
diff --git a/util.c b/util.c
index 59f94182..f74228ef 100644
--- a/util.c
+++ b/util.c
@@ -446,58 +446,3 @@ void kill_all(int sig)
}
}
-/* this is the rsync debugging function. Call it with FINFO or FERROR */
-void rprintf(int fd, const char *format, ...)
-{
- va_list ap;
- char buf[1024];
- int len;
- FILE *f=NULL;
-
- va_start(ap, format);
-
-#if HAVE_VSNPRINTF
- len = vsnprintf(buf, sizeof(buf)-1, format, ap);
-#else
- len = vsprintf(buf, format, ap);
-#endif
- va_end(ap);
-
- if (len < 0) exit_cleanup(1);
-
- if (fd == FERROR) {
- f = stderr;
- }
-
- if (fd == FINFO) {
- extern int am_server;
- if (am_server)
- f = stderr;
- else
- f = stdout;
- }
-
- if (!f) exit_cleanup(1);
-
- if (fwrite(buf, len, 1, f) != 1) exit_cleanup(1);
-}
-
-void rflush(int fd)
-{
- FILE *f = NULL;
-
- if (fd == FERROR) {
- f = stderr;
- }
-
- if (fd == FINFO) {
- extern int am_server;
- if (am_server)
- f = stderr;
- else
- f = stdout;
- }
-
- if (!f) exit_cleanup(1);
- fflush(f);
-}