mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5783c065ba | ||
|
|
adc19c987b | ||
|
|
3d38277706 | ||
|
|
64c704f0b9 | ||
|
|
69c6522734 | ||
|
|
0f8f98c8ff | ||
|
|
e384bfbdcb | ||
|
|
08e5094d7f | ||
|
|
4b3977bf00 | ||
|
|
c80ccabb0c | ||
|
|
ef5d23ebcd | ||
|
|
27b9a19be0 | ||
|
|
14175f1e77 | ||
|
|
269833af78 | ||
|
|
fca3ef06cd | ||
|
|
07a14ef8b2 | ||
|
|
21cde2888c | ||
|
|
4a7481889c | ||
|
|
0adb99b9dc | ||
|
|
36349ea0be | ||
|
|
ec3f7d1b61 | ||
|
|
f0359dd00d | ||
|
|
ef55c686bc | ||
|
|
5f7ce2041c | ||
|
|
328fcf113a | ||
|
|
24c857f1de | ||
|
|
a784e10d00 |
@@ -10,4 +10,6 @@
|
||||
#undef HAVE_SHORT_INO_T
|
||||
#undef HAVE_GETOPT_LONG
|
||||
#undef REPLACE_INET_NTOA
|
||||
#undef REPLACE_INET_ATON
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
2
backup.c
2
backup.c
@@ -197,7 +197,7 @@ static int keep_backup(char *fname)
|
||||
if (do_stat (fname, &st)) return 1;
|
||||
#endif
|
||||
|
||||
file = make_file (0, fname);
|
||||
file = make_file (0, fname, 0);
|
||||
|
||||
/* make a complete pathname for backup file */
|
||||
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {
|
||||
|
||||
@@ -363,7 +363,7 @@ static int start_daemon(int fd)
|
||||
|
||||
set_socket_options(fd,"SO_KEEPALIVE");
|
||||
set_socket_options(fd,lp_socket_options());
|
||||
|
||||
set_nonblocking(fd);
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
|
||||
114
configure.in
114
configure.in
@@ -48,12 +48,68 @@ if test x"$rsync_cv_errno" = x"yes"; then
|
||||
AC_DEFINE(HAVE_ERRNO_DECL)
|
||||
fi
|
||||
|
||||
# The following test taken from the cvs sources
|
||||
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
|
||||
# These need checks to be before checks for any other functions that
|
||||
# might be in the same libraries.
|
||||
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
|
||||
# libsocket.so which has a bad implementation of gethostbyname (it
|
||||
# only looks in /etc/hosts), so we only look for -lsocket if we need
|
||||
# it.
|
||||
AC_CHECK_FUNCS(connect)
|
||||
if test x"$ac_cv_func_connect" = x"no"; then
|
||||
case "$LIBS" in
|
||||
*-lnsl*) ;;
|
||||
*) AC_CHECK_LIB(nsl_s, printf) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-lnsl*) ;;
|
||||
*) AC_CHECK_LIB(nsl, printf) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-lsocket*) ;;
|
||||
*) AC_CHECK_LIB(socket, connect) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-linet*) ;;
|
||||
*) AC_CHECK_LIB(inet, connect) ;;
|
||||
esac
|
||||
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
|
||||
dnl has been cached.
|
||||
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
|
||||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
|
||||
# ac_cv_func_connect=yes
|
||||
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
|
||||
AC_DEFINE(HAVE_CONNECT)
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
if test x"$ac_cv_func_strcasecmp" = x"no"; then
|
||||
AC_CHECK_LIB(resolv, strcasecmp)
|
||||
fi
|
||||
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy inet_aton socketpair)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy)
|
||||
|
||||
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
|
||||
AC_TRY_RUN([#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
main() {
|
||||
int fd[2];
|
||||
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
|
||||
}],
|
||||
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
|
||||
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SOCKETPAIR)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
|
||||
AC_TRY_RUN([#include <fnmatch.h>
|
||||
@@ -154,53 +210,25 @@ AC_TRY_RUN([
|
||||
#include <arpa/inet.h>
|
||||
main() { struct in_addr ip; ip.s_addr = 0x12345678;
|
||||
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
|
||||
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
|
||||
exit(1);}],
|
||||
rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=cross)])
|
||||
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(1); }
|
||||
exit(0);}],
|
||||
rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=cross)])
|
||||
if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
|
||||
AC_DEFINE(REPLACE_INET_NTOA)
|
||||
fi
|
||||
|
||||
# The following test taken from the cvs sources
|
||||
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
|
||||
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
|
||||
# libsocket.so which has a bad implementation of gethostbyname (it
|
||||
# only looks in /etc/hosts), so we only look for -lsocket if we need
|
||||
# it.
|
||||
AC_CHECK_FUNCS(connect)
|
||||
if test x"$ac_cv_func_connect" = x"no"; then
|
||||
case "$LIBS" in
|
||||
*-lnsl*) ;;
|
||||
*) AC_CHECK_LIB(nsl_s, printf) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-lnsl*) ;;
|
||||
*) AC_CHECK_LIB(nsl, printf) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-lsocket*) ;;
|
||||
*) AC_CHECK_LIB(socket, connect) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-linet*) ;;
|
||||
*) AC_CHECK_LIB(inet, connect) ;;
|
||||
esac
|
||||
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
|
||||
dnl has been cached.
|
||||
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
|
||||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
|
||||
# ac_cv_func_connect=yes
|
||||
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
|
||||
AC_DEFINE(HAVE_CONNECT)
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
if test x"$ac_cv_func_strcasecmp" = x"no"; then
|
||||
AC_CHECK_LIB(resolv, strcasecmp)
|
||||
AC_CACHE_CHECK([for broken inet_aton],rsync_cv_REPLACE_INET_ATON,[
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
main() { struct in_addr ip;
|
||||
if (inet_aton("example", &ip) == 0) exit(0); exit(1);}],
|
||||
rsync_cv_REPLACE_INET_ATON=no,rsync_cv_REPLACE_INET_ATON=yes,rsync_cv_REPLACE_INET_ATON=cross)])
|
||||
if test x"$rsync_cv_REPLACE_INET_ATON" = x"yes"; then
|
||||
AC_DEFINE(REPLACE_INET_ATON)
|
||||
fi
|
||||
|
||||
#
|
||||
|
||||
121
flist.c
121
flist.c
@@ -51,8 +51,60 @@ static char topsrcname[MAXPATHLEN];
|
||||
|
||||
static struct exclude_struct **local_exclude_list;
|
||||
|
||||
static struct file_struct null_file;
|
||||
|
||||
static void clean_flist(struct file_list *flist, int strip_root);
|
||||
|
||||
struct string_area *string_area_new(int size)
|
||||
{
|
||||
struct string_area *a;
|
||||
|
||||
if (size <= 0) size = ARENA_SIZE;
|
||||
a = malloc(sizeof(*a));
|
||||
if (!a) out_of_memory("string_area_new");
|
||||
a->current = a->base = malloc(size);
|
||||
if (!a->current) out_of_memory("string_area_new buffer");
|
||||
a->end = a->base + size;
|
||||
a->next = 0;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
void string_area_free(struct string_area *a)
|
||||
{
|
||||
struct string_area *next;
|
||||
|
||||
for ( ; a ; a = next) {
|
||||
next = a->next;
|
||||
free(a->base);
|
||||
}
|
||||
}
|
||||
|
||||
char *string_area_malloc(struct string_area **ap, int size)
|
||||
{
|
||||
char *p;
|
||||
struct string_area *a;
|
||||
|
||||
/* does the request fit into the current space? */
|
||||
a = *ap;
|
||||
if (a->current + size >= a->end) {
|
||||
/* no; get space, move new string_area to front of the list */
|
||||
a = string_area_new(size > ARENA_SIZE ? size : ARENA_SIZE);
|
||||
a->next = *ap;
|
||||
*ap = a;
|
||||
}
|
||||
|
||||
/* have space; do the "allocation." */
|
||||
p = a->current;
|
||||
a->current += size;
|
||||
return p;
|
||||
}
|
||||
|
||||
char *string_area_strdup(struct string_area **ap, const char *src)
|
||||
{
|
||||
char* dest = string_area_malloc(ap, strlen(src) + 1);
|
||||
return strcpy(dest, src);
|
||||
}
|
||||
|
||||
static void list_file_entry(struct file_struct *f)
|
||||
{
|
||||
@@ -413,8 +465,11 @@ static int skip_filesystem(char *fname, STRUCT_STAT *st)
|
||||
return (st2.st_dev != filesystem_dev);
|
||||
}
|
||||
|
||||
#define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
|
||||
#define MALLOC(ap, i) (ap ? string_area_malloc(ap, i) : malloc(i))
|
||||
|
||||
/* create a file_struct for a named file */
|
||||
struct file_struct *make_file(int f, char *fname)
|
||||
struct file_struct *make_file(int f, char *fname, struct string_area **ap)
|
||||
{
|
||||
struct file_struct *file;
|
||||
STRUCT_STAT st;
|
||||
@@ -468,14 +523,14 @@ struct file_struct *make_file(int f, char *fname)
|
||||
if (lastdir && strcmp(fname, lastdir)==0) {
|
||||
file->dirname = lastdir;
|
||||
} else {
|
||||
file->dirname = strdup(fname);
|
||||
file->dirname = STRDUP(ap, fname);
|
||||
lastdir = file->dirname;
|
||||
}
|
||||
file->basename = strdup(p+1);
|
||||
file->basename = STRDUP(ap, p+1);
|
||||
*p = '/';
|
||||
} else {
|
||||
file->dirname = NULL;
|
||||
file->basename = strdup(fname);
|
||||
file->basename = STRDUP(ap, fname);
|
||||
}
|
||||
|
||||
file->modtime = st.st_mtime;
|
||||
@@ -491,12 +546,12 @@ struct file_struct *make_file(int f, char *fname)
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
file->link = strdup(linkbuf);
|
||||
file->link = STRDUP(ap, linkbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (always_checksum) {
|
||||
file->sum = (char *)malloc(MD4_SUM_LENGTH);
|
||||
file->sum = (char *)MALLOC(ap, MD4_SUM_LENGTH);
|
||||
if (!file->sum) out_of_memory("md4 sum");
|
||||
/* drat. we have to provide a null checksum for non-regular
|
||||
files in order to be compatible with earlier versions
|
||||
@@ -513,7 +568,7 @@ struct file_struct *make_file(int f, char *fname)
|
||||
if (lastdir && strcmp(lastdir, flist_dir)==0) {
|
||||
file->basedir = lastdir;
|
||||
} else {
|
||||
file->basedir = strdup(flist_dir);
|
||||
file->basedir = STRDUP(ap, flist_dir);
|
||||
lastdir = file->basedir;
|
||||
}
|
||||
} else {
|
||||
@@ -533,7 +588,7 @@ void send_file_name(int f,struct file_list *flist,char *fname,
|
||||
{
|
||||
struct file_struct *file;
|
||||
|
||||
file = make_file(f,fname);
|
||||
file = make_file(f,fname, &flist->string_area);
|
||||
|
||||
if (!file) return;
|
||||
|
||||
@@ -623,7 +678,6 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
{
|
||||
int i,l;
|
||||
@@ -640,14 +694,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
|
||||
start_write = stats.total_written;
|
||||
|
||||
flist = (struct file_list *)malloc(sizeof(flist[0]));
|
||||
if (!flist) out_of_memory("send_file_list");
|
||||
|
||||
flist->count=0;
|
||||
flist->malloced = 1000;
|
||||
flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
|
||||
flist->malloced);
|
||||
if (!flist->files) out_of_memory("send_file_list");
|
||||
flist = flist_new();
|
||||
|
||||
if (f != -1) {
|
||||
io_start_buffering(f);
|
||||
@@ -862,7 +909,8 @@ 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) {
|
||||
extern int module_id;
|
||||
if (lp_ignore_errors(module_id)) {
|
||||
extern int ignore_errors;
|
||||
if (lp_ignore_errors(module_id) || ignore_errors) {
|
||||
read_int(f);
|
||||
} else {
|
||||
io_error |= read_int(f);
|
||||
@@ -934,10 +982,32 @@ void free_file(struct file_struct *file)
|
||||
if (file->basename) free(file->basename);
|
||||
if (file->link) free(file->link);
|
||||
if (file->sum) free(file->sum);
|
||||
memset((char *)file, 0, sizeof(*file));
|
||||
*file = null_file;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* allocate a new file list
|
||||
*/
|
||||
struct file_list *flist_new()
|
||||
{
|
||||
struct file_list *flist;
|
||||
|
||||
flist = (struct file_list *)malloc(sizeof(flist[0]));
|
||||
if (!flist) out_of_memory("send_file_list");
|
||||
|
||||
flist->count=0;
|
||||
flist->malloced = 1000;
|
||||
flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
|
||||
flist->malloced);
|
||||
if (!flist->files) out_of_memory("send_file_list");
|
||||
#if ARENA_SIZE > 0
|
||||
flist->string_area = string_area_new(0);
|
||||
#else
|
||||
flist->string_area = 0;
|
||||
#endif
|
||||
return flist;
|
||||
}
|
||||
/*
|
||||
* free up all elements in a flist
|
||||
*/
|
||||
@@ -945,11 +1015,14 @@ void flist_free(struct file_list *flist)
|
||||
{
|
||||
int i;
|
||||
for (i=1;i<flist->count;i++) {
|
||||
free_file(flist->files[i]);
|
||||
if (!flist->string_area)
|
||||
free_file(flist->files[i]);
|
||||
free(flist->files[i]);
|
||||
}
|
||||
memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
|
||||
free(flist->files);
|
||||
if (flist->string_area)
|
||||
string_area_free(flist->string_area);
|
||||
memset((char *)flist, 0, sizeof(*flist));
|
||||
free(flist);
|
||||
}
|
||||
@@ -978,7 +1051,13 @@ static void clean_flist(struct file_list *flist, int strip_root)
|
||||
if (verbose > 1 && !am_server)
|
||||
rprintf(FINFO,"removing duplicate name %s from file list %d\n",
|
||||
f_name(flist->files[i-1]),i-1);
|
||||
free_file(flist->files[i]);
|
||||
/* it's not great that the flist knows the semantics of the
|
||||
* file memory usage, but i'd rather not add a flag byte
|
||||
* to that struct. XXX can i use a bit in the flags field? */
|
||||
if (flist->string_area)
|
||||
flist->files[i][0] = null_file;
|
||||
else
|
||||
free_file(flist->files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -246,8 +246,8 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
return;
|
||||
}
|
||||
}
|
||||
delete_file(fname);
|
||||
}
|
||||
delete_file(fname);
|
||||
if (do_symlink(file->link,fname) != 0) {
|
||||
rprintf(FERROR,"symlink %s -> %s : %s\n",
|
||||
fname,file->link,strerror(errno));
|
||||
|
||||
34
io.c
34
io.c
@@ -27,6 +27,8 @@
|
||||
/* if no timeout is specified then use a 60 second select timeout */
|
||||
#define SELECT_TIMEOUT 60
|
||||
|
||||
extern int bwlimit;
|
||||
|
||||
static int io_multiplexing_out;
|
||||
static int io_multiplexing_in;
|
||||
static int multiplex_in_fd;
|
||||
@@ -49,6 +51,7 @@ void setup_readbuffer(int f_in)
|
||||
|
||||
static void check_timeout(void)
|
||||
{
|
||||
extern int am_server, am_daemon;
|
||||
time_t t;
|
||||
|
||||
if (!io_timeout) return;
|
||||
@@ -61,8 +64,10 @@ static void check_timeout(void)
|
||||
t = time(NULL);
|
||||
|
||||
if (last_io && io_timeout && (t-last_io) >= io_timeout) {
|
||||
rprintf(FERROR,"io timeout after %d second - exiting\n",
|
||||
(int)(t-last_io));
|
||||
if (!am_server && !am_daemon) {
|
||||
rprintf(FERROR,"io timeout after %d second - exiting\n",
|
||||
(int)(t-last_io));
|
||||
}
|
||||
exit_cleanup(RERR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
@@ -159,6 +164,11 @@ static int read_timeout(int fd, char *buf, int len)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == -1 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (n == 0) {
|
||||
if (eof_error) {
|
||||
@@ -364,17 +374,35 @@ static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
if (FD_ISSET(fd, &w_fds)) {
|
||||
int ret, n = len-total;
|
||||
|
||||
ret = write(fd,buf+total,n?n:1);
|
||||
ret = write(fd,buf+total,n);
|
||||
|
||||
if (ret == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret == -1 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
/* Sleep after writing to limit I/O bandwidth */
|
||||
if (bwlimit)
|
||||
{
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = ret * 1000 / bwlimit;
|
||||
while (tv.tv_usec > 1000000)
|
||||
{
|
||||
tv.tv_sec++;
|
||||
tv.tv_usec -= 1000000;
|
||||
}
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
total += ret;
|
||||
|
||||
if (io_timeout)
|
||||
|
||||
37
lib/compat.c
37
lib/compat.c
@@ -95,21 +95,6 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
char *rep_inet_ntoa(struct in_addr ip)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)&ip.s_addr;
|
||||
static char buf[18];
|
||||
#if WORDS_BIGENDIAN
|
||||
slprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
|
||||
#else
|
||||
slprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* like strncpy but does not 0 fill the buffer and always null
|
||||
@@ -146,7 +131,23 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
char *rep_inet_ntoa(struct in_addr ip)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)&ip.s_addr;
|
||||
static char buf[18];
|
||||
#if WORDS_BIGENDIAN
|
||||
slprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
|
||||
#else
|
||||
slprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_INET_ATON
|
||||
int inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
unsigned int a1, a2, a3, a4;
|
||||
@@ -154,12 +155,12 @@
|
||||
|
||||
if (strcmp(cp, "255.255.255.255") == 0) {
|
||||
inp->s_addr = (unsigned) -1;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
|
||||
a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;
|
||||
|
||||
@@ -162,7 +162,7 @@ static service sDefault =
|
||||
NULL, /* include from */
|
||||
"%o %h [%a] %m (%u) %f %l", /* log format */
|
||||
NULL, /* refuse options */
|
||||
"*.gz *.tgz *.zip *.z *.rpm *.deb", /* dont compress */
|
||||
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
|
||||
0, /* timeout */
|
||||
0 /* max connections */
|
||||
};
|
||||
|
||||
28
main.c
28
main.c
@@ -112,6 +112,7 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
|
||||
char *tok,*dir=NULL;
|
||||
extern int local_server;
|
||||
extern char *rsync_path;
|
||||
extern int blocking_io;
|
||||
|
||||
if (!local_server) {
|
||||
if (!cmd)
|
||||
@@ -144,6 +145,9 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
|
||||
args[argc++] = rsync_path;
|
||||
|
||||
server_options(args,&argc);
|
||||
|
||||
|
||||
if (strcmp(cmd, RSYNC_RSH) == 0) blocking_io = 1;
|
||||
}
|
||||
|
||||
args[argc++] = ".";
|
||||
@@ -236,6 +240,7 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
char *dir = argv[0];
|
||||
extern int relative_paths;
|
||||
extern int recurse;
|
||||
extern int remote_version;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
|
||||
@@ -267,7 +272,12 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
}
|
||||
|
||||
send_files(flist,f_out,f_in);
|
||||
io_flush();
|
||||
report(f_out);
|
||||
if (remote_version >= 24) {
|
||||
/* final goodbye message */
|
||||
read_int(f_in);
|
||||
}
|
||||
io_flush();
|
||||
exit_cleanup(0);
|
||||
}
|
||||
@@ -319,14 +329,16 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
set_error_fd(error_pipe[1]);
|
||||
|
||||
recv_files(f_in,flist,local_name,recv_pipe[1]);
|
||||
io_flush();
|
||||
report(f_in);
|
||||
|
||||
write_int(recv_pipe[1],1);
|
||||
close(recv_pipe[1]);
|
||||
io_flush();
|
||||
/* finally we go to sleep until our parent kills us with
|
||||
a USR2 signal */
|
||||
while (1) sleep(60);
|
||||
/* finally we go to sleep until our parent kills us
|
||||
with a USR2 signal. We sleepp for a short time as on
|
||||
some OSes a signal won't interrupt a sleep! */
|
||||
while (1) sleep(1);
|
||||
}
|
||||
|
||||
close(recv_pipe[1]);
|
||||
@@ -417,6 +429,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
|
||||
setup_protocol(f_out, f_in);
|
||||
|
||||
set_nonblocking(f_in);
|
||||
set_nonblocking(f_out);
|
||||
|
||||
if (remote_version >= 23)
|
||||
io_start_multiplex_out(f_out);
|
||||
|
||||
@@ -440,6 +455,9 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
|
||||
extern int list_only;
|
||||
extern int remote_version;
|
||||
|
||||
set_nonblocking(f_in);
|
||||
set_nonblocking(f_out);
|
||||
|
||||
setup_protocol(f_out,f_in);
|
||||
|
||||
if (remote_version >= 23)
|
||||
@@ -464,11 +482,11 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
|
||||
io_flush();
|
||||
wait_process(pid, &status);
|
||||
}
|
||||
report(-1);
|
||||
if (remote_version >= 24) {
|
||||
/* final goodbye message */
|
||||
read_int(f_in);
|
||||
}
|
||||
report(-1);
|
||||
exit_cleanup(status);
|
||||
}
|
||||
|
||||
@@ -695,6 +713,8 @@ int main(int argc,char *argv[])
|
||||
#endif
|
||||
|
||||
if (am_server) {
|
||||
set_nonblocking(STDIN_FILENO);
|
||||
set_nonblocking(STDOUT_FILENO);
|
||||
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
34
options.c
34
options.c
@@ -62,9 +62,12 @@ int safe_symlinks=0;
|
||||
int copy_unsafe_links=0;
|
||||
int block_size=BLOCK_SIZE;
|
||||
int size_only=0;
|
||||
int bwlimit=0;
|
||||
int delete_after=0;
|
||||
int only_existing=0;
|
||||
int max_delete=0;
|
||||
int ignore_errors=0;
|
||||
int blocking_io=0;
|
||||
|
||||
char *backup_suffix = BACKUP_SUFFIX;
|
||||
char *tmpdir = NULL;
|
||||
@@ -133,6 +136,7 @@ void usage(enum logcode F)
|
||||
rprintf(F," --delete delete files that don't exist on the sending side\n");
|
||||
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
|
||||
rprintf(F," --delete-after delete after transferring, not before\n");
|
||||
rprintf(F," --ignore-errors delete even if there are IO errors\n");
|
||||
rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
|
||||
rprintf(F," --partial keep partially transferred files\n");
|
||||
rprintf(F," --force force deletion of directories even if not empty\n");
|
||||
@@ -153,10 +157,12 @@ void usage(enum logcode F)
|
||||
rprintf(F," --address bind to the specified address\n");
|
||||
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
|
||||
rprintf(F," --port=PORT specify alternate rsyncd port number\n");
|
||||
rprintf(F," --blocking-io use blocking IO for the remote shell\n");
|
||||
rprintf(F," --stats give some file transfer stats\n");
|
||||
rprintf(F," --progress show progress during transfer\n");
|
||||
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," -h, --help show this help screen\n");
|
||||
|
||||
rprintf(F,"\n");
|
||||
@@ -171,7 +177,8 @@ enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
|
||||
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
|
||||
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
|
||||
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
|
||||
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR};
|
||||
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
|
||||
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO};
|
||||
|
||||
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
|
||||
|
||||
@@ -228,9 +235,12 @@ static struct option long_options[] = {
|
||||
{"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},
|
||||
@@ -528,6 +538,14 @@ int parse_arguments(int argc, char *argv[], int frommain)
|
||||
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;
|
||||
@@ -544,6 +562,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
|
||||
case OPT_LOG_FORMAT:
|
||||
log_format = optarg;
|
||||
break;
|
||||
|
||||
case OPT_BWLIMIT:
|
||||
bwlimit = atoi(optarg);
|
||||
break;
|
||||
|
||||
case OPT_ADDRESS:
|
||||
{
|
||||
@@ -576,6 +598,8 @@ void server_options(char **args,int *argc)
|
||||
static char bsize[30];
|
||||
static char iotime[30];
|
||||
static char mdelete[30];
|
||||
static char bw[50];
|
||||
|
||||
int i, x;
|
||||
|
||||
args[ac++] = "--server";
|
||||
@@ -647,6 +671,11 @@ void server_options(char **args,int *argc)
|
||||
args[ac++] = iotime;
|
||||
}
|
||||
|
||||
if (bwlimit) {
|
||||
slprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
|
||||
args[ac++] = bw;
|
||||
}
|
||||
|
||||
if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
|
||||
args[ac++] = "--suffix";
|
||||
args[ac++] = backup_suffix;
|
||||
@@ -670,6 +699,9 @@ void server_options(char **args,int *argc)
|
||||
if (delete_after)
|
||||
args[ac++] = "--delete-after";
|
||||
|
||||
if (ignore_errors)
|
||||
args[ac++] = "--ignore-errors";
|
||||
|
||||
if (copy_unsafe_links)
|
||||
args[ac++] = "--copy-unsafe-links";
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.4.1
|
||||
Version: 2.4.4
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.4.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.4.4.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -108,13 +108,14 @@ void delete_files(struct file_list *flist)
|
||||
int i, j;
|
||||
char *name;
|
||||
extern int module_id;
|
||||
extern int ignore_errors;
|
||||
extern int max_delete;
|
||||
static int deletion_count;
|
||||
|
||||
if (cvs_exclude)
|
||||
add_cvs_excludes();
|
||||
|
||||
if (io_error && !lp_ignore_errors(module_id)) {
|
||||
if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
|
||||
rprintf(FINFO,"IO error encountered - skipping file deletion\n");
|
||||
return;
|
||||
}
|
||||
|
||||
19
rsync.h
19
rsync.h
@@ -305,10 +305,20 @@ struct file_struct {
|
||||
};
|
||||
|
||||
|
||||
#define ARENA_SIZE (32 * 1024)
|
||||
|
||||
struct string_area {
|
||||
char *base;
|
||||
char *end;
|
||||
char *current;
|
||||
struct string_area *next;
|
||||
};
|
||||
|
||||
struct file_list {
|
||||
int count;
|
||||
int malloced;
|
||||
struct file_struct **files;
|
||||
struct string_area *string_area;
|
||||
};
|
||||
|
||||
struct sum_buf {
|
||||
@@ -457,6 +467,15 @@ extern int errno;
|
||||
#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
|
||||
#endif
|
||||
|
||||
/* work out what fcntl flag to use for non-blocking */
|
||||
#ifdef O_NONBLOCK
|
||||
# define NONBLOCK_FLAG O_NONBLOCK
|
||||
#elif defined(SYSV)
|
||||
# define NONBLOCK_FLAG O_NDELAY
|
||||
#else
|
||||
# define NONBLOCK_FLAG FNDELAY
|
||||
#endif
|
||||
|
||||
|
||||
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
|
||||
|
||||
|
||||
48
rsync.yo
48
rsync.yo
@@ -248,6 +248,7 @@ verb(
|
||||
--delete delete files that don't exist on the sending side
|
||||
--delete-excluded also delete excluded files on the receiving side
|
||||
--delete-after delete after transferring, not before
|
||||
--ignore-errors delete even if there are IO errors
|
||||
--max-delete=NUM don't delete more than NUM files
|
||||
--partial keep partially transferred files
|
||||
--force force deletion of directories even if not empty
|
||||
@@ -268,10 +269,12 @@ verb(
|
||||
--address bind to the specified address
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--port=PORT specify alternate rsyncd port number
|
||||
--blocking-io use blocking IO for the remote shell
|
||||
--stats give some file transfer stats
|
||||
--progress show progress during transfer
|
||||
--log-format=FORMAT log file transfers using specified format
|
||||
--password-file=FILE get password from FILE
|
||||
--bwlimit=KBPS limit I/O bandwidth, KBytes per second
|
||||
-h, --help show this help screen
|
||||
)
|
||||
|
||||
@@ -609,6 +612,11 @@ specified.
|
||||
dit(bf(--port=PORT)) This specifies an alternate TCP port number to use
|
||||
rather than the default port 873.
|
||||
|
||||
dit(bf(--blocking-io)) This specifies whether rsync will use blocking
|
||||
IO when launching a remote shell transport. You may find this is
|
||||
needed for some remote shells that can't handle the default
|
||||
non-blocking IO.
|
||||
|
||||
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
|
||||
rsync client logs to stdout on a per-file basis. The log format is
|
||||
specified using the same format conventions as the log format option in
|
||||
@@ -642,6 +650,14 @@ transport, not when using a remote shell as the transport. The file
|
||||
must not be world readable. It should contain just the password as a
|
||||
single line.
|
||||
|
||||
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
|
||||
transfer rate in kilobytes per second. This option is most effective when
|
||||
using rsync with large files (several megabytes and up). Due to the nature
|
||||
of rsync transfers, blocks of data are sent, then if rsync determines the
|
||||
transfer was too fast, it will wait before sending the next data block. The
|
||||
result is an average transfer rate equalling the specified limit. A value
|
||||
of zero specifies no limit.
|
||||
|
||||
enddit()
|
||||
|
||||
manpagesection(EXCLUDE PATTERNS)
|
||||
@@ -657,7 +673,11 @@ skipped. If it is an include pattern then that filename is not
|
||||
skipped. If no matching include/exclude pattern is found then the
|
||||
filename is not skipped.
|
||||
|
||||
Note that the --include and --exclude options take one pattern
|
||||
Note that when used with -r (which is implied by -a), every subcomponent of
|
||||
every path is visited from top down, so include/exclude patterns get
|
||||
applied recursively to each subcomponent.
|
||||
|
||||
Note also that the --include and --exclude options take one pattern
|
||||
each. To add multiple patterns use the --include-from and
|
||||
--exclude-from options or multiple --include and --exclude options.
|
||||
|
||||
@@ -666,9 +686,11 @@ The patterns can take several forms. The rules are:
|
||||
itemize(
|
||||
it() if the pattern starts with a / then it is matched against the
|
||||
start of the filename, otherwise it is matched against the end of
|
||||
the filename. Thus /foo would match a file called foo
|
||||
at the base of the tree whereas foo would match any file
|
||||
called foo anywhere in the tree.
|
||||
the filename. Thus "/foo" would match a file called "foo" at the base of
|
||||
the tree. On the other hand, "foo" would match any file called "foo"
|
||||
anywhere in the tree because the algorithm is applied recursively from
|
||||
top down; it behaves as if each path component gets a turn at being the
|
||||
end of the file name.
|
||||
|
||||
it() if the pattern ends with a / then it will only match a
|
||||
directory, not a file, link or device.
|
||||
@@ -677,12 +699,15 @@ itemize(
|
||||
*?[ then expression matching is applied using the shell filename
|
||||
matching rules. Otherwise a simple string match is used.
|
||||
|
||||
it() if the pattern includes a double asterisk "**" then all wildcards in
|
||||
the pattern will match slashes, otherwise they will stop at slashes.
|
||||
|
||||
it() if the pattern contains a / (not counting a trailing /) then it
|
||||
is matched against the full filename, including any leading
|
||||
directory. If the pattern doesn't contain a / then it is matched
|
||||
only against the final component of the filename. Furthermore, if
|
||||
the pattern includes a double asterisk "**" then all wildcards in
|
||||
the pattern will match slashes, otherwise they will stop at slashes.
|
||||
only against the final component of the filename. Again, remember
|
||||
that the algorithm is applied recursively so "full filename" can
|
||||
actually be any portion of a path.
|
||||
|
||||
it() if the pattern starts with "+ " (a plus followed by a space)
|
||||
then it is always considered an include pattern, even if specified as
|
||||
@@ -699,7 +724,14 @@ itemize(
|
||||
The +/- rules are most useful in exclude lists, allowing you to have a
|
||||
single exclude list that contains both include and exclude options.
|
||||
|
||||
Here are some examples:
|
||||
If you end an exclude list with --exclude '*', note that since the
|
||||
algorithm is applied recursively that unless you explicitly include
|
||||
parent directories of files you want to include then the algorithm
|
||||
will stop at the parent directories and never see the files below
|
||||
them. To include all directories, use --include '*/' before the
|
||||
--exclude '*'.
|
||||
|
||||
Here are some exclude/include examples:
|
||||
|
||||
itemize(
|
||||
it() --exclude "*.o" would exclude all filenames matching *.o
|
||||
|
||||
@@ -128,8 +128,11 @@ dit(bf(use chroot)) If "use chroot" is true, the rsync server will chroot
|
||||
to the "path" before starting the file transfer with the client. This has
|
||||
the advantage of extra protection against possible implementation security
|
||||
holes, but it has the disadvantages of requiring super-user privileges and
|
||||
of not being able to follow symbolic links outside of the new root path.
|
||||
The default is to use chroot.
|
||||
of not being able to follow symbolic links outside of the new root path
|
||||
when reading. For writing when "use chroot" is false, for security reasons
|
||||
symlinks may only be relative paths pointing to other files within the
|
||||
root path, and leading slashes are removed from absolute paths. The
|
||||
default for "use chroot" is true.
|
||||
|
||||
dit(bf(max connections)) The "max connections" option allows you to
|
||||
specify the maximum number of simultaneous connections you will allow
|
||||
@@ -342,7 +345,7 @@ The "dont compress" option takes a space separated list of
|
||||
case-insensitive wildcard patterns. Any source filename matching one
|
||||
of the patterns will not be compressed during transfer.
|
||||
|
||||
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb)
|
||||
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
|
||||
|
||||
enddit()
|
||||
|
||||
|
||||
108
util.c
108
util.c
@@ -26,24 +26,78 @@
|
||||
|
||||
extern int verbose;
|
||||
|
||||
/* create a file descriptor - like pipe() but use socketpair if
|
||||
possible (because of blocking issues on pipes */
|
||||
int fd_pair(int fd[2])
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into nonblocking mode
|
||||
****************************************************************************/
|
||||
void set_nonblocking(int fd)
|
||||
{
|
||||
#if HAVE_SOCKETPAIR
|
||||
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
#else
|
||||
return pipe(fd);
|
||||
#endif
|
||||
int val;
|
||||
|
||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
return;
|
||||
if (!(val & NONBLOCK_FLAG)) {
|
||||
val |= NONBLOCK_FLAG;
|
||||
fcntl(fd, F_SETFL, val);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into blocking mode
|
||||
****************************************************************************/
|
||||
void set_blocking(int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
return;
|
||||
if (val & NONBLOCK_FLAG) {
|
||||
val &= ~NONBLOCK_FLAG;
|
||||
fcntl(fd, F_SETFL, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* this is taken from CVS */
|
||||
/* create a file descriptor pair - like pipe() but use socketpair if
|
||||
possible (because of blocking issues on pipes)
|
||||
|
||||
always set non-blocking
|
||||
*/
|
||||
int fd_pair(int fd[2])
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if HAVE_SOCKETPAIR
|
||||
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
#else
|
||||
ret = pipe(fd);
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
set_nonblocking(fd[0]);
|
||||
set_nonblocking(fd[1]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* this is derived from CVS code
|
||||
|
||||
note that in the child STDIN is set to blocking and STDOUT
|
||||
is set to non-blocking. This is necessary as rsh relies on stdin being blocking
|
||||
and ssh relies on stdout being non-blocking
|
||||
|
||||
if blocking_io is set then use blocking io on both fds. That can be
|
||||
used to cope with badly broken rsh implementations like the one on
|
||||
solaris.
|
||||
*/
|
||||
int piped_child(char **command,int *f_in,int *f_out)
|
||||
{
|
||||
int pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int blocking_io;
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 ||
|
||||
fd_pair(from_child_pipe) < 0) {
|
||||
@@ -71,6 +125,10 @@ int piped_child(char **command,int *f_in,int *f_out)
|
||||
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
|
||||
umask(orig_umask);
|
||||
set_blocking(STDIN_FILENO);
|
||||
if (blocking_io) {
|
||||
set_blocking(STDOUT_FILENO);
|
||||
}
|
||||
execvp(command[0], command);
|
||||
rprintf(FERROR,"Failed to exec %s : %s\n",
|
||||
command[0],strerror(errno));
|
||||
@@ -883,3 +941,35 @@ void wait_process(pid_t pid, int *status)
|
||||
waitpid(pid, status, 0);
|
||||
*status = WEXITSTATUS(*status);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __INSURE__
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*******************************************************************
|
||||
This routine is a trick to immediately catch errors when debugging
|
||||
with insure. A xterm with a gdb is popped up when insure catches
|
||||
a error. It is Linux specific.
|
||||
********************************************************************/
|
||||
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
|
||||
{
|
||||
static int (*fn)();
|
||||
int ret;
|
||||
char cmd[1024];
|
||||
|
||||
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) {
|
||||
static void *h;
|
||||
h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
|
||||
fn = dlsym(h, "_Insure_trap_error");
|
||||
}
|
||||
|
||||
ret = fn(a1, a2, a3, a4, a5, a6);
|
||||
|
||||
system(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user