static int tar_set_file_perms(TAR *t, char *realname) { mode_t mode; uid_t uid; gid_t gid; struct utimbuf ut; char *filename; filename = (realname ? realname : th_get_pathname(t)); mode = th_get_mode(t); uid = th_get_uid(t); gid = th_get_gid(t); ut.modtime = ut.actime = th_get_mtime(t); /* change owner/group */ if (geteuid() == 0) #ifdef HAVE_LCHOWN if (lchown(filename, uid, gid) == -1) { # ifdef DEBUG fprintf(stderr, "lchown(\"%s\", %d, %d): %s\n", filename, uid, gid, strerror(errno)); # endif #else /* ! HAVE_LCHOWN */ if (!TH_ISSYM(t) && chown(filename, uid, gid) == -1) { # ifdef DEBUG fprintf(stderr, "chown(\"%s\", %d, %d): %s\n", filename, uid, gid, strerror(errno)); # endif #endif /* HAVE_LCHOWN */ return -1; } /* change access/modification time */ if (!TH_ISSYM(t) && utime(filename, &ut) == -1) { #ifdef DEBUG perror("utime()"); #endif return -1; } /* change permissions */ if (!TH_ISSYM(t) && chmod(filename, mode) == -1) { #ifdef DEBUG perror("chmod()"); #endif return -1; } return 0; } /* switchboard */ int tar_extract_file(TAR *t, char *realname) { int i; char *lnp; int pathname_len; int realname_len; if (t->options & TAR_NOOVERWRITE) { struct stat s; if (lstat(realname, &s) == 0 || errno != ENOENT) { errno = EEXIST; return -1; } } if (TH_ISDIR(t)) { i = tar_extract_dir(t, realname); if (i == 1) i = 0; } else if (TH_ISLNK(t)) i = tar_extract_hardlink(t, realname); else if (TH_ISSYM(t)) i = tar_extract_symlink(t, realname); else if (TH_ISCHR(t)) i = tar_extract_chardev(t, realname); else if (TH_ISBLK(t)) i = tar_extract_blockdev(t, realname); else if (TH_ISFIFO(t)) i = tar_extract_fifo(t, realname); else /* if (TH_ISREG(t)) */ i = tar_extract_regfile(t, realname); if (i != 0) return i; i = tar_set_file_perms(t, realname); if (i != 0) return i; pathname_len = strlen(th_get_pathname(t)) + 1; realname_len = strlen(realname) + 1; lnp = (char *)calloc(1, pathname_len + realname_len); if (lnp == NULL) return -1; strcpy(&lnp[0], th_get_pathname(t)); strcpy(&lnp[pathname_len], realname); #ifdef DEBUG printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", " "value=\"%s\"\n", th_get_pathname(t), realname); #endif if (libtar_hash_add(t->h, lnp) != 0) return -1; return 0; }
static int tar_set_file_perms(TAR *t, char *realname) { mode_t mode; uid_t uid; gid_t gid; struct utimbuf ut; char *filename; filename = (realname ? realname : th_get_pathname(t)); mode = th_get_mode(t); uid = th_get_uid(t); gid = th_get_gid(t); ut.modtime = ut.actime = th_get_mtime(t); #ifdef DEBUG printf(" ==> setting perms: %s (mode %04o, uid %d, gid %d)\n", filename, mode, uid, gid); #endif /* change owner/group */ if (geteuid() == 0) #ifdef HAVE_LCHOWN if (lchown(filename, uid, gid) == -1) { # ifdef DEBUG fprintf(stderr, "lchown(\"%s\", %d, %d): %s\n", filename, uid, gid, strerror(errno)); # endif #else /* ! HAVE_LCHOWN */ if (!TH_ISSYM(t) && chown(filename, uid, gid) == -1) { # ifdef DEBUG fprintf(stderr, "chown(\"%s\", %d, %d): %s\n", filename, uid, gid, strerror(errno)); # endif #endif /* HAVE_LCHOWN */ return -1; } /* change access/modification time */ if (!TH_ISSYM(t) && utime(filename, &ut) == -1) { #ifdef DEBUG perror("utime()"); #endif return -1; } /* change permissions */ if (!TH_ISSYM(t) && chmod(filename, mode) == -1) { #ifdef DEBUG perror("chmod()"); #endif return -1; } return 0; } /* switchboard */ int tar_extract_file(TAR *t, char *realname, char *prefix, const int *progress_fd) { int i; char *lnp; int pathname_len; int realname_len; if (t->options & TAR_NOOVERWRITE) { struct stat s; if (lstat(realname, &s) == 0 || errno != ENOENT) { errno = EEXIST; return -1; } } if (TH_ISDIR(t)) { printf("dir\n"); i = tar_extract_dir(t, realname); if (i == 1) i = 0; } else if (TH_ISLNK(t)) { printf("link\n"); i = tar_extract_hardlink(t, realname, prefix); } else if (TH_ISSYM(t)) { printf("sym\n"); i = tar_extract_symlink(t, realname); } else if (TH_ISCHR(t)) { printf("chr\n"); i = tar_extract_chardev(t, realname); } else if (TH_ISBLK(t)) { printf("blk\n"); i = tar_extract_blockdev(t, realname); } else if (TH_ISFIFO(t)) { printf("fifo\n"); i = tar_extract_fifo(t, realname); } else /* if (TH_ISREG(t)) */ { printf("reg\n"); i = tar_extract_regfile(t, realname, progress_fd); } if (i != 0) { printf("FAILED RESTORE OF FILE i: %s\n", realname); return i; } i = tar_set_file_perms(t, realname); if (i != 0) { printf("FAILED SETTING PERMS: %d\n", i); return i; } #ifdef HAVE_SELINUX if((t->options & TAR_STORE_SELINUX) && t->th_buf.selinux_context != NULL) { #ifdef DEBUG printf(" Restoring SELinux context %s to file %s\n", t->th_buf.selinux_context, realname); #endif if (lsetfilecon(realname, t->th_buf.selinux_context) < 0) { fprintf(stderr, "Failed to restore SELinux context %s!\n", strerror(errno)); } } #endif /* pathname_len = strlen(th_get_pathname(t)) + 1; realname_len = strlen(realname) + 1; lnp = (char *)calloc(1, pathname_len + realname_len); if (lnp == NULL) return -1; strcpy(&lnp[0], th_get_pathname(t)); strcpy(&lnp[pathname_len], realname); #ifdef DEBUG printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", " "value=\"%s\"\n", th_get_pathname(t), realname); #endif if (libtar_hash_add(t->h, lnp) != 0) return -1; free(lnp); */ return 0; }