aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-02-24 14:45:19 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-02-24 14:45:19 +0200
commitb1472caae9a1b6905b6bbe42e69539b29febcf5c (patch)
tree3aaf7a2b4b95ecbdeceefcb8d649c4cb726e84fa
parentf7834b6f1aa00b7173a2fe338756c2bad4e3927b (diff)
downloadwydawca-b1472caae9a1b6905b6bbe42e69539b29febcf5c.tar.gz
wydawca-b1472caae9a1b6905b6bbe42e69539b29febcf5c.tar.bz2
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.
-rw-r--r--gconf/gconf-gram.y117
-rw-r--r--src/cmdline.opt6
-rw-r--r--src/config.c3
-rw-r--r--src/job.c16
-rw-r--r--src/net.c6
-rw-r--r--src/process.c30
-rw-r--r--src/wydawca.c10
-rw-r--r--src/wydawca.h6
8 files changed, 139 insertions, 55 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,15 +796,11 @@ 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);
-
- while (gl_list_iterator_next (&itr, &p, NULL))
- {
- const gconf_value_t *vp = p;
+ gl_list_t list;
size_t size;
- 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: "
@@ -780,10 +809,22 @@ process_ident (struct gconf_keyword *kwp, gconf_value_t *value)
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;
+
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,26 +839,37 @@ 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();
}
+
+ 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
+ {
ptr = xmalloc (size);
if (string_convert (ptr, type, value->v.string))
{
@@ -826,6 +878,7 @@ process_ident (struct gconf_keyword *kwp, gconf_value_t *value)
return;
}
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 <http://www.gnu.org/licenses/>. */
#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)
{
+ 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,10 +112,15 @@ handle_connection (FILE *fp)
spool = wydawca_find_spool (buf);
if (!spool)
{
+ 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);
else
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.