int tar_append_tree(TAR *t, char *realdir, char *savedir) { char realpath[MAXPATHLEN]; char savepath[MAXPATHLEN]; struct dirent *dent; DIR *dp; struct stat s; #ifdef TAR_DEBUG printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n", t, realdir, (savedir ? savedir : "[NULL]")); #endif if (tar_append_file(t, realdir, savedir) != 0) return -1; #ifdef TAR_DEBUG puts(" tar_append_tree(): done with tar_append_file()..."); #endif dp = opendir(realdir); if (dp == NULL) { if (errno == ENOTDIR) return 0; return -1; } while ((dent = readdir(dp)) != NULL) { if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, dent->d_name); if (savedir) snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, dent->d_name); if (lstat(realpath, &s) != 0) return -1; if (S_ISDIR(s.st_mode)) { if (tar_append_tree(t, realpath, (savedir ? savepath : NULL)) != 0) return -1; continue; } if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0) return -1; } closedir(dp); return 0; }
int main(int ac, const char *av[]) { struct rlimit r; unsigned count, i; char *s; TAR *t; if (ac != 2) error(1, 0, "exactly two arguments expected"); if (getrlimit(RLIMIT_STACK, &r)) error(1, errno, "getrlimit RLIMIT_STACK"); count = r.rlim_cur / 3 + 1; if (!(s = malloc(count * 3 + 1))) error(1, errno, "malloc: %u", count * 3 + 1); for (i = 0; i < count; ++i) memcpy(s + i * 3, "../", 3); s[count * 3] = '\0'; if (tar_open(&t, av[1], NULL, O_WRONLY|O_CREAT, 0644, TAR_GNU)) error(1, errno, "tar_open: %s", av[1]); if (tar_append_file(t, "/dev/null", s)) error(1, errno, "tar_append_file: %s", av[1]); if (tar_close(t)) error(1, errno, "tar_close"); return 0; }
static int do_add(struct dirent *d) { int ret; char realname[PATH_MAX]; char savename[PATH_MAX]; sprintf(realname, "%s%s/%s", base2, prefix, d->d_name); sprintf(savename, "%s%s/%s", "add", prefix, d->d_name); fprintf(stderr, "%s/%s was added\n", prefix, d->d_name); if(!t) return 0; if(d->d_type == DT_DIR) ret = tar_append_tree(t, realname, savename); else ret = tar_append_file(t, realname, savename); if(ret < 0) perror("tar_append_file"); }
int mpk_package_packmpk(struct mpk_pkginfo *pkg, const char *srcdir, const char *outdir) { TAR *tar; BZFILE *bz2; FILE *tbz2_file; int tar_fd; int bzerr; char src[PATH_MAX + 1]; char dst[PATH_MAX + 1]; char tar_fpath[PATH_MAX + 1]; char tbz2_fpath[PATH_MAX + 1]; unsigned char buffer[CHUNKSIZE]; int size; struct mpk_file *file; /* create tar */ sprintf(tar_fpath, "/tmp/%s_files.tar", pkg->name); if (access(tar_fpath, F_OK) == 0) if (unlink(tar_fpath) != 0) goto err0; if (tar_open(&tar, tar_fpath, NULL, O_WRONLY|O_CREAT, 0644, 0) != 0) goto err0; for (file = pkg->tool.lh_first; file; file = file->items.le_next) { sprintf(src, "%s/tool/%s", srcdir, file->name); sprintf(dst, "tool/%s", file->name); if (tar_append_tree(tar, src, dst) != 0) goto err2; } for (file = pkg->data.lh_first; file; file = file->items.le_next) { if (file->type == MPK_FILE_TYPE_R || file->type == MPK_FILE_TYPE_EXE || file->type == MPK_FILE_TYPE_W || file->type == MPK_FILE_TYPE_S) { sprintf(src, "%s/data/%s", srcdir, file->name); sprintf(dst, "data/%s", file->name); if (tar_append_tree(tar, src, dst) != 0) goto err2; } } sprintf(src, "%s/manifest.txt", srcdir); if (tar_append_file(tar, src, "manifest.txt") != 0) goto err2; tar_close(tar); /* compress using bz2 */ int version_str_len = mpk_version_serializedsize(&pkg->version); char *version_str; if (!(version_str = malloc(version_str_len + 1))) goto err2; if (mpk_version_serialize(version_str, NULL, version_str_len, &pkg->version) != MPK_SUCCESS) { free(version_str); goto err2; } version_str[version_str_len] = 0; sprintf(tbz2_fpath, "%s/%s-%s.mpk", outdir, pkg->name, version_str); free(version_str); printf("path:%s\n", tbz2_fpath); if ((tar_fd = open(tar_fpath, O_RDONLY)) == -1) goto err1; if ((tbz2_file = fopen(tbz2_fpath, "wb")) == NULL) goto err3; bz2 = BZ2_bzWriteOpen(&bzerr, tbz2_file, 9, 0, 30); if (bzerr != BZ_OK) goto err4; while ((size = read(tar_fd, buffer, CHUNKSIZE)) > 0) BZ2_bzWrite(&bzerr, bz2, buffer, size); BZ2_bzWriteClose(&bzerr, bz2, 0, NULL, NULL); fclose(tbz2_file); close(tar_fd); if (bzerr != BZ_OK || size < 0) goto err1; if (unlink(tar_fpath) != 0) goto err0; return MPK_SUCCESS; err4: fclose(tbz2_file); err3: close(tar_fd); goto err1; err2: tar_close(tar); err1: unlink(tar_fpath); err0: return MPK_FAILURE; }
static int create_and_upload_archive( const char *dump_dir_name, map_string_t *settings) { int result = 1; /* error */ pid_t child; TAR* tar = NULL; const char* errmsg = NULL; char* tempfile = NULL; struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) xfunc_die(); /* error msg is already logged by dd_opendir */ /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ log(_("Compressing data")); //TODO: //Encrypt = yes //ArchiveType = .tar.bz2 //ExcludeFiles = foo,bar*,b*z const char* opt = getenv("Upload_URL"); if (!opt) opt = get_map_string_item_or_empty(settings, "URL"); char *url = opt[0] != '\0' ? xstrdup(opt) : ask_url(_("Please enter a URL (scp, ftp, etc.) where the problem data is to be exported:")); /* Create a child gzip which will compress the data */ /* SELinux guys are not happy with /tmp, using /var/run/abrt */ /* Reverted back to /tmp for ABRT2 */ /* Changed again to /var/tmp because of Fedora feature tmp-on-tmpfs */ tempfile = concat_path_basename(LARGE_DATA_TMP_DIR, dump_dir_name); tempfile = append_to_malloced_string(tempfile, ".tar.gz"); int pipe_from_parent_to_child[2]; xpipe(pipe_from_parent_to_child); child = vfork(); if (child == 0) { /* child */ close(pipe_from_parent_to_child[1]); xmove_fd(pipe_from_parent_to_child[0], 0); xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); execlp("gzip", "gzip", NULL); perror_msg_and_die("Can't execute '%s'", "gzip"); } close(pipe_from_parent_to_child[0]); /* If child died (say, in xopen), then parent might get SIGPIPE. * We want to properly unlock dd, therefore we must not die on SIGPIPE: */ signal(SIGPIPE, SIG_IGN); /* Create tar writer object */ if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) { errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR; goto ret; } /* Write data to the tarball */ { string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements(); dd_init_next_file(dd); char *short_name, *full_name; while (dd_get_next_file(dd, &short_name, &full_name)) { if (exclude_from_report && is_in_string_list(short_name, (const_string_vector_const_ptr_t)exclude_from_report)) goto next; // dd_get_next_file guarantees that it's a REG: //struct stat stbuf; //if (stat(full_name, &stbuf) != 0) // || !S_ISREG(stbuf.st_mode) //) { // goto next; //} if (tar_append_file(tar, full_name, short_name) != 0) { errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR; free(short_name); free(full_name); goto ret; } next: free(short_name); free(full_name); } } dd_close(dd); dd = NULL; /* Close tar writer... */ if (tar_append_eof(tar) != 0 || tar_close(tar) != 0) { errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR; goto ret; } tar = NULL; /* ...and check that gzip child finished successfully */ int status; safe_waitpid(child, &status, 0); child = -1; if (status != 0) { /* We assume the error was out-of-disk-space or out-of-quota */ errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR; goto ret; } /* Upload the tarball */ /* Upload from /tmp to /tmp + deletion -> BAD, exclude this possibility */ if (url && url[0] && strcmp(url, "file://"LARGE_DATA_TMP_DIR"/") != 0) { post_state_t *state = new_post_state(POST_WANT_ERROR_MSG); state->username = getenv("Upload_Username"); char *password_inp = NULL; if (state->username != NULL && state->username[0] != '\0') { /* Load Password only if Username is configured, it doesn't make */ /* much sense to load Password without Username. */ state->password = getenv("Upload_Password"); if (state->password == NULL) { /* Be permissive and nice, ask only once and don't check */ /* the result. User can dismiss this prompt but the upload */ /* may work somehow??? */ char *msg = xasprintf(_("Please enter password for uploading:"), state->username); state->password = password_inp = ask_password(msg); free(msg); } } char *remote_name = upload_file_ext(state, url, tempfile, UPLOAD_FILE_HANDLE_ACCESS_DENIALS); result = (remote_name == NULL); /* error if NULL */ free(remote_name); free(password_inp); free_post_state(state); /* cleanup code will delete tempfile */ } else { result = 0; /* success */ log(_("Archive is created: '%s'"), tempfile); free(tempfile); tempfile = NULL; } ret: free(url); dd_close(dd); if (tar) tar_close(tar); /* close(pipe_from_parent_to_child[1]); - tar_close() does it itself */ if (child > 0) safe_waitpid(child, NULL, 0); if (tempfile) { unlink(tempfile); free(tempfile); } if (errmsg) error_msg_and_die("%s", errmsg); return result; }
int tar_append_tree(TAR *t, char *realdir, char *savedir) { char realpath[TAR_MAXPATHLEN]; char savepath[TAR_MAXPATHLEN]; size_t plen; #if defined(HAVE_DIRENT_H) struct dirent *dent; DIR *dp; #else kwDirEntry * dent; kwDirectory *dp; #endif struct stat s; strncpy(realpath, realdir, sizeof(realpath)); realpath[sizeof(realpath)-1] = 0; plen = strlen(realpath); if ( realpath[plen-1] == '/' ) { realpath[plen-1] = 0; } #ifdef DEBUG printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n", t, realdir, (savedir ? savedir : "[NULL]")); #endif if (tar_append_file(t, realdir, savedir) != 0) return -1; #ifdef DEBUG puts(" tar_append_tree(): done with tar_append_file()..."); #endif if ( stat(realpath, &s) != 0 ) { return -1; } if ( #if defined(_WIN32) && !defined(__CYGWIN__) (s.st_mode & _S_IFDIR) == 0 #else !S_ISDIR(s.st_mode) #endif ) return 0; #if defined(HAVE_DIRENT_H) dp = opendir(realdir); #else dp = kwOpenDir(realdir); #endif if (dp == NULL) { if (errno == ENOTDIR) return 0; return -1; } #if defined(HAVE_DIRENT_H) while ((dent = readdir(dp)) != NULL) #else while ((dent = kwReadDir(dp)) != NULL) #endif { if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; snprintf(realpath, TAR_MAXPATHLEN, "%s/%s", realdir, dent->d_name); if (savedir) snprintf(savepath, TAR_MAXPATHLEN, "%s/%s", savedir, dent->d_name); #ifndef WIN32 if (lstat(realpath, &s) != 0) return -1; #else if (stat(realpath, &s) != 0) return -1; #endif if (S_ISDIR(s.st_mode)) { if (tar_append_tree(t, realpath, (savedir ? savepath : NULL)) != 0) return -1; continue; } if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0) return -1; } #if defined(HAVE_DIRENT_H) closedir(dp); #else kwCloseDir(dp); #endif return 0; }