- char *p;
- char cleaned_name[MAXPATHLEN];
- char linkbuf[MAXPATHLEN];
- extern int delete_excluded;
-
- strlcpy(cleaned_name, fname, MAXPATHLEN);
- cleaned_name[MAXPATHLEN-1] = 0;
- clean_fname(cleaned_name);
- if (sanitize_paths) {
- sanitize_path(cleaned_name, NULL);
+ char thisname[MAXPATHLEN];
+ char linkname[MAXPATHLEN];
+ int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
+ char *basename, *dirname, *bp;
+ unsigned short flags = 0;
+
+ if (!flist || !flist->count) /* Ignore lastdir when invalid. */
+ lastdir_len = -1;
+
+ if (strlcpy(thisname, fname, sizeof thisname)
+ >= sizeof thisname - flist_dir_len) {
+ rprintf(FINFO, "skipping overly long name: %s\n",
+ safe_fname(fname));
+ return NULL;
+ }
+ clean_fname(thisname, 0);
+ if (sanitize_paths)
+ sanitize_path(thisname, thisname, "", 0);
+
+ memset(sum, 0, SUM_LENGTH);
+
+ if (readlink_stat(thisname, &st, linkname) != 0) {
+ int save_errno = errno;
+ /* See if file is excluded before reporting an error. */
+ if (filter_level != NO_FILTERS
+ && is_excluded(thisname, 0, filter_level))
+ return NULL;
+ if (save_errno == ENOENT) {
+#ifdef SUPPORT_LINKS
+ /* Avoid "vanished" error if symlink points nowhere. */
+ if (copy_links && do_lstat(thisname, &st) == 0
+ && S_ISLNK(st.st_mode)) {
+ io_error |= IOERR_GENERAL;
+ rprintf(FERROR, "symlink has no referent: %s\n",
+ full_fname(thisname));
+ } else
+#endif
+ {
+ enum logcode c = am_daemon && protocol_version < 28
+ ? FERROR : FINFO;
+ io_error |= IOERR_VANISHED;
+ rprintf(c, "file has vanished: %s\n",
+ full_fname(thisname));
+ }
+ } else {
+ io_error |= IOERR_GENERAL;
+ rsyserr(FERROR, save_errno, "readlink %s failed",
+ full_fname(thisname));
+ }
+ return NULL;