summaryrefslogtreecommitdiffabout
path: root/src
authorSergey 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)
commit4213ec5ef9695aa504938c0e764ba9a4f08921b2 (patch) (unidiff)
tree88ac2b2eb01337f0924d687df38b2a163bc94e11 /src
parent337a06f32fb530e0e0884fef2f5f630cca9911a1 (diff)
downloadwydawca-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.
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/Makefile.am4
-rw-r--r--src/cmdline.opt48
-rw-r--r--src/config.c40
-rw-r--r--src/directive.c2
-rw-r--r--src/diskio.c14
-rw-r--r--src/gpg.c4
-rw-r--r--src/job.c278
-rw-r--r--src/mail.c15
-rw-r--r--src/net.c227
-rw-r--r--src/null.c22
-rw-r--r--src/pidfile.c90
-rw-r--r--src/process.c66
-rw-r--r--src/triplet.c18
-rw-r--r--src/verify.c4
-rw-r--r--src/vtab.c8
-rw-r--r--src/wydawca.c112
-rw-r--r--src/wydawca.h83
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@
56INCLUDES = -I$(top_srcdir)/gconf -I$(top_srcdir)/gnu -I../gnu @MAILUTILS_INCLUDES@ 59INCLUDES = -I$(top_srcdir)/gconf -I$(top_srcdir)/gnu -I../gnu @MAILUTILS_INCLUDES@
57AM_CPPFLAGS= \ 60AM_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;
18static int pp_cmd_stack_init; 18static int pp_cmd_stack_init;
19 19
20static gl_list_t source_list; 20static gl_list_t source_list;
21static gl_list_t tag_list;
21 22
22static bool 23static bool
23source_eq (const void *elt1, const void *elt2) 24source_eq (const void *elt1, const void *elt2)
@@ -28,9 +29,10 @@ source_eq (const void *elt1, const void *elt2)
28int 29int
29enabled_spool_p (const struct spool *spool) 30enabled_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
36OPTIONS_BEGIN(gnu, "wydawca", 38OPTIONS_BEGIN(gnu, "wydawca",
@@ -61,12 +63,47 @@ BEGIN
61 dry_run_mode = 1; 63 dry_run_mode = 1;
62END 64END
63 65
66OPTION(cron,,,
67 [<force cron mode>])
68BEGIN
69 cron_option = 1;
70 log_to_stderr = 0;
71END
72
73OPTION(force,,,
74 [<force start up even if the pid file already exists>])
75BEGIN
76 force_startup = 1;
77 END
78
79OPTION(foreground,,,
80 [<foreground mode>])
81BEGIN
82 foreground_option = 1;
83END
84
85OPTION(single-process,,,
86 [<single process mode>])
87BEGIN
88 single_process_option = 1;
89 END
90
64OPTION(config-file,c,FILE, 91OPTION(config-file,c,FILE,
65 [<use FILE instead of the default configuration>]) 92 [<use FILE instead of the default configuration>])
66BEGIN 93BEGIN
67 conffile = optarg; 94 conffile = optarg;
68END 95END
69 96
97OPTION(spool,S,TAG,
98 [<process only spool with the given tag>])
99BEGIN
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);
105END
106
70OPTION(source,s,SOURCE-DIR, 107OPTION(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)>])
72BEGIN 109BEGIN
@@ -79,9 +116,8 @@ END
79 116
80GROUP(Logging) 117GROUP(Logging)
81 118
82OPTION(cron,,, 119OPTION(syslog,,,
83 [<log to syslog>]) 120 [<log to syslog>])
84ALIAS(syslog)
85BEGIN 121BEGIN
86 log_to_stderr = 0; 122 log_to_stderr = 0;
87END 123END
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
1087static int 1082static int
1088cb_destination_url (enum gconf_callback_command cmd, 1083cb_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
1124static struct gconf_keyword spool_kw[] = { 1114static 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
1235static struct gconf_keyword wydawca_kw[] = { 1229static 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 */
304int 304int
305process_directives (struct file_triplet *trp, struct spool *spool) 305process_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. */
306int 306int
307backup_file (const char *dst_file, const char *dst_dir, const char *file, 307backup_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. */
381int 381int
382do_archive_file (const char *dst_file, const char *dst_dir, const char *file, 382do_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. */
412int 412int
413dir_move_file (struct file_triplet *trp, struct spool *spool, 413dir_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*/
449int 449int
450archive_single_file (struct file_triplet *trp, struct spool *spool, 450archive_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*/
519int 519int
520dir_archive_file (struct file_triplet *trp, struct spool *spool, 520dir_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. */
539int 539int
540dir_symlink_file (struct file_triplet *trp, struct spool *spool, 540dir_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. */
699int 699int
700dir_rmsymlink_file (struct file_triplet *trp, struct spool *spool, 700dir_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;
diff --git a/src/gpg.c b/src/gpg.c
index d6e2301..6f7dfb6 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -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 */
204int 204int
205verify_directive_signature (struct file_triplet *trp, 205verify_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). */
262int 262int
263verify_detached_signature (struct file_triplet *trp, 263verify_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
23struct 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
34struct job *queue;
35size_t jobmax;
36size_t jobcnt;
37
38struct job *
39job_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
48size_t
49job_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
59void
60wydawca_scanner (struct job *job)
61{
62 scan_spool (job->spool, 1, &job->uid);
63 mail_finish ();
64}
65
66int
67job_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
106void
107job_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
124void
125job_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
146int
147schedule_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
169static void
170print_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
222static int wakeup;
223
224RETSIGTYPE
225queue_signal (int sig)
226{
227 wakeup = 1;
228 signal (sig, queue_signal);
229}
230
231void
232job_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
274void
275job_init ()
276{
277 signal (SIGCHLD, queue_signal);
278}
diff --git a/src/mail.c b/src/mail.c
index 7987819..ea74b8c 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -104,7 +104,10 @@ void
104mail_finish () 104mail_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
19static int
20open_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
86static void
87trim_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
98void
99handle_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
152static int reconfigure;
153static int terminate;
154
155RETSIGTYPE
156sig_hup (int sig)
157{
158 reconfigure = 1;
159 terminate = 1;
160}
161
162RETSIGTYPE
163sig_term (int sig)
164{
165 terminate = 1;
166}
167
168void
169wydawca_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
diff --git a/src/null.c b/src/null.c
index 7ead150..6a1b0a7 100644
--- a/src/null.c
+++ b/src/null.c
@@ -17,13 +17,13 @@
17#include "wydawca.h" 17#include "wydawca.h"
18 18
19int 19int
20null_move_file (struct file_triplet *trp, struct spool *spool, 20null_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
37int 37int
38null_archive_file (struct file_triplet *trp, struct spool *spool, 38null_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
47int 47int
48null_symlink_file (struct file_triplet *trp, struct spool *spool, 48null_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
59int 59int
60null_rmsymlink_file (struct file_triplet *trp, struct spool *spool, 60null_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
19char *pidfile = LOCALSTATEDIR "/run/wydawca.pid";
20int force_startup;
21
22
23void
24remove_pidfile (void)
25{
26 unlink (pidfile);
27}
28
29void
30check_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
36static int
37spool_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
57struct spool *
58wydawca_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 */
38int 73int
@@ -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
138int
139match_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 */
105void 152void
106scan_spool (struct spool *spool) 153scan_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
193static void 241static void
@@ -200,7 +248,7 @@ close_methods (struct spool *spool)
200 248
201/* Scan all configured update directories */ 249/* Scan all configured update directories */
202void 250void
203scan_directories () 251scan_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
182triplet_processor (void *data, void *proc_data) 182triplet_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 */
232void 232void
233enumerate_triplets (struct spool *spool) 233enumerate_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
259static const char * 259static const char *
260expand_tag (struct metadef *def, void *data)
261{
262 struct file_triplet *trp = data;
263 return trp->spool->tag;
264}
265
266static const char *
260expand_url (struct metadef *def, void *data) 267expand_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)
576struct metadef triplet_meta[] = { 583struct 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 */
94int 94int
95check_access_rights (struct file_triplet *trp, struct spool *spool, 95check_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
145int 145int
146verify_directive_file (struct file_triplet *trp, struct spool *spool) 146verify_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;
diff --git a/src/vtab.c b/src/vtab.c
index c34896c..36d8af8 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -51,7 +51,7 @@ url_to_vtab (mu_url_t url, struct virt_tab *vtab)
51 51
52 52
53int 53int
54move_file (struct file_triplet *trp, struct spool *spool, 54move_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
63int 63int
64archive_file (struct file_triplet *trp, struct spool *spool, 64archive_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
73int 73int
74symlink_file (struct file_triplet *trp, struct spool *spool, 74symlink_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
86int 86int
87rmsymlink_file (struct file_triplet *trp, struct spool *spool, 87rmsymlink_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";
32int archive_signatures = 1; /* Archive sig files by default */ 32int archive_signatures = 1; /* Archive sig files by default */
33int lint_mode = 0; 33int lint_mode = 0;
34int preprocess_only = 0; 34int preprocess_only = 0;
35int cron_option = 0;
36int foreground_option = -1;
37int single_process_option = -1;
38
39int daemon_mode = 0;
40int foreground;
41int single_process;
42time_t wakeup_interval;
43
44struct gconf_sockaddr listen_sockaddr;
35 45
36unsigned wydawca_stat[MAX_STAT]; 46unsigned wydawca_stat[MAX_STAT];
37 47
@@ -106,46 +116,20 @@ logmsg (int prio, char *fmt, ...)
106} 116}
107 117
108 118
109
110enum {
111 SYSLOG_OPTION = 256,
112 CONFIG_HELP_OPTION,
113 DUMP_GRAMMAR_TRACE_OPTION,
114 DUMP_LEX_TRACE_OPTION
115};
116
117struct 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
135static char *stat_name[MAX_STAT] = { 119static 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
151static char *stat_kwname[MAX_STAT] = { 135static 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
246static int uidc; 230static int uidc;
247static char *uidv; 231static uid_t *uidv;
248 232
249static int 233static int
250collect_uids (int argc, char **argv) 234collect_uids (int argc, char **argv)
@@ -272,18 +256,6 @@ collect_uids (int argc, char **argv)
272 } 256 }
273} 257}
274 258
275int
276match_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
288int 260int
289wydawca_uid (uid_t uid) 261wydawca_uid (uid_t uid)
@@ -308,6 +280,21 @@ wydawca_uid (uid_t uid)
308} 280}
309 281
310 282
283void
284wydawca_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
313int 300int
@@ -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 */
202struct spool 210struct 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
307extern char *admin_stat_message; 317extern char *admin_stat_message;
308 318
319extern char *pidfile;
320extern int force_startup;
321
322extern int daemon_mode;
323extern time_t wakeup_interval;
324extern int foreground;
325extern int single_process;
326extern 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 */
344void scan_directories (void); 363void scan_spool (const struct spool *spool, int uc, uid_t *uv);
364void scan_directories (int, uid_t *);
365
345void register_spool (struct spool *spool); 366void register_spool (struct spool *spool);
367struct spool *wydawca_find_spool (const char *name);
346void register_file (struct file_info *finfo); 368void register_file (struct file_info *finfo);
347void enumerate_triplets (struct spool *); 369void enumerate_triplets (const struct spool *);
348size_t count_collected_triplets (void); 370size_t count_collected_triplets (void);
349char *triplet_expand_param (const char *tmpl, struct file_triplet *trp); 371char *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 */
371int verify_directive_file (struct file_triplet *trp, 393int verify_directive_file (struct file_triplet *trp,
372 struct spool *spool); 394 const struct spool *spool);
373int verify_directive_signature (struct file_triplet *trp, 395int verify_directive_signature (struct file_triplet *trp,
374 struct spool *spool, 396 const struct spool *spool,
375 const char *pubkey); 397 const char *pubkey);
376int verify_detached_signature (struct file_triplet *trp, 398int verify_detached_signature (struct file_triplet *trp,
377 struct spool *spool); 399 const struct spool *spool);
378int fill_project_name (struct file_triplet *trp); 400int 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,
390int directive_next (struct file_triplet *trp, int n, 412int directive_next (struct file_triplet *trp, int n,
391 const char **pkey, const char **pval); 413 const char **pkey, const char **pval);
392int process_directives (struct file_triplet *trp, 414int process_directives (struct file_triplet *trp,
393 struct spool *spool); 415 const struct spool *spool);
394 416
395int match_uid_p (uid_t uid);
396int enabled_spool_p (const struct spool *spool); 417int enabled_spool_p (const struct spool *spool);
397 418
398int wydawca_uid (uid_t uid); 419int wydawca_uid (uid_t uid);
@@ -410,42 +431,42 @@ void config_help (void);
410int url_to_vtab (mu_url_t url, struct virt_tab *vtab); 431int url_to_vtab (mu_url_t url, struct virt_tab *vtab);
411 432
412int 433int
413move_file (struct file_triplet *trp, struct spool *spool, 434move_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);
415int 436int
416archive_file (struct file_triplet *trp, struct spool *spool, 437archive_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);
418int 439int
419symlink_file (struct file_triplet *trp, struct spool *spool, 440symlink_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);
422int 443int
423rmsymlink_file (struct file_triplet *trp, struct spool *spool, 444rmsymlink_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
429int dir_test_url (mu_url_t url, gconf_locus_t *locus); 450int dir_test_url (mu_url_t url, gconf_locus_t *locus);
430int dir_move_file (struct file_triplet *trp, struct spool *spool, 451int 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);
432int dir_archive_file (struct file_triplet *trp, struct spool *spool, 453int 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);
434int dir_symlink_file (struct file_triplet *trp, struct spool *spool, 455int 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);
437int dir_rmsymlink_file (struct file_triplet *trp, struct spool *spool, 458int 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 */
441int null_move_file (struct file_triplet *trp, struct spool *spool, 462int 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);
443int null_archive_file (struct file_triplet *trp, struct spool *spool, 464int 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);
445int null_symlink_file (struct file_triplet *trp, struct spool *spool, 466int 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);
448int null_rmsymlink_file (struct file_triplet *trp, struct spool *spool, 469int 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);
469void report_add (const char *fmt, ...); 490void report_add (const char *fmt, ...);
470void report_finish (void); 491void report_finish (void);
471extern char *report_string; 492extern char *report_string;
493
494
495/* job.c */
496int schedule_job (const struct spool *spool, uid_t uid);
497void job_init (void);
498void job_queue_runner (void);
499
500
501/* profile.c */
502void check_pidfile (void);
503
504
505/* net.c */
506void wydawca_listener (void);

Return to:

Send suggestions and report system problems to the System administrator.