int restore( FILE *file, const char *filename) { char *path_p; struct stat stat; uid_t uid; gid_t gid; seq_t seq = NULL; int line = 0, backup_line; int error, status = 0; memset(&stat, 0, sizeof(stat)); for(;;) { backup_line = line; error = read_acl_comments(file, &line, &path_p, &uid, &gid); if (error < 0) goto fail; if (error == 0) return 0; if (path_p == NULL) { if (filename) { fprintf(stderr, _("%s: %s: No filename found " "in line %d, aborting\n"), progname, xquote(filename), backup_line); } else { fprintf(stderr, _("%s: No filename found in " "line %d of standard input, " "aborting\n"), progname, backup_line); } goto getout; } if (!(seq = seq_init())) goto fail; if (seq_append_cmd(seq, CMD_REMOVE_ACL, ACL_TYPE_ACCESS) || seq_append_cmd(seq, CMD_REMOVE_ACL, ACL_TYPE_DEFAULT)) goto fail; error = read_acl_seq(file, seq, CMD_ENTRY_REPLACE, SEQ_PARSE_WITH_PERM | SEQ_PARSE_NO_RELATIVE | SEQ_PARSE_DEFAULT | SEQ_PARSE_MULTI, &line, NULL); if (error != 0) { fprintf(stderr, _("%s: %s: %s in line %d\n"), progname, xquote(filename), strerror(errno), line); goto getout; } error = lstat(path_p, &stat); if (opt_test && error != 0) { fprintf(stderr, "%s: %s: %s\n", progname, xquote(path_p), strerror(errno)); status = 1; } stat.st_uid = uid; stat.st_gid = gid; error = do_set(path_p, &stat, seq); if (error != 0) { status = 1; goto resume; } if (!opt_test && (uid != ACL_UNDEFINED_ID || gid != ACL_UNDEFINED_ID)) { if (chown(path_p, uid, gid) != 0) { fprintf(stderr, _("%s: %s: Cannot change " "owner/group: %s\n"), progname, xquote(path_p), strerror(errno)); status = 1; } } resume: if (path_p) { free(path_p); path_p = NULL; } if (seq) { seq_free(seq); seq = NULL; } } getout: if (path_p) { free(path_p); path_p = NULL; } if (seq) { seq_free(seq); seq = NULL; } return status; fail: fprintf(stderr, "%s: %s: %s\n", progname, xquote(filename), strerror(errno)); status = 1; goto getout; }
int restore( FILE *file, const char *filename) { char *path_p; struct stat st; uid_t uid; gid_t gid; mode_t mask, flags; struct do_set_args args = { }; int line = 0, backup_line; int error, status = 0; int chmod_required = 0; memset(&st, 0, sizeof(st)); for(;;) { backup_line = line; error = read_acl_comments(file, &line, &path_p, &uid, &gid, &flags); if (error < 0) { error = -error; goto fail; } if (error == 0) return status; if (path_p == NULL) { if (filename) { fprintf(stderr, _("%s: %s: No filename found " "in line %d, aborting\n"), progname, xquote(filename, "\n\r"), backup_line); } else { fprintf(stderr, _("%s: No filename found in " "line %d of standard input, " "aborting\n"), progname, backup_line); } status = 1; goto getout; } if (!(args.seq = seq_init())) goto fail_errno; if (seq_append_cmd(args.seq, CMD_REMOVE_ACL, ACL_TYPE_ACCESS) || seq_append_cmd(args.seq, CMD_REMOVE_ACL, ACL_TYPE_DEFAULT)) goto fail_errno; error = read_acl_seq(file, args.seq, CMD_ENTRY_REPLACE, SEQ_PARSE_WITH_PERM | SEQ_PARSE_DEFAULT | SEQ_PARSE_MULTI, &line, NULL); if (error != 0) { fprintf(stderr, _("%s: %s: %s in line %d\n"), progname, xquote(filename, "\n\r"), strerror(errno), line); status = 1; goto getout; } error = stat(path_p, &st); if (opt_test && error != 0) { fprintf(stderr, "%s: %s: %s\n", progname, xquote(path_p, "\n\r"), strerror(errno)); status = 1; } args.mode = 0; error = do_set(path_p, &st, 0, &args); if (error != 0) { status = 1; goto resume; } if (uid != ACL_UNDEFINED_ID && uid != st.st_uid) st.st_uid = uid; else st.st_uid = -1; if (gid != ACL_UNDEFINED_ID && gid != st.st_gid) st.st_gid = gid; else st.st_gid = -1; if (!opt_test && (st.st_uid != -1 || st.st_gid != -1)) { if (chown(path_p, st.st_uid, st.st_gid) != 0) { fprintf(stderr, _("%s: %s: Cannot change " "owner/group: %s\n"), progname, xquote(path_p, "\n\r"), strerror(errno)); status = 1; } /* chown() clears setuid/setgid so force a chmod if * S_ISUID/S_ISGID was expected */ if ((st.st_mode & flags) & (S_ISUID | S_ISGID)) chmod_required = 1; } mask = S_ISUID | S_ISGID | S_ISVTX; if (chmod_required || ((st.st_mode & mask) != (flags & mask))) { if (!args.mode) args.mode = st.st_mode; args.mode &= (S_IRWXU | S_IRWXG | S_IRWXO); if (chmod(path_p, flags | args.mode) != 0) { fprintf(stderr, _("%s: %s: Cannot change " "mode: %s\n"), progname, xquote(path_p, "\n\r"), strerror(errno)); status = 1; } } resume: if (path_p) { free(path_p); path_p = NULL; } if (args.seq) { seq_free(args.seq); args.seq = NULL; } } getout: if (path_p) { free(path_p); path_p = NULL; } if (args.seq) { seq_free(args.seq); args.seq = NULL; } return status; fail_errno: error = errno; fail: fprintf(stderr, "%s: %s: %s\n", progname, xquote(filename, "\n\r"), strerror(error)); status = 1; goto getout; }