author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-23 22:49:40 (GMT) |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-23 22:57:16 (GMT) |
commit | 4213ec5ef9695aa504938c0e764ba9a4f08921b2 (patch) (unidiff) | |
tree | 88ac2b2eb01337f0924d687df38b2a163bc94e11 /src | |
parent | 337a06f32fb530e0e0884fef2f5f630cca9911a1 (diff) | |
download | wydawca-4213ec5ef9695aa504938c0e764ba9a4f08921b2.tar.gz wydawca-4213ec5ef9695aa504938c0e764ba9a4f08921b2.tar.bz2 |
Initial implementation of daemon mode.
* gconf/gconf-gram.y (string_to_sockaddr_: Take struct gconf_sockaddr as the
first argument.
* gconf/gconf.h (struct gconf_sockaddr): New data type.
* src/job.c, src/net.c, src/pidfile.c: New files.
* src/Makefile.am (wydawca_SOURCES): Add job.c, net.c, pidfile.c
* src/cmdline.opt: New options: --cron (change semantics), --force,
--foreground, --single-process, --spool
* src/wydawca.c: New daemon mode.
* src/config.c: New statements: spool.alias, daemon, foreground,
single-process, wakeup-interval, pidfile, listen
* src/directive.c, src/diskio.c, src/gpg.c, src/mail.c, src/null.c,
src/process.c, src/triplet.c, src/verify.c, src/vtab.c, src/wydawca.h: use
static struct spool wherever feasible.
* src/triplet.c: New meta-variable "spool"
* tests/etc/wydawca.rcin: Update.
* tests/upload-dry.at: Update.
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/cmdline.opt | 48 | ||||
-rw-r--r-- | src/config.c | 40 | ||||
-rw-r--r-- | src/directive.c | 2 | ||||
-rw-r--r-- | src/diskio.c | 14 | ||||
-rw-r--r-- | src/gpg.c | 4 | ||||
-rw-r--r-- | src/job.c | 278 | ||||
-rw-r--r-- | src/mail.c | 15 | ||||
-rw-r--r-- | src/net.c | 227 | ||||
-rw-r--r-- | src/null.c | 22 | ||||
-rw-r--r-- | src/pidfile.c | 90 | ||||
-rw-r--r-- | src/process.c | 66 | ||||
-rw-r--r-- | src/triplet.c | 18 | ||||
-rw-r--r-- | src/verify.c | 4 | ||||
-rw-r--r-- | src/vtab.c | 8 | ||||
-rw-r--r-- | src/wydawca.c | 112 | ||||
-rw-r--r-- | src/wydawca.h | 83 |
17 files changed, 885 insertions, 150 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7ba9832..903b754 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -25,8 +25,11 @@ wydawca_SOURCES=\ | |||
25 | exec.c\ | 25 | exec.c\ |
26 | gpg.c\ | 26 | gpg.c\ |
27 | interval.c\ | 27 | interval.c\ |
28 | job.c\ | ||
28 | meta.c\ | 29 | meta.c\ |
29 | method.c\ | 30 | method.c\ |
31 | net.c\ | ||
32 | pidfile.c\ | ||
30 | process.c\ | 33 | process.c\ |
31 | sql.c\ | 34 | sql.c\ |
32 | sql.h\ | 35 | sql.h\ |
@@ -56,6 +59,7 @@ LDADD=../gconf/libgconf.a ../gnu/libgnu.a @SQLLIB@ @GPGMELIB@ @MAILUTILS_LIBS@ | |||
56 | INCLUDES = -I$(top_srcdir)/gconf -I$(top_srcdir)/gnu -I../gnu @MAILUTILS_INCLUDES@ | 59 | INCLUDES = -I$(top_srcdir)/gconf -I$(top_srcdir)/gnu -I../gnu @MAILUTILS_INCLUDES@ |
57 | AM_CPPFLAGS= \ | 60 | AM_CPPFLAGS= \ |
58 | -DSYSCONFDIR=\"$(sysconfdir)\"\ | 61 | -DSYSCONFDIR=\"$(sysconfdir)\"\ |
62 | -DLOCALSTATEDIR=\"$(localstatedir)\"\ | ||
59 | -DDEFAULT_VERSION_INCLUDE_DIR=\"$(incdir)\"\ | 63 | -DDEFAULT_VERSION_INCLUDE_DIR=\"$(incdir)\"\ |
60 | -DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"\ | 64 | -DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"\ |
61 | -DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)" | 65 | -DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)" |
diff --git a/src/cmdline.opt b/src/cmdline.opt index 53bdd00..b61517b 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt | |||
@@ -18,6 +18,7 @@ static struct obstack pp_cmd_stack; | |||
18 | static int pp_cmd_stack_init; | 18 | static int pp_cmd_stack_init; |
19 | 19 | ||
20 | static gl_list_t source_list; | 20 | static gl_list_t source_list; |
21 | static gl_list_t tag_list; | ||
21 | 22 | ||
22 | static bool | 23 | static bool |
23 | source_eq (const void *elt1, const void *elt2) | 24 | source_eq (const void *elt1, const void *elt2) |
@@ -28,9 +29,10 @@ source_eq (const void *elt1, const void *elt2) | |||
28 | int | 29 | int |
29 | enabled_spool_p (const struct spool *spool) | 30 | enabled_spool_p (const struct spool *spool) |
30 | { | 31 | { |
31 | if (!source_list) | 32 | if (source_list || tag_list) |
32 | return 1; | 33 | return (source_list && gl_list_search (source_list, spool->source_dir)) |
33 | return !!gl_list_search (source_list, spool->source_dir); | 34 | || (tag_list && gl_list_search (tag_list, spool->tag)); |
35 | return 1; | ||
34 | } | 36 | } |
35 | 37 | ||
36 | OPTIONS_BEGIN(gnu, "wydawca", | 38 | OPTIONS_BEGIN(gnu, "wydawca", |
@@ -61,12 +63,47 @@ BEGIN | |||
61 | dry_run_mode = 1; | 63 | dry_run_mode = 1; |
62 | END | 64 | END |
63 | 65 | ||
66 | OPTION(cron,,, | ||
67 | [<force cron mode>]) | ||
68 | BEGIN | ||
69 | cron_option = 1; | ||
70 | log_to_stderr = 0; | ||
71 | END | ||
72 | |||
73 | OPTION(force,,, | ||
74 | [<force start up even if the pid file already exists>]) | ||
75 | BEGIN | ||
76 | force_startup = 1; | ||
77 | END | ||
78 | |||
79 | OPTION(foreground,,, | ||
80 | [<foreground mode>]) | ||
81 | BEGIN | ||
82 | foreground_option = 1; | ||
83 | END | ||
84 | |||
85 | OPTION(single-process,,, | ||
86 | [<single process mode>]) | ||
87 | BEGIN | ||
88 | single_process_option = 1; | ||
89 | END | ||
90 | |||
64 | OPTION(config-file,c,FILE, | 91 | OPTION(config-file,c,FILE, |
65 | [<use FILE instead of the default configuration>]) | 92 | [<use FILE instead of the default configuration>]) |
66 | BEGIN | 93 | BEGIN |
67 | conffile = optarg; | 94 | conffile = optarg; |
68 | END | 95 | END |
69 | 96 | ||
97 | OPTION(spool,S,TAG, | ||
98 | [<process only spool with the given tag>]) | ||
99 | BEGIN | ||
100 | if (!tag_list) | ||
101 | tag_list = gl_list_create_empty (&gl_linked_list_implementation, | ||
102 | source_eq, NULL, | ||
103 | NULL, false); | ||
104 | gl_list_add_last (tag_list, optarg); | ||
105 | END | ||
106 | |||
70 | OPTION(source,s,SOURCE-DIR, | 107 | OPTION(source,s,SOURCE-DIR, |
71 | [<process only spool with the given source (may be used multiple times)>]) | 108 | [<process only spool with the given source (may be used multiple times)>]) |
72 | BEGIN | 109 | BEGIN |
@@ -79,9 +116,8 @@ END | |||
79 | 116 | ||
80 | GROUP(Logging) | 117 | GROUP(Logging) |
81 | 118 | ||
82 | OPTION(cron,,, | 119 | OPTION(syslog,,, |
83 | [<log to syslog>]) | 120 | [<log to syslog>]) |
84 | ALIAS(syslog) | ||
85 | BEGIN | 121 | BEGIN |
86 | log_to_stderr = 0; | 122 | log_to_stderr = 0; |
87 | END | 123 | END |
diff --git a/src/config.c b/src/config.c index dd444fe..94afb20 100644 --- a/src/config.c +++ b/src/config.c | |||
@@ -263,11 +263,6 @@ cb_mailer (enum gconf_callback_command cmd, | |||
263 | 263 | ||
264 | if (assert_string_arg (locus, cmd, value)) | 264 | if (assert_string_arg (locus, cmd, value)) |
265 | return 1; | 265 | return 1; |
266 | if (cmd != gconf_callback_set_value) | ||
267 | { | ||
268 | gconf_error (locus, 0, _("Unexpected block statement")); | ||
269 | return 1; | ||
270 | } | ||
271 | rc = mu_mailer_create (&mailer, value->v.string); | 266 | rc = mu_mailer_create (&mailer, value->v.string); |
272 | if (rc) | 267 | if (rc) |
273 | gconf_error (locus, 0, _("cannot create mailer `%s': %s"), | 268 | gconf_error (locus, 0, _("cannot create mailer `%s': %s"), |
@@ -1085,22 +1080,17 @@ cb_access_method (enum gconf_callback_command cmd, | |||
1085 | } | 1080 | } |
1086 | 1081 | ||
1087 | static int | 1082 | static int |
1088 | cb_destination_url (enum gconf_callback_command cmd, | 1083 | cb_url (enum gconf_callback_command cmd, |
1089 | gconf_locus_t *locus, | 1084 | gconf_locus_t *locus, |
1090 | void *varptr, | 1085 | void *varptr, |
1091 | gconf_value_t *value, | 1086 | gconf_value_t *value, |
1092 | void *cb_data) | 1087 | void *cb_data) |
1093 | { | 1088 | { |
1094 | mu_url_t *purl = varptr, url; | 1089 | mu_url_t *purl = varptr, url; |
1095 | int rc; | 1090 | int rc; |
1096 | 1091 | ||
1097 | if (assert_string_arg (locus, cmd, value)) | 1092 | if (assert_string_arg (locus, cmd, value)) |
1098 | return 1; | 1093 | return 1; |
1099 | if (cmd != gconf_callback_set_value) | ||
1100 | { | ||
1101 | gconf_error (locus, 0, _("Unexpected block statement")); | ||
1102 | return 1; | ||
1103 | } | ||
1104 | rc = mu_url_create (&url, value->v.string); | 1094 | rc = mu_url_create (&url, value->v.string); |
1105 | if (rc) | 1095 | if (rc) |
1106 | { | 1096 | { |
@@ -1122,11 +1112,15 @@ cb_destination_url (enum gconf_callback_command cmd, | |||
1122 | 1112 | ||
1123 | 1113 | ||
1124 | static struct gconf_keyword spool_kw[] = { | 1114 | static struct gconf_keyword spool_kw[] = { |
1115 | { "url", N_("arg"), N_("URL corresponding to this spool"), | ||
1116 | gconf_type_string, NULL, offsetof(struct spool, url) }, | ||
1117 | { "alias", N_("arg"), N_("Aliases"), | ||
1118 | gconf_type_string|GCONF_LIST, NULL, offsetof(struct spool, aliases) }, | ||
1125 | { "source", N_("dir"), N_("Source directory"), | 1119 | { "source", N_("dir"), N_("Source directory"), |
1126 | gconf_type_string, NULL, offsetof(struct spool, source_dir) }, | 1120 | gconf_type_string, NULL, offsetof(struct spool, source_dir) }, |
1127 | { "destination", N_("dir"), N_("Destination directory"), | 1121 | { "destination", N_("dir"), N_("Destination directory"), |
1128 | gconf_type_string, NULL, offsetof(struct spool, dest_url), | 1122 | gconf_type_string, NULL, offsetof(struct spool, dest_url), |
1129 | cb_destination_url }, | 1123 | cb_url }, |
1130 | { "file-sweep-time", N_("interval"), N_("Define file sweep time"), | 1124 | { "file-sweep-time", N_("interval"), N_("Define file sweep time"), |
1131 | gconf_type_string, NULL, offsetof(struct spool, file_sweep_time), | 1125 | gconf_type_string, NULL, offsetof(struct spool, file_sweep_time), |
1132 | cb_interval }, | 1126 | cb_interval }, |
@@ -1164,7 +1158,7 @@ cb_spool (enum gconf_callback_command cmd, | |||
1164 | return 1; | 1158 | return 1; |
1165 | } | 1159 | } |
1166 | spool = xzalloc (sizeof (*spool)); | 1160 | spool = xzalloc (sizeof (*spool)); |
1167 | spool->url = xstrdup (value->v.string); | 1161 | spool->tag = xstrdup (value->v.string); |
1168 | spool->file_sweep_time = file_sweep_time; | 1162 | spool->file_sweep_time = file_sweep_time; |
1169 | for (i = 0; i < NITEMS (spool->access_method); i++) | 1163 | for (i = 0; i < NITEMS (spool->access_method); i++) |
1170 | spool->access_method[i] = default_access_method[i]; | 1164 | spool->access_method[i] = default_access_method[i]; |
@@ -1233,6 +1227,18 @@ cb_spool (enum gconf_callback_command cmd, | |||
1233 | 1227 | ||
1234 | 1228 | ||
1235 | static struct gconf_keyword wydawca_kw[] = { | 1229 | static struct gconf_keyword wydawca_kw[] = { |
1230 | { "daemon", NULL, N_("Enable daemon mode"), | ||
1231 | gconf_type_bool, &daemon_mode }, | ||
1232 | { "foreground", NULL, N_("Start in foreground even in daemon mode"), | ||
1233 | gconf_type_bool, &foreground }, | ||
1234 | { "single-process", NULL, N_("Do not spawn subprocesses"), | ||
1235 | gconf_type_bool, &single_process }, | ||
1236 | { "wakeup-interval", N_("time"), N_("Set wake-up interval"), | ||
1237 | gconf_type_string, &wakeup_interval, 0, cb_interval }, | ||
1238 | { "pidfile", N_("file"), N_("Set pid file name"), | ||
1239 | gconf_type_string, &pidfile }, | ||
1240 | { "listen", N_("socket"), N_("Listen on this address"), | ||
1241 | gconf_type_sockaddr, &listen_sockaddr, }, | ||
1236 | { "mailer", N_("url"), N_("Set mailer URL"), | 1242 | { "mailer", N_("url"), N_("Set mailer URL"), |
1237 | gconf_type_string, &mailer, 0, cb_mailer }, | 1243 | gconf_type_string, &mailer, 0, cb_mailer }, |
1238 | { "admin-address", N_("email"), N_("Set admin email address"), | 1244 | { "admin-address", N_("email"), N_("Set admin email address"), |
diff --git a/src/directive.c b/src/directive.c index 46e3196..37ce241 100644 --- a/src/directive.c +++ b/src/directive.c | |||
@@ -302,7 +302,7 @@ verify_directive_format (struct file_triplet *trp) | |||
302 | 302 | ||
303 | /* Process the directives from TRP, using given SPOOL */ | 303 | /* Process the directives from TRP, using given SPOOL */ |
304 | int | 304 | int |
305 | process_directives (struct file_triplet *trp, struct spool *spool) | 305 | process_directives (struct file_triplet *trp, const struct spool *spool) |
306 | { | 306 | { |
307 | int rc, n; | 307 | int rc, n; |
308 | const char *key, *val; | 308 | const char *key, *val; |
diff --git a/src/diskio.c b/src/diskio.c index 69a3cbe..ccff5c2 100644 --- a/src/diskio.c +++ b/src/diskio.c | |||
@@ -305,7 +305,7 @@ tar_append_file (const char *archive, const char *file) | |||
305 | Do nothing if dry_run_mode is set. */ | 305 | Do nothing if dry_run_mode is set. */ |
306 | int | 306 | int |
307 | backup_file (const char *dst_file, const char *dst_dir, const char *file, | 307 | backup_file (const char *dst_file, const char *dst_dir, const char *file, |
308 | struct archive_descr *archive, uid_t uid, gid_t gid, | 308 | const struct archive_descr *archive, uid_t uid, gid_t gid, |
309 | const char *reldir) | 309 | const char *reldir) |
310 | { | 310 | { |
311 | int rc = 0; | 311 | int rc = 0; |
@@ -380,7 +380,7 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, | |||
380 | for the argument description. */ | 380 | for the argument description. */ |
381 | int | 381 | int |
382 | do_archive_file (const char *dst_file, const char *dst_dir, const char *file, | 382 | do_archive_file (const char *dst_file, const char *dst_dir, const char *file, |
383 | struct archive_descr *archive, uid_t uid, gid_t gid, | 383 | const struct archive_descr *archive, uid_t uid, gid_t gid, |
384 | const char *reldir) | 384 | const char *reldir) |
385 | { | 385 | { |
386 | switch (archive->type) | 386 | switch (archive->type) |
@@ -410,7 +410,7 @@ do_archive_file (const char *dst_file, const char *dst_dir, const char *file, | |||
410 | 410 | ||
411 | Do nothing if dry_run_mode is set. */ | 411 | Do nothing if dry_run_mode is set. */ |
412 | int | 412 | int |
413 | dir_move_file (struct file_triplet *trp, struct spool *spool, | 413 | dir_move_file (struct file_triplet *trp, const struct spool *spool, |
414 | enum file_type file_id, const char *reldir) | 414 | enum file_type file_id, const char *reldir) |
415 | { | 415 | { |
416 | char *dst_file; | 416 | char *dst_file; |
@@ -447,7 +447,7 @@ dir_move_file (struct file_triplet *trp, struct spool *spool, | |||
447 | Do nothing if dry_run_mode is set. | 447 | Do nothing if dry_run_mode is set. |
448 | */ | 448 | */ |
449 | int | 449 | int |
450 | archive_single_file (struct file_triplet *trp, struct spool *spool, | 450 | archive_single_file (struct file_triplet *trp, const struct spool *spool, |
451 | const char *file_name, const char *reldir, | 451 | const char *file_name, const char *reldir, |
452 | int noentok) | 452 | int noentok) |
453 | { | 453 | { |
@@ -517,7 +517,7 @@ make_signame (const char *file_name) | |||
517 | Do nothing if dry_run_mode is set. | 517 | Do nothing if dry_run_mode is set. |
518 | */ | 518 | */ |
519 | int | 519 | int |
520 | dir_archive_file (struct file_triplet *trp, struct spool *spool, | 520 | dir_archive_file (struct file_triplet *trp, const struct spool *spool, |
521 | const char *reldir, const char *file_name) | 521 | const char *reldir, const char *file_name) |
522 | { | 522 | { |
523 | int rc; | 523 | int rc; |
@@ -537,7 +537,7 @@ dir_archive_file (struct file_triplet *trp, struct spool *spool, | |||
537 | 537 | ||
538 | Do nothing if dry_run_mode is set. */ | 538 | Do nothing if dry_run_mode is set. */ |
539 | int | 539 | int |
540 | dir_symlink_file (struct file_triplet *trp, struct spool *spool, | 540 | dir_symlink_file (struct file_triplet *trp, const struct spool *spool, |
541 | const char *reldir, | 541 | const char *reldir, |
542 | const char *wanted_src, const char *wanted_dst) | 542 | const char *wanted_src, const char *wanted_dst) |
543 | { | 543 | { |
@@ -697,7 +697,7 @@ do_rmsymlink_file (const char *dst_file, int noentok) | |||
697 | 697 | ||
698 | Do nothing if dry_run_mode is set. */ | 698 | Do nothing if dry_run_mode is set. */ |
699 | int | 699 | int |
700 | dir_rmsymlink_file (struct file_triplet *trp, struct spool *spool, | 700 | dir_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, |
701 | const char *reldir, const char *file_name) | 701 | const char *reldir, const char *file_name) |
702 | { | 702 | { |
703 | char *dst_file; | 703 | char *dst_file; |
@@ -203,7 +203,7 @@ gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig) | |||
203 | /* FIXME: spool currently unused */ | 203 | /* FIXME: spool currently unused */ |
204 | int | 204 | int |
205 | verify_directive_signature (struct file_triplet *trp, | 205 | verify_directive_signature (struct file_triplet *trp, |
206 | struct spool *spool, const char *pubkey) | 206 | const struct spool *spool, const char *pubkey) |
207 | { | 207 | { |
208 | gpgme_ctx_t ctx; | 208 | gpgme_ctx_t ctx; |
209 | gpgme_data_t key_data, directive_data, plain; | 209 | gpgme_data_t key_data, directive_data, plain; |
@@ -261,7 +261,7 @@ verify_directive_signature (struct file_triplet *trp, | |||
261 | a previous call to verify_directive_signature). */ | 261 | a previous call to verify_directive_signature). */ |
262 | int | 262 | int |
263 | verify_detached_signature (struct file_triplet *trp, | 263 | verify_detached_signature (struct file_triplet *trp, |
264 | struct spool *spool) | 264 | const struct spool *spool) |
265 | { | 265 | { |
266 | gpgme_engine_info_t info; | 266 | gpgme_engine_info_t info; |
267 | const char *argv[5]; | 267 | const char *argv[5]; |
diff --git a/src/job.c b/src/job.c new file mode 100644 index 0000000..9678139 --- a/dev/null +++ b/src/job.c | |||
@@ -0,0 +1,278 @@ | |||
1 | /* wydawca - automatic release submission daemon | ||
2 | Copyright (C) 2009 Sergey Poznyakoff | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU General Public License as published by the | ||
6 | Free Software Foundation; either version 3 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License along | ||
15 | with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #include "wydawca.h" | ||
18 | |||
19 | #define STATE_FINISHED 0x01 | ||
20 | #define STATE_QUEUED 0x02 | ||
21 | #define STATE_ACTIVE 0x04 | ||
22 | |||
23 | struct job | ||
24 | { | ||
25 | struct job *next, *prev; | ||
26 | int state; | ||
27 | const struct spool *spool; | ||
28 | uid_t uid; | ||
29 | pid_t pid; | ||
30 | time_t timestamp; | ||
31 | int exit_status; | ||
32 | }; | ||
33 | |||
34 | struct job *queue; | ||
35 | size_t jobmax; | ||
36 | size_t jobcnt; | ||
37 | |||
38 | struct job * | ||
39 | job_locate (const struct spool *spool, uid_t uid) | ||
40 | { | ||
41 | struct job *p; | ||
42 | for (p = queue; p; p = p->next) | ||
43 | if (p->spool == spool && p->uid == uid) | ||
44 | break; | ||
45 | return p; | ||
46 | } | ||
47 | |||
48 | size_t | ||
49 | job_active_count () | ||
50 | { | ||
51 | struct job *job; | ||
52 | size_t count = 0; | ||
53 | for (job = queue; job; job = job->next) | ||
54 | if (job->state & STATE_ACTIVE) | ||
55 | count++; | ||
56 | return count; | ||
57 | } | ||
58 | |||
59 | void | ||
60 | wydawca_scanner (struct job *job) | ||
61 | { | ||
62 | scan_spool (job->spool, 1, &job->uid); | ||
63 | mail_finish (); | ||
64 | } | ||
65 | |||
66 | int | ||
67 | job_start (struct job *job) | ||
68 | { | ||
69 | pid_t pid; | ||
70 | |||
71 | if (jobmax && jobcnt == jobmax) | ||
72 | { | ||
73 | logmsg (LOG_NOTICE, "maximum number of processes active"); | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | if (debug_level) | ||
78 | logmsg (LOG_DEBUG, _("starting job: %s, %lu"), job->spool->tag, job->uid); | ||
79 | |||
80 | if (single_process) | ||
81 | { | ||
82 | wydawca_scanner (job); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | pid = fork (); | ||
87 | if (pid == 0) | ||
88 | { | ||
89 | wydawca_scanner (job); | ||
90 | exit (0); | ||
91 | } | ||
92 | else if (pid == -1) | ||
93 | { | ||
94 | logmsg (LOG_CRIT, "fork: %s", strerror (errno)); | ||
95 | return -1; | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | job->state = STATE_ACTIVE; | ||
100 | job->pid = pid; | ||
101 | jobcnt++; | ||
102 | } | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | void | ||
107 | job_remove (struct job *job) | ||
108 | { | ||
109 | struct job *p; | ||
110 | |||
111 | if (debug_level) | ||
112 | logmsg (LOG_DEBUG, _("removing job: %s, %lu"), job->spool->tag, job->uid); | ||
113 | p = job->prev; | ||
114 | if (p) | ||
115 | p->next = job->next; | ||
116 | else | ||
117 | queue = job->next; | ||
118 | |||
119 | p = job->next; | ||
120 | if (p) | ||
121 | p->prev = job->prev; | ||
122 | } | ||
123 | |||
124 | void | ||
125 | job_insert (struct job *job, struct job *elt) | ||
126 | { | ||
127 | struct job *p; | ||
128 | |||
129 | job->prev = elt; | ||
130 | if (!elt) | ||
131 | { | ||
132 | if (queue) | ||
133 | queue->prev = job; | ||
134 | job->next = queue; | ||
135 | queue = job; | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | p = elt->next; | ||
140 | elt->next = job; | ||
141 | |||
142 | if (p) | ||
143 | p->prev = job; | ||
144 | } | ||
145 | |||
146 | int | ||
147 | schedule_job (const struct spool *spool, uid_t uid) | ||
148 | { | ||
149 | struct job *job; | ||
150 | |||
151 | if (debug_level) | ||
152 | logmsg (LOG_DEBUG, _("scheduling job: %s, %lu"), spool->tag, uid); | ||
153 | |||
154 | job = job_locate (spool, uid); | ||
155 | if (!job) | ||
156 | { | ||
157 | job = xzalloc (sizeof (*job)); | ||
158 | job->spool = spool; | ||
159 | job->uid = uid; | ||
160 | job->pid = -1; | ||
161 | time (&job->timestamp); | ||
162 | job_insert (job, NULL); | ||
163 | } | ||
164 | |||
165 | job->state |= STATE_QUEUED; | ||
166 | job_start (job); | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | print_status (struct job *job, int expect_term) | ||
171 | { | ||
172 | struct passwd *pw = getpwuid (job->uid); | ||
173 | int status = job->exit_status; | ||
174 | |||
175 | if (WIFEXITED (status)) | ||
176 | { | ||
177 | if (WEXITSTATUS (status) == 0) | ||
178 | { | ||
179 | if (debug_level) | ||
180 | logmsg (LOG_DEBUG, | ||
181 | _("%lu (%s, %s) exited successfully"), | ||
182 | (unsigned long) job->pid, job->spool->tag, pw->pw_name); | ||
183 | } | ||
184 | else | ||
185 | logmsg (LOG_ERR, | ||
186 | _("%lu (%s, %s) failed with status %d"), | ||
187 | (unsigned long) job->pid, job->spool->tag, pw->pw_name, | ||
188 | WEXITSTATUS (status)); | ||
189 | } | ||
190 | else if (WIFSIGNALED (status)) | ||
191 | { | ||
192 | int prio; | ||
193 | if (expect_term && WTERMSIG (status) == SIGTERM) | ||
194 | { | ||
195 | if (!debug_level) | ||
196 | return; | ||
197 | prio = LOG_DEBUG; | ||
198 | } | ||
199 | else | ||
200 | prio = LOG_ERR; | ||
201 | |||
202 | logmsg (prio, | ||
203 | _("%lu (%s, %s) terminated on signal %d"), | ||
204 | job->pid, job->spool->tag, pw->pw_name, WTERMSIG (status)); | ||
205 | } | ||
206 | else if (WIFSTOPPED (status)) | ||
207 | logmsg (LOG_NOTICE, | ||
208 | _("%lu (%s, %s) stopped on signal %d"), | ||
209 | job->pid, job->spool->tag, pw->pw_name, WSTOPSIG (status)); | ||
210 | #ifdef WCOREDUMP | ||
211 | else if (WCOREDUMP (status)) | ||
212 | logmsg (LOG_NOTICE, | ||
213 | _("%lu (%s, %s) dumped core"), | ||
214 | job->pid, job->spool->tag, pw->pw_name); | ||
215 | #endif | ||
216 | else | ||
217 | logmsg (LOG_ERR, | ||
218 | _("%lu (%s, %s) terminated with unrecognized status"), | ||
219 | job->pid, job->spool->tag, pw->pw_name); | ||
220 | } | ||
221 | |||
222 | static int wakeup; | ||
223 | |||
224 | RETSIGTYPE | ||
225 | queue_signal (int sig) | ||
226 | { | ||
227 | wakeup = 1; | ||
228 | signal (sig, queue_signal); | ||
229 | } | ||
230 | |||
231 | void | ||
232 | job_queue_runner () | ||
233 | { | ||
234 | int status; | ||
235 | struct job *job; | ||
236 | |||
237 | if (!wakeup) | ||
238 | return; | ||
239 | wakeup = 0; | ||
240 | |||
241 | for (;;) | ||
242 | { | ||
243 | pid_t pid = waitpid ((pid_t)-1, &status, WNOHANG); | ||
244 | if (pid <= 0) | ||
245 | break; | ||
246 | for (job = queue; job; job = job->next) | ||
247 | { | ||
248 | if ((job->state & STATE_ACTIVE) && job->pid == pid) | ||
249 | { | ||
250 | job->state &= ~STATE_ACTIVE; | ||
251 | job->state |= STATE_FINISHED; | ||
252 | job->exit_status = status; | ||
253 | jobcnt--; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | |||
258 | for (job = queue; job;) | ||
259 | { | ||
260 | struct job *next = job->next; | ||
261 | if (job->state & STATE_FINISHED) | ||
262 | { | ||
263 | print_status (job, 0); | ||
264 | if ((job->state &= ~STATE_FINISHED) == 0) | ||
265 | job_remove (job); | ||
266 | } | ||
267 | if (job->state == STATE_QUEUED) | ||
268 | if (job_start (job)) | ||
269 | pause (); | ||
270 | job = next; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | void | ||
275 | job_init () | ||
276 | { | ||
277 | signal (SIGCHLD, queue_signal); | ||
278 | } | ||
@@ -104,7 +104,10 @@ void | |||
104 | mail_finish () | 104 | mail_finish () |
105 | { | 105 | { |
106 | if (mailer_opened) | 106 | if (mailer_opened) |
107 | mu_mailer_close (mailer); | 107 | { |
108 | mu_mailer_close (mailer); | ||
109 | mailer_opened = 0; | ||
110 | } | ||
108 | } | 111 | } |
109 | 112 | ||
110 | 113 | ||
@@ -269,14 +272,14 @@ get_recipient (struct access_method *method, struct file_triplet *trp, | |||
269 | 272 | ||
270 | if (method->type == method_none) | 273 | if (method->type == method_none) |
271 | { | 274 | { |
272 | *errp = "access method is not configured"; | 275 | *errp = N_("access method is not configured"); |
273 | return NULL; | 276 | return NULL; |
274 | } | 277 | } |
275 | 278 | ||
276 | md = method_open (method); | 279 | md = method_open (method); |
277 | if (!md) | 280 | if (!md) |
278 | { | 281 | { |
279 | *errp = "failed to open access method"; | 282 | *errp = N_("failed to open access method"); |
280 | return NULL; | 283 | return NULL; |
281 | } | 284 | } |
282 | 285 | ||
@@ -289,7 +292,7 @@ get_recipient (struct access_method *method, struct file_triplet *trp, | |||
289 | free (text); | 292 | free (text); |
290 | if (rc) | 293 | if (rc) |
291 | { | 294 | { |
292 | *errp = "cannot obtain recipient emails"; | 295 | *errp = N_("cannot obtain recipient emails"); |
293 | method_close (method, md); | 296 | method_close (method, md); |
294 | return NULL; | 297 | return NULL; |
295 | } | 298 | } |
@@ -299,7 +302,7 @@ get_recipient (struct access_method *method, struct file_triplet *trp, | |||
299 | 302 | ||
300 | if (nrows == 0) | 303 | if (nrows == 0) |
301 | { | 304 | { |
302 | *errp = "cannot obtain recipient emails"; | 305 | *errp = N_("cannot obtain recipient emails"); |
303 | return NULL; | 306 | return NULL; |
304 | } | 307 | } |
305 | 308 | ||
@@ -350,7 +353,7 @@ do_notify (struct file_triplet *trp, enum notification_event ev, | |||
350 | logmsg (LOG_ERR, _("not notifying %s (project %s) about %s: %s"), | 353 | logmsg (LOG_ERR, _("not notifying %s (project %s) about %s: %s"), |
351 | notification_target_str (ntf->tgt), | 354 | notification_target_str (ntf->tgt), |
352 | trp->project, | 355 | trp->project, |
353 | notification_event_str (ev), errp); | 356 | notification_event_str (ev), gettext (errp)); |
354 | return; | 357 | return; |
355 | } | 358 | } |
356 | 359 | ||
diff --git a/src/net.c b/src/net.c new file mode 100644 index 0000000..efb6225 --- a/dev/null +++ b/src/net.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* wydawca - automatic release submission daemon | ||
2 | Copyright (C) 2007, 2009 Sergey Poznyakoff | ||
3 | |||
4 | Wydawca is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU General Public License as published by the | ||
6 | Free Software Foundation; either version 3 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | Wydawca is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License along | ||
15 | with wydawca. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #include "wydawca.h" | ||
18 | |||
19 | static int | ||
20 | open_listener () | ||
21 | { | ||
22 | int fd; | ||
23 | |||
24 | if (listen_sockaddr.sa == NULL) | ||
25 | { | ||
26 | logmsg (LOG_CRIT, _("listener address is not configured")); | ||
27 | exit (1); | ||
28 | } | ||
29 | |||
30 | fd = socket (listen_sockaddr.sa->sa_family, SOCK_STREAM, 0); | ||
31 | if (fd == -1) | ||
32 | { | ||
33 | logmsg (LOG_CRIT, _("cannot create socket: %s"), | ||
34 | strerror(errno)); | ||
35 | exit (1); | ||
36 | } | ||
37 | if (listen_sockaddr.sa->sa_family == AF_UNIX) | ||
38 | { | ||
39 | struct stat st; | ||
40 | struct sockaddr_un *s_un = (struct sockaddr_un *) listen_sockaddr.sa; | ||
41 | if (stat (s_un->sun_path, &st)) | ||
42 | { | ||
43 | if (errno != ENOENT) | ||
44 | { | ||
45 | logmsg (LOG_CRIT, _("%s: cannot stat socket: %s"), | ||
46 | s_un->sun_path, strerror (errno)); | ||
47 | exit (1); | ||
48 | } | ||
49 | } | ||
50 | else | ||
51 | { | ||
52 | /* FIXME: Check permissions? */ | ||
53 | if (!S_ISSOCK (st.st_mode)) | ||
54 | { | ||
55 | logmsg (LOG_CRIT, _("%s: not a socket"), | ||
56 | s_un->sun_path, strerror (errno)); | ||
57 | exit (1); | ||
58 | } | ||
59 | unlink (s_un->sun_path); | ||
60 | } | ||
61 | /* FIXME: Setup umask */ | ||
62 | } | ||
63 | else | ||
64 | { | ||
65 | int yes = 1; | ||
66 | setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void *) &yes, sizeof(yes)); | ||
67 | } | ||
68 | |||
69 | if (bind (fd, listen_sockaddr.sa, listen_sockaddr.len) < 0) | ||
70 | { | ||
71 | logmsg (LOG_CRIT, _("cannot bind to local address: %s"), | ||
72 | strerror (errno)); | ||
73 | close (fd); | ||
74 | exit (1); | ||
75 | } | ||
76 | if (listen (fd, 8) == -1) | ||
77 | { | ||
78 | logmsg (LOG_CRIT, "listen: %s", strerror (errno)); | ||
79 | close (fd); | ||
80 | exit (1); | ||
81 | } | ||
82 | |||
83 | return fd; | ||
84 | } | ||
85 | |||
86 | static void | ||
87 | trim_crlf (char *s) | ||
88 | { | ||
89 | size_t len = strlen (s); | ||
90 | if (len > 0 && s[len-1] == '\n') | ||
91 | { | ||
92 | s[--len] = 0; | ||
93 | if (len > 0 && s[len-1] == '\r') | ||
94 | s[--len] = 0; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | void | ||
99 | handle_connection (FILE *fp) | ||
100 | { | ||
101 | char *buf = NULL; | ||
102 | size_t buflen = 0; | ||
103 | const struct spool *spool; | ||
104 | char *p; | ||
105 | struct passwd *pw; | ||
106 | |||
107 | if (getline (&buf, &buflen, fp) <= 0) | ||
108 | return; | ||
109 | trim_crlf (buf); | ||
110 | if (debug_level) | ||
111 | logmsg (LOG_DEBUG, "recv: %s", buf); | ||
112 | spool = wydawca_find_spool (buf); | ||
113 | if (!spool) | ||
114 | { | ||
115 | fprintf (fp, "- Unknown service name\r\n"); | ||
116 | free (buf); | ||
117 | return; | ||
118 | } | ||
119 | else if (spool->url) | ||
120 | fprintf (fp, "+ OK, URL %s\r\n", spool->url); | ||
121 | else | ||
122 | fprintf (fp, "+ OK, spool %s\r\n", spool->tag); | ||
123 | |||
124 | if (getline (&buf, &buflen, fp) <= 0) | ||
125 | { | ||
126 | logmsg (LOG_ERR, "protocol error"); | ||
127 | free (buf); | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | if (debug_level) | ||
132 | logmsg (LOG_DEBUG, "recv: %s", buf); | ||
133 | |||
134 | p = strchr (buf, ' '); | ||
135 | if (p) | ||
136 | { | ||
137 | *p++ = 0; | ||
138 | while (*p && (*p == ' ' || *p == '\t')) | ||
139 | p++; | ||
140 | } | ||
141 | else | ||
142 | p = ""; | ||
143 | |||
144 | pw = getpwnam (buf); | ||
145 | if (pw) | ||
146 | schedule_job (spool, pw->pw_uid); | ||
147 | else | ||
148 | logmsg (LOG_ERR, "no such user: %s", buf); | ||
149 | free (buf); | ||
150 | } | ||
151 | |||
152 | static int reconfigure; | ||
153 | static int terminate; | ||
154 | |||
155 | RETSIGTYPE | ||
156 | sig_hup (int sig) | ||
157 | { | ||
158 | reconfigure = 1; | ||
159 | terminate = 1; | ||
160 | } | ||
161 | |||
162 | RETSIGTYPE | ||
163 | sig_term (int sig) | ||
164 | { | ||
165 | terminate = 1; | ||
166 | } | ||
167 | |||
168 | void | ||
169 | wydawca_listener () | ||
170 | { | ||
171 | int ctlfd = open_listener (); | ||
172 | |||
173 | job_init (); | ||
174 | signal (SIGHUP, sig_hup); | ||
175 | signal (SIGTERM, sig_term); | ||
176 | signal (SIGQUIT, sig_term); | ||
177 | signal (SIGINT, sig_term); | ||
178 | while (!terminate) | ||
179 | { | ||
180 | int fd; | ||
181 | FILE *fp; | ||
182 | int rc; | ||
183 | fd_set rset; | ||
184 | struct timeval to, *pto; | ||
185 | union { | ||
186 | struct sockaddr sa; | ||
187 | struct sockaddr_in s_in; | ||
188 | struct sockaddr_un s_un; | ||
189 | } addr; | ||
190 | socklen_t len; | ||
191 | |||
192 | job_queue_runner (); | ||
193 | FD_ZERO (&rset); | ||
194 | FD_SET (ctlfd, &rset); | ||
195 | |||
196 | if (wakeup_interval) | ||
197 | { | ||
198 | to.tv_sec = wakeup_interval; | ||
199 | to.tv_usec = 0; | ||
200 | *pto = to; | ||
201 | } | ||
202 | else | ||
203 | pto = NULL; | ||
204 | |||
205 | rc = select (ctlfd + 1, &rset, NULL, NULL, pto); | ||
206 | if (rc == 0) | ||
207 | continue; | ||
208 | else if (rc < 0) | ||
209 | { | ||
210 | if (errno == EINTR) | ||
211 | continue; | ||
212 | logmsg (LOG_ERR, "select: %s", strerror (errno)); | ||
213 | break; | ||
214 | } | ||
215 | |||
216 | len = sizeof (addr); | ||
217 | fd = accept (ctlfd, (struct sockaddr*) &addr, &len); | ||
218 | if (fd == -1) | ||
219 | continue; | ||
220 | /* FIXME: Check if the connection is allowed */ | ||
221 | fp = fdopen (fd, "r+"); | ||
222 | handle_connection (fp); | ||
223 | fclose (fp); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | |||
@@ -17,13 +17,13 @@ | |||
17 | #include "wydawca.h" | 17 | #include "wydawca.h" |
18 | 18 | ||
19 | int | 19 | int |
20 | null_move_file (struct file_triplet *trp, struct spool *spool, | 20 | null_move_file (struct file_triplet *trp, const struct spool *spool, |
21 | enum file_type file_id, const char *reldir) | 21 | enum file_type file_id, const char *reldir) |
22 | { | 22 | { |
23 | const char *file_name = trp->file[file_id].name; | 23 | const char *file_name = trp->file[file_id].name; |
24 | if (debug_level) | 24 | if (debug_level) |
25 | logmsg (LOG_DEBUG, _("%s: installing file `%s/%s'"), | 25 | logmsg (LOG_DEBUG, _("spool %s: installing file `%s/%s'"), |
26 | spool->url, reldir, file_name); | 26 | spool->tag, reldir, file_name); |
27 | UPDATE_STATS (STAT_UPLOADS); | 27 | UPDATE_STATS (STAT_UPLOADS); |
28 | if (unlink (file_name)) | 28 | if (unlink (file_name)) |
29 | { | 29 | { |
@@ -35,34 +35,34 @@ null_move_file (struct file_triplet *trp, struct spool *spool, | |||
35 | } | 35 | } |
36 | 36 | ||
37 | int | 37 | int |
38 | null_archive_file (struct file_triplet *trp, struct spool *spool, | 38 | null_archive_file (struct file_triplet *trp, const struct spool *spool, |
39 | const char *file_name, const char *reldir) | 39 | const char *file_name, const char *reldir) |
40 | { | 40 | { |
41 | if (debug_level) | 41 | if (debug_level) |
42 | logmsg (LOG_DEBUG, _("%s: archiving `%s'"), spool->url, file_name); | 42 | logmsg (LOG_DEBUG, _("spool %s: archiving `%s'"), spool->tag, file_name); |
43 | UPDATE_STATS (STAT_ARCHIVES); | 43 | UPDATE_STATS (STAT_ARCHIVES); |
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | int | 47 | int |
48 | null_symlink_file (struct file_triplet *trp, struct spool *spool, | 48 | null_symlink_file (struct file_triplet *trp, const struct spool *spool, |
49 | const char *reldir, | 49 | const char *reldir, |
50 | const char *wanted_src, const char *wanted_dst) | 50 | const char *wanted_src, const char *wanted_dst) |
51 | { | 51 | { |
52 | if (debug_level) | 52 | if (debug_level) |
53 | logmsg (LOG_DEBUG, _("%s: symlinking `%s' to `%s'"), | 53 | logmsg (LOG_DEBUG, _("spool %s: symlinking `%s' to `%s'"), |
54 | spool->url, wanted_src, wanted_dst); | 54 | spool->tag, wanted_src, wanted_dst); |
55 | UPDATE_STATS (STAT_SYMLINKS); | 55 | UPDATE_STATS (STAT_SYMLINKS); |
56 | return 0; | 56 | return 0; |
57 | } | 57 | } |
58 | 58 | ||
59 | int | 59 | int |
60 | null_rmsymlink_file (struct file_triplet *trp, struct spool *spool, | 60 | null_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, |
61 | const char *reldir, const char *file_name) | 61 | const char *reldir, const char *file_name) |
62 | { | 62 | { |
63 | if (debug_level) | 63 | if (debug_level) |
64 | logmsg (LOG_DEBUG, _("%s: removing symlink `%s/%s'"), | 64 | logmsg (LOG_DEBUG, _("spool %s: removing symlink `%s/%s'"), |
65 | spool->url, reldir, file_name); | 65 | spool->tag, reldir, file_name); |
66 | UPDATE_STATS (STAT_RMSYMLINKS); | 66 | UPDATE_STATS (STAT_RMSYMLINKS); |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
diff --git a/src/pidfile.c b/src/pidfile.c new file mode 100644 index 0000000..484cabd --- a/dev/null +++ b/src/pidfile.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* wydawca - automatic release submission daemon | ||
2 | Copyright (C) 2007, 2009 Sergey Poznyakoff | ||
3 | |||
4 | Wydawca is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU General Public License as published by the | ||
6 | Free Software Foundation; either version 3 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | Wydawca is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License along | ||
15 | with wydawca. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #include "wydawca.h" | ||
18 | |||
19 | char *pidfile = LOCALSTATEDIR "/run/wydawca.pid"; | ||
20 | int force_startup; | ||
21 | |||
22 | |||
23 | void | ||
24 | remove_pidfile (void) | ||
25 | { | ||
26 | unlink (pidfile); | ||
27 | } | ||
28 | |||
29 | void | ||
30 | check_pidfile () | ||
31 | { | ||
32 | FILE *fp = fopen (pidfile, "r+"); | ||
33 | |||
34 | if (fp) | ||
35 | { | ||
36 | unsigned long pid; | ||
37 | if (fscanf (fp, "%ul\n", &pid) != 1) | ||
38 | { | ||
39 | logmsg (LOG_ERR, _("malformed pidfile %s"), pidfile); | ||
40 | if (!force_startup) | ||
41 | exit (1); | ||
42 | } | ||
43 | else | ||
44 | { | ||
45 | if (kill (pid, 0)) | ||
46 | { | ||
47 | if (errno != ESRCH) | ||
48 | { | ||
49 | logmsg (LOG_ERR, | ||
50 | _("cannot verify if PID %lu is running: %s"), | ||
51 | pid, strerror (errno)); | ||
52 | if (!force_startup) | ||
53 | exit (1); | ||
54 | } | ||
55 | } | ||
56 | else if (!force_startup) | ||
57 | { | ||
58 | logmsg (LOG_ERR, | ||
59 | _("another wydawca instance may be running (PID %lu)"), | ||
60 | pid); | ||
61 | exit (1); | ||
62 | } | ||
63 | } | ||
64 | logmsg (LOG_NOTICE, _("replacing pidfile %s (PID %lu)"), | ||
65 | pidfile, pid); | ||
66 | fseek (fp, 0, SEEK_SET); | ||
67 | } | ||
68 | else if (errno != ENOENT) | ||
69 | { | ||
70 | logmsg (LOG_ERR, _("cannot open pidfile %s: %s"), pidfile, | ||
71 | strerror (errno)); | ||
72 | exit (1); | ||
73 | } | ||
74 | else | ||
75 | { | ||
76 | fp = fopen (pidfile, "w"); | ||
77 | if (!fp) | ||
78 | { | ||
79 | logmsg (LOG_ERR, | ||
80 | _("cannot open pidfile %s for writing: %s"), | ||
81 | pidfile, strerror (errno)); | ||
82 | exit (1); | ||
83 | } | ||
84 | } | ||
85 | fprintf (fp, "%lu\n", getpid ()); | ||
86 | fclose (fp); | ||
87 | atexit (remove_pidfile); | ||
88 | } | ||
89 | |||
90 | |||
diff --git a/src/process.c b/src/process.c index 0d2bf5e..20bfd38 100644 --- a/src/process.c +++ b/src/process.c | |||
@@ -33,6 +33,41 @@ register_spool (struct spool *spool) | |||
33 | spool_list = sp; | 33 | spool_list = sp; |
34 | } | 34 | } |
35 | 35 | ||
36 | static int | ||
37 | spool_check_alias (struct spool *spool, const char *name) | ||
38 | { | ||
39 | int rc = 0; | ||
40 | |||
41 | if (spool->aliases) | ||
42 | { | ||
43 | gl_list_iterator_t itr = gl_list_iterator (spool->aliases); | ||
44 | const void *p; | ||
45 | |||
46 | while (gl_list_iterator_next (&itr, &p, NULL)) | ||
47 | if (strcmp (name, p) == 0) | ||
48 | { | ||
49 | rc = 1; | ||
50 | break; | ||
51 | } | ||
52 | gl_list_iterator_free (&itr); | ||
53 | } | ||
54 | return rc; | ||
55 | } | ||
56 | |||
57 | struct spool * | ||
58 | wydawca_find_spool (const char *name) | ||
59 | { | ||
60 | struct spool_list *sp; | ||
61 | |||
62 | for (sp = spool_list; sp; sp = sp->next) | ||
63 | { | ||
64 | if (strcmp (sp->spool.tag, name) == 0 | ||
65 | || spool_check_alias (&sp->spool, name)) | ||
66 | return &sp->spool; | ||
67 | } | ||
68 | return NULL; | ||
69 | } | ||
70 | |||
36 | /* Return true if NAME is a directory. If stat fails, return the error | 71 | /* Return true if NAME is a directory. If stat fails, return the error |
37 | code in EC */ | 72 | code in EC */ |
38 | int | 73 | int |
@@ -100,10 +135,22 @@ parse_file_name (const char *name, struct file_info *finfo) | |||
100 | abort (); /* should not happen */ | 135 | abort (); /* should not happen */ |
101 | } | 136 | } |
102 | 137 | ||
138 | int | ||
139 | match_uid_p (uid_t uid, int uc, uid_t *uv) | ||
140 | { | ||
141 | int i; | ||
142 | if (!uv) | ||
143 | return 1; | ||
144 | for (i = 0; i < uc; i++) | ||
145 | if (uv[i] == uid) | ||
146 | return 1; | ||
147 | return 0; | ||
148 | } | ||
149 | |||
103 | /* Scan upload directory from the DPAIR and register all files found | 150 | /* Scan upload directory from the DPAIR and register all files found |
104 | there, forming triplets when possible */ | 151 | there, forming triplets when possible */ |
105 | void | 152 | void |
106 | scan_spool (struct spool *spool) | 153 | scan_spool (const struct spool *spool, int uc, uid_t *uv) |
107 | { | 154 | { |
108 | DIR *dir; | 155 | DIR *dir; |
109 | struct dirent *ent; | 156 | struct dirent *ent; |
@@ -127,8 +174,9 @@ scan_spool (struct spool *spool) | |||
127 | return; | 174 | return; |
128 | } | 175 | } |
129 | 176 | ||
130 | timer_start ("directory"); | 177 | timer_start ("spool"); |
131 | timer_start (spool->url); | 178 | /* FIXME: prefix spool tag with something */ |
179 | timer_start (spool->tag); | ||
132 | while ((ent = readdir (dir))) | 180 | while ((ent = readdir (dir))) |
133 | { | 181 | { |
134 | struct stat st; | 182 | struct stat st; |
@@ -152,7 +200,7 @@ scan_spool (struct spool *spool) | |||
152 | continue; | 200 | continue; |
153 | } | 201 | } |
154 | 202 | ||
155 | if (!match_uid_p (st.st_uid)) | 203 | if (!match_uid_p (st.st_uid, uc, uv)) |
156 | { | 204 | { |
157 | if (debug_level) | 205 | if (debug_level) |
158 | logmsg (LOG_DEBUG, _("ignoring file: %s/%s"), | 206 | logmsg (LOG_DEBUG, _("ignoring file: %s/%s"), |
@@ -164,7 +212,7 @@ scan_spool (struct spool *spool) | |||
164 | parse_file_name (ent->d_name, &finfo); | 212 | parse_file_name (ent->d_name, &finfo); |
165 | 213 | ||
166 | if (debug_level) | 214 | if (debug_level) |
167 | logmsg (LOG_DEBUG, _("file %s: %s, root %.*s"), ent->d_name, | 215 | logmsg (LOG_DEBUG, _("found file %s: %s, stem: %.*s"), ent->d_name, |
168 | file_type_str (finfo.type), finfo.root_len, finfo.name); | 216 | file_type_str (finfo.type), finfo.root_len, finfo.name); |
169 | 217 | ||
170 | register_file (&finfo); | 218 | register_file (&finfo); |
@@ -186,8 +234,8 @@ scan_spool (struct spool *spool) | |||
186 | } | 234 | } |
187 | enumerate_triplets (spool); | 235 | enumerate_triplets (spool); |
188 | } | 236 | } |
189 | timer_stop (spool->url); | 237 | timer_stop (spool->tag); |
190 | timer_stop ("directory"); | 238 | timer_stop ("spool"); |
191 | } | 239 | } |
192 | 240 | ||
193 | static void | 241 | static void |
@@ -200,7 +248,7 @@ close_methods (struct spool *spool) | |||
200 | 248 | ||
201 | /* Scan all configured update directories */ | 249 | /* Scan all configured update directories */ |
202 | void | 250 | void |
203 | scan_directories () | 251 | scan_directories (int uidc, uid_t *uidv) |
204 | { | 252 | { |
205 | struct spool_list *sp; | 253 | struct spool_list *sp; |
206 | 254 | ||
@@ -208,7 +256,7 @@ scan_directories () | |||
208 | 256 | ||
209 | for (sp = spool_list; sp; sp = sp->next) | 257 | for (sp = spool_list; sp; sp = sp->next) |
210 | if (enabled_spool_p (&sp->spool)) | 258 | if (enabled_spool_p (&sp->spool)) |
211 | scan_spool (&sp->spool); | 259 | scan_spool (&sp->spool, uidc, uidv); |
212 | 260 | ||
213 | for (sp = spool_list; sp; sp = sp->next) | 261 | for (sp = spool_list; sp; sp = sp->next) |
214 | close_methods (&sp->spool); | 262 | close_methods (&sp->spool); |
diff --git a/src/triplet.c b/src/triplet.c index 6641211..717fd2a 100644 --- a/src/triplet.c +++ b/src/triplet.c | |||
@@ -182,7 +182,7 @@ static bool | |||
182 | triplet_processor (void *data, void *proc_data) | 182 | triplet_processor (void *data, void *proc_data) |
183 | { | 183 | { |
184 | struct file_triplet *trp = data; | 184 | struct file_triplet *trp = data; |
185 | struct spool *spool = proc_data; | 185 | const struct spool *spool = proc_data; |
186 | 186 | ||
187 | trp->spool = spool; | 187 | trp->spool = spool; |
188 | 188 | ||
@@ -230,14 +230,14 @@ triplet_processor (void *data, void *proc_data) | |||
230 | 230 | ||
231 | /* Process all triplets from the table according to the SPOOL */ | 231 | /* Process all triplets from the table according to the SPOOL */ |
232 | void | 232 | void |
233 | enumerate_triplets (struct spool *spool) | 233 | enumerate_triplets (const struct spool *spool) |
234 | { | 234 | { |
235 | if (debug_level) | 235 | if (debug_level) |
236 | logmsg (LOG_DEBUG, _("processing files for %s (%s)"), | 236 | logmsg (LOG_DEBUG, _("processing spool %s (%s)"), |
237 | spool->url, mu_url_to_string (spool->dest_url)); | 237 | spool->tag, mu_url_to_string (spool->dest_url)); |
238 | if (triplet_table) | 238 | if (triplet_table) |
239 | { | 239 | { |
240 | hash_do_for_each (triplet_table, triplet_processor, spool); | 240 | hash_do_for_each (triplet_table, triplet_processor, (void*) spool); |
241 | hash_clear (triplet_table); | 241 | hash_clear (triplet_table); |
242 | } | 242 | } |
243 | } | 243 | } |
@@ -257,6 +257,13 @@ expand_project_base (struct metadef *def, void *data) | |||
257 | } | 257 | } |
258 | 258 | ||
259 | static const char * | 259 | static const char * |
260 | expand_tag (struct metadef *def, void *data) | ||
261 | { | ||
262 | struct file_triplet *trp = data; | ||
263 | return trp->spool->tag; | ||
264 | } | ||
265 | |||
266 | static const char * | ||
260 | expand_url (struct metadef *def, void *data) | 267 | expand_url (struct metadef *def, void *data) |
261 | { | 268 | { |
262 | struct file_triplet *trp = data; | 269 | struct file_triplet *trp = data; |
@@ -576,6 +583,7 @@ DECL_EXPAND_TIMER(system) | |||
576 | struct metadef triplet_meta[] = { | 583 | struct metadef triplet_meta[] = { |
577 | { "project", NULL, expand_project_base, NULL }, | 584 | { "project", NULL, expand_project_base, NULL }, |
578 | { "url", NULL, expand_url, NULL }, | 585 | { "url", NULL, expand_url, NULL }, |
586 | { "spool", NULL, expand_tag, NULL }, | ||
579 | { "dir", NULL, expand_relative_dir, NULL }, | 587 | { "dir", NULL, expand_relative_dir, NULL }, |
580 | { "dest-dir", NULL, expand_dest_dir, NULL }, | 588 | { "dest-dir", NULL, expand_dest_dir, NULL }, |
581 | { "source-dir", NULL, expand_source_dir, NULL }, | 589 | { "source-dir", NULL, expand_source_dir, NULL }, |
diff --git a/src/verify.c b/src/verify.c index 14651d2..522b865 100644 --- a/src/verify.c +++ b/src/verify.c | |||
@@ -92,7 +92,7 @@ make_default_meta (struct metadef def[5], const char *user, | |||
92 | /* Verify if USER has upload rights on the directory (project) requested | 92 | /* Verify if USER has upload rights on the directory (project) requested |
93 | by TRP */ | 93 | by TRP */ |
94 | int | 94 | int |
95 | check_access_rights (struct file_triplet *trp, struct spool *spool, | 95 | check_access_rights (struct file_triplet *trp, const struct spool *spool, |
96 | const char *user) | 96 | const char *user) |
97 | { | 97 | { |
98 | struct access_method *method = spool->access_method[verify_method]; | 98 | struct access_method *method = spool->access_method[verify_method]; |
@@ -143,7 +143,7 @@ check_access_rights (struct file_triplet *trp, struct spool *spool, | |||
143 | } | 143 | } |
144 | 144 | ||
145 | int | 145 | int |
146 | verify_directive_file (struct file_triplet *trp, struct spool *spool) | 146 | verify_directive_file (struct file_triplet *trp, const struct spool *spool) |
147 | { | 147 | { |
148 | struct passwd *pw; | 148 | struct passwd *pw; |
149 | char *command; | 149 | char *command; |
@@ -51,7 +51,7 @@ url_to_vtab (mu_url_t url, struct virt_tab *vtab) | |||
51 | 51 | ||
52 | 52 | ||
53 | int | 53 | int |
54 | move_file (struct file_triplet *trp, struct spool *spool, | 54 | move_file (struct file_triplet *trp, const const struct spool *spool, |
55 | enum file_type file_id, const char *reldir) | 55 | enum file_type file_id, const char *reldir) |
56 | { | 56 | { |
57 | int rc = spool->vtab.move_file (trp, spool, file_id, reldir); | 57 | int rc = spool->vtab.move_file (trp, spool, file_id, reldir); |
@@ -61,7 +61,7 @@ move_file (struct file_triplet *trp, struct spool *spool, | |||
61 | } | 61 | } |
62 | 62 | ||
63 | int | 63 | int |
64 | archive_file (struct file_triplet *trp, struct spool *spool, | 64 | archive_file (struct file_triplet *trp, const struct spool *spool, |
65 | const char *reldir, const char *file_name) | 65 | const char *reldir, const char *file_name) |
66 | { | 66 | { |
67 | int rc = spool->vtab.archive_file (trp, spool, reldir, file_name); | 67 | int rc = spool->vtab.archive_file (trp, spool, reldir, file_name); |
@@ -71,7 +71,7 @@ archive_file (struct file_triplet *trp, struct spool *spool, | |||
71 | } | 71 | } |
72 | 72 | ||
73 | int | 73 | int |
74 | symlink_file (struct file_triplet *trp, struct spool *spool, | 74 | symlink_file (struct file_triplet *trp, const struct spool *spool, |
75 | const char *reldir, | 75 | const char *reldir, |
76 | const char *wanted_src, const char *wanted_dst) | 76 | const char *wanted_src, const char *wanted_dst) |
77 | { | 77 | { |
@@ -84,7 +84,7 @@ symlink_file (struct file_triplet *trp, struct spool *spool, | |||
84 | } | 84 | } |
85 | 85 | ||
86 | int | 86 | int |
87 | rmsymlink_file (struct file_triplet *trp, struct spool *spool, | 87 | rmsymlink_file (struct file_triplet *trp, const struct spool *spool, |
88 | const char *reldir, const char *file_name) | 88 | const char *reldir, const char *file_name) |
89 | { | 89 | { |
90 | int rc = spool->vtab.rmsymlink_file (trp, spool, reldir, file_name); | 90 | int rc = spool->vtab.rmsymlink_file (trp, spool, reldir, file_name); |
diff --git a/src/wydawca.c b/src/wydawca.c index ce78fc1..cc6c8f0 100644 --- a/src/wydawca.c +++ b/src/wydawca.c | |||
@@ -32,6 +32,16 @@ char *tar_command_name = "tar"; | |||
32 | int archive_signatures = 1; /* Archive sig files by default */ | 32 | int archive_signatures = 1; /* Archive sig files by default */ |
33 | int lint_mode = 0; | 33 | int lint_mode = 0; |
34 | int preprocess_only = 0; | 34 | int preprocess_only = 0; |
35 | int cron_option = 0; | ||
36 | int foreground_option = -1; | ||
37 | int single_process_option = -1; | ||
38 | |||
39 | int daemon_mode = 0; | ||
40 | int foreground; | ||
41 | int single_process; | ||
42 | time_t wakeup_interval; | ||
43 | |||
44 | struct gconf_sockaddr listen_sockaddr; | ||
35 | 45 | ||
36 | unsigned wydawca_stat[MAX_STAT]; | 46 | unsigned wydawca_stat[MAX_STAT]; |
37 | 47 | ||
@@ -106,46 +116,20 @@ logmsg (int prio, char *fmt, ...) | |||
106 | } | 116 | } |
107 | 117 | ||
108 | 118 | ||
109 | |||
110 | enum { | ||
111 | SYSLOG_OPTION = 256, | ||
112 | CONFIG_HELP_OPTION, | ||
113 | DUMP_GRAMMAR_TRACE_OPTION, | ||
114 | DUMP_LEX_TRACE_OPTION | ||
115 | }; | ||
116 | |||
117 | struct option options[] = { | ||
118 | { "config-file", required_argument, NULL, 'c' }, | ||
119 | { "config-help", no_argument, NULL, CONFIG_HELP_OPTION }, | ||
120 | { "dump-grammar-trace", no_argument, NULL, DUMP_GRAMMAR_TRACE_OPTION }, | ||
121 | { "dump-lex-trace", no_argument, NULL, DUMP_LEX_TRACE_OPTION }, | ||
122 | { "debug", no_argument, NULL, 'd' }, | ||
123 | { "stderr", no_argument, NULL, 'e' }, | ||
124 | { "syslog", no_argument, NULL, SYSLOG_OPTION }, | ||
125 | { "cron", no_argument, NULL, SYSLOG_OPTION }, | ||
126 | { "help", no_argument, NULL, 'h' }, | ||
127 | { "version", no_argument, NULL, 'v' }, | ||
128 | { "dry-run", no_argument, NULL, 'n' }, | ||
129 | { "lint", no_argument, NULL, 't' }, | ||
130 | { "include-directory", optional_argument, NULL, 'I' }, | ||
131 | { NULL } | ||
132 | }; | ||
133 | |||
134 | |||
135 | static char *stat_name[MAX_STAT] = { | 119 | static char *stat_name[MAX_STAT] = { |
136 | "errors", | 120 | N_("errors"), |
137 | "warnings", | 121 | N_("warnings"), |
138 | "bad signatures", | 122 | N_("bad signatures"), |
139 | "access violation attempts", | 123 | N_("access violation attempts"), |
140 | "complete triplets", | 124 | N_("complete triplets"), |
141 | "incomplete triplets", | 125 | N_("incomplete triplets"), |
142 | "bad triplets", | 126 | N_("bad triplets"), |
143 | "expired triplets", | 127 | N_("expired triplets"), |
144 | "triplet successes", | 128 | N_("triplet successes"), |
145 | "files uploaded", | 129 | N_("files uploaded"), |
146 | "files archived", | 130 | N_("files archived"), |
147 | "symlinks created", | 131 | N_("symlinks created"), |
148 | "symlinks removed", | 132 | N_("symlinks removed"), |
149 | }; | 133 | }; |
150 | 134 | ||
151 | static char *stat_kwname[MAX_STAT] = { | 135 | static char *stat_kwname[MAX_STAT] = { |
@@ -212,7 +196,7 @@ logstats () | |||
212 | { | 196 | { |
213 | for (i = 0; i < MAX_STAT; i++) | 197 | for (i = 0; i < MAX_STAT; i++) |
214 | if (print_stats & STAT_MASK (i)) | 198 | if (print_stats & STAT_MASK (i)) |
215 | logmsg (LOG_INFO, "%s: %u", stat_name[i], wydawca_stat[i]); | 199 | logmsg (LOG_INFO, "%s: %u", gettext (stat_name[i]), wydawca_stat[i]); |
216 | } | 200 | } |
217 | 201 | ||
218 | mail_stats (); | 202 | mail_stats (); |
@@ -244,7 +228,7 @@ gconf_print_diag (gconf_locus_t *locus, int err, int errcode, const char *msg) | |||
244 | 228 | ||
245 | 229 | ||
246 | static int uidc; | 230 | static int uidc; |
247 | static char *uidv; | 231 | static uid_t *uidv; |
248 | 232 | ||
249 | static int | 233 | static int |
250 | collect_uids (int argc, char **argv) | 234 | collect_uids (int argc, char **argv) |
@@ -272,18 +256,6 @@ collect_uids (int argc, char **argv) | |||
272 | } | 256 | } |
273 | } | 257 | } |
274 | 258 | ||
275 | int | ||
276 | match_uid_p (uid_t uid) | ||
277 | { | ||
278 | int i; | ||
279 | if (!uidv) | ||
280 | return 1; | ||
281 | for (i = 0; i < uidc; i++) | ||
282 | if (uidv[i] == uid) | ||
283 | return 1; | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | 259 | ||
288 | int | 260 | int |
289 | wydawca_uid (uid_t uid) | 261 | wydawca_uid (uid_t uid) |
@@ -308,6 +280,21 @@ wydawca_uid (uid_t uid) | |||
308 | } | 280 | } |
309 | 281 | ||
310 | 282 | ||
283 | void | ||
284 | wydawca_daemon () | ||
285 | { | ||
286 | check_pidfile (); | ||
287 | |||
288 | if (!foreground && daemon (0, 0)) | ||
289 | { | ||
290 | logmsg (LOG_ERR, "%s", strerror (errno)); | ||
291 | exit (1); | ||
292 | } | ||
293 | |||
294 | wydawca_listener (); | ||
295 | } | ||
296 | |||
297 | |||
311 | #include "cmdline.h" | 298 | #include "cmdline.h" |
312 | 299 | ||
313 | int | 300 | int |
@@ -333,8 +320,15 @@ main (int argc, char **argv) | |||
333 | if (lint_mode) | 320 | if (lint_mode) |
334 | exit (0); | 321 | exit (0); |
335 | 322 | ||
323 | if (cron_option) | ||
324 | daemon_mode = 0; | ||
325 | if (foreground_option >= 0) | ||
326 | foreground = foreground_option; | ||
327 | if (single_process_option >= 0) | ||
328 | single_process = single_process_option; | ||
329 | |||
336 | if (log_to_stderr == -1) | 330 | if (log_to_stderr == -1) |
337 | log_to_stderr = isatty (0); | 331 | log_to_stderr = (!daemon_mode || foreground) && isatty (0); |
338 | 332 | ||
339 | gconf_log_to_stderr = log_to_stderr; | 333 | gconf_log_to_stderr = log_to_stderr; |
340 | if (!log_to_stderr) | 334 | if (!log_to_stderr) |
@@ -346,10 +340,16 @@ main (int argc, char **argv) | |||
346 | mail_init (); | 340 | mail_init (); |
347 | 341 | ||
348 | logmsg (LOG_NOTICE, _("wydawca (%s) started"), PACKAGE_STRING); | 342 | logmsg (LOG_NOTICE, _("wydawca (%s) started"), PACKAGE_STRING); |
349 | scan_directories (); | ||
350 | 343 | ||
344 | if (!daemon_mode) | ||
345 | { | ||
346 | scan_directories (uidc, uidv); | ||
347 | logstats (); | ||
348 | } | ||
349 | else | ||
350 | wydawca_daemon (); | ||
351 | |||
351 | logmsg (LOG_NOTICE, _("wydawca (%s) finished"), PACKAGE_STRING); | 352 | logmsg (LOG_NOTICE, _("wydawca (%s) finished"), PACKAGE_STRING); |
352 | logstats (); | ||
353 | 353 | ||
354 | mail_finish (); | 354 | mail_finish (); |
355 | 355 | ||
diff --git a/src/wydawca.h b/src/wydawca.h index 3f28919..8a716e4 100644 --- a/src/wydawca.h +++ b/src/wydawca.h | |||
@@ -32,7 +32,14 @@ | |||
32 | #include <limits.h> | 32 | #include <limits.h> |
33 | #include <dirent.h> | 33 | #include <dirent.h> |
34 | #include <sys/stat.h> | 34 | #include <sys/stat.h> |
35 | #include <sys/socket.h> | ||
36 | #include <netinet/in.h> | ||
37 | #include <sys/un.h> | ||
38 | #include <sys/wait.h> | ||
39 | #include <netdb.h> | ||
40 | #include <arpa/inet.h> | ||
35 | #include <fcntl.h> | 41 | #include <fcntl.h> |
42 | #include <time.h> | ||
36 | 43 | ||
37 | #include <mailutils/types.h> | 44 | #include <mailutils/types.h> |
38 | #include <mailutils/url.h> | 45 | #include <mailutils/url.h> |
@@ -47,6 +54,7 @@ | |||
47 | #include "backupfile.h" | 54 | #include "backupfile.h" |
48 | #include "inttostr.h" | 55 | #include "inttostr.h" |
49 | #include "gconf.h" | 56 | #include "gconf.h" |
57 | #include "gl_list.h" | ||
50 | #include "argcv.h" | 58 | #include "argcv.h" |
51 | 59 | ||
52 | #define gettext(s) s | 60 | #define gettext(s) s |
@@ -156,7 +164,7 @@ struct file_triplet | |||
156 | char *name; /* Triplet base name */ | 164 | char *name; /* Triplet base name */ |
157 | gid_t gid; /* Owner GID */ | 165 | gid_t gid; /* Owner GID */ |
158 | struct file_info file[FILE_TYPE_COUNT]; /* Components */ | 166 | struct file_info file[FILE_TYPE_COUNT]; /* Components */ |
159 | struct spool *spool; /* Owning spool */ | 167 | const struct spool *spool; /* Owning spool */ |
160 | char **directive; /* Decoded directive pairs (key: value\0) */ | 168 | char **directive; /* Decoded directive pairs (key: value\0) */ |
161 | char *blurb; /* Block of directives: directive[i] points here */ | 169 | char *blurb; /* Block of directives: directive[i] points here */ |
162 | char *tmp; /* Temporary storage */ | 170 | char *tmp; /* Temporary storage */ |
@@ -179,20 +187,20 @@ struct virt_tab | |||
179 | { | 187 | { |
180 | int (*test_url) (mu_url_t url, gconf_locus_t *loc); | 188 | int (*test_url) (mu_url_t url, gconf_locus_t *loc); |
181 | int (*move_file) (struct file_triplet *trp, | 189 | int (*move_file) (struct file_triplet *trp, |
182 | struct spool *spool, | 190 | const struct spool *spool, |
183 | enum file_type file_id, | 191 | enum file_type file_id, |
184 | const char *reldir); | 192 | const char *reldir); |
185 | int (*archive_file) (struct file_triplet *trp, | 193 | int (*archive_file) (struct file_triplet *trp, |
186 | struct spool *spool, | 194 | const struct spool *spool, |
187 | const char *reldir, | 195 | const char *reldir, |
188 | const char *file_name); | 196 | const char *file_name); |
189 | int (*symlink_file) (struct file_triplet *trp, | 197 | int (*symlink_file) (struct file_triplet *trp, |
190 | struct spool *spool, | 198 | const struct spool *spool, |
191 | const char *reldir, | 199 | const char *reldir, |
192 | const char *wanted_src, | 200 | const char *wanted_src, |
193 | const char *wanted_dst); | 201 | const char *wanted_dst); |
194 | int (*rmsymlink_file)(struct file_triplet *trp, | 202 | int (*rmsymlink_file)(struct file_triplet *trp, |
195 | struct spool *spool, | 203 | const struct spool *spool, |
196 | const char *reldir, | 204 | const char *reldir, |
197 | const char *file_name); | 205 | const char *file_name); |
198 | }; | 206 | }; |
@@ -201,6 +209,8 @@ struct virt_tab | |||
201 | files from source to destination */ | 209 | files from source to destination */ |
202 | struct spool | 210 | struct spool |
203 | { | 211 | { |
212 | char *tag; | ||
213 | gl_list_t aliases; | ||
204 | char *url; /* Download URL */ | 214 | char *url; /* Download URL */ |
205 | char *source_dir; /* Source directory */ | 215 | char *source_dir; /* Source directory */ |
206 | mu_url_t dest_url; /* Destination URL */ | 216 | mu_url_t dest_url; /* Destination URL */ |
@@ -306,6 +316,15 @@ extern int archive_signatures; | |||
306 | 316 | ||
307 | extern char *admin_stat_message; | 317 | extern char *admin_stat_message; |
308 | 318 | ||
319 | extern char *pidfile; | ||
320 | extern int force_startup; | ||
321 | |||
322 | extern int daemon_mode; | ||
323 | extern time_t wakeup_interval; | ||
324 | extern int foreground; | ||
325 | extern int single_process; | ||
326 | extern struct gconf_sockaddr listen_sockaddr; | ||
327 | |||
309 | #define UPDATE_STATS(what) \ | 328 | #define UPDATE_STATS(what) \ |
310 | do \ | 329 | do \ |
311 | { \ | 330 | { \ |
@@ -341,10 +360,13 @@ enum exec_result wydawca_exec (int argc, const char **argv, int *retcode); | |||
341 | 360 | ||
342 | 361 | ||
343 | /* Directory scanning and registering */ | 362 | /* Directory scanning and registering */ |
344 | void scan_directories (void); | 363 | void scan_spool (const struct spool *spool, int uc, uid_t *uv); |
364 | void scan_directories (int, uid_t *); | ||
365 | |||
345 | void register_spool (struct spool *spool); | 366 | void register_spool (struct spool *spool); |
367 | struct spool *wydawca_find_spool (const char *name); | ||
346 | void register_file (struct file_info *finfo); | 368 | void register_file (struct file_info *finfo); |
347 | void enumerate_triplets (struct spool *); | 369 | void enumerate_triplets (const struct spool *); |
348 | size_t count_collected_triplets (void); | 370 | size_t count_collected_triplets (void); |
349 | char *triplet_expand_param (const char *tmpl, struct file_triplet *trp); | 371 | char *triplet_expand_param (const char *tmpl, struct file_triplet *trp); |
350 | 372 | ||
@@ -369,12 +391,12 @@ unsigned method_num_cols (struct access_method *method); | |||
369 | 391 | ||
370 | /* Verification functions */ | 392 | /* Verification functions */ |
371 | int verify_directive_file (struct file_triplet *trp, | 393 | int verify_directive_file (struct file_triplet *trp, |
372 | struct spool *spool); | 394 | const struct spool *spool); |
373 | int verify_directive_signature (struct file_triplet *trp, | 395 | int verify_directive_signature (struct file_triplet *trp, |
374 | struct spool *spool, | 396 | const struct spool *spool, |
375 | const char *pubkey); | 397 | const char *pubkey); |
376 | int verify_detached_signature (struct file_triplet *trp, | 398 | int verify_detached_signature (struct file_triplet *trp, |
377 | struct spool *spool); | 399 | const struct spool *spool); |
378 | int fill_project_name (struct file_triplet *trp); | 400 | int fill_project_name (struct file_triplet *trp); |
379 | 401 | ||
380 | /* Directive file support */ | 402 | /* Directive file support */ |
@@ -390,9 +412,8 @@ int directive_first (struct file_triplet *trp, | |||
390 | int directive_next (struct file_triplet *trp, int n, | 412 | int directive_next (struct file_triplet *trp, int n, |
391 | const char **pkey, const char **pval); | 413 | const char **pkey, const char **pval); |
392 | int process_directives (struct file_triplet *trp, | 414 | int process_directives (struct file_triplet *trp, |
393 | struct spool *spool); | 415 | const struct spool *spool); |
394 | 416 | ||
395 | int match_uid_p (uid_t uid); | ||
396 | int enabled_spool_p (const struct spool *spool); | 417 | int enabled_spool_p (const struct spool *spool); |
397 | 418 | ||
398 | int wydawca_uid (uid_t uid); | 419 | int wydawca_uid (uid_t uid); |
@@ -410,42 +431,42 @@ void config_help (void); | |||
410 | int url_to_vtab (mu_url_t url, struct virt_tab *vtab); | 431 | int url_to_vtab (mu_url_t url, struct virt_tab *vtab); |
411 | 432 | ||
412 | int | 433 | int |
413 | move_file (struct file_triplet *trp, struct spool *spool, | 434 | move_file (struct file_triplet *trp, const struct spool *spool, |
414 | enum file_type file_id, const char *reldir); | 435 | enum file_type file_id, const char *reldir); |
415 | int | 436 | int |
416 | archive_file (struct file_triplet *trp, struct spool *spool, | 437 | archive_file (struct file_triplet *trp, const struct spool *spool, |
417 | const char *reldir, const char *file_name); | 438 | const char *reldir, const char *file_name); |
418 | int | 439 | int |
419 | symlink_file (struct file_triplet *trp, struct spool *spool, | 440 | symlink_file (struct file_triplet *trp, const struct spool *spool, |
420 | const char *reldir, | 441 | const char *reldir, |
421 | const char *wanted_src, const char *wanted_dst); | 442 | const char *wanted_src, const char *wanted_dst); |
422 | int | 443 | int |
423 | rmsymlink_file (struct file_triplet *trp, struct spool *spool, | 444 | rmsymlink_file (struct file_triplet *trp, const struct spool *spool, |
424 | const char *reldir, const char *file_name); | 445 | const char *reldir, const char *file_name); |
425 | 446 | ||
426 | 447 | ||
427 | /* diskio.c */ | 448 | /* diskio.c */ |
428 | 449 | ||
429 | int dir_test_url (mu_url_t url, gconf_locus_t *locus); | 450 | int dir_test_url (mu_url_t url, gconf_locus_t *locus); |
430 | int dir_move_file (struct file_triplet *trp, struct spool *spool, | 451 | int dir_move_file (struct file_triplet *trp, const struct spool *spool, |
431 | enum file_type file_id, const char *reldir); | 452 | enum file_type file_id, const char *reldir); |
432 | int dir_archive_file (struct file_triplet *trp, struct spool *spool, | 453 | int dir_archive_file (struct file_triplet *trp, const struct spool *spool, |
433 | const char *file_name, const char *reldir); | 454 | const char *file_name, const char *reldir); |
434 | int dir_symlink_file (struct file_triplet *trp, struct spool *spool, | 455 | int dir_symlink_file (struct file_triplet *trp, const struct spool *spool, |
435 | const char *reldir, | 456 | const char *reldir, |
436 | const char *wanted_src, const char *wanted_dst); | 457 | const char *wanted_src, const char *wanted_dst); |
437 | int dir_rmsymlink_file (struct file_triplet *trp, struct spool *spool, | 458 | int dir_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, |
438 | const char *reldir, const char *file_name); | 459 | const char *reldir, const char *file_name); |
439 | 460 | ||
440 | /* null.c */ | 461 | /* null.c */ |
441 | int null_move_file (struct file_triplet *trp, struct spool *spool, | 462 | int null_move_file (struct file_triplet *trp, const struct spool *spool, |
442 | enum file_type file_id, const char *reldir); | 463 | enum file_type file_id, const char *reldir); |
443 | int null_archive_file (struct file_triplet *trp, struct spool *spool, | 464 | int null_archive_file (struct file_triplet *trp, const struct spool *spool, |
444 | const char *file_name, const char *reldir); | 465 | const char *file_name, const char *reldir); |
445 | int null_symlink_file (struct file_triplet *trp, struct spool *spool, | 466 | int null_symlink_file (struct file_triplet *trp, const struct spool *spool, |
446 | const char *reldir, | 467 | const char *reldir, |
447 | const char *wanted_src, const char *wanted_dst); | 468 | const char *wanted_src, const char *wanted_dst); |
448 | int null_rmsymlink_file (struct file_triplet *trp, struct spool *spool, | 469 | int null_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, |
449 | const char *reldir, const char *file_name); | 470 | const char *reldir, const char *file_name); |
450 | 471 | ||
451 | 472 | ||
@@ -469,3 +490,17 @@ void report_init (void); | |||
469 | void report_add (const char *fmt, ...); | 490 | void report_add (const char *fmt, ...); |
470 | void report_finish (void); | 491 | void report_finish (void); |
471 | extern char *report_string; | 492 | extern char *report_string; |
493 | |||
494 | |||
495 | /* job.c */ | ||
496 | int schedule_job (const struct spool *spool, uid_t uid); | ||
497 | void job_init (void); | ||
498 | void job_queue_runner (void); | ||
499 | |||
500 | |||
501 | /* profile.c */ | ||
502 | void check_pidfile (void); | ||
503 | |||
504 | |||
505 | /* net.c */ | ||
506 | void wydawca_listener (void); | ||