diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-08-26 13:03:32 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-08-26 13:03:32 +0000 |
commit | b89ece30bebb5b9dd06e4e061537b6bf068566f2 (patch) | |
tree | c7f65b64fccfac2f0e7e134e5f7666a4fb1907d1 /src/config.c | |
parent | 338c0d9c35c56f35c636df1c1da0852a466e731f (diff) | |
download | wydawca-b89ece30bebb5b9dd06e4e061537b6bf068566f2.tar.gz wydawca-b89ece30bebb5b9dd06e4e061537b6bf068566f2.tar.bz2 |
Implement project owner notifications.
* wydawca/wydawca.c (syslog_printer): Reduce the number of memory
reallocations
(make_stat_expansion): Update
* wydawca/method.c: Implement a new framework: methods may return
2-dimensional arrays of strings.
* wydawca/sql.c, wydawca/sql.h: Implement the new method framework.
* wydawca/verify.c (expand_param): kw_expansion may provide
expansion functions. An additional argument supplies user-defined
data for expansions.
(escape_kwexp): Extern
(free_kwexp): Improve
(get_project_name): New function
(make_default_kwexp): New function
(check_access_rights): Call get_project_name. Use
make_default_kwexp to initialize expansions
(verify_directive_file): Use make_default_kwexp to initialize
expansions
* wydawca/wydawca.h (NITEMS): New macro
(enum access_method_type): New members: ncol, nrow
(struct directory_pair): New members url,project_owner_method,
user_data_method
(struct file_info): Replace mtime, uid with struct stat sb
(struct file_triplet): New members project, dpair, user_data
(TRIPLET_UID): Take into account the changes to struct file_info
(enum notification_event): New data type
(notify_project_owner, notify_admin, notify): New functions
(struct kw_expansion): New members static_p, expand and data.
(escape_kwexp,make_default_kwexp): New proto
(expand_param): Change signature
(triplet_expand_param): New function
(method_result): Change prototype
(method_num_rows,method_num_cols): New functions
* wydawca/config.c: New statements project-owner, user-data,
admin-address, mail-user, user-message
directory can take an optional argument specifying base URL for
notification messages
* wydawca/gpg.c (verify_directive_signature): Expand directives
even if the signature does not match. Useful for notifications.
Add notifications.
* wydawca/process.c: Add notifications.
* wydawca/directive.c: Add notifications
* wydawca/wydawca.rc: Update
* wydawca/mail.c, wydawca/mail.h: Implement project owner
notifications
* wydawca/triplet.c (triplet_expand_param): New function
* lib/cfg.c (read_cont_line): Fix counting of input lines.
git-svn-id: file:///svnroot/wydawca/trunk@297 6bb4bd81-ecc2-4fd4-a2d4-9571d19c0d33
Diffstat (limited to 'src/config.c')
-rw-r--r-- | src/config.c | 162 |
1 files changed, 156 insertions, 6 deletions
diff --git a/src/config.c b/src/config.c index 559e995..81db423 100644 --- a/src/config.c +++ b/src/config.c @@ -27,9 +27,13 @@ static struct obstack cfg_stk; static struct access_method default_verify_method; static struct access_method default_gpg_key_method; +static struct access_method default_project_owner_method; +static struct access_method default_user_data_method; static struct archive_descr default_archive_descr; +#define ISHSPACE(c) ((c)==' ' || (c)=='\t') #define skip_ws(s) while (*(s) && isspace (*(s))) (s)++; +#define skip_hws(s) while (*(s) && ISHSPACE (*(s))) (s)++; #define skip_word(s) while (*(s) && !isspace (*(s))) (s)++; /* Return a pointer to the next word from *PSTR. Advanse *PSTR to the beginning @@ -40,6 +44,12 @@ get_word (char **pstr) char *word; char *str = *pstr; + if (!str) + { + *pstr = ""; + return *pstr; + } + skip_ws (str); word = str; @@ -319,6 +329,30 @@ cfg_gpg_key (gsc_config_file_t *file, char *kw, char *val, void *data) _cfg_access_method (file, kw, val, method); } +static void +cfg_project_owner (gsc_config_file_t *file, char *kw, char *val, void *data) +{ + struct directory_pair *dp = data; + struct access_method *method; + if (dp) + method = dp->project_owner_method = method_new (method_builtin); + else + method = &default_project_owner_method; + _cfg_access_method (file, kw, val, method); +} + +static void +cfg_user_data (gsc_config_file_t *file, char *kw, char *val, void *data) +{ + struct directory_pair *dp = data; + struct access_method *method; + if (dp) + method = dp->user_data_method = method_new (method_builtin); + else + method = &default_user_data_method; + _cfg_access_method (file, kw, val, method); +} + static char const * const backup_args[] = { /* In a series of synonyms, present the most meaningful first, so @@ -447,6 +481,7 @@ static void cfg_directory (gsc_config_file_t *file, char *kw, char *val, void *unused) { int ec; + char *word; struct directory_pair dpair; static struct gsc_config_keyword keywords[] = { { "source", cfg_source }, @@ -454,18 +489,27 @@ cfg_directory (gsc_config_file_t *file, char *kw, char *val, void *unused) { "file-sweep-time", cfg_file_sweep_time }, { "verify-user", cfg_verify_user }, { "gpg-key", cfg_gpg_key }, + { "project-owner", cfg_project_owner }, + { "user-data", cfg_user_data }, { "archive", cfg_archive }, { NULL } }; - if (val) + memset (&dpair, 0, sizeof dpair); + word = get_word (&val); + if (!word) + dpair.url = NULL; + else + dpair.url = xstrdup (word); + if (val && val[0]) file->error_msg (file->file_name, file->line, "warning: junk in line ignored"); - memset (&dpair, 0, sizeof dpair); dpair.file_sweep_time = file_sweep_time; dpair.verify_method = &default_verify_method; dpair.gpg_key_method = &default_gpg_key_method; + dpair.project_owner_method = &default_project_owner_method; + dpair.user_data_method = &default_user_data_method; dpair.archive = default_archive_descr; gsc_config_parse_block (file, &dpair, keywords, "end"); @@ -799,21 +843,32 @@ _cfg_raw_read (gsc_config_file_t *file, char *val, struct obstack *stk) char *word = val ? get_word (&val) : ""; size_t wlen; size_t start_line = file->line; - + int skip_initial_ws = 0; + if (word[0] == 0) word = "end"; + if (word[0] == '-') + { + skip_initial_ws = 1; + word++; + } wlen = strlen (word); while (getline (&buf, &size, file->fp) > 0) { + char *p = buf; + file->line++; - if (end_marker_p (buf, word, wlen)) + + if (skip_initial_ws) + skip_hws (p); + if (end_marker_p (p, word, wlen)) { obstack_1grow (stk, 0); free (buf); return 0; } - obstack_grow (stk, buf, strlen (buf)); + obstack_grow (stk, p, strlen (p)); } file->error_msg (file->file_name, start_line, "missing end marker"); @@ -831,6 +886,95 @@ cfg_admin_stat_message (gsc_config_file_t *file, char *kw, char *val, +static const char *event_args[] = { + "success", + "bad_ownership", + "bad-ownership", + "bad_directive_signature", + "bad-directive-signature", + "bad_detached_signature", + "bad-detached-signature", + NULL +}; + +static enum notification_event event_types[] = { + ev_success, + ev_bad_ownership, + ev_bad_ownership, + ev_bad_directive_signature, + ev_bad_directive_signature, + ev_bad_detached_signature, + ev_bad_detached_signature +}; + +ARGMATCH_VERIFY (event_args, event_types); + +int +string_to_notification_event (gsc_config_file_t *file, char *val, + enum notification_event *pret) +{ + ptrdiff_t x = ARGMATCH (val, event_args, event_types); + + if (x == (ptrdiff_t)-1) + { + file->error_msg (file->file_name, file->line, + "unknown notification type: %s", val); + file->error_count++; + return 1; + } + *pret = event_types[x]; + return 0; +} + +static void +cfg_mail_user (gsc_config_file_t *file, char *kw, char *val, void *unused) +{ + int i; + int argc; + char **argv; + + if (argcv_get (val, NULL, NULL, &argc, &argv)) + { + file->error_msg (file->file_name, file->line, + "cannot parse value: %s", strerror (errno)); + file->error_count++; + return; + } + + for (i = 0; i < argc; i++) + { + enum notification_event evt; + + if (string_to_notification_event (file, argv[i], &evt)) + break; + owner_notification_flags |= STAT_MASK (evt); + } + argcv_free (argc, argv); +} + +static void +cfg_user_message (gsc_config_file_t *file, char *kw, char *val, void *unused) +{ + enum notification_event evt; + char *word = get_word (&val); + + if (!*word) + { + file->error_msg (file->file_name, file->line, + "not enough arguments"); + file->error_count++; + return; + } + + if (string_to_notification_event (file, word, &evt)) + return; + + if (_cfg_raw_read (file, val, &cfg_stk) == 0) + user_message_template[evt] = obstack_finish (&cfg_stk); +} + + + static struct gsc_config_keyword kw_handler[] = { { "syslog-tag", cfg_syslog_tag }, { "syslog-facility", cfg_syslog_facility }, @@ -841,14 +985,18 @@ static struct gsc_config_keyword kw_handler[] = { { "sql", cfg_sql }, { "verify-user", cfg_verify_user }, { "gpg-key", cfg_gpg_key }, + { "project-owner", cfg_project_owner }, + { "user-data", cfg_user_data }, { "umask", cfg_umask }, { "tar-program", cfg_tar_program }, { "archive", cfg_archive }, { "mailer", cfg_mailer }, - { "admin-addres", cfg_admin_address }, + { "admin-address", cfg_admin_address }, { "from-address", cfg_from_address }, { "mail-admin-stat", cfg_mail_admin_stat }, { "admin-stat-message", cfg_admin_stat_message }, + { "mail-user", cfg_mail_user }, + { "user-message", cfg_user_message }, { NULL } }; @@ -857,6 +1005,8 @@ parse_config () { default_verify_method.type = method_builtin; default_gpg_key_method.type = method_builtin; + default_project_owner_method.type = method_none; + default_user_data_method.type = method_none; default_archive_descr.type = archive_none; default_archive_descr.backup_type = no_backups; |