On Tuesday 26 of June 2012 12:34:46 Jiri Moskovcak wrote:
- should be used in call from hook api,
maybe it can even replace the former
create_dump_dir_from_problem_data
---
po/POTFILES.in | 1 +
src/include/problem_data.h | 2 +
src/include/report.h | 8 ++++
src/lib/create_dump_dir.c | 94
++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105
insertions(+)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3203183..09ff83e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,6 +9,7 @@ src/gtk-helpers/event_config_dialog.c
src/gui-wizard-gtk/main.c
src/gui-wizard-gtk/wizard.c
src/gui-wizard-gtk/wizard.glade
+src/lib/create_dump_dir.c
src/lib/event_config.c
src/lib/parse_options.c
src/lib/curl.c
diff --git a/src/include/problem_data.h b/src/include/problem_data.h
index 9bf46f5..c90f4a1 100644
--- a/src/include/problem_data.h
+++ b/src/include/problem_data.h
@@ -35,6 +35,7 @@ enum {
/* Show this element in "short" info (report-cli -l) */
CD_FLAG_LIST = (1 << 4),
CD_FLAG_UNIXTIME = (1 << 5),
+ CD_FLAG_FILE = (1 << 6),
};
struct problem_item {
@@ -61,6 +62,7 @@ void add_basics_to_problem_data(problem_data_t *pd);
static inline void free_problem_data(problem_data_t *problem_data)
{
+ //TODO: leaks problem item;
if (problem_data)
g_hash_table_destroy(problem_data);
}
diff --git a/src/include/report.h b/src/include/report.h
index 3735ef6..21557ac 100644
--- a/src/include/report.h
+++ b/src/include/report.h
@@ -39,6 +39,12 @@ enum {
LIBREPORT_RUN_NEWT = (1 << 8), /* run 'report-newt' */
};
+typedef enum {
+ LR_OK = 0,
+ LR_MISSING_ITEM = (1 << 1),
+ LR_ERROR = (1 << 2),
+} LibreportError;
+
int report_problem_in_dir(const char *dirname, int flags);
/* Reports a problem stored in problem_data_t.
@@ -49,6 +55,8 @@ int report_problem_in_memory(problem_data_t *pd, int
flags); /* Simple wrapper for trivial uses */
int report_problem(problem_data_t *pd);
+LibreportError save_dump_dir_from_problem_data(problem_data_t
*problem_data, char **problem_id, const char *base_dir_name); +
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c
index 137da12..a089a3b 100644
--- a/src/lib/create_dump_dir.c
+++ b/src/lib/create_dump_dir.c
@@ -19,6 +19,8 @@
#include "internal_libreport.h"
+#define NEW_PD_SUFFIX ".new"
+
static struct dump_dir *try_dd_create(const char *base_dir_name, const char
*dir_name) {
char *path = concat_path_file(base_dir_name, dir_name);
@@ -88,3 +90,95 @@ struct dump_dir
*create_dump_dir_from_problem_data(problem_data_t *problem_data,
return dd;
}
+
+LibreportError save_dump_dir_from_problem_data(problem_data_t
*problem_data, char **problem_id, const char *base_dir_name) +{
+ char *type = get_problem_item_content_or_NULL(problem_data, "type");
Shouldn't we use FILENAME_TYPE instead of a string literal?
+
+ if(!type)
+ {
+ error_msg(_("Missing required item: 'type'"));
+ return LR_MISSING_ITEM;
+ }
+
+ char *time_s = get_problem_item_content_or_NULL(problem_data, "time");
Shouldn't we use FILENAME_TIME instead of a string literal?
+ if(!time_s)
+ {
+ /* 64 is a randomly picked constant which should be
+ * enough to hold the time in seconds for a long time..
+ */
+ char buf[64];
You known that you are casting the t variable to long unsigned, so why not to
set buf's size to sizeof(long unsigned)*3 ?
+ time_t t = time(NULL);
+ /* time is a required field, so if it's not provided add a default
one */ + snprintf(buf, sizeof(buf), "%lu", (long unsigned)t);
+ add_to_problem_data_ext(problem_data, "time", buf, CD_FLAG_TXT);
+ }
+
+ char dir_name[strlen(type) +
sizeof("-"LIBREPORT_ISO_DATE_STRING_SAMPLE"-%lu") + sizeof(long)*3];
+
*problem_id = (char *)xmalloc(sizeof(dir_name));
+ snprintf(*problem_id, sizeof(dir_name), "%s-%s-%lu"NEW_PD_SUFFIX, type,
iso_date_string(NULL), (long)getpid()); + strncpy(dir_name, *problem_id,
sizeof(dir_name));
I guess, xasprintf() could be used here. It is not necessary to use an extra
variable dir_name. (please, see line 167)
+
+ VERB2 log("Saving to %s/%s", base_dir_name, *problem_id);
+ struct dump_dir *dd = try_dd_create(base_dir_name, dir_name);
+ if (!dd)
+ {
+ perror_msg("Can't create problem directory");
+ *problem_id = NULL;
Leaking problem_id
+ return LR_ERROR;
+ }
+
+ GHashTableIter iter;
+ char *name;
+ struct problem_item *value;
+ g_hash_table_iter_init(&iter, problem_data);
+ while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value))
+ {
+ if (value->flags & CD_FLAG_FILE)
+ {
+ char dest[PATH_MAX+1];
+ snprintf(dest, sizeof(dest), "%s/%s", dd->dd_dirname, name);
+ VERB2 log("copying '%s' to '%s'",
value->content, dest);
+ off_t copied = copy_file(value->content, dest, 0644);
+ if (copied < 0)
+ error_msg("Can't copy %s to %s", value->content,
dest);
+
+ VERB2 log("copied %li bytes", (unsigned long)copied);
+
+ continue;
+ }
+
+ /* only files should contain '/' and those are handled earlier */
+ if (name[0] == '.' || strchr(name, '/'))
+ {
+ error_msg("Problem data field name contains disallowed chars:
'%s'", name); + continue;
+ }
+
+//FIXME: what to do with CD_FLAG_BINs??
+ if (value->flags & CD_FLAG_BIN)
+ continue;
+
+ dd_save_text(dd, name, value->content);
+ }
+
+
+
+ char *suffix = strstr(*problem_id, NEW_PD_SUFFIX);
+ if (suffix)
+ *suffix = '\0';
+
+ char* new_path = concat_path_file(base_dir_name, *problem_id);
+
+ VERB2 log("Renaming from'%s' to '%s'", dd->dd_dirname,
new_path);
+ if (dd_rename(dd, new_path) != 0)
+ {
+ *problem_id = NULL;
Leaking problem_id
+ return LR_ERROR;
+ }
+ free(new_path);
+
+ dd_close(dd);
+
+ return LR_OK;
+}
Regards,
Jakub