static int list(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { print_file(f); } xar_iter_free(i); xar_close(x); return Err; }
int main(int argc, char *argv[]) { char *file = argv[1]; xar_t x; xar_iter_t ifile, iprop, iattr; xar_file_t f; const char *key; int fd; off_t off; xar_header_t hdr; x = xar_open(file, READ); if( !x ) { fprintf(stderr, "Error opening archive\n"); exit(1); } fd = open(file, O_RDONLY); if( fd < 0 ) { fprintf(stderr, "Error opening archive\n"); exit(1); } read(fd, &hdr, sizeof(hdr)); hdr.size = htons(hdr.size); hdr.toc_length_compressed = xar_ntoh64(hdr.toc_length_compressed); HeapOff = hdr.size + hdr.toc_length_compressed; ifile = xar_iter_new(); if( !ifile ) { fprintf(stderr, "Error creating file iterator"); exit(1); } for(f = xar_file_first(x, ifile); f; f = xar_file_next(ifile)) { prop_check(fd, x, f); } }
int pkg_toc_process(const char *path, const char *toc) { u_int32_t pkgid; xar_t x; xar_iter_t i; xar_file_t f; struct vfs_fake_stat sb; if (!(x = xar_open(path, READ))) { Log(LOG_ERROR, "failed opening package %s", path); return EXIT_FAILURE; } xar_register_errhandler(x, pkg_xar_err_callback, NULL); if (!(i = xar_iter_new())) { Log(LOG_ERROR, "failed getting new xar iter in pkg %s", path); return EXIT_FAILURE; } db_pkg_remove(path); pkgid = db_pkg_add(path); fprintf(stderr, "id: %d\n", pkgid); for (f = xar_file_first(x, i); f; f = xar_file_next(i)) { char *size = xar_get_size(x, f); char *xpath = xar_get_path(f); char *xtype = xar_get_type(x, f); char *mode = xar_get_mode(x, f); char *user = xar_get_owner(x, f); char *group = xar_get_group(x, f); char *mtime = xar_get_mtime(x, f); const char *offset; char type = 'u'; /* * (f)ile, (d)irectory, (l)ink, (p)ipe * f(i)fo, (c)haracter, (b)lock, (s)ocket, * (u)ndefined */ if (!strcasecmp(xtype, "file")) { xar_prop_get(f, "data/offset", &offset); type = 'f'; } else { offset = "0"; if (!strcasecmp(xtype, "directory")) type = 'd'; else if (!strcasecmp(xtype, "hardlink")) type = 'l'; else if (!strcasecmp(xtype, "symlink")) type = 'l'; } #if 0 /* * what we gonna do with target? */ printf("%s: %s %8s/%-8s %10s %s %s @ %s\n", xtype, mode, user, group, size, mtime, xpath, offset); db_query(QUERY_INT, "INSERT INTO files (package, path, type, owner, group, size, offset, ctime, mode) VALUES (%lu, '%s', '%s', %s, %s, %s, %s, %s, %s, %s);", pkgid, xpath, type, user, group, size, offset, mtime); #endif free(mtime); free(group); free(user); free(mode); free(xtype); free(xpath); free(size); } return EXIT_SUCCESS; }
std::map<std::string, std::string> Extract(std::string file, std::string prefix) { std::map<std::string, std::string> files; #ifdef HAVE_LIBXAR xar_t x; xar_iter_t xi; xar_file_t xf; xar_stream xs; char buffer[8192]; x = xar_open(file.c_str(), READ); if (x == nullptr) { std::cerr << "Could not open xar archive" << std::endl; } xi = xar_iter_new(); if (xi == nullptr) { xar_close(x); std::cerr << "Could not read xar archive" << std::endl; } for (xf = xar_file_first(x, xi); xf != nullptr; xf = xar_file_next(xi)) { char *path = xar_get_path(xf); const char *type; xar_prop_get(xf, "type", &type); if (type == nullptr) { std::cerr << "File has no type" << std::endl; free(path); continue; } if (std::strcmp(type, "file") != 0) { free(path); continue; } if (xar_extract_tostream_init(x, xf, &xs) != XAR_STREAM_OK) { std::cerr << "Error initializing stream" << std::endl; free(path); continue; } const std::string fileName = prefix + util::uuid::UuidToString(util::uuid::GenerateUUID()); // Write bitcode to file std::FILE *output = std::fopen(fileName.c_str(), "wb"); if (output == nullptr) { std::cerr << "Error opening output file" << std::endl; continue; } xs.avail_out = sizeof(buffer); xs.next_out = buffer; int32_t ret; while ((ret = xar_extract_tostream(&xs)) != XAR_STREAM_END) { if (ret == XAR_STREAM_ERR) { std::cerr << "Error extracting stream" << std::endl; break; } std::fwrite(buffer, sizeof(char), sizeof(buffer) - xs.avail_out, output); xs.avail_out = sizeof(buffer); xs.next_out = buffer; } if (xar_extract_tostream_end(&xs) != XAR_STREAM_OK) { std::cerr << "Error ending stream" << std::endl; } std::fclose(output); // Add to list of extracted files files[std::string(path)] = fileName; free(path); } xar_iter_free(xi); xar_close(x); #endif return files; }
int main(int argc, char *argv[]) { xar_t x; xar_iter_t i; xar_file_t f; xar_stream s; char buffer[8192]; x = xar_open(argv[1], READ); if( !x ) { fprintf(stderr, "Error opening archive\n"); exit(1); } xar_register_errhandler(x, err_callback, NULL); i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { char *path; const char *type; int32_t ret; int fd; path = xar_get_path(f); xar_prop_get(f, "type", &type); if( !type ) { fprintf(stderr, "File has no type %s\n", path); free(path); continue; } if( strcmp(type, "file") != 0 ) { fprintf(stderr, "Skipping %s\n", path); free(path); continue; } fprintf(stderr, "Extracting %s\n", path); if( xar_extract_tostream_init(x, f, &s) != XAR_STREAM_OK ) { fprintf(stderr, "Error initializing stream %s\n", path); free(path); continue; } fd = open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); if( !fd ) { fprintf(stderr, "Error opening output file %s\n", path); free(path); continue; } s.avail_out = sizeof(buffer); s.next_out = buffer; while( (ret = xar_extract_tostream(&s)) != XAR_STREAM_END ) { if( ret == XAR_STREAM_ERR ) { fprintf(stderr, "Error extracting stream %s\n", path); exit(2); } write(fd, buffer, sizeof(buffer)-s.avail_out); s.avail_out = sizeof(buffer); s.next_out = buffer; } if( xar_extract_tostream_end(&s) != XAR_STREAM_OK ) { fprintf(stderr, "Error ending stream %s\n", path); } close(fd); free(path); } }
static int extract(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; int files_extracted = 0; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } xar_register_errhandler(x, err_callback, NULL); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } if ( Rsize != NULL ) { xar_opt_set(x, XAR_OPT_RSIZE, Rsize); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { int matched = 0; int exclude_match = 1; struct lnode *i; char *path = xar_get_path(f); if( args[0] ) { int i; for(i = 0; args[i]; i++) { if( strcmp(path, args[i]) == 0 ) { matched = 1; break; } } } else { matched = 1; } for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", path); free(path); continue; } if( matched ) { files_extracted++; print_file(f); xar_extract(x, f); } free(path); } if( args[0] && (files_extracted == 0) ) { fprintf(stderr, "No files matched extraction criteria.\n"); Err = 3; } if( Subdoc ) extract_subdoc(x, NULL); xar_iter_free(i); if( xar_close(x) != 0 ) { fprintf(stderr, "Error extracting the archive\n"); if( !Err ) Err = 42; } return Err; }
/* replace_sign: rip out all current signatures and certs and insert a new pair Since libxar is currently not capable of doing this directly, we have to create a new xar archive, copy all the files and options from the current archive, and sign the new archive */ static void replace_sign(const char *filename) { xar_t old_xar, new_xar; xar_signature_t sig; char *new_xar_path = (char *)malloc(15); strncpy(new_xar_path, "/tmp/xar.XXXXX", 15); new_xar_path = mktemp(new_xar_path); char *systemcall; int err; // open both archives old_xar = xar_open(filename, READ); if ( old_xar == NULL ) { fprintf(stderr, "Could not open archive %s!\n", filename); exit(1); } new_xar = xar_open(new_xar_path, WRITE); if( !new_xar ) { fprintf(stderr, "Error creating new archive %s\n", new_xar_path); exit(1); } // install new signature and new certs in new_xar sig = xar_signature_new(new_xar, "RSA", SigSize, &signingCallback, NULL); if ( LeafCertPath ) insert_cert(sig, LeafCertPath); if ( IntermediateCertPath ) insert_cert(sig, IntermediateCertPath); // copy options char *opts[6] = {XAR_OPT_TOCCKSUM, XAR_OPT_COMPRESSION, XAR_OPT_COALESCE, XAR_OPT_LINKSAME, XAR_OPT_RSIZE, XAR_OPT_OWNERSHIP}; int i; const char *opt; for (i=0; i<6; i++) { opt = xar_opt_get(old_xar, opts[i]); if (opt) xar_opt_set(new_xar, opts[i], opt); } // skip copy subdocs for now since we don't use them yet // copy files xar_iter_t iter = xar_iter_new(); xar_file_t f = xar_file_first(old_xar, iter); // xar_file_next iterates the archive depth-first, i.e. all children are enumerated before the siblings. const char *name; char *f_dirname, *stack_top_dirname; stack s_new = stack_new(); stack s_old = stack_new(); xar_file_t last_copied = NULL, last_added; xar_iter_t loopIter = xar_iter_new(); xar_file_t current_xar_file; for (current_xar_file = xar_file_first(old_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter)) { printf("old_xar -> %s (parent: %s)\n",xar_get_path(current_xar_file),XAR_FILE(current_xar_file)->parent?xar_get_path(XAR_FILE(current_xar_file)->parent):"(nil)"); } do { // parent is the parent in the new archive! // 3 cases: // 1. the file has no parent. Happens for every file at the top level of the archive. // 2. the file's parent is the last file we added. Happens while descending down a path // 3. the file's parent is one of the ancestors of the last file (and not NULL, that would be case 1) // that means we either go back up the tree and add a sibling of one of the ancestors, or we add a // sibling on the same level xar_prop_get(f, "name", &name); // filename, without any path info if (!XAR_FILE(f)->parent) { // case 1 printf("root: %s\n",xar_get_path(f)); last_added = xar_add_from_archive(new_xar, NULL, name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } else if (f->parent == last_copied) { // case 2 printf("child: %s -> %s\n",xar_get_path(f->parent),xar_get_path(f)); last_added = xar_add_from_archive(new_xar, last_added, name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } else { // case 3 printf("searching for parent: %s ?\n",xar_get_path(f)); while (XAR_FILE(f)->parent != XAR_FILE(s_old->top->data)->parent) { printf("popping: %s\n",xar_get_path(XAR_FILE(s_old->top->data))); stack_pop(s_new); stack_pop(s_old); } printf("found: %s -> %s\n",xar_get_path(XAR_FILE(s_new->top->data)),xar_get_path(f)); stack_pop(s_new); stack_pop(s_old); last_added = xar_add_from_archive(new_xar, (xar_file_t)(s_new->top->data), name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } } while (f = xar_file_next(iter)); loopIter = xar_iter_new(); for (current_xar_file = xar_file_first(new_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter)) { char * current_path = xar_get_path(current_xar_file); printf("new_xar -> %s\n",current_path); } xar_iter_free(iter); stack_free(s_new); stack_free(s_old); if( xar_close(new_xar) != 0 ) { fprintf(stderr, "Error creating the archive\n"); if( !Err ) Err = 42; } xar_close(old_xar); // write signature offset to file (have to re-open so xar_close can figure out the correct offset) new_xar = xar_open(new_xar_path, READ); if( !new_xar ) { fprintf(stderr, "Error re-opening new archive %s\n", new_xar_path); unlink(new_xar_path); exit(1); } if (extract_sig_offset(new_xar, SigOffsetDumpPath)) { xar_close(new_xar); unlink(new_xar_path); exit(1); } xar_close(new_xar); // delete old archive, move new in its place unlink(filename); asprintf(&systemcall, "cp \"%s\" \"%s\"", new_xar_path, filename); err = system(systemcall); if (err) { fprintf(stderr, "Could not copy new archive to final location (system() returned %i)\n", err); unlink(new_xar_path); exit(1); } // Delete the tmp archive unlink(new_xar_path); free(systemcall); }
static int list(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; int argi = 0; struct lnode *list_files = NULL; struct lnode *list_tail = NULL; struct lnode *lnodei = NULL; for(argi = 0; args[argi]; argi++) { struct lnode *tmp; int err; tmp = malloc(sizeof(struct lnode)); tmp->str = strdup(args[argi]); tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( list_files == NULL ) { list_files = tmp; list_tail = tmp; } else { list_tail->next = tmp; list_tail = tmp; } } x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { int matched = 0; if( args[0] ) { char *path = xar_get_path(f); if (xar_path_issane(path) == 0) { fprintf(stderr, "Warning, archive contains invalid path: %s\n", path); free(path); continue; } for(lnodei = list_files; lnodei != NULL; lnodei = lnodei->next) { int list_match = 1; list_match = regexec(&lnodei->reg, path, 0, NULL, 0); if( !list_match ) { matched = 1; break; } } free(path); } else { matched = 1; } if( matched ) print_file(x, f); } xar_iter_free(i); xar_close(x); for(lnodei = list_files; lnodei != NULL; ) { struct lnode *tmp; free(lnodei->str); regfree(&lnodei->reg); tmp = lnodei; lnodei = lnodei->next; free(tmp); } return Err; }
static int extract(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; int files_extracted = 0; int argi; struct lnode *extract_files = NULL; struct lnode *extract_tail = NULL; struct lnode *lnodei = NULL; struct lnode *dirs = NULL; for(argi = 0; args[argi]; argi++) { struct lnode *tmp; int err; tmp = malloc(sizeof(struct lnode)); tmp->str = strdup(args[argi]); tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( extract_files == NULL ) { extract_files = tmp; extract_tail = tmp; } else { extract_tail->next = tmp; extract_tail = tmp; } /* Add a clause for recursive extraction */ tmp = malloc(sizeof(struct lnode)); asprintf(&tmp->str, "%s/.*", args[argi]); tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( extract_files == NULL ) { extract_files = tmp; extract_tail = tmp; } else { extract_tail->next = tmp; extract_tail = tmp; } } x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } if(Chdir) { if( chdir(Chdir) != 0 ) { fprintf(stderr, "Unable to chdir to %s\n", Chdir); exit(1); } } xar_register_errhandler(x, err_callback, NULL); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } if ( Rsize != NULL ) { xar_opt_set(x, XAR_OPT_RSIZE, Rsize); } if( SaveSuid ) { xar_opt_set(x, XAR_OPT_SAVESUID, XAR_OPT_VAL_TRUE); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { int matched = 0; int exclude_match = 1; struct lnode *i; char *path = xar_get_path(f); if( args[0] ) { for(i = extract_files; i != NULL; i = i->next) { int extract_match = 1; extract_match = regexec(&i->reg, path, 0, NULL, 0); if( !extract_match ) { matched = 1; break; } } } else { matched = 1; } for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", path); free(path); continue; } if (!xar_path_issane(path)) { if (Verbose) printf("Warning, not extracting file \"%s\" because it's path is invalid.\n", path); free(path); continue; } if( matched ) { struct stat sb; if( NoOverwrite && (lstat(path, &sb) == 0) ) { printf("%s already exists, not overwriting\n", path); } else { const char *prop = NULL; int deferred = 0; if( xar_prop_get(f, "type", &prop) == 0 ) { if( strcmp(prop, "directory") == 0 ) { struct lnode *tmpl = calloc(sizeof(struct lnode),1); tmpl->str = (char *)f; tmpl->next = dirs; dirs = tmpl; deferred = 1; } } if( ! deferred ) { files_extracted++; print_file(x, f); xar_extract(x, f); } } } free(path); } for(lnodei = dirs; lnodei; lnodei = lnodei->next) { files_extracted++; print_file(x,(xar_file_t)lnodei->str); xar_extract(x, (xar_file_t)lnodei->str); } if( args[0] && (files_extracted == 0) ) { fprintf(stderr, "No files matched extraction criteria.\n"); Err = 3; } if( Subdoc ) extract_subdoc(x, NULL); xar_iter_free(i); if( xar_close(x) != 0 ) { fprintf(stderr, "Error extracting the archive\n"); if( !Err ) Err = 42; } for(lnodei = extract_files; lnodei != NULL; ) { struct lnode *tmp; free(lnodei->str); regfree(&lnodei->reg); tmp = lnodei; lnodei = lnodei->next; free(tmp); } return Err; }