int tar_extract_all(TAR *t, char *prefix) { char *filename; char buf[MAXPATHLEN]; int i; #ifdef TAR_DEBUG printf("==> tar_extract_all(TAR *t, \"%s\")\n", (prefix ? prefix : "(null)")); #endif while ((i = th_read(t)) == 0) { #ifdef TAR_DEBUG puts(" tar_extract_all(): calling th_get_pathname()"); #endif filename = th_get_pathname(t); if (t->options & TAR_VERBOSE) th_print_long_ls(t); if (prefix != NULL) snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); else strlcpy(buf, filename, sizeof(buf)); #ifdef TAR_DEBUG printf(" tar_extract_all(): calling tar_extract_file(t, " "\"%s\")\n", buf); #endif if (tar_extract_file(t, buf) != 0) return -1; } return (i == 1 ? 0 : -1); }
int tar_extract_glob(TAR *t, char *globname, char *prefix) { char *filename; char buf[MAXPATHLEN]; int i; while ((i = th_read(t)) == 0) { filename = th_get_pathname(t); if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD)) { if (TH_ISREG(t) && tar_skip_regfile(t)) return -1; continue; } if (t->options & TAR_VERBOSE) th_print_long_ls(t); if (prefix != NULL) snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); else strlcpy(buf, filename, sizeof(buf)); if (tar_extract_file(t, filename) != 0) return -1; } return (i == 1 ? 0 : -1); }
static int par_list(char *file) { PAR *t; int i; if (par_open(&t, file, 1, O_RDONLY, 0, 0) == -1) { fprintf(stderr, "tar_open(): %s\n", strerror(errno)); return -1; } if (par_read_header(t) != 0) { fprintf(stderr, "par_read_header(): %s\n", strerror(errno)); par_close(t); return -1; } while ((i = th_read(t)) == 0) { th_print_long_ls(t); #ifdef DEBUG th_print(t); #endif if (TH_ISREG(t) && par_skip_regfile(t) != 0) { fprintf(stderr, "tar_skip_regfile(): %s\n", strerror(errno)); return -1; } } if (par_close(t) != 0) { fprintf(stderr, "tar_close(): %s\n", strerror(errno)); return -1; } return 0; }
static int list(char *tarfile) { TAR *t; int i; if (tar_open(&t, tarfile, #ifdef HAVE_LIBZ (use_zlib ? &gztype : NULL), #else NULL, #endif O_RDONLY, 0, (verbose ? TAR_VERBOSE : 0) | (use_gnu ? TAR_GNU : 0)) == -1) { fprintf(stderr, "tar_open(): %s\n", strerror(errno)); return -1; } while ((i = th_read(t)) == 0) { th_print_long_ls(t); #ifdef DEBUG th_print(t); #endif if (TH_ISREG(t) && tar_skip_regfile(t) != 0) { fprintf(stderr, "tar_skip_regfile(): %s\n", strerror(errno)); return -1; } } #ifdef DEBUG printf("th_read() returned %d\n", i); printf("EOF mark encountered after %ld bytes\n", # ifdef HAVE_LIBZ (use_zlib ? gzseek((gzFile) t->fd, 0, SEEK_CUR) : # endif lseek(t->fd, 0, SEEK_CUR) # ifdef HAVE_LIBZ ) # endif ); #endif if (tar_close(t) != 0) { fprintf(stderr, "tar_close(): %s\n", strerror(errno)); return -1; } (void)i; return 0; }
static int do_delete(struct dirent *d) { int ret; struct stat sb; char realname[PATH_MAX]; char savename[PATH_MAX]; sprintf(realname, "%s%s/%s", base1, prefix, d->d_name); sprintf(savename, "%s%s/%s", "delete", prefix, d->d_name); if(d->d_type == DT_DIR) { DIR *dir; struct dirent *dp; int len = strlen(prefix); strcat(prefix, "/"); strcat(prefix, d->d_name); dir = opendir(realname); while ((dp = readdir(dir)) != NULL) { if (!filter(dp)) continue; do_delete(dp); } prefix[len] = 0; } fprintf(stderr, "%s/%s was deleted\n", prefix, d->d_name); if(!t) return 0; ret = lstat(realname, &sb); th_set_from_stat(t, &sb); th_set_path(t, savename); th_set_size(t, 0); th_finish(t); if(t->options & TAR_VERBOSE) th_print_long_ls(t); th_write(t); }
static int do_diff(struct dirent *d1, struct dirent *d2) { int ret; struct stat sb; char realname1[PATH_MAX]; char realname2[PATH_MAX]; char savename[PATH_MAX]; //char cmd[4096]; fprintf(stderr, "%s/%s differs\n", prefix, d1->d_name); if(!t) return 0; sprintf(realname1, "%s%s/%s", base1, prefix, d1->d_name); sprintf(realname2, "%s%s/%s", base2, prefix, d2->d_name); sprintf(savename, "%s%s/%s", "diff", prefix, d1->d_name); //sprintf(cmd, "cp %s patch", realname2); //sprintf(cmd, "/home/stephan/rdiff %s %s patch", realname1, realname2); //sprintf(cmd, "/usr/bin/xdelta3 -e -s %s %s patch", realname1, realname2); //sprintf(cmd, "/usr/bin/xdelta3 -e -S djw -9 -s %s %s patch", realname1, realname2); //sprintf(cmd, "/usr/bin/bsdiff %s %s patch", realname1, realname2); //sprintf(cmd, "/home/stephan/src/fsdiff/bsdiff %s %s patch", realname1, realname2); //system(cmd); bsdiff(realname1, realname2, "patch"); ret = lstat(realname2, &sb); th_set_from_stat(t, &sb); th_set_path(t, savename); ret = lstat("patch", &sb); th_set_size(t, sb.st_size); th_finish(t); if(t->options & TAR_VERBOSE) th_print_long_ls(t); th_write(t); tar_append_regfile(t, "patch"); //system("rm patch"); unlink("patch"); }
/* appends a file to the tar archive */ int tar_append_file(TAR *t, char *realname, char *savename) { struct stat s; int i; libtar_hashptr_t hp; tar_dev_t *td = NULL; tar_ino_t *ti = NULL; char path[MAXPATHLEN]; #ifdef DEBUG printf("==> tar_append_file(TAR=0x%lx (\"%s\"), realname=\"%s\", " "savename=\"%s\")\n", t, t->pathname, realname, (savename ? savename : "[NULL]")); #endif if (lstat(realname, &s) != 0) { #ifdef DEBUG perror("lstat()"); #endif return -1; } /* set header block */ #ifdef DEBUG puts(" tar_append_file(): setting header block..."); #endif memset(&(t->th_buf), 0, sizeof(struct tar_header)); th_set_from_stat(t, &s); /* set the header path */ #ifdef DEBUG puts(" tar_append_file(): setting header path..."); #endif th_set_path(t, (savename ? savename : realname)); #ifdef HAVE_SELINUX /* get selinux context */ if(t->options & TAR_STORE_SELINUX) { if(t->th_buf.selinux_context != NULL) { free(t->th_buf.selinux_context); t->th_buf.selinux_context = NULL; } security_context_t selinux_context = NULL; if (lgetfilecon(realname, &selinux_context) >= 0) { t->th_buf.selinux_context = strdup(selinux_context); printf("setting selinux context: %s\n", selinux_context); freecon(selinux_context); } else perror("Failed to get selinux context"); } #endif /* check if it's a hardlink */ #ifdef DEBUG puts(" tar_append_file(): checking inode cache for hardlink..."); #endif libtar_hashptr_reset(&hp); if (libtar_hash_getkey(t->h, &hp, &(s.st_dev), (libtar_matchfunc_t)dev_match) != 0) td = (tar_dev_t *)libtar_hashptr_data(&hp); else { #ifdef DEBUG printf("+++ adding hash for device (0x%lx, 0x%lx)...\n", major(s.st_dev), minor(s.st_dev)); #endif td = (tar_dev_t *)calloc(1, sizeof(tar_dev_t)); td->td_dev = s.st_dev; td->td_h = libtar_hash_new(256, (libtar_hashfunc_t)ino_hash); if (td->td_h == NULL) return -1; if (libtar_hash_add(t->h, td) == -1) return -1; } libtar_hashptr_reset(&hp); if (libtar_hash_getkey(td->td_h, &hp, &(s.st_ino), (libtar_matchfunc_t)ino_match) != 0) { ti = (tar_ino_t *)libtar_hashptr_data(&hp); #ifdef DEBUG printf(" tar_append_file(): encoding hard link \"%s\" " "to \"%s\"...\n", realname, ti->ti_name); #endif t->th_buf.typeflag = LNKTYPE; th_set_link(t, ti->ti_name); } else { #ifdef DEBUG printf("+++ adding entry: device (0x%lx,0x%lx), inode %ld " "(\"%s\")...\n", major(s.st_dev), minor(s.st_dev), s.st_ino, realname); #endif ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t)); if (ti == NULL) return -1; ti->ti_ino = s.st_ino; snprintf(ti->ti_name, sizeof(ti->ti_name), "%s", savename ? savename : realname); libtar_hash_add(td->td_h, ti); } /* check if it's a symlink */ if (TH_ISSYM(t)) { i = readlink(realname, path, sizeof(path)); if (i == -1) return -1; if (i >= MAXPATHLEN) i = MAXPATHLEN - 1; path[i] = '\0'; #ifdef DEBUG printf(" tar_append_file(): encoding symlink \"%s\" -> " "\"%s\"...\n", realname, path); #endif th_set_link(t, path); } /* print file info */ if (t->options & TAR_VERBOSE) th_print_long_ls(t); #ifdef DEBUG puts(" tar_append_file(): writing header"); #endif /* write header */ if (th_write(t) != 0) { #ifdef DEBUG printf("t->fd = %d\n", t->fd); #endif return -1; } #ifdef DEBUG puts(" tar_append_file(): back from th_write()"); #endif /* if it's a regular file, write the contents as well */ if (TH_ISREG(t) && tar_append_regfile(t, realname) != 0) return -1; return 0; }