aboutsummaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-08-26 13:03:32 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-08-26 13:03:32 +0000
commitb89ece30bebb5b9dd06e4e061537b6bf068566f2 (patch)
treec7f65b64fccfac2f0e7e134e5f7666a4fb1907d1 /src/config.c
parent338c0d9c35c56f35c636df1c1da0852a466e731f (diff)
downloadwydawca-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.c162
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;

Return to:

Send suggestions and report system problems to the System administrator.