From b1472caae9a1b6905b6bbe42e69539b29febcf5c Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 24 Feb 2009 14:45:19 +0200 Subject: Improve daemon mode. * gconf/gconf-gram.y: Provide created lists with appropriate equal tests. Special handling for lists of strings. * src/cmdline.opt: Minor fix. * src/config.c: New keyword all-spools. * src/job.c: Hanlde "all spools" requests. * src/net.c: Likewise. * src/process.c (spool_check_alias): Rewrite using gl_list_search (scan_directories): Rename to scan_all_spools. (spool_create_timers): New function. * src/wydawca.c (all_spool_aliases): New global. (initstats): New function. * src/wydawca.h: Add new declarations. --- gconf/gconf-gram.y | 139 ++++++++++++++++++++++++++++++++++++----------------- src/cmdline.opt | 6 +-- src/config.c | 3 ++ src/job.c | 18 ++++++- src/net.c | 12 +++-- src/process.c | 30 +++++------- src/wydawca.c | 10 +++- src/wydawca.h | 6 ++- 8 files changed, 154 insertions(+), 70 deletions(-) diff --git a/gconf/gconf-gram.y b/gconf/gconf-gram.y index f7ee710..66b5416 100644 --- a/gconf/gconf-gram.y +++ b/gconf/gconf-gram.y @@ -708,29 +708,62 @@ string_convert (void *target, enum gconf_data_type type, const char *string) return 0; } -size_t gconf_type_size_tab[] = { - 0 /* gconf_type_void */, - sizeof (char*) /* gconf_type_string */, - sizeof (short) /* gconf_type_short */, - sizeof (unsigned short) /* gconf_type_ushort */, - sizeof (int) /* gconf_type_int */, - sizeof (unsigned int) /* gconf_type_uint */, - sizeof (long) /* gconf_type_long */, - sizeof (unsigned long) /* gconf_type_ulong */, - sizeof (size_t) /* gconf_type_size */, +struct gconf_prop +{ + size_t size; + gl_listelement_equals_fn eqfn; +}; + +static bool +string_eq (const void *elt1, const void *elt2) +{ + return strcmp ((const char *)elt1, (const char *)elt2) == 0; +} + +#define __gconf_name_cat__(a,b) a ## b +#define NUMEQ(type) __gconf_name_cat__(type,_eq) +#define __DECL_NUMEQ(type,ctype) \ + static bool \ + NUMEQ(type) (const void *elt1, const void *elt2) \ + { \ + return memcmp (elt1, elt2, sizeof (ctype)) == 0; \ + } +#define DECL_NUMEQ(type) __DECL_NUMEQ(type,type) + +DECL_NUMEQ(short) +DECL_NUMEQ(int) +DECL_NUMEQ(long) +DECL_NUMEQ(size_t) +DECL_NUMEQ(uintmax_t) +DECL_NUMEQ(intmax_t) +DECL_NUMEQ(time_t) +__DECL_NUMEQ(in_addr, struct in_addr) +__DECL_NUMEQ(gconf_sockaddr, struct gconf_sockaddr) + +struct gconf_prop gconf_prop_tab[] = { + { 0, NULL }, /* gconf_type_void */ + { sizeof (char*), string_eq }, /* gconf_type_string */ + { sizeof (short), NUMEQ (short) }, /* gconf_type_short */ + { sizeof (unsigned short), NUMEQ (short) }, /* gconf_type_ushort */ + { sizeof (int), NUMEQ (int) }, /* gconf_type_int */ + { sizeof (unsigned int), NUMEQ (int) }, /* gconf_type_uint */ + { sizeof (long), NUMEQ (long) }, /* gconf_type_long */ + { sizeof (unsigned long), NUMEQ (long) }, /* gconf_type_ulong */ + { sizeof (size_t), NUMEQ (size_t) }, /* gconf_type_size */ /* gconf_type_off,*/ - sizeof (uintmax_t) /* gconf_type_uintmax */, - sizeof (intmax_t) /* gconf_type_intmax */, - sizeof (time_t) /* gconf_type_time */, - sizeof (int) /* gconf_type_bool */, - sizeof (struct in_addr) /* gconf_type_ipv4 */, - 0 /* FIXME: gconf_type_cidr */, - sizeof (struct in_addr) /* gconf_type_host */, - sizeof (struct gconf_sockaddr) /* gconf_type_sockaddr */, - 0 /* gconf_type_section */ + { sizeof (uintmax_t), NUMEQ (uintmax_t) }, /* gconf_type_uintmax */ + { sizeof (intmax_t), NUMEQ (intmax_t) }, /* gconf_type_intmax */ + { sizeof (time_t), NUMEQ (time_t) }, /* gconf_type_time */ + { sizeof (int), NUMEQ (int) }, /* gconf_type_bool */ + { sizeof (struct in_addr), NUMEQ (in_addr) }, /* gconf_type_ipv4 */ + { 0, NULL }, /* FIXME: gconf_type_cidr */ + { sizeof (struct in_addr), NUMEQ (in_addr) }, /* gconf_type_host */ + { sizeof (struct gconf_sockaddr), NUMEQ (gconf_sockaddr) }, + /* gconf_type_sockaddr */ + { 0, NULL } /* gconf_type_section */ }; -#define gconf_type_size_count \ - (sizeof (gconf_type_size_tab) / sizeof (gconf_type_size_tab[0])) +#define gconf_prop_count \ + (sizeof (gconf_prop_tab) / sizeof (gconf_prop_tab[0])) static void process_ident (struct gconf_keyword *kwp, gconf_value_t *value) @@ -763,27 +796,35 @@ process_ident (struct gconf_keyword *kwp, gconf_value_t *value) enum gconf_data_type type = GCONF_TYPE (kwp->type); int num = 1; const void *p; - gl_list_t list = simple_list_create (true); + gl_list_t list; + size_t size; + if (type >= gconf_prop_count + || (size = gconf_prop_tab[type].size) == 0) + { + gconf_error (&gconf_current_locus, 0, + _("INTERNAL ERROR at %s:%d: " + "unhandled data type %d"), + __FILE__, __LINE__, type); + abort (); + } + + list = gl_list_create_empty (&gl_linked_list_implementation, + gconf_prop_tab[type].eqfn, + NULL, + listel_dispose, + false); + while (gl_list_iterator_next (&itr, &p, NULL)) { const gconf_value_t *vp = p; - size_t size; - if (type >= gconf_type_size_count - || (size = gconf_type_size_tab[type]) == 0) - { - gconf_error (&gconf_current_locus, 0, - _("INTERNAL ERROR at %s:%d: " - "unhandled data type %d"), - __FILE__, __LINE__, type); - abort (); - } - if (vp->type != GCONF_TYPE_STRING) gconf_error (&gconf_current_locus, 0, _("%s: incompatible data type in list item #%d"), kwp->ident, num); + else if (type == gconf_type_string) + gl_list_add_last (list, vp->v.string); else { void *ptr = xmalloc (size); @@ -798,34 +839,46 @@ process_ident (struct gconf_keyword *kwp, gconf_value_t *value) } else { - gconf_error (&gconf_current_locus, 0, _("incompatible data type for `%s'"), + gconf_error (&gconf_current_locus, 0, + _("incompatible data type for `%s'"), kwp->ident); return; } } else if (GCONF_IS_LIST (kwp->type)) { - gl_list_t list = simple_list_create (true); + gl_list_t list; enum gconf_data_type type = GCONF_TYPE (kwp->type); size_t size; void *ptr; - if (type >= gconf_type_size_count - || (size = gconf_type_size_tab[type]) == 0) + if (type >= gconf_prop_count + || (size = gconf_prop_tab[type].size) == 0) { gconf_error (&gconf_current_locus, 0, _("INTERNAL ERROR at %s:%d: unhandled data type %d"), __FILE__, __LINE__, type); abort(); } - ptr = xmalloc (size); - if (string_convert (ptr, type, value->v.string)) + + list = gl_list_create_empty (&gl_linked_list_implementation, + gconf_prop_tab[type].eqfn, + NULL, + listel_dispose, + false); + if (type == gconf_type_string) + gl_list_add_last (list, value->v.string); + else { - free (ptr); - gl_list_free (list); - return; + ptr = xmalloc (size); + if (string_convert (ptr, type, value->v.string)) + { + free (ptr); + gl_list_free (list); + return; + } + gl_list_add_last (list, ptr); } - gl_list_add_last (list, ptr); *(gl_list_t*)target = list; } else diff --git a/src/cmdline.opt b/src/cmdline.opt index b61517b..8b45791 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -21,7 +21,7 @@ static gl_list_t source_list; static gl_list_t tag_list; static bool -source_eq (const void *elt1, const void *elt2) +string_eq (const void *elt1, const void *elt2) { return strcmp ((const char *)elt1, (const char *)elt2) == 0; } @@ -99,7 +99,7 @@ OPTION(spool,S,TAG, BEGIN if (!tag_list) tag_list = gl_list_create_empty (&gl_linked_list_implementation, - source_eq, NULL, + string_eq, NULL, NULL, false); gl_list_add_last (tag_list, optarg); END @@ -109,7 +109,7 @@ OPTION(source,s,SOURCE-DIR, BEGIN if (!source_list) source_list = gl_list_create_empty (&gl_linked_list_implementation, - source_eq, NULL, + string_eq, NULL, NULL, false); gl_list_add_last (source_list, optarg); END diff --git a/src/config.c b/src/config.c index 94afb20..facfcbc 100644 --- a/src/config.c +++ b/src/config.c @@ -1287,6 +1287,9 @@ static struct gconf_keyword wydawca_kw[] = { gconf_type_section, NULL, 0, cb_spool, NULL, spool_kw }, + { "all-spools", NULL, N_("Service names that request scanning all spools"), + gconf_type_string|GCONF_LIST, &all_spool_aliases }, + { NULL } }; diff --git a/src/job.c b/src/job.c index 9678139..545d270 100644 --- a/src/job.c +++ b/src/job.c @@ -15,6 +15,7 @@ with this program. If not, see . */ #include "wydawca.h" +#include "mail.h" #define STATE_FINISHED 0x01 #define STATE_QUEUED 0x02 @@ -35,6 +36,8 @@ struct job *queue; size_t jobmax; size_t jobcnt; +static struct spool fake_spool = { "all spools" }; + struct job * job_locate (const struct spool *spool, uid_t uid) { @@ -59,8 +62,18 @@ job_active_count () void wydawca_scanner (struct job *job) { - scan_spool (job->spool, 1, &job->uid); + initstats(); + timer_start ("wydawca"); + if (job->spool == &fake_spool) + scan_all_spools (1, &job->uid); + else + { + spool_create_timers (); + scan_spool (job->spool, 1, &job->uid); + } + timer_stop ("wydawca"); mail_finish (); + logstats (); } int @@ -148,6 +161,9 @@ schedule_job (const struct spool *spool, uid_t uid) { struct job *job; + if (!spool) + spool = &fake_spool; + if (debug_level) logmsg (LOG_DEBUG, _("scheduling job: %s, %lu"), spool->tag, uid); diff --git a/src/net.c b/src/net.c index efb6225..03f9a5a 100644 --- a/src/net.c +++ b/src/net.c @@ -112,9 +112,14 @@ handle_connection (FILE *fp) spool = wydawca_find_spool (buf); if (!spool) { - fprintf (fp, "- Unknown service name\r\n"); - free (buf); - return; + if (all_spool_aliases && gl_list_search (all_spool_aliases, buf)) + fprintf (fp, "+ OK, all spools\r\n"); + else + { + fprintf (fp, "- Unknown service name\r\n"); + free (buf); + return; + } } else if (spool->url) fprintf (fp, "+ OK, URL %s\r\n", spool->url); @@ -128,6 +133,7 @@ handle_connection (FILE *fp) return; } + trim_crlf (buf); if (debug_level) logmsg (LOG_DEBUG, "recv: %s", buf); diff --git a/src/process.c b/src/process.c index 20bfd38..1a6b01d 100644 --- a/src/process.c +++ b/src/process.c @@ -36,22 +36,9 @@ register_spool (struct spool *spool) static int spool_check_alias (struct spool *spool, const char *name) { - int rc = 0; - - if (spool->aliases) - { - gl_list_iterator_t itr = gl_list_iterator (spool->aliases); - const void *p; - - while (gl_list_iterator_next (&itr, &p, NULL)) - if (strcmp (name, p) == 0) - { - rc = 1; - break; - } - gl_list_iterator_free (&itr); - } - return rc; + if (spool->aliases && gl_list_search (spool->aliases, name)) + return 1; + return 0; } struct spool * @@ -248,12 +235,11 @@ close_methods (struct spool *spool) /* Scan all configured update directories */ void -scan_directories (int uidc, uid_t *uidv) +scan_all_spools (int uidc, uid_t *uidv) { struct spool_list *sp; timer_start ("wydawca"); - for (sp = spool_list; sp; sp = sp->next) if (enabled_spool_p (&sp->spool)) scan_spool (&sp->spool, uidc, uidv); @@ -263,3 +249,11 @@ scan_directories (int uidc, uid_t *uidv) timer_stop ("wydawca"); } +void +spool_create_timers () +{ + struct spool_list *sp; + + for (sp = spool_list; sp; sp = sp->next) + timer_start (sp->spool.tag); +} diff --git a/src/wydawca.c b/src/wydawca.c index cc6c8f0..f9818ed 100644 --- a/src/wydawca.c +++ b/src/wydawca.c @@ -40,11 +40,18 @@ int daemon_mode = 0; int foreground; int single_process; time_t wakeup_interval; +gl_list_t all_spool_aliases; struct gconf_sockaddr listen_sockaddr; unsigned wydawca_stat[MAX_STAT]; +void +initstats () +{ + memset (wydawca_stat, 0, sizeof wydawca_stat); +} + /* Logging */ void @@ -227,6 +234,7 @@ gconf_print_diag (gconf_locus_t *locus, int err, int errcode, const char *msg) } + static int uidc; static uid_t *uidv; @@ -343,7 +351,7 @@ main (int argc, char **argv) if (!daemon_mode) { - scan_directories (uidc, uidv); + scan_all_spools (uidc, uidv); logstats (); } else diff --git a/src/wydawca.h b/src/wydawca.h index 8a716e4..6384738 100644 --- a/src/wydawca.h +++ b/src/wydawca.h @@ -325,6 +325,8 @@ extern int foreground; extern int single_process; extern struct gconf_sockaddr listen_sockaddr; +extern gl_list_t all_spool_aliases; + #define UPDATE_STATS(what) \ do \ { \ @@ -335,6 +337,8 @@ extern struct gconf_sockaddr listen_sockaddr; int stat_mask_p (unsigned long mask); struct metadef *make_stat_expansion (size_t count); +void initstats (void); +void logstats (void); /* Utility functions */ @@ -361,7 +365,7 @@ enum exec_result wydawca_exec (int argc, const char **argv, int *retcode); /* Directory scanning and registering */ void scan_spool (const struct spool *spool, int uc, uid_t *uv); -void scan_directories (int, uid_t *); +void scan_all_spools (int, uid_t *); void register_spool (struct spool *spool); struct spool *wydawca_find_spool (const char *name); -- cgit v1.2.1