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

Reply via email to