+
+#define SC_CHECKSUM_CHANGED (1<<0)
+#define SC_UPDATING (1<<1)
+#define SC_NO_DEST_AND_NO_UPDATE (1<<2)
+#define SC_SKIP_NL (1<<3)
+
+static void showchg(const char *fname, struct file_struct *file, int statret,
+ STRUCT_STAT *st, int flags)
+{
+ static char ch[] = "*Xcstpog";
+ int keep_time;
+ char *s;
+
+ ch[0] = flags & SC_UPDATING ? '*' : ' ';
+ ch[1] = S_ISDIR(file->mode) ? 'd' : IS_DEVICE(file->mode) ? 'D'
+ : S_ISLNK(file->mode) ? 'L' : 'f';
+
+ if (statret < 0) {
+ for (s = ch + 2; *s; ) *s++ = '+';
+ goto print_it;
+ }
+
+ keep_time = !preserve_times ? 0
+ : S_ISDIR(file->mode) ? !omit_dir_times : !S_ISLNK(file->mode);
+
+ ch[2] = !(flags & SC_CHECKSUM_CHANGED) ? '-' : 'c';
+ ch[3] = !S_ISREG(file->mode) || file->length == st->st_size ? '-' : 's';
+ ch[4] = flags & SC_UPDATING && !keep_time ? 'T'
+ : !keep_time || file->modtime == st->st_mtime ? '-' : 't';
+ ch[5] = !preserve_perms || file->mode == st->st_mode ? '-' : 'p';
+ ch[6] = !am_root || !preserve_uid || file->uid == st->st_uid ? '-' : 'o';
+ ch[7] = preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid ? 'g' : '-';
+
+ if (flags & SC_NO_DEST_AND_NO_UPDATE)
+ ch[4] = ch[5] = ch[6] = ch[7] = '-';
+
+ if (!(flags & SC_UPDATING)) {
+ for (s = ch + 2; *s == '-'; s++) {}
+ if (!*s)
+ return;
+ }
+
+ print_it:
+ rprintf(FINFO, "%s %s%s%s", ch, safe_fname(fname),
+ ch[1] == 'd' ? "/" : "",
+ flags & SC_SKIP_NL ? "" : "\n");
+}
+
+