mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d64488e169 | ||
|
|
29110570f8 | ||
|
|
3e607d2354 | ||
|
|
a6801c3977 | ||
|
|
3ef56fee8f | ||
|
|
f9e940efc7 | ||
|
|
1a016bfdec | ||
|
|
e42c9458c2 | ||
|
|
087bf010d2 | ||
|
|
f240c06902 | ||
|
|
a87b3b2ac2 |
10
Makefile.in
10
Makefile.in
@@ -30,7 +30,9 @@ OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ)
|
||||
.c.o:
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
|
||||
|
||||
all: rsync rsync.1 rsyncd.conf.5
|
||||
all: rsync
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
|
||||
install: all
|
||||
-mkdir -p ${INSTALL_BIN}
|
||||
@@ -44,12 +46,10 @@ rsync: $(OBJS)
|
||||
$(CC) $(CFLAGS) -o rsync $(OBJS) $(LIBS)
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man rsync.yo
|
||||
mv rsync.man rsync.1
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man rsyncd.conf.yo
|
||||
mv rsyncd.conf.man rsyncd.conf.5
|
||||
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
|
||||
|
||||
proto:
|
||||
cat *.c | awk -f mkproto.awk > proto.h
|
||||
|
||||
@@ -28,7 +28,6 @@ static void base64_encode(char *buf, int len, char *out)
|
||||
char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
int bit_offset, byte_offset, idx, i;
|
||||
unsigned char *d = (unsigned char *)buf;
|
||||
char *p;
|
||||
int bytes = (len*8 + 5)/6;
|
||||
|
||||
memset(out, 0, bytes+1);
|
||||
@@ -56,7 +55,7 @@ static void gen_challenge(char *addr, char *challenge)
|
||||
|
||||
memset(input, 0, sizeof(input));
|
||||
|
||||
strncpy((char *)input, addr, 16);
|
||||
strlcpy((char *)input, addr, 16);
|
||||
gettimeofday(&tv, NULL);
|
||||
SIVAL(input, 16, tv.tv_sec);
|
||||
SIVAL(input, 20, tv.tv_usec);
|
||||
@@ -74,8 +73,8 @@ static int get_secret(int module, char *user, char *secret, int len)
|
||||
{
|
||||
char *fname = lp_secrets_file(module);
|
||||
int fd, found=0;
|
||||
char line[1024];
|
||||
char *p, *pass;
|
||||
char line[MAXPATHLEN];
|
||||
char *p, *pass=NULL;
|
||||
|
||||
if (!fname || !*fname) return 0;
|
||||
|
||||
@@ -108,12 +107,7 @@ static int get_secret(int module, char *user, char *secret, int len)
|
||||
close(fd);
|
||||
if (!found) return 0;
|
||||
|
||||
if (strlen(pass) > len-1) {
|
||||
memset(line, 0, sizeof(line));
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(secret, pass);
|
||||
strlcpy(secret, pass, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -137,7 +131,7 @@ int auth_server(int fd, int module, char *addr, char *leader)
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[16];
|
||||
char b64_challenge[30];
|
||||
char line[1024];
|
||||
char line[MAXPATHLEN];
|
||||
char user[100];
|
||||
char secret[100];
|
||||
char pass[30];
|
||||
|
||||
@@ -30,7 +30,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
int fd, i;
|
||||
char *sargs[MAX_ARGS];
|
||||
int sargc=0;
|
||||
char line[1024];
|
||||
char line[MAXPATHLEN];
|
||||
char *p, *user=NULL;
|
||||
extern int remote_version;
|
||||
|
||||
@@ -102,13 +102,12 @@ static int rsync_module(int fd, int i)
|
||||
int argc=0;
|
||||
char *argv[MAX_ARGS];
|
||||
char **argp;
|
||||
char line[1024];
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char line[MAXPATHLEN];
|
||||
uid_t uid = (uid_t)-2;
|
||||
gid_t gid = (gid_t)-2;
|
||||
char *p;
|
||||
char *addr = client_addr(fd);
|
||||
char *host = client_name(fd);
|
||||
char *auth;
|
||||
char *name = lp_name(i);
|
||||
int start_glob=0;
|
||||
|
||||
@@ -134,8 +133,6 @@ static int rsync_module(int fd, int i)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rprintf(FINFO,"rsync on module %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
|
||||
module_id = i;
|
||||
|
||||
@@ -168,22 +165,28 @@ static int rsync_module(int fd, int i)
|
||||
p = lp_exclude(i);
|
||||
add_exclude_line(p);
|
||||
|
||||
log_open();
|
||||
|
||||
if (chroot(lp_path(i))) {
|
||||
rprintf(FERROR,"chroot %s failed\n", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chroot failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chdir("/")) {
|
||||
rprintf(FERROR,"chdir %s failed\n", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setgid(gid)) {
|
||||
if (setgid(gid) || getgid() != gid) {
|
||||
rprintf(FERROR,"setgid %d failed\n", gid);
|
||||
io_printf(fd,"@ERROR: setgid failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setuid(uid)) {
|
||||
if (setuid(uid) || getuid() != uid) {
|
||||
rprintf(FERROR,"setuid %d failed\n", uid);
|
||||
io_printf(fd,"@ERROR: setuid failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -201,18 +204,18 @@ static int rsync_module(int fd, int i)
|
||||
|
||||
p = line;
|
||||
|
||||
if (start_glob && strncmp(p, name, strlen(name)) == 0) {
|
||||
p += strlen(name);
|
||||
if (!*p) p = ".";
|
||||
}
|
||||
|
||||
argv[argc] = strdup(p);
|
||||
if (!argv[argc]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (start_glob) {
|
||||
glob_expand(argv, &argc, MAX_ARGS);
|
||||
if (start_glob == 1) {
|
||||
rprintf(FINFO,"rsync on %s from %s (%s)\n",
|
||||
p, host, addr);
|
||||
start_glob++;
|
||||
}
|
||||
glob_expand(name, argv, &argc, MAX_ARGS);
|
||||
} else {
|
||||
argc++;
|
||||
}
|
||||
@@ -263,11 +266,13 @@ static int start_daemon(int fd)
|
||||
extern char *config_file;
|
||||
extern int remote_version;
|
||||
|
||||
if (!lp_load(config_file)) {
|
||||
if (!lp_load(config_file, 0)) {
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
set_socket_options(fd,"SO_KEEPALIVE");
|
||||
set_socket_options(fd,lp_socket_options());
|
||||
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
@@ -324,6 +329,8 @@ static int start_daemon(int fd)
|
||||
|
||||
int daemon_main(void)
|
||||
{
|
||||
extern char *config_file;
|
||||
|
||||
if (is_a_socket(STDIN_FILENO)) {
|
||||
/* we are running via inetd */
|
||||
return start_daemon(STDIN_FILENO);
|
||||
@@ -331,6 +338,15 @@ int daemon_main(void)
|
||||
|
||||
become_daemon();
|
||||
|
||||
if (!lp_load(config_file, 1)) {
|
||||
fprintf(stderr,"failed to load config file %s\n", config_file);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
log_open();
|
||||
|
||||
rprintf(FINFO,"rsyncd version %s starting\n",VERSION);
|
||||
|
||||
start_accept_loop(rsync_port, start_daemon);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -205,8 +205,8 @@ void add_cvs_excludes(void)
|
||||
add_exclude(cvs_ignore_list[i]);
|
||||
|
||||
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
|
||||
sprintf(fname,"%s/.cvsignore",p);
|
||||
add_exclude_file(fname,0);
|
||||
slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p);
|
||||
add_exclude_file(fname,0);
|
||||
}
|
||||
|
||||
add_exclude_line(getenv("CVSIGNORE"));
|
||||
|
||||
8
flist.c
8
flist.c
@@ -521,7 +521,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
closedir(d);
|
||||
return;
|
||||
}
|
||||
strcat(fname,"/");
|
||||
strlcat(fname,"/", MAXPATHLEN-1);
|
||||
l++;
|
||||
}
|
||||
p = fname + strlen(fname);
|
||||
@@ -585,7 +585,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
|
||||
l = strlen(fname);
|
||||
if (l != 1 && fname[l-1] == '/') {
|
||||
strcat(fname,".");
|
||||
strlcat(fname,".",MAXPATHLEN-1);
|
||||
}
|
||||
|
||||
if (link_stat(fname,&st) != 0) {
|
||||
@@ -616,7 +616,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
thus getting their permissions right */
|
||||
*p = 0;
|
||||
if (strcmp(lastpath,fname)) {
|
||||
strcpy(lastpath, fname);
|
||||
strlcpy(lastpath, fname, sizeof(lastpath)-1);
|
||||
*p = '/';
|
||||
for (p=fname+1; (p=strchr(p,'/')); p++) {
|
||||
*p = 0;
|
||||
@@ -878,7 +878,7 @@ char *f_name(struct file_struct *f)
|
||||
n = (n+1)%10;
|
||||
|
||||
if (f->dirname) {
|
||||
sprintf(p, "%s/%s", f->dirname, f->basename);
|
||||
slprintf(p, MAXPATHLEN-1, "%s/%s", f->dirname, f->basename);
|
||||
} else {
|
||||
strlcpy(p, f->basename, MAXPATHLEN-1);
|
||||
}
|
||||
|
||||
8
io.c
8
io.c
@@ -521,13 +521,7 @@ void io_printf(int fd, const char *format, ...)
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
#if HAVE_VSNPRINTF
|
||||
len = vsnprintf(buf, sizeof(buf)-1, format, ap);
|
||||
#else
|
||||
vsprintf(buf, format, ap);
|
||||
len = strlen(buf);
|
||||
#endif
|
||||
len = vslprintf(buf, sizeof(buf)-1, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len < 0) exit_cleanup(1);
|
||||
|
||||
31
loadparm.c
31
loadparm.c
@@ -101,6 +101,7 @@ typedef struct
|
||||
char *lock_file;
|
||||
int syslog_facility;
|
||||
int max_connections;
|
||||
char *socket_options;
|
||||
} global;
|
||||
|
||||
static global Globals;
|
||||
@@ -230,6 +231,7 @@ static struct parm_struct parm_table[] =
|
||||
{"motd file", P_STRING, P_GLOBAL, &Globals.motd_file, NULL, 0},
|
||||
{"lock file", P_STRING, P_GLOBAL, &Globals.lock_file, NULL, 0},
|
||||
{"syslog facility", P_ENUM, P_GLOBAL, &Globals.syslog_facility, enum_facilities,0},
|
||||
{"socket options", P_STRING, P_GLOBAL, &Globals.socket_options,NULL, 0},
|
||||
|
||||
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
|
||||
@@ -253,6 +255,7 @@ Initialise the global parameter structure.
|
||||
***************************************************************************/
|
||||
static void init_globals(void)
|
||||
{
|
||||
memset(&Globals, 0, sizeof(Globals));
|
||||
#ifdef LOG_DAEMON
|
||||
Globals.syslog_facility = LOG_DAEMON;
|
||||
#endif
|
||||
@@ -293,8 +296,10 @@ static void init_locals(void)
|
||||
|
||||
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
|
||||
FN_GLOBAL_STRING(lp_lock_file, &Globals.lock_file)
|
||||
FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
|
||||
FN_GLOBAL_INTEGER(lp_max_connections, &Globals.max_connections)
|
||||
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
|
||||
|
||||
FN_LOCAL_STRING(lp_name, name)
|
||||
FN_LOCAL_STRING(lp_comment, comment)
|
||||
FN_LOCAL_STRING(lp_path, path)
|
||||
@@ -583,7 +588,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
|
||||
break;
|
||||
|
||||
case P_GSTRING:
|
||||
strcpy((char *)parm_ptr,parmvalue);
|
||||
strlcpy((char *)parm_ptr,parmvalue,sizeof(pstring)-1);
|
||||
break;
|
||||
|
||||
case P_ENUM:
|
||||
@@ -664,26 +669,26 @@ static BOOL do_section(char *sectionname)
|
||||
Load the services array from the services file. Return True on success,
|
||||
False on failure.
|
||||
***************************************************************************/
|
||||
BOOL lp_load(char *pszFname)
|
||||
BOOL lp_load(char *pszFname, int globals_only)
|
||||
{
|
||||
pstring n2;
|
||||
BOOL bRetval;
|
||||
pstring n2;
|
||||
BOOL bRetval;
|
||||
|
||||
bRetval = False;
|
||||
bRetval = False;
|
||||
|
||||
bInGlobalSection = True;
|
||||
bInGlobalSection = True;
|
||||
|
||||
init_globals();
|
||||
init_globals();
|
||||
|
||||
pstrcpy(n2,pszFname);
|
||||
pstrcpy(n2,pszFname);
|
||||
|
||||
/* We get sections first, so have to start 'behind' to make up */
|
||||
iServiceIndex = -1;
|
||||
bRetval = pm_process(n2, do_section, do_parameter);
|
||||
/* We get sections first, so have to start 'behind' to make up */
|
||||
iServiceIndex = -1;
|
||||
bRetval = pm_process(n2, globals_only?NULL:do_section, do_parameter);
|
||||
|
||||
bLoaded = True;
|
||||
bLoaded = True;
|
||||
|
||||
return (bRetval);
|
||||
return (bRetval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
44
log.c
44
log.c
@@ -23,6 +23,31 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
void log_open(void)
|
||||
{
|
||||
static int initialised;
|
||||
int options = LOG_PID;
|
||||
|
||||
if (initialised) return;
|
||||
initialised = 1;
|
||||
|
||||
#ifdef LOG_NDELAY
|
||||
options |= LOG_NDELAY;
|
||||
#endif
|
||||
|
||||
#ifdef LOG_DAEMON
|
||||
openlog("rsyncd", options, lp_syslog_facility());
|
||||
#else
|
||||
openlog("rsyncd", options);
|
||||
#endif
|
||||
|
||||
#ifndef LOG_NDELAY
|
||||
syslog(LOG_INFO,"rsyncd started\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* this is the rsync debugging function. Call it with FINFO or FERROR */
|
||||
void rprintf(int fd, const char *format, ...)
|
||||
{
|
||||
@@ -33,13 +58,7 @@ void rprintf(int fd, const char *format, ...)
|
||||
extern int am_daemon;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
#if HAVE_VSNPRINTF
|
||||
len = vsnprintf(buf, sizeof(buf)-1, format, ap);
|
||||
#else
|
||||
vsprintf(buf, format, ap);
|
||||
len = strlen(buf);
|
||||
#endif
|
||||
len = vslprintf(buf, sizeof(buf)-1, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len < 0) exit_cleanup(1);
|
||||
@@ -49,19 +68,10 @@ void rprintf(int fd, const char *format, ...)
|
||||
buf[len] = 0;
|
||||
|
||||
if (am_daemon) {
|
||||
static int initialised;
|
||||
int priority = LOG_INFO;
|
||||
if (fd == FERROR) priority = LOG_WARNING;
|
||||
|
||||
if (!initialised) {
|
||||
initialised = 1;
|
||||
#ifdef LOG_DAEMON
|
||||
openlog("rsyncd", LOG_PID, lp_syslog_facility());
|
||||
#else
|
||||
openlog("rsyncd", LOG_PID);
|
||||
#endif
|
||||
}
|
||||
|
||||
log_open();
|
||||
syslog(priority, "%s", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
1
main.c
1
main.c
@@ -190,7 +190,6 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
struct file_list *flist;
|
||||
char *dir = argv[0];
|
||||
extern int relative_paths;
|
||||
extern int am_daemon;
|
||||
extern int recurse;
|
||||
|
||||
if (verbose > 2)
|
||||
|
||||
10
params.c
10
params.c
@@ -451,10 +451,11 @@ static BOOL Parse( FILE *InFile,
|
||||
break;
|
||||
|
||||
case '[': /* Section Header. */
|
||||
if( !Section( InFile, sfunc ) )
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
if (!sfunc) return True;
|
||||
if( !Section( InFile, sfunc ) )
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case '\\': /* Bogus backslash. */
|
||||
c = EatWhitespace( InFile );
|
||||
@@ -558,3 +559,4 @@ BOOL pm_process( char *FileName,
|
||||
} /* pm_process */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
17
rsync.c
17
rsync.c
@@ -111,10 +111,7 @@ static int delete_file(char *fname)
|
||||
if (strcmp(dname,".")==0 ||
|
||||
strcmp(dname,"..")==0)
|
||||
continue;
|
||||
strlcpy(buf, fname, (MAXPATHLEN-strlen(dname))-2);
|
||||
strcat(buf, "/");
|
||||
strcat(buf, dname);
|
||||
buf[MAXPATHLEN-1] = 0;
|
||||
slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"deleting %s\n", buf);
|
||||
if (delete_file(buf) != 0) {
|
||||
@@ -831,7 +828,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
close(fd1);
|
||||
continue;
|
||||
}
|
||||
sprintf(fnametmp,"%s/.%s.XXXXXX",tmpdir,f);
|
||||
slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f);
|
||||
} else {
|
||||
char *f = strrchr(fname,'/');
|
||||
|
||||
@@ -844,10 +841,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
|
||||
if (f) {
|
||||
*f = 0;
|
||||
sprintf(fnametmp,"%s/.%s.XXXXXX",fname,f+1);
|
||||
slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1);
|
||||
*f = '/';
|
||||
} else {
|
||||
sprintf(fnametmp,".%s.XXXXXX",fname);
|
||||
slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname);
|
||||
}
|
||||
}
|
||||
if (NULL == do_mktemp(fnametmp)) {
|
||||
@@ -893,7 +890,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
continue;
|
||||
}
|
||||
sprintf(fnamebak,"%s%s",fname,backup_suffix);
|
||||
slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
|
||||
rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
|
||||
continue;
|
||||
@@ -998,10 +995,10 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
fname);
|
||||
return;
|
||||
}
|
||||
strcat(fname,"/");
|
||||
strlcat(fname,"/",MAXPATHLEN-1);
|
||||
offset = strlen(file->basedir)+1;
|
||||
}
|
||||
strncat(fname,f_name(file),MAXPATHLEN-strlen(fname));
|
||||
strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
|
||||
|
||||
2
rsync.yo
2
rsync.yo
@@ -450,7 +450,7 @@ times are transferred as unix time_t values
|
||||
file permissions, devices etc are transferred as native numerical
|
||||
values
|
||||
|
||||
see also the comments on the -delete option
|
||||
see also the comments on the --delete option
|
||||
|
||||
Please report bugs! The rsync bug tracking system is online at
|
||||
url(http://samba.anu.edu.au/rsync/)(http://samba.anu.edu.au/rsync/)
|
||||
|
||||
@@ -99,6 +99,13 @@ ftp, kern, lpr, mail, news, security, syslog, user, uucp, local0,
|
||||
local1, local2, local3, local4, local5, local6 and local7. The default
|
||||
is daemon.
|
||||
|
||||
dit(bf(socket options)) This option can provide endless fun for people
|
||||
who like to tune their systems to the utmost degree. You can set all
|
||||
sorts of socket options which may make transfers faster (or
|
||||
slower!). Read the man page for the setsockopt() system call for
|
||||
details on some of the options you may be able to set. By default no
|
||||
special socket options are set.
|
||||
|
||||
enddit()
|
||||
|
||||
|
||||
|
||||
2
socket.c
2
socket.c
@@ -216,6 +216,8 @@ set user socket options
|
||||
void set_socket_options(int fd, char *options)
|
||||
{
|
||||
char *tok;
|
||||
if (!options || !*options) return;
|
||||
|
||||
options = strdup(options);
|
||||
|
||||
if (!options) out_of_memory("set_socket_options");
|
||||
|
||||
187
util.c
187
util.c
@@ -60,44 +60,49 @@ struct map_struct *map_file(int fd,OFF_T len)
|
||||
|
||||
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
{
|
||||
int nread = -2;
|
||||
int nread;
|
||||
|
||||
if (map->map)
|
||||
return map->map+offset;
|
||||
if (map->map)
|
||||
return map->map+offset;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->p + (offset - map->p_offset));
|
||||
}
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->p + (offset - map->p_offset));
|
||||
}
|
||||
|
||||
len = MAX(len,CHUNK_SIZE);
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
len = MAX(len,CHUNK_SIZE);
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
if (len > map->p_size) {
|
||||
if (map->p) free(map->p);
|
||||
map->p = (char *)malloc(len);
|
||||
if (!map->p) out_of_memory("map_ptr");
|
||||
map->p_size = len;
|
||||
}
|
||||
if (len > map->p_size) {
|
||||
if (map->p) free(map->p);
|
||||
map->p = (char *)malloc(len);
|
||||
if (!map->p) out_of_memory("map_ptr");
|
||||
map->p_size = len;
|
||||
}
|
||||
|
||||
if (do_lseek(map->fd,offset,SEEK_SET) != offset ||
|
||||
(nread=read(map->fd,map->p,len)) != len) {
|
||||
rprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n",
|
||||
(int)offset, len, nread, errno);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
map->p_offset = offset;
|
||||
map->p_len = len;
|
||||
|
||||
map->p_offset = offset;
|
||||
map->p_len = len;
|
||||
if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
|
||||
rprintf(FERROR,"lseek failed in map_ptr\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
return map->p;
|
||||
if ((nread=read(map->fd,map->p,len)) != len) {
|
||||
if (nread < 0) nread = 0;
|
||||
/* the best we can do is zero the buffer - the file
|
||||
has changed mid transfer! */
|
||||
memset(map->p+nread, 0, len - nread);
|
||||
}
|
||||
|
||||
return map->p;
|
||||
}
|
||||
|
||||
|
||||
@@ -456,6 +461,21 @@ void strlcpy(char *d, char *s, int maxlen)
|
||||
d[len] = 0;
|
||||
}
|
||||
|
||||
/* like strncat but does not 0 fill the buffer and always null
|
||||
terminates (thus it can use maxlen+1 space in d) */
|
||||
void strlcat(char *d, char *s, int maxlen)
|
||||
{
|
||||
int len1 = strlen(d);
|
||||
int len2 = strlen(s);
|
||||
if (len1+len2 > maxlen) {
|
||||
len2 = maxlen-len1;
|
||||
}
|
||||
if (len2 > 0) {
|
||||
memcpy(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* turn a user name into a uid */
|
||||
int name_to_uid(char *name, uid_t *uid)
|
||||
{
|
||||
@@ -506,15 +526,21 @@ int lock_range(int fd, int offset, int len)
|
||||
}
|
||||
|
||||
|
||||
void glob_expand(char **argv, int *argc, int maxargs)
|
||||
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
|
||||
{
|
||||
#ifndef HAVE_GLOB
|
||||
if (!*s) s = ".";
|
||||
argv[*argc] = strdup(s);
|
||||
(*argc)++;
|
||||
return;
|
||||
#else
|
||||
glob_t globbuf;
|
||||
int i;
|
||||
|
||||
if (!*s) s = ".";
|
||||
|
||||
argv[*argc] = strdup(s);
|
||||
|
||||
memset(&globbuf, 0, sizeof(globbuf));
|
||||
glob(argv[*argc], 0, NULL, &globbuf);
|
||||
if (globbuf.gl_pathc == 0) {
|
||||
@@ -532,6 +558,36 @@ void glob_expand(char **argv, int *argc, int maxargs)
|
||||
#endif
|
||||
}
|
||||
|
||||
void glob_expand(char *base, char **argv, int *argc, int maxargs)
|
||||
{
|
||||
char *s = argv[*argc];
|
||||
char *p, *q;
|
||||
|
||||
if (!s || !*s) return;
|
||||
|
||||
if (strncmp(s, base, strlen(base)) == 0) {
|
||||
s += strlen(base);
|
||||
}
|
||||
|
||||
s = strdup(s);
|
||||
if (!s) out_of_memory("glob_expand");
|
||||
|
||||
q = s;
|
||||
while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
|
||||
if (p != q && *(p-1) == ' ' && p[strlen(base)] == '/') {
|
||||
/* split it at this point */
|
||||
*(p-1) = 0;
|
||||
glob_expand_one(q, argv, argc, maxargs);
|
||||
q = p+strlen(base)+1;
|
||||
} else {
|
||||
q++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
convert a string to lower case
|
||||
@@ -543,3 +599,74 @@ void strlower(char *s)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is like vsnprintf but the 'n' limit does not include
|
||||
the terminating null. So if you have a 1024 byte buffer then
|
||||
pass 1023 for n */
|
||||
int vslprintf(char *str, int n, const char *format, va_list ap)
|
||||
{
|
||||
#ifdef HAVE_VSNPRINTF
|
||||
int ret = vsnprintf(str, n, format, ap);
|
||||
if (ret > n || ret < 0) {
|
||||
str[n] = 0;
|
||||
return -1;
|
||||
}
|
||||
str[ret] = 0;
|
||||
return ret;
|
||||
#else
|
||||
static char *buf;
|
||||
static int len=MAXPATHLEN*8;
|
||||
int ret;
|
||||
|
||||
/* this code is NOT a proper vsnprintf() implementation. It
|
||||
relies on the fact that all calls to slprintf() in rsync
|
||||
pass strings which have already been checked to be less
|
||||
than MAXPATHLEN in length and never more than 2 strings are
|
||||
concatenated. This means the above buffer is absolutely
|
||||
ample and can never be overflowed.
|
||||
|
||||
In the future we would like to replace this with a proper
|
||||
vsnprintf() implementation but right now we need a solution
|
||||
that is secure and portable. This is it. */
|
||||
|
||||
if (!buf) {
|
||||
buf = malloc(len);
|
||||
if (!buf) {
|
||||
/* can't call debug or we would recurse */
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = vsprintf(buf, format, ap);
|
||||
|
||||
if (ret < 0) {
|
||||
str[0] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < n) {
|
||||
n = ret;
|
||||
} else if (ret > n) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
buf[n] = 0;
|
||||
|
||||
memcpy(str, buf, n+1);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user