int add_reported_to_data(char **reported_to, const char *line) { if (*reported_to) { unsigned len_line = strlen(line); char *p = *reported_to; while (*p) { if (strncmp(p, line, len_line) == 0 && (p[len_line] == '\n' || p[len_line] == '\0')) return 0; p = strchrnul(p, '\n'); if (!*p) break; p++; } if (p != *reported_to && p[-1] != '\n') *reported_to = append_to_malloced_string(*reported_to, "\n"); *reported_to = append_to_malloced_string(*reported_to, line); *reported_to = append_to_malloced_string(*reported_to, "\n"); } else *reported_to = xasprintf("%s\n", line); return 1; }
static int create_and_upload_archive( const char *dump_dir_name, const char *url, map_string_t *settings, char **remote_name) { int result = 1; /* error */ char* tempfile = NULL; /* 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"); string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements(); struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) xfunc_die(); /* error msg is already logged by dd_opendir */ /* Compressing e.g. 0.5gig coredump takes a while. Let client know what we are doing */ log_warning(_("Compressing data")); if (dd_create_archive(dd, tempfile, (const_string_vector_const_ptr_t)exclude_from_report, 0) != 0) { log_error("Can't create temporary file in %s", LARGE_DATA_TMP_DIR); goto ret; } dd_close(dd); dd = NULL; /* Upload the archive */ /* Upload from /tmp to /tmp + deletion -> BAD, exclude this possibility */ if (url && url[0] && strcmp(url, "file://"LARGE_DATA_TMP_DIR"/") != 0) result = interactive_upload_file(url, tempfile, settings, remote_name); else { result = 0; /* success */ log_warning(_("Archive is created: '%s'"), tempfile); *remote_name = tempfile; tempfile = NULL; } ret: dd_close(dd); if (tempfile) { unlink(tempfile); free(tempfile); } return result; }
static GList* load_bzrep_conf_file(const char *path) { FILE *fp = stdin; if (strcmp(path, "-") != 0) { fp = fopen(path, "r"); if (!fp) return NULL; } GList *sections = NULL; char *line; while ((line = xmalloc_fgetline(fp)) != NULL) { /* Skip comments */ char first = *skip_whitespace(line); if (first == '#') goto free_line; /* Handle trailing backslash continuation */ check_continuation: ; unsigned len = strlen(line); if (len && line[len-1] == '\\') { line[len-1] = '\0'; char *next_line = xmalloc_fgetline(fp); if (next_line) { line = append_to_malloced_string(line, next_line); free(next_line); goto check_continuation; } } /* We are reusing line buffer to form temporary * "key\0values\0..." in its beginning */ bool summary_line = false; char *value = NULL; char *src; char *dst; for (src = dst = line; *src; src++) { char c = *src; /* did we reach the value list? */ if (!value && c == ':' && src[1] == ':') { *dst++ = '\0'; /* terminate key */ src += 2; value = dst; /* remember where value starts */ summary_line = (strcmp(line, "%summary") == 0); if (summary_line) { value = src; break; } continue; } /* skip whitespace in value list */ if (value && isspace(c)) continue; *dst++ = c; /* store next key or value char */ } GList *item_list = NULL; if (summary_line) { /* %summary is special */ item_list = g_list_append(NULL, xstrdup(skip_whitespace(value))); } else { *dst = '\0'; /* terminate value (or key) */ if (value) item_list = split_string_on_char(value, ','); } section_t *sec = xzalloc(sizeof(*sec)); sec->name = xstrdup(line); sec->items = item_list; sections = g_list_prepend(sections, sec); free_line: free(line); } if (fp != stdin) fclose(fp); return g_list_reverse(sections); }
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; }
static GList* load_stream(FILE *fp) { assert(fp); GList *sections = NULL; section_t *master = section_new("%description"); section_t *sec = NULL; sections = g_list_append(sections, master); char *line; while ((line = xmalloc_fgetline(fp)) != NULL) { /* Skip comments */ char first = *skip_whitespace(line); if (first == '#') goto free_line; /* Handle trailing backslash continuation */ check_continuation: ; unsigned len = strlen(line); if (len && line[len-1] == '\\') { line[len-1] = '\0'; char *next_line = xmalloc_fgetline(fp); if (next_line) { line = append_to_malloced_string(line, next_line); free(next_line); goto check_continuation; } } /* We are reusing line buffer to form temporary * "key\0values\0..." in its beginning */ bool summary_line = false; char *value = NULL; char *src; char *dst; for (src = dst = line; *src; src++) { char c = *src; /* did we reach the value list? */ if (!value && c == ':' && src[1] == ':') { *dst++ = '\0'; /* terminate key */ src += 1; value = dst; /* remember where value starts */ summary_line = (strcmp(line, "%summary") == 0); if (summary_line) { value = (src + 1); break; } continue; } /* skip whitespace in value list */ if (value && isspace(c)) continue; *dst++ = c; /* store next key or value char */ } GList *item_list = NULL; if (summary_line) { /* %summary is special */ item_list = g_list_append(NULL, xstrdup(skip_whitespace(value))); } else { *dst = '\0'; /* terminate value (or key) */ if (value) item_list = split_string_on_char(value, ','); } sec = section_new(line); sec->items = item_list; if (sec->name[0] == '%') { if (!summary_line && strcmp(sec->name, "%attach") != 0) { master->children = g_list_reverse(master->children); master = sec; } sections = g_list_prepend(sections, sec); } else master->children = g_list_prepend(master->children, sec); free_line: free(line); } /* If master equals sec, then master's children list was not yet reversed. * * %description is the default section (i.e is not explicitly mentioned) * and %summary nor %attach cause its children list to reverse. */ if (master == sec || strcmp(master->name, "%description") == 0) master->children = g_list_reverse(master->children); return sections; }