Created
April 7, 2017 12:10
-
-
Save thread13/d3929856865a525093f9473e240805ea to your computer and use it in GitHub Desktop.
rsync 3.1.1 : --ignore-missing-args
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// definition | |
#line 941 options.c | |
{"delete-missing-args",0,POPT_BIT_SET, &missing_args, 2, 0, 0 }, | |
{"ignore-missing-args",0,POPT_BIT_SET, &missing_args, 1, 0, 0 }, | |
// structure definition -- just in case ) | |
#line 115 popt/popt.h | |
/** \ingroup popt | |
*/ | |
struct poptOption { | |
/*@observer@*/ /*@null@*/ | |
const char * longName; /*!< may be NULL */ | |
char shortName; /*!< may be NUL */ | |
int argInfo; | |
/*@shared@*/ /*@null@*/ | |
void * arg; /*!< depends on argInfo */ | |
int val; /*!< 0 means don't return, just update flag */ | |
/*@observer@*/ /*@null@*/ | |
const char * descrip; /*!< description for autohelp -- may be NULL */ | |
/*@observer@*/ /*@null@*/ | |
const char * argDescrip; /*!< argument description for autohelp */ | |
}; | |
// declaration | |
#line 88 --//-- | |
int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */ | |
// usage | |
#line 2275 flist.c | |
if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0 | |
|| (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode))) | |
|| (relative_paths && path_is_daemon_excluded(fbuf, 1))) { | |
if (errno != ENOENT || missing_args == 0) { | |
/* This is a transfer error, but inhibit deletion | |
* only if we might be omitting an existing file. */ | |
if (errno != ENOENT) | |
io_error |= IOERR_GENERAL; | |
rsyserr(FERROR_XFER, errno, "link_stat %s failed", | |
full_fname(fbuf)); | |
continue; | |
} else if (missing_args == 1) { | |
/* Just ignore the arg. */ | |
continue; | |
} else /* (missing_args == 2) */ { | |
/* Send the arg as a "missing" entry with | |
* mode 0, which tells the generator to delete it. */ | |
memset(&st, 0, sizeof st); | |
} | |
} | |
// | |
// now for the error: | |
// | |
// message origin | |
#line 554 rsync.c | |
if (!preserve_times | |
|| (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode)) | |
|| (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode))) | |
flags |= ATTRS_SKIP_MTIME; | |
if (!(flags & ATTRS_SKIP_MTIME) | |
&& cmp_time(sxp->st.st_mtime, file->modtime) != 0) { | |
int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode); | |
if (ret < 0) { | |
rsyserr(FERROR_XFER, errno, "failed to set times on %s", | |
full_fname(fname)); | |
goto cleanup; | |
} | |
if (ret == 0) /* ret == 1 if symlink could not be set */ | |
updated = 1; | |
else | |
file->flags |= FLAG_TIME_FAILED; | |
} | |
// 'FERROR_XFER' : definition | |
#line 223 rsync.h | |
/* Log-message categories. FLOG only goes to the log file, not the client; | |
* FCLIENT is the opposite. */ | |
enum logcode { | |
FNONE=0, /* never sent */ | |
FERROR_XFER=1, FINFO=2, /* sent over socket for any protocol */ | |
FERROR=3, FWARNING=4, /* sent over socket for protocols >= 30 */ | |
FERROR_SOCKET=5, FLOG=6, /* only sent via receiver -> generator pipe */ | |
FERROR_UTF8=8, /* only sent via receiver -> generator pipe */ | |
FCLIENT=7 /* never transmitted (e.g. server converts to FINFO) */ | |
}; | |
// NB: mentioned -- | |
#line 1235 OLDNEWS | |
- There are more internal logging categories available in protocol 30 than | |
the age-old FINFO and FERROR, including FERROR_XFER and FWARN. These new | |
categories allow some errors and warnings to go to stderr without causing | |
an erroneous end-of-run warning about some files not being able to be | |
transferred. | |
// rsyserr(FERROR_XFER) code -- calls rwrite(FERROR_XFER) | |
#line 444 log.c | |
/* This is like rprintf, but it also tries to print some | |
* representation of the error code. Normally errcode = errno. | |
* | |
* Unlike rprintf, this always adds a newline and there should not be | |
* one in the format string. | |
* | |
* Note that since strerror might involve dynamically loading a | |
* message catalog we need to call it once before chroot-ing. */ | |
void rsyserr(enum logcode code, int errcode, const char *format, ...) | |
{ | |
va_list ap; | |
char buf[BIGPATHBUFLEN]; | |
size_t len; | |
strlcpy(buf, RSYNC_NAME ": ", sizeof buf); | |
len = (sizeof RSYNC_NAME ": ") - 1; | |
va_start(ap, format); | |
len += vsnprintf(buf + len, sizeof buf - len, format, ap); | |
va_end(ap); | |
if (len < sizeof buf) { | |
len += snprintf(buf + len, sizeof buf - len, | |
": %s (%d)\n", strerror(errcode), errcode); | |
} | |
if (len >= sizeof buf) | |
exit_cleanup(RERR_MESSAGEIO); | |
rwrite(code, buf, len, 0); | |
} | |
// FERROR_XFER -- consequences | |
#line 333 log.c | |
/* this is the underlying (unformatted) rsync debugging function. Call | |
* it with FINFO, FERROR_*, FWARNING, FLOG, or FCLIENT. Note: recursion | |
* can happen with certain fatal conditions. */ | |
void rwrite(enum logcode code, const char *buf, int len, int is_utf8) | |
{ | |
// ... | |
output_msg: | |
switch (code) { | |
case FERROR_XFER: | |
got_xfer_error = 1; | |
/* FALL THROUGH */ | |
// ... | |
} | |
// 'got_xfer_error' -- consequences: | |
#line 218 cleanup.c | |
if (exit_code == 0) { | |
if (code) | |
exit_code = code; | |
if (io_error & IOERR_DEL_LIMIT) | |
exit_code = RERR_DEL_LIMIT; | |
if (io_error & IOERR_VANISHED) | |
exit_code = RERR_VANISHED; | |
if (io_error & IOERR_GENERAL || got_xfer_error) | |
exit_code = RERR_PARTIAL; | |
} | |
// 'got_xfer_error' -- alt consequences | |
#line 1424 main.c | |
static RETSIGTYPE sigusr2_handler(UNUSED(int val)) | |
{ | |
if (!am_server) | |
output_summary(); | |
close_all(); | |
if (got_xfer_error) | |
_exit(RERR_PARTIAL); | |
_exit(0); | |
} | |
// RERR_PARTIAL -- error message | |
#line 96 log.c | |
struct { | |
int code; | |
char const *name; | |
} const rerr_names[] = { | |
{ RERR_SYNTAX , "syntax or usage error" }, | |
{ RERR_PROTOCOL , "protocol incompatibility" }, | |
{ RERR_FILESELECT , "errors selecting input/output files, dirs" }, | |
{ RERR_UNSUPPORTED, "requested action not supported" }, | |
{ RERR_STARTCLIENT, "error starting client-server protocol" }, | |
{ RERR_SOCKETIO , "error in socket IO" }, | |
{ RERR_FILEIO , "error in file IO" }, | |
{ RERR_STREAMIO , "error in rsync protocol data stream" }, | |
{ RERR_MESSAGEIO , "errors with program diagnostics" }, | |
{ RERR_IPC , "error in IPC code" }, | |
{ RERR_CRASHED , "sibling process crashed" }, | |
{ RERR_TERMINATED , "sibling process terminated abnormally" }, | |
{ RERR_SIGNAL1 , "received SIGUSR1" }, | |
{ RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, | |
{ RERR_WAITCHILD , "waitpid() failed" }, | |
{ RERR_MALLOC , "error allocating core memory buffers" }, | |
{ RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" }, | |
{ RERR_VANISHED , "some files vanished before they could be transferred" }, | |
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" }, | |
{ RERR_TIMEOUT , "timeout in data send/receive" }, | |
{ RERR_CONTIMEOUT , "timeout waiting for daemon connection" }, | |
{ RERR_CMD_FAILED , "remote shell failed" }, | |
{ RERR_CMD_KILLED , "remote shell killed" }, | |
{ RERR_CMD_RUN , "remote command could not be run" }, | |
{ RERR_CMD_NOTFOUND,"remote command not found" }, | |
{ 0, NULL } | |
}; | |
// NB: '22' and "Invalid argument" in the log are coming from EINVAL | |
// RERR_PARTIAL -- definition (23) | |
#line 43 errcode.h | |
/* If you change these, please also update the string mappings in log.c and | |
* the EXIT VALUES in rsync.yo. */ | |
#define RERR_OK 0 | |
#define RERR_SYNTAX 1 /* syntax or usage error */ | |
#define RERR_PROTOCOL 2 /* protocol incompatibility */ | |
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */ | |
#define RERR_UNSUPPORTED 4 /* requested action not supported */ | |
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */ | |
#define RERR_SOCKETIO 10 /* error in socket IO */ | |
#define RERR_FILEIO 11 /* error in file IO */ | |
#define RERR_STREAMIO 12 /* error in rsync protocol data stream */ | |
#define RERR_MESSAGEIO 13 /* errors with program diagnostics */ | |
#define RERR_IPC 14 /* error in IPC code */ | |
#define RERR_CRASHED 15 /* sibling crashed */ | |
#define RERR_TERMINATED 16 /* sibling terminated abnormally */ | |
#define RERR_SIGNAL1 19 /* status returned when sent SIGUSR1 */ | |
#define RERR_SIGNAL 20 /* status returned when sent SIGINT, SIGTERM, SIGHUP */ | |
#define RERR_WAITCHILD 21 /* some error returned by waitpid() */ | |
#define RERR_MALLOC 22 /* error allocating core memory buffers */ | |
#define RERR_PARTIAL 23 /* partial transfer */ | |
#define RERR_VANISHED 24 /* file(s) vanished on sender side */ | |
#define RERR_DEL_LIMIT 25 /* skipped some deletes due to --max-delete */ | |
#define RERR_TIMEOUT 30 /* timeout in data send/receive */ | |
#define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */ | |
// | |
// Ok, now let us follow 'file->flags' logic : | |
// | |
// 'file->flags' : definition | |
#line 704 rsync.h | |
struct file_struct { | |
const char *dirname; /* The dir info inside the transfer */ | |
time_t modtime; /* When the item was last modified */ | |
uint32 len32; /* Lowest 32 bits of the file's length */ | |
uint16 mode; /* The item's type and permissions */ | |
uint16 flags; /* The FLAG_* bits for this item */ | |
const char basename[1]; /* The basename (AKA filename) follows */ | |
}; | |
// w-what does it say about symlinks? | |
#line 497 generator.c | |
void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret, | |
stat_x *sxp, int32 iflags, uchar fnamecmp_type, | |
const char *xname) | |
{ | |
if (statret >= 0) { /* A from-dest-dir statret can == 1! */ | |
int keep_time = !preserve_times ? 0 | |
: S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES | |
: S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES | |
: 1; | |
if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size) | |
iflags |= ITEM_REPORT_SIZE; | |
if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */ | |
if (iflags & ITEM_LOCAL_CHANGE) | |
iflags |= symlink_timeset_failed_flags; | |
} else if (keep_time | |
? cmp_time(file->modtime, sxp->st.st_mtime) != 0 | |
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) | |
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) | |
iflags |= ITEM_REPORT_TIME; | |
// 'symlink_timeset_failed_flags' -- declaration: | |
#line 109 generator.c | |
static int symlink_timeset_failed_flags; | |
// setting 'symlink_timeset_failed_flags' -- not too helpful | |
#line 2186 generator.c | |
void generate_files(int f_out, const char *local_name) | |
{ | |
// ... | |
loopchk_limit = allowed_lull ? allowed_lull * 5 : 200; | |
symlink_timeset_failed_flags = ITEM_REPORT_TIME | |
| (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0); | |
implied_dirs_are_missing = relative_paths && !implied_dirs && protocol_version < 30; | |
// | |
// ... and these are all the references for 'symlink_timeset_failed_flags' ? | |
// | |
// | |
// probably it goes to the logs -- somthing like this: | |
// | |
$ grep -rn 'ITEM_REPORT_TIME' * | |
generator.c:502: iflags |= ITEM_REPORT_TIME; | |
generator.c:2186: symlink_timeset_failed_flags = ITEM_REPORT_TIME | |
generator.c:2187: | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0); | |
log.c:708: c[4] = !(iflags & ITEM_REPORT_TIME) ? '.' | |
log.c:710: || (iflags & ITEM_REPORT_TIMEFAIL) ? 'T' : 't'; | |
log.c:716: c[4] = !(iflags & ITEM_REPORT_TIME) ? '.' | |
rsync.h:187:#define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */ | |
rsync.h:188:#define ITEM_REPORT_TIME (1<<3) | |
// man rsync : | |
o A t means the modification time is different | |
and is being updated to the sender’s value (requires --times). | |
An alternate value of T means that the modification | |
time will be set to the transfer time, | |
which happens when a file/symlink/device is | |
updated without --times and when a symlink is changed | |
and the receiver can’t set its time. | |
( Note: when using an rsync 3.0.0 client, | |
you might see the s flag combined with t | |
instead of the proper T flag for this time-setting failure. ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment