summaryrefslogtreecommitdiffabout
path: root/src
Side-by-side diff
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/Makefile.am5
-rw-r--r--src/backup.c165
-rw-r--r--src/builtin.c10
-rw-r--r--src/config.c26
-rw-r--r--src/dictionary.c11
-rw-r--r--src/directive.c8
-rw-r--r--src/diskio.c6
-rw-r--r--src/exec.c2
-rw-r--r--src/gpg.c7
-rw-r--r--src/job.c2
-rw-r--r--src/lock.c12
-rw-r--r--src/mail.c14
-rw-r--r--src/net.c4
-rw-r--r--src/process.c4
-rw-r--r--src/sql.c4
-rw-r--r--src/timer.c5
-rw-r--r--src/triplet.c17
-rw-r--r--src/txtacc.c16
-rw-r--r--src/verify.c4
-rw-r--r--src/wydawca.c8
-rw-r--r--src/wydawca.h20
21 files changed, 268 insertions, 82 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8139849..3b524ba 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,71 +1,72 @@
# This file is part of Wydawca
# Copyright (C) 2007, 2009, 2010 Sergey Poznyakoff
#
# Wydawca is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# Wydawca is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Wydawca. If not, see <http://www.gnu.org/licenses/>.
sbin_PROGRAMS=wydawca
wydawca_SOURCES=\
+ backup.c\
builtin.c\
builtin.h\
cmdline.h\
config.c\
dictionary.c\
directive.c\
diskio.c\
exec.c\
gpg.c\
interval.c\
job.c\
lock.c\
meta.c\
net.c\
pidfile.c\
process.c\
pushd.c\
sql.c\
sql.h\
tcpwrap.c\
triplet.c\
userprivs.c\
verify.c\
wydawca.c\
wydawca.h\
mail.h\
mail.c\
vtab.c\
null.c\
timer.c\
txtacc.c\
report.c
BUILT_SOURCES=cmdline.h
EXTRA_DIST=cmdline.opt pp-setup update-2.0.awk
SUFFIXES=.opt .c .h
.opt.h:
$(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@
incdir=$(pkgdatadir)/$(VERSION)/include
inc_DATA = $(PP_SETUP_FILE)
-LDADD=../grecs/src/libgrecs.a ../gnu/libgnu.a @SQLLIB@ @GPGMELIB@ @MAILUTILS_LIBS@
-INCLUDES = -I$(top_srcdir)/grecs/src/ -I$(top_srcdir)/gnu -I../gnu @MAILUTILS_INCLUDES@
+LDADD=../grecs/src/libgrecs.a @SQLLIB@ @GPGMELIB@ @MAILUTILS_LIBS@
+INCLUDES = -I$(top_srcdir)/grecs/src/ @MAILUTILS_INCLUDES@
AM_CPPFLAGS= \
-DSYSCONFDIR=\"$(sysconfdir)\"\
-DLOCALSTATEDIR=\"$(localstatedir)\"\
-DDEFAULT_VERSION_INCLUDE_DIR=\"$(incdir)\"\
-DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"\
-DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)"
diff --git a/src/backup.c b/src/backup.c
new file mode 100644
index 0000000..312375d
--- a/dev/null
+++ b/src/backup.c
@@ -0,0 +1,165 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 2011 Sergey Poznyakoff
+
+ Wydawca is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ Wydawca is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with wydawca. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "wydawca.h"
+
+char const *simple_backup_suffix = "~";
+
+static const char *
+split_filename (char const *file, char **pdir)
+{
+ const char *p = strrchr (file, '/');
+
+ if (!p)
+ {
+ *pdir = grecs_strdup (".");
+ p = file;
+ }
+ else
+ {
+ size_t len = p - file;
+ char *dir = grecs_malloc (len + 1);
+ memcpy (dir, file, len);
+ dir[len] = 0;
+ *pdir = dir;
+ p++;
+ }
+ return p;
+}
+
+#define MINSUFSIZE 8
+#define ISDIGIT(c) ('0' <= (c) && (c) <= '9')
+
+static char *
+get_backup_suffix (char const *file, enum backup_type type)
+{
+ char *dirname;
+ const char *basename;
+ size_t baselen;
+ DIR *dir;
+ struct dirent *ent;
+ char *lastsuf = NULL;
+ size_t lastsuflen = 0;
+ size_t lastsufsize = 0;
+ int carry;
+ char *newsuf;
+ char *q;
+
+ if (type == simple_backups)
+ return grecs_strdup (simple_backup_suffix);
+
+ basename = split_filename (file, &dirname);
+ baselen = strlen (basename);
+ dir = opendir (dirname);
+ if (!dir)
+ {
+ int ec = errno;
+ free (dirname);
+ errno = ec;
+ return NULL;
+ }
+
+ while ((ent = readdir (dir)))
+ {
+ size_t len = strlen (ent->d_name);
+ const char *p;
+ size_t suflen;
+
+ if (len < baselen + 4 || memcmp (ent->d_name, basename, baselen))
+ continue;
+ p = ent->d_name + baselen;
+ suflen = len - baselen;
+ if (p[0] == '.' && p[1] == '~' && p[suflen-1] == '~' &&
+ (suflen > lastsuflen
+ || (suflen == lastsuflen &&
+ memcmp (p, lastsuf, lastsuflen) > 0)))
+ {
+ carry = 1;
+ for (q = (char*) p + suflen - 2; q > p + 1 && ISDIGIT (*q); q--)
+ if (*q != '9')
+ carry = 0;
+ q++;
+ if (!ISDIGIT (*q))
+ continue;
+
+ if (suflen > lastsufsize)
+ {
+ lastsufsize = suflen;
+ if (!lastsuf)
+ {
+ if (lastsufsize < MINSUFSIZE)
+ lastsufsize = MINSUFSIZE;
+ lastsuf = grecs_malloc (lastsufsize);
+ }
+ else
+ lastsuf = grecs_realloc (lastsuf, lastsufsize);
+ }
+ memcpy (lastsuf, p, suflen);
+ lastsuflen = suflen;
+ }
+ }
+ closedir (dir);
+ free (dirname);
+
+ if (lastsuf)
+ {
+ size_t newsuflen;
+
+ newsuflen = lastsuflen + carry;
+ newsuf = grecs_malloc (newsuflen + 1);
+ newsuf[0] = '.';
+ newsuf[1] = '~';
+ newsuf[2] = '0';
+ memcpy (newsuf + 2 + carry, lastsuf + 2, lastsuflen - 3);
+ newsuf[newsuflen-1] = '~';
+ newsuf[newsuflen] = 0;
+
+ for (q = newsuf + newsuflen - 2; *q == '9'; q--)
+ *q = '0';
+ ++*q;
+ free (lastsuf);
+ }
+ else if (type == numbered_existing_backups)
+ newsuf = grecs_strdup (simple_backup_suffix);
+ else
+ newsuf = grecs_strdup (".~1~");
+ return newsuf;
+}
+
+char *
+find_backup_file_name (char const *file, enum backup_type type)
+{
+ size_t flen;
+ char *suffix;
+ char *newname;
+
+ if (type == no_backups)
+ {
+ errno = 0;
+ return NULL;
+ }
+
+ suffix = get_backup_suffix (file, type);
+ if (!suffix)
+ return NULL;
+ flen = strlen (file);
+ newname = grecs_malloc (flen + strlen (suffix) + 1);
+ memcpy (newname, file, flen);
+ strcpy (newname + flen, suffix);
+ free (suffix);
+ /* FIXME: Check newname length */
+ return newname;
+}
diff --git a/src/builtin.c b/src/builtin.c
index 9d1063c..8a07eab 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -1,44 +1,46 @@
/* wydawca - automatic release submission daemon
Copyright (C) 2009, 2010 Sergey Poznyakoff
Wydawca is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
Wydawca is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
#include "builtin.h"
-#include "fnmatch.h"
-#include "regex.h"
+
+#ifndef FNM_CASEFOLD
+# define FNM_CASEFOLD 0
+#endif
int
builtin_init (struct dictionary *dict)
{
return 0;
}
int
builtin_done (struct dictionary *dict)
{
return 0;
}
void *
builtin_open (struct dictionary *dict)
{
return dict;
}
#define CMP_EXACT 0
#define CMP_FNMATCH 1
#define CMP_REGEX 2
#define RF_ICASE 0x1
@@ -199,51 +201,51 @@ builtin_lookup (struct dictionary *dict, void *handle, const char *req)
{
char *val = dict->parmv[i + j];
txtacc_grow (acc, val, strlen (val) + 1);
}
count++;
}
i += ncol;
}
dict->nrow = count;
dict->ncol = ncol;
if (count == 0)
{
txtacc_free (acc);
bds = NULL;
rc = 1;
}
else
{
size_t i;
char *p;
- bds = xmalloc (sizeof (*bds));
+ bds = grecs_malloc (sizeof (*bds));
count *= ncol;
- bds->wp = xcalloc (count, sizeof (bds->wp[0]));
+ bds->wp = grecs_calloc (count, sizeof (bds->wp[0]));
bds->acc = acc;
p = txtacc_finish (acc, 0);
for (i = 0; i < count; i++)
{
bds->wp[i] = p;
p += strlen (p) + 1;
}
rc = 0;
}
dict->storage = bds;
return rc;
}
int
builtin_free_result (struct dictionary *dict, void *handle)
{
if (dict->storage)
{
struct builtin_data_storage *bds = dict->storage;
txtacc_free (bds->acc);
free (bds->wp);
diff --git a/src/config.c b/src/config.c
index df9816e..8250749 100644
--- a/src/config.c
+++ b/src/config.c
@@ -125,49 +125,49 @@ safe_file_name (char *file_name)
/* Copy stuff */
p = q;
while ((*q++ = *s++))
;
continue;
}
}
p++;
}
if (file_name[0] == 0)
{
file_name[0] = '/';
file_name[1] = 0;
}
return file_name;
}
/* Same as safe_file_name, but returns an allocated copy. */
char *
safe_file_name_alloc (const char *file_name)
{
- char *s = xstrdup (file_name);
+ char *s = grecs_strdup (file_name);
char *ns = safe_file_name (s);
if (!ns)
free (s);
return ns;
}
static struct keyword event_tab[] = {
{ "success", ev_success },
{ "bad-ownership", ev_bad_ownership },
{ "bad-directive-signature", ev_bad_directive_signature },
{ "bad-detached-signature", ev_bad_detached_signature },
{ "check-failure", ev_check_fail },
{ NULL }
};
const char *
notification_event_str (enum notification_event evt)
{
const char *ret;
if (tok_to_keyword (evt, event_tab, &ret))
{
grecs_error (NULL, 0,
_("INTERNAL ERROR: unknown notification event number: %d"),
@@ -528,94 +528,94 @@ cb_statistics (enum grecs_callback_command cmd,
return parse_statmask (locus, value, varptr);
}
static int
cb_sql_host (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr,
grecs_value_t *value,
void *cb_data)
{
struct sqlconn *pconn = varptr;
char *p;
if (assert_string_arg (locus, cmd, value))
return 1;
p = strchr (value->v.string, ':');
if (p)
{
/* FIXME: Modifies constant string */
*p++ = 0;
if (p[0] == '/')
{
- pconn->socket = xstrdup (p);
- pconn->host = xstrdup ("localhost");
+ pconn->socket = grecs_strdup (p);
+ pconn->host = grecs_strdup ("localhost");
}
else
{
char *end;
unsigned long n = strtoul (p, &end, 10);
if (*end)
{
grecs_error (locus, 0, _("invalid port number (near %s)"), end);
return 0;
}
if (n == 0 || n > USHRT_MAX)
{
grecs_error (locus, 0, _("port number out of range 1..%d"),
USHRT_MAX);
return 0;
}
pconn->port = n;
/* Save host name */
- pconn->host = xstrdup (value->v.string);
+ pconn->host = grecs_strdup (value->v.string);
}
}
else
- pconn->host = xstrdup (value->v.string);
+ pconn->host = grecs_strdup (value->v.string);
return 0;
}
static int
cb_sql (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr,
grecs_value_t *value,
void *cb_data)
{
struct sqlconn *pconn;
void **pdata = cb_data;
switch (cmd) {
case grecs_callback_section_begin:
if (!value || value->type != GRECS_TYPE_STRING)
{
grecs_error(locus, 0, _("tag must be a string"));
return 0;
}
- pconn = xzalloc (sizeof (*pconn));
+ pconn = grecs_zalloc (sizeof (*pconn));
pconn->ident = strdup (value->v.string);
*pdata = pconn;
break;
case grecs_callback_section_end:
pconn = *pdata;
sql_register_conn (pconn);
free (pconn);
*pdata = NULL;
break;
case grecs_callback_set_value:
grecs_error (locus, 0, _("invalid use of block statement"));
}
return 0;
}
static struct grecs_keyword sql_kw[] = {
{ "config-file", N_("file"), N_("Read MySQL configuration from <file>"),
grecs_type_string, NULL, offsetof(struct sqlconn, config_file) },
{ "config-group", N_("name"),
N_("Read the named group from the SQL configuration file"),
grecs_type_string, NULL, offsetof(struct sqlconn, config_group) },
{ "host", N_("host"), N_("Set SQL server hostname or IP address"),
@@ -875,49 +875,49 @@ static struct grecs_keyword notify_event_kw[] = {
{ "recipient", N_("who"), N_("Notify this recipient"),
grecs_type_string, NULL, offsetof(struct notification, tgt),
cb_recipient },
{ "message", N_("text-or-id"),
N_("Text of the notification or identifier of a defined message template"),
grecs_type_string, NULL, offsetof(struct notification, msg) },
{ "gpg-sign", N_("key"),
N_("Sign message with this key"),
grecs_type_string, NULL, offsetof(struct notification, sign_keys) },
{ NULL }
};
static int
cb_notify_event (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr,
grecs_value_t *value,
void *cb_data)
{
struct notification *ntf;
void **pdata = cb_data;
switch (cmd) {
case grecs_callback_section_begin:
- ntf = xzalloc (sizeof (*ntf));
+ ntf = grecs_zalloc (sizeof (*ntf));
*pdata = ntf;
break;
case grecs_callback_section_end:
ntf = *pdata;
if (!ntf->msg)
grecs_error (locus, 0, _("missing message definition"));
else
{
struct notification **p = (struct notification **) varptr;
ntf->next = *p;
*p = ntf;
/* FIXME: check ev and tgt? */
}
break;
case grecs_callback_set_value:
grecs_error (locus, 0, _("invalid use of block statement"));
}
return 0;
}
@@ -963,58 +963,58 @@ cb_dictionary_params (enum grecs_callback_command cmd,
if (cmd != grecs_callback_set_value)
{
grecs_error (locus, 0, _("Unexpected block statement"));
return 1;
}
if (!value || value->type != GRECS_TYPE_LIST)
{
grecs_error (locus, 0, _("expected list value"));
return 1;
}
size = grecs_list_size (value->v.list);
if (size == 0)
{
meth->parmc = 0;
meth->parmv = NULL;
}
else
{
int i;
struct grecs_list_entry *ep;
meth->parmc = size;
- meth->parmv = xcalloc (size + 1, sizeof (meth->parmv[0]));
+ meth->parmv = grecs_calloc (size + 1, sizeof (meth->parmv[0]));
for (i = 0, ep = value->v.list->head; ep; ep = ep->next, i++)
{
const grecs_value_t *vp = ep->data;
if (assert_string_arg (locus, cmd, vp))
break;
- meth->parmv[i] = xstrdup (vp->v.string);
+ meth->parmv[i] = grecs_strdup (vp->v.string);
}
meth->parmv[i] = NULL;
}
return 0;
}
static struct grecs_keyword dictionary_kw[] = {
{ "type", N_("type"), N_("Dictionary type"),
grecs_type_string, NULL, offsetof(struct dictionary, type),
cb_dictionary_type },
{ "query", N_("string"), N_("Query template"),
grecs_type_string, NULL, offsetof(struct dictionary, query) },
{ "params", N_("arg"), N_("Set dictionary parameters"),
grecs_type_string|GRECS_LIST, NULL, 0,
cb_dictionary_params },
{ NULL }
};
int
string_to_dictionary_id (grecs_locus_t *locus,
const char *str, enum dictionary_id *idp)
{
static struct keyword id_tab[] = {
{ "project-uploader", project_uploader_dict },
@@ -1138,50 +1138,50 @@ static struct grecs_keyword spool_kw[] = {
grecs_type_string, NULL, offsetof(struct spool, check_script) },
{ NULL }
};
static int
cb_spool (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr,
grecs_value_t *value,
void *cb_data)
{
struct spool *spool;
void **pdata = cb_data;
int rc, ec, i;
switch (cmd)
{
case grecs_callback_section_begin:
if (!value || value->type != GRECS_TYPE_STRING)
{
grecs_error (locus, 0, _("tag must be a string"));
return 1;
}
- spool = xzalloc (sizeof (*spool));
- spool->tag = xstrdup (value->v.string);
+ spool = grecs_zalloc (sizeof (*spool));
+ spool->tag = grecs_strdup (value->v.string);
spool->file_sweep_time = file_sweep_time;
for (i = 0; i < NITEMS (spool->dictionary); i++)
spool->dictionary[i] = default_dictionary[i];
spool->archive = default_archive_descr;
*pdata = spool;
break;
case grecs_callback_section_end:
rc = 0;
spool = *pdata;
if (!spool->source_dir)
{
grecs_error (locus, 0, _("source is not given"));
rc = 1;
}
else if (test_dir (spool->source_dir, &ec))
{
if (ec)
grecs_error (locus, ec, _("cannot access %s"), spool->source_dir);
else
grecs_error (locus, 0, _("%s is not a directory"),
spool->source_dir);
rc = 1;
}
@@ -1256,50 +1256,50 @@ cb_supp_groups (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr,
grecs_value_t *value,
void *cb_data)
{
if (cmd != grecs_callback_set_value)
{
grecs_error (locus, 0, _("Unexpected block statement"));
return 1;
}
if (!value || value->type != GRECS_TYPE_LIST)
{
grecs_error (locus, 0, _("expected list value"));
return 1;
}
wydawca_supp_groupc = grecs_list_size (value->v.list);
if (wydawca_supp_groupc == 0)
wydawca_supp_groups = NULL;
else
{
int i;
struct grecs_list_entry *ep;
- wydawca_supp_groups = xcalloc (wydawca_supp_groupc,
- sizeof (wydawca_supp_groups[0]));
+ wydawca_supp_groups = grecs_calloc (wydawca_supp_groupc,
+ sizeof (wydawca_supp_groups[0]));
for (i = 0, ep = value->v.list->head; ep; ep = ep->next, i++)
{
const grecs_value_t *vp = ep->data;
struct group *grp;
if (assert_string_arg (locus, cmd, vp))
break;
grp = getgrnam (vp->v.string);
if (!grp)
{
grecs_error (locus, 0, _("no such group: %s"), value->v.string);
break;
}
wydawca_supp_groups[i] = grp->gr_gid;
}
}
return 0;
}
static struct grecs_keyword locking_kw[] = {
{ "enable", NULL, N_("Enable or disable locking"),
grecs_type_bool, &enable_locking },
diff --git a/src/dictionary.c b/src/dictionary.c
index b7baf05..2b995d4 100644
--- a/src/dictionary.c
+++ b/src/dictionary.c
@@ -27,92 +27,93 @@ struct dictionary_descr
int (*free) (struct dictionary *, void *);
void *(*open) (struct dictionary *);
int (*close) (struct dictionary *, void *);
int (*get) (struct dictionary *, void *, unsigned, unsigned);
int (*lookup) (struct dictionary *, void *, const char *);
int (*quote) (struct dictionary *, void *, const char *, char **, size_t *);
};
static struct dictionary_descr dictionary_tab[] = {
{ "none", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "sql", sql_init_dictionary, sql_done_dictionary, sql_free_result,
sql_open, NULL, sql_get_dictionary, sql_lookup_dictionary, sql_quote },
{ "builtin", builtin_init, builtin_done, builtin_free_result,
builtin_open, NULL,
builtin_get,
builtin_lookup },
{ "external", NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
struct dictionary *
dictionary_new (enum dictionary_id id, enum dictionary_type type)
{
- struct dictionary *mp = xmalloc (sizeof mp[0]);
- memset (mp, 0, sizeof mp[0]);
+ struct dictionary *mp = grecs_zalloc (sizeof mp[0]);
mp->id = id;
mp->type = type;
return mp;
}
int
dictionary_init (struct dictionary *dict)
{
struct dictionary_descr *mp = dictionary_tab + dict->type;
int rc = 0;
if (dict->init_passed++)
return 0;
if (debug_level > 1)
{
int i;
logmsg (LOG_DEBUG, _("initializing dictionary: %s \"%s\""),
mp->name, SP (dict->query));
for (i = 0; i < dict->parmc; i++)
logmsg (LOG_DEBUG, " parmv[%d]=%s", i, dict->parmv[i]);
}
if (mp->init)
rc = mp->init (dict);
if (rc == 0)
dict->init_passed = 1;
return rc;
}
void *
dictionary_open (struct dictionary *dict)
{
struct dictionary_descr *mp = dictionary_tab + dict->type;
if (!mp->open)
return NULL;
return mp->open (dict);
}
int
dictionary_close (struct dictionary *dict, void *handle)
{
struct dictionary_descr *mp = dictionary_tab + dict->type;
+ if (mp->free)
+ mp->free (dict, handle);
if (!mp->close)
return 0;
return mp->close (dict, handle);
}
int
dictionary_done (struct dictionary *dict)
{
struct dictionary_descr *mp = dictionary_tab + dict->type;
int rc = 0;
if (dict->init_passed == 0)
return 0;
if (--dict->init_passed)
return 0;
if (debug_level > 1)
{
int i;
logmsg (LOG_DEBUG, _("closing dictionary: %s \"%s\""),
mp->name, SP (dict->query));
for (i = 0; i < dict->parmc; i++)
logmsg (LOG_DEBUG, " parmv[%d]=%s", i, dict->parmv[i]);
}
if (mp->done)
@@ -165,64 +166,64 @@ dictionary_num_rows (struct dictionary *dict)
unsigned
dictionary_num_cols (struct dictionary *dict)
{
return dict->ncol;
}
const char *
dictionary_result (struct dictionary *dict, void *handle,
unsigned nrow, unsigned ncol)
{
struct dictionary_descr *mp = dictionary_tab + dict->type;
if (nrow >= dict->nrow || ncol >= dict->ncol
|| mp->get (dict, handle, nrow, ncol))
return NULL;
return dict->result;
}
void
dictionary_copy_result (struct dictionary *dict, const char *res, size_t size)
{
if (dict->result_size < size + 1)
{
dict->result_size = size + 1;
- dict->result = x2realloc (dict->result, &dict->result_size);
+ dict->result = grecs_realloc (dict->result, dict->result_size);
}
memcpy (dict->result, res, size);
dict->result[size] = 0;
}
/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed
quoted string. Return its length. */
int
dictionary_quote_string (struct dictionary *dict, void *handle,
const char *input,
char **poutput, size_t *psize)
{
struct dictionary_descr *mp = dictionary_tab + dict->type;
size_t size;
int quote;
char *output;
if (!input)
{
- *poutput = xmalloc (1);
+ *poutput = grecs_malloc (1);
(*poutput)[0] = 0;
*psize = 1;
return 0;
}
if (mp->quote)
return mp->quote (dict, handle, input, poutput, psize);
size = wordsplit_c_quoted_length (input, 0, &quote);
- output = xmalloc (size + 1);
+ output = grecs_malloc (size + 1);
wordsplit_c_quote_copy (output, input, 0);
output[size] = 0;
*poutput = output;
if (psize)
*psize = size;
return 0;
}
diff --git a/src/directive.c b/src/directive.c
index 08a14df..fadaedf 100644
--- a/src/directive.c
+++ b/src/directive.c
@@ -13,49 +13,49 @@
You should have received a copy of the GNU General Public License along
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
/* Directive file support */
/* Parse directives from TRP->blurb. Fill TRP->directive */
int
directive_parse (struct file_triplet *trp)
{
size_t dcount, i, j;
char *p;
if (debug_level > 2)
logmsg (LOG_DEBUG, _("%s: parsing directive blurb: %s"),
trp->file[file_directive].name, trp->blurb);
dcount = 0;
for (p = trp->blurb; *p; p++)
if (*p == '\n')
dcount++;
- trp->directive = xcalloc (dcount + 1, sizeof trp->directive[0]);
+ trp->directive = grecs_calloc (dcount + 1, sizeof trp->directive[0]);
p = trp->blurb;
for (i = j = 0; i < dcount; i++)
{
trp->directive[j] = p;
p = strchr (p, '\n');
if (p)
*p++ = 0;
if (trim (trp->directive[j]) == 0) /* ignore empty lines */
continue;
if (strchr (trp->directive[j], ':') == NULL)
{
logmsg (LOG_ERR, _("%s: invalid line: %s"),
trp->file[file_directive].name, trp->directive[j]);
free (trp->directive);
trp->directive = NULL;
return 1;
}
j++;
if (!p)
break;
}
trp->directive[j] = NULL;
return 0;
}
@@ -90,49 +90,49 @@ directive_get_value (struct file_triplet *trp, const char *key,
Arguments:
N - Index of the current directive,
TRP - Triplet,
PKEY, PVAL - Return addresses.
The function points PKEY and PVAL to the keyword and value of the Nth
directive, and returns N + 1.
If N points past all the directive, the function returns 0. */
static int
_directive_seq_get (int n, struct file_triplet *trp,
const char **pkey, const char **pval)
{
char *p;
size_t len;
if (trp->directive[n] == NULL)
return 0;
p = strchr (trp->directive[n], ':');
len = p - trp->directive[n];
if (len + 1 > trp->tmpsize)
{
trp->tmpsize = len + 1;
- trp->tmp = x2realloc (trp->tmp, &trp->tmpsize);
+ trp->tmp = grecs_realloc (trp->tmp, trp->tmpsize);
}
memcpy (trp->tmp, trp->directive[n], len);
trp->tmp[len] = 0;
*pkey = trp->tmp;
for (p++; *p && isspace (*p); p++)
;
if (pval)
*pval = p;
return ++n;
}
/* Get the first directive from TRP. Point *PKEY to its keyword and
*PVAL to its value. Return 1 on success, 0 on failure. */
int
directive_first (struct file_triplet *trp,
const char **pkey, const char **pval)
{
int n = 0;
return _directive_seq_get (n, trp, pkey, pval);
}
/* Get the first directive from TRP. Point *PKEY to its keyword and
*PVAL to its value. Return 1 on success, 0 on failure.
Return non-0 on success, 0 on failure */
@@ -359,49 +359,49 @@ stderr_redirector (const char *tag)
if (pipe (p))
{
logmsg (LOG_CRIT, "redirector pipe: %s", strerror (errno));
return -1;
}
pid = fork ();
if (pid == -1)
{
logmsg (LOG_CRIT, "redirector fork: %s", strerror (errno));
return -1;
}
if (pid == 0)
{
FILE *fp;
size_t size = 0;
char *buf = NULL;
close (p[1]);
fp = fdopen (p[0], "r");
if (!fp)
_exit (127);
- while (getline (&buf, &size, fp) >= 0)
+ while (grecs_getline (&buf, &size, fp) >= 0)
{
trim_crlf (buf);
logmsg (LOG_NOTICE, "%s: %s", tag, buf);
}
_exit (0);
}
close (p[0]);
return p[1];
}
static int
run_check_script (const char *script, struct file_triplet *trp,
const char *descr)
{
static char *script_file;
pid_t pid;
int status;
int p[2];
RETSIGTYPE (*oldsig)();
FILE *fp;
char *buf;
size_t size, total;
@@ -472,49 +472,49 @@ run_check_script (const char *script, struct file_triplet *trp,
setenv ("WYDAWCA_SOURCE", spool->source_dir, 1);
setenv ("WYDAWCA_DEST", spool->dest_dir, 1);
setenv ("WYDAWCA_URL", spool->url, 1);
setenv ("WYDAWCA_TRIPLET_BASE", trp->name, 1);
setenv ("WYDAWCA_DIST_FILE", trp->file[file_dist].name, 1);
chdir (temp_homedir);
argv[0] = "sh";
argv[1] = script_file;
argv[2] = NULL;
execv ("/bin/sh", argv);
_exit (127);
}
/* Master */
free (script_file);
close (p[1]);
fp = fdopen (p[0], "r");
buf = NULL;
size = total = 0;
if (debug_level > 2)
logmsg (LOG_DEBUG, _("reading script output..."));
- while (getline (&buf, &size, fp) > 0)
+ while (grecs_getline (&buf, &size, fp) > 0)
{
size_t len = strlen (buf);
if (debug_level > 2)
logmsg (LOG_DEBUG, _("read: %s"), buf);
txtacc_grow (trp->acc, buf, len);
total += size;
}
txtacc_1grow (trp->acc, 0);
if (debug_level > 2)
logmsg (LOG_DEBUG, _("bytes read: %lu"), (unsigned long)total);
fclose (fp);
waitpid (pid, &status, 0);
signal (SIGCHLD, oldsig);
if (total)
trp->check_diag = txtacc_finish (trp->acc, 0);
trp->check_result = status;
if (WIFEXITED (status))
{
status = WEXITSTATUS (status);
if (status)
diff --git a/src/diskio.c b/src/diskio.c
index 9addd9b..b175a45 100644
--- a/src/diskio.c
+++ b/src/diskio.c
@@ -25,49 +25,49 @@ sub_dir_p (const char *arg, const char *dir)
if (!arg)
return 0;
dlen = strlen (dir);
return strlen (arg) > dlen
&& memcmp (dir, arg, dlen) == 0
&& arg[dlen] == '/';
}
/* Concatenate BASE directory name, a single directory separator (/) and
NAME. Return in PBASELEN the length of BASE, not counting eventual trailing
slash. */
char *
concat_dir (const char *base, const char *name, size_t *pbaselen)
{
size_t len = strlen (base);
size_t size;
char *dir;
while (len > 0 && base[len-1] == '/')
len--;
size = len + 1 + strlen (name);
- dir = xmalloc (size + 1);
+ dir = grecs_malloc (size + 1);
memcpy (dir, base, len);
dir[len++] = '/';
strcpy (dir + len, name);
if (pbaselen)
*pbaselen = len;
return dir;
}
/* Create the directory DIR, eventually creating all intermediate directories
starting from DIR + BASELEN. */
int
create_hierarchy (char *dir, size_t baselen)
{
int rc;
struct stat st;
char *p;
if (stat (dir, &st) == 0)
{
if (!S_ISDIR (st.st_mode))
{
logmsg (LOG_ERR, _("component %s is not a directory"), dir);
return 1;
@@ -150,49 +150,49 @@ copy_file (const char *file, const char *dst_file)
if (fstat (in_fd, &st))
{
logmsg (LOG_ERR, _("cannot stat source file %s: %s"),
file, strerror (errno));
close (in_fd);
return 1;
}
out_fd = creat (dst_file, CREAT_PERMISSIONS);
if (out_fd == -1)
{
logmsg (LOG_ERR, _("cannot create destination file %s: %s"),
file, strerror (errno));
close (in_fd);
return 1;
}
buf = NULL;
fsize = st.st_size;
for (bufsize = fsize; bufsize > 0 && (buf = malloc (bufsize)) == NULL;
bufsize /= 2)
;
if (bufsize == 0)
- xalloc_die ();
+ grecs_alloc_die ();
rc = 0;
while (fsize > 0)
{
size_t rest;
size_t rdbytes;
rest = fsize > bufsize ? bufsize : fsize;
rdbytes = read (in_fd, buf, rest);
if (rdbytes == -1)
{
logmsg (LOG_ERR, _("unexpected error reading %s: %s"),
file, strerror (errno));
rc = 1;
break;
}
rest = write (out_fd, buf, rdbytes);
if (rest == -1)
{
logmsg (LOG_ERR, _("unexpected error writing to %s: %s"),
dst_file, strerror (errno));
rc = 1;
break;
}
@@ -471,49 +471,49 @@ archive_single_file (struct file_triplet *trp, const char *file_name,
if (!noentok)
logmsg (LOG_NOTICE, _("nothing to archive: file `%s' does not exist"),
dst_file);
}
else
{
logmsg (LOG_ERR, _("canot access file `%s': %s"),
dst_file, strerror (errno));
rc = 1;
}
free (dst_file);
free (dst_dir);
return rc;
}
static char *
make_signame (const char *file_name)
{
size_t len;
if (((len = strlen (file_name)) > SUF_SIG_LEN
&& memcmp (file_name + len - SUF_SIG_LEN, SUF_SIG, SUF_SIG_LEN)))
{
- char *signame = xmalloc (len + SUF_SIG_LEN + 1);
+ char *signame = grecs_malloc (len + SUF_SIG_LEN + 1);
strcpy (signame, file_name);
return strcat (signame, SUF_SIG);
}
return NULL;
}
/* Archive the file FILE_NAME, located in DPAIR->dest_dir, and remove the
file. Get user IDs from the triplet TRP. Unless FILE_NAME ends in
".sig", do the same with FILE_NAME.sig, if such a file exists.
Do nothing if dry_run_mode is set.
*/
int
dir_archive_file (struct file_triplet *trp, const char *file_name)
{
int rc;
char *signame;
rc = archive_single_file (trp, file_name, 0);
if (rc == 0 && archive_signatures && (signame = make_signame (file_name)))
{
rc = archive_single_file (trp, signame, 1);
free (signame);
}
return rc;
diff --git a/src/exec.c b/src/exec.c
index ed7ee1e..7ebf152 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -54,49 +54,49 @@ start_prog (int argc, const char **argv, pid_t *ppid)
logmsg (LOG_CRIT, _("cannot run `%s': fork failed: %s"),
argv[0], strerror (errno));
return NULL;
default:
/* Master process */
close (p[1]);
fp = fdopen (p[0], "r");
if (!fp)
logmsg (LOG_ERR, _("cannot fdopen: %s"), strerror (errno));
*ppid = pid;
}
return fp;
}
/* Log everything read from FP as the output from the program PROG, using
syslog priority PRIO. */
void
log_output (int prio, const char *prog, FILE *fp)
{
size_t size = 0;
char *buf = NULL;
logmsg (prio, _("%s output follows:"), prog);
- while (getline (&buf, &size, fp) > 0)
+ while (grecs_getline (&buf, &size, fp) > 0)
logmsg (prio, "%s", buf);
logmsg (prio, _("end of %s output"), prog);
free (buf);
}
/* Execute ARGC/ARGV. Return the exit code in RETCODE. */
enum exec_result
wydawca_exec (int argc, const char **argv, int *retcode)
{
FILE *fp;
pid_t pid, npid;
int status;
int i;
enum exec_result res;
fp = start_prog (5, argv, &pid);
if (!fp)
{
logmsg (LOG_CRIT, _("cannot start %s"), argv[0]);
return exec_error;
}
for (i = 0; i < 5 && (npid = waitpid (pid, &status, WNOHANG)) == 0; i++)
sleep (1);
diff --git a/src/gpg.c b/src/gpg.c
index 474d94b..d4f9b71 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -111,49 +111,49 @@ rmdir_r (const char *name)
name, strerror (errno));
return 1;
}
return rc;
}
/* Remove temporary GPG home directory */
static void
remove_homedir ()
{
if (debug_level > 1)
logmsg (LOG_DEBUG, _("removing GNUPG home directory: %s"), temp_homedir);
if (rmdir_r (temp_homedir))
logmsg (LOG_CRIT, _("failed to remove GPG directory %s"), temp_homedir);
}
/* Create a temporary GPG home directory */
static int
create_gpg_homedir ()
{
if (temp_homedir)
return 0;
- temp_homedir = xstrdup ("/tmp/wydawca-XXXXXX");
+ temp_homedir = grecs_strdup ("/tmp/wydawca-XXXXXX");
if (!mkdtemp (temp_homedir))
{
logmsg (LOG_CRIT, _("cannot create GPG home directory (%s): %s"),
temp_homedir, strerror (errno));
return 1;
}
atexit (remove_homedir);
if (debug_level > 1)
logmsg (LOG_DEBUG, _("GNUPG home directory: %s"), temp_homedir);
setenv ("GNUPGHOME", temp_homedir, 1);
return 0;
}
static int
gpg_verify_signature (gpgme_ctx_t ctx, gpgme_signature_t sig,
struct file_triplet *trp)
{
if (!sig)
return 0;
for (; sig; sig = sig->next)
{
const char *uid;
gpgme_key_t key;
@@ -216,83 +216,84 @@ gpg_verify_signature (gpgme_ctx_t ctx, gpgme_signature_t sig,
int
verify_directive_signature (struct file_triplet *trp)
{
gpgme_ctx_t ctx;
gpgme_data_t key_data, directive_data, plain;
gpgme_error_t ec;
int rc;
struct uploader_info *uptr;
create_gpg_homedir ();
fail_if_err (gpgme_new (&ctx));
for (uptr = trp->uploader_list; uptr; uptr = uptr->next)
{
gpgme_import_result_t res;
gpgme_import_status_t pstat;
fail_if_err (gpgme_data_new_from_mem (&key_data,
uptr->gpg_key,
strlen (uptr->gpg_key),
0));
fail_if_err (gpgme_op_import (ctx, key_data));
res = gpgme_op_import_result (ctx);
pstat = res->imports;
- uptr->fpr = xstrdup (pstat->fpr);
+ uptr->fpr = grecs_strdup (pstat->fpr);
if (debug_level > 2)
logmsg (LOG_DEBUG, _("imported key: user = %s, fingerprint = %s"),
uptr->name, uptr->fpr);
}
fail_if_err (gpgme_data_new_from_file (&directive_data,
trp->file[file_directive].name, 1));
gpgme_data_new (&plain);
ec = gpgme_op_verify (ctx, directive_data, NULL, plain);
if (ec == GPG_ERR_NO_ERROR)
{
gpgme_verify_result_t result;
result = gpgme_op_verify_result (ctx);
if (!gpg_verify_signature (ctx, result->signatures, trp))
{
UPDATE_STATS (STAT_BAD_SIGNATURE);
notify (trp->spool->notification, trp, ev_bad_directive_signature);
rc = 1;
}
else
rc = 0;
}
else
{
rc = 1;
UPDATE_STATS (STAT_BAD_SIGNATURE);
logmsg (LOG_ERR, _("%s: directive verification failed: %s"),
trp->name, gpgme_strerror (ec));
}
gpgme_data_release (directive_data);
gpgme_data_release (key_data);
-
+ gpgme_release (ctx);
+
return rc;
}
/* Verify the detached signature of TRP.
NOTE: It is assumed that the public key is already registered (by
a previous call to verify_directive_signature). */
int
verify_detached_signature (struct file_triplet *trp)
{
gpgme_engine_info_t info;
const char *argv[5];
const struct spool *spool;
ASGN_SPOOL (spool, trp, return 1);
fail_if_err (gpgme_get_engine_info (&info));
while (info && info->protocol != GPGME_PROTOCOL_OpenPGP)
info = info->next;
if (!info)
{
logmsg (LOG_CRIT,
_("cannot find path to gpg binary (attempting to verify "
"the detached signature for %s"), trp->name);
return 1;
diff --git a/src/job.c b/src/job.c
index 7e3fdf5..764e463 100644
--- a/src/job.c
+++ b/src/job.c
@@ -184,49 +184,49 @@ job_insert (struct job *job, struct job *elt)
}
p = elt->next;
elt->next = job;
if (p)
p->prev = job;
}
void
schedule_job (const struct spool *spool, uid_t uid)
{
struct job *job;
if (!spool)
spool = &fake_spool;
if (debug_level)
logmsg (LOG_DEBUG, _("scheduling job: %s, %lu"),
spool->tag, (unsigned long)uid);
job = job_locate (spool, uid);
if (!job)
{
- job = xzalloc (sizeof (*job));
+ job = grecs_zalloc (sizeof (*job));
job->spool = spool;
job->uid = uid;
job->pid = -1;
time (&job->timestamp);
job_insert (job, NULL);
}
job->state |= STATE_QUEUED;
job_start (job);
}
static void
print_status (struct job *job, int expect_term)
{
struct passwd *pw = getpwuid (job->uid);
int status = job->exit_status;
if (WIFEXITED (status))
{
int exit_code = WEXITSTATUS (status);
if (exit_code == 0)
{
if (debug_level)
logmsg (LOG_DEBUG,
diff --git a/src/lock.c b/src/lock.c
index 32367de..dece75d 100644
--- a/src/lock.c
+++ b/src/lock.c
@@ -166,57 +166,57 @@ expire_stale_lock (const char *file)
if ((time (NULL) - stbuf.st_mtime) > lock_expire_time)
stale = 1;
}
close (fd);
if (stale)
unlink (file);
}
static char *
host_name ()
{
static char *hostbuf = NULL;
size_t size = 0;
int rc;
if (hostbuf)
return hostbuf;
do
{
if (!hostbuf)
{
size = 256;
- hostbuf = xmalloc (size);
+ hostbuf = grecs_malloc (size);
}
else
{
size_t ns = size * 2;
if (size < ns)
- xalloc_die ();
+ grecs_alloc_die ();
size = ns;
- hostbuf = xrealloc (hostbuf, size);
+ hostbuf = grecs_realloc (hostbuf, size);
}
}
while ((rc = gethostname (hostbuf, size )) == -1 &&
(errno == EINVAL
#ifdef ENAMETOOLONG
|| errno == ENAMETOOLONG
#endif
));
if (rc)
{
logmsg (LOG_ERR, _("cannot get hostname: %s"), strerror (rc));
exit (EX_SOFTWARE);
}
return hostbuf;
}
int
wydawca_lock (const char *lockname)
{
char *tempname = NULL;
size_t size = 0;
int rc;
if (!enable_locking)
@@ -240,57 +240,57 @@ wydawca_lock (const char *lockname)
if (rc == LOCK_RETRY)
sleep (1);
else
break;
}
while (time (NULL) - start < lock_timeout);
}
else
rc = _lock_internal (lockname, tempname);
free (tempname);
return rc;
}
void
wydawca_unlock (const char *lockfile)
{
if (enable_locking)
unlink (lockfile);
}
static char *
fix_tagname (const char *tag)
{
- char *tagname = xstrdup (tag);
+ char *tagname = grecs_strdup (tag);
char *p;
for (p = tagname; *p; p++)
if (!isalnum (*p) && *p != '_' && *p != '-')
*p = '_';
return tagname;
}
char *
wydawca_lockname (const char *tag)
{
char *lockname = NULL;
size_t size = 0;
char *tagname = fix_tagname (tag);
grecs_asprintf (&lockname, &size, "%s/LCK.%s", lockdir, tagname);
if (!lockname)
- xalloc_die ();
+ grecs_alloc_die ();
free (tagname);
return lockname;
}
void
wydawca_lock_init ()
{
if (enable_locking)
{
if (!lockdir)
- lockdir = xstrdup (LOCALSTATEDIR "/lock/" PACKAGE);
+ lockdir = grecs_strdup (LOCALSTATEDIR "/lock/" PACKAGE);
if (create_hierarchy (lockdir, 0))
exit (EX_OSFILE);
}
}
diff --git a/src/mail.c b/src/mail.c
index bac0381..6855ed7 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -270,58 +270,58 @@ mail_send_message (mu_address_t rcpt, const char *text,
{
int rc;
mu_message_t msg;
mu_stream_t stream = NULL;
mu_header_t hdr;
static char *x_mailer = "wydawca (" PACKAGE_STRING ")";
size_t size;
char *buf;
const char *sval;
mu_static_memory_stream_create (&stream, text, strlen (text));
rc = mu_stream_to_message (stream, &msg);
mu_stream_unref (stream);
if (rc)
{
logmsg (LOG_CRIT, _("cannot create message: %s"), mu_strerror (rc));
return;
}
mu_message_get_header (msg, &hdr);
mu_header_append (hdr, "X-Mailer", x_mailer);
if (rcpt)
{
mu_address_to_string (rcpt, NULL, 0, &size);
- buf = xmalloc (size + 1);
+ buf = grecs_malloc (size + 1);
mu_address_to_string (rcpt, buf, size + 1, NULL);
mu_header_set_value (hdr, "To", buf, 1);
free (buf);
if (from_address && mu_header_sget_value (hdr, "From", &sval))
{
mu_address_to_string (from_address, NULL, 0, &size);
- buf = xmalloc (size + 1);
+ buf = grecs_malloc (size + 1);
mu_address_to_string (from_address, buf, size + 1, NULL);
mu_header_set_value (hdr, "From", buf, 1);
free (buf);
}
}
if (debug_level > 1)
{
mu_debug_level_t level;
mu_debug_get_category_level (MU_DEBCAT_MAILER, &level);
level |= MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE0) |
MU_DEBUG_LEVEL_MASK (MU_DEBUG_PROT);
if (debug_level > 2)
level |= MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE7);
mu_debug_set_category_level (MU_DEBCAT_MAILER, level);
}
if (!mailer_opened)
{
if ((rc = mu_mailer_open (mailer, 0)))
{
mu_url_t url = NULL;
mu_mailer_get_url (mailer, &url);
@@ -413,59 +413,59 @@ resolve_message_template (const char *name)
void
mail_stats ()
{
struct metadef *exp;
time_t t;
const char *tmpl;
char *text;
size_t tc;
if (!admin_stat_message || !stat_mask_p (mail_admin_mask) || !mailer)
return;
if (!admin_address)
{
logmsg (LOG_ERR, _("cannot mail statistics: admin-address not defined"));
return;
}
if (debug_level)
{
size_t size;
char *buf;
mu_address_to_string (admin_address, NULL, 0, &size);
- buf = xmalloc (size + 1);
+ buf = grecs_malloc (size + 1);
mu_address_to_string (admin_address, buf, size + 1, NULL);
logmsg (LOG_DEBUG, _("sending stats to %s"), buf);
free (buf);
}
tc = timer_get_count () * 3;
exp = make_stat_expansion (tc + 1);
time (&t);
exp[0].kw = "date";
- exp[0].value = exp[0].storage = xstrdup (ctime (&t));
+ exp[0].value = exp[0].storage = grecs_strdup (ctime (&t));
exp[0].value [strlen (exp[0].value) - 1] = 0;
timer_fill_meta (exp + 1, tc);
tmpl = resolve_message_template (admin_stat_message);
if (!tmpl)
{
logmsg (LOG_ERR, _("undefined message reference: %s"),
admin_stat_message);
return;
}
text = meta_expand_string (tmpl, exp, NULL, NULL, NULL);
mail_send_message (admin_address, text, admin_stat_sign_key);
free (text);
meta_free (exp);
timer_free_meta (exp + 1, tc);
free (exp);
}
mu_address_t
get_uploader_email (struct uploader_info *info, struct file_triplet *trp,
const char **errp)
{
@@ -577,106 +577,106 @@ do_notify (struct file_triplet *trp, enum notification_event ev,
rcpt = get_uploader_email (trp->uploader, trp, &errp);
break;
case notify_owner:
rcpt = get_recipient (trp->spool->dictionary[project_owner_dict],
trp, &errp);
}
if (!rcpt && ntf->tgt != notify_read)
{
logmsg (LOG_ERR, _("not notifying %s (project %s) about %s: %s"),
notification_target_str (ntf->tgt),
trp->project,
notification_event_str (ev), gettext (errp));
return;
}
if (debug_level)
{
if (rcpt)
{
size_t size;
char *buf;
mu_address_to_string (rcpt, NULL, 0, &size);
- buf = xmalloc (size + 1);
+ buf = grecs_malloc (size + 1);
mu_address_to_string (rcpt, buf, size + 1, NULL);
logmsg (LOG_DEBUG, _("notifying %s (project %s) about %s"),
buf, trp->project, notification_event_str (ev));
free (buf);
}
else
logmsg (LOG_DEBUG,
_("notifying message recipients (project %s) about %s"),
trp->project, notification_event_str (ev));
}
msg = resolve_message_template (ntf->msg);
if (!msg)
logmsg (LOG_ERR, _("undefined message reference: %s"), ntf->msg);
else
{
char *text = triplet_expand_param (msg, trp);
mail_send_message (rcpt, text, ntf->sign_keys);
free (text);
}
mu_address_destroy (&rcpt);
}
void
notify (struct notification *notification_list,
struct file_triplet *trp, enum notification_event ev)
{
struct notification *p;
for (p = notification_list; p; p = p->next)
if (p->ev == ev)
do_notify (trp, ev, p);
/* FIXME */
}
const char *
expand_email_admin (struct metadef *def, void *data)
{
size_t size;
if (mu_address_to_string (admin_address, NULL, 0, &size) == 0)
{
size++;
- def->storage = xmalloc (size);
+ def->storage = grecs_malloc (size);
mu_address_to_string (admin_address, def->storage, size, NULL);
def->value = def->storage;
}
else
def->value = "";
return def->value;
}
const char *
expand_email_owner (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
mu_address_t addr;
const char *errp;
size_t size;
addr = get_recipient (trp->spool->dictionary[project_owner_dict],
trp, &errp);
if (!addr)
{
logmsg (LOG_ERR, _("cannot get email of the %s's owner: %s"),
trp->project, gettext (errp));
def->value = "";
}
else if (mu_address_to_string (addr, NULL, 0, &size) == 0)
{
size++;
- def->storage = xmalloc (size);
+ def->storage = grecs_malloc (size);
mu_address_to_string (addr, def->storage, size, NULL);
def->value = def->storage;
mu_address_destroy (&addr);
}
else
def->value = "";
return def->value;
}
diff --git a/src/net.c b/src/net.c
index 3e9fe30..d08a6ba 100644
--- a/src/net.c
+++ b/src/net.c
@@ -82,71 +82,71 @@ open_listener ()
return fd;
}
void
trim_crlf (char *s)
{
size_t len = strlen (s);
if (len > 0 && s[len-1] == '\n')
{
s[--len] = 0;
if (len > 0 && s[len-1] == '\r')
s[--len] = 0;
}
}
void
handle_connection (FILE *in, FILE *out)
{
char *buf = NULL;
size_t buflen = 0;
const struct spool *spool;
char *p;
struct passwd *pw;
- if (getline (&buf, &buflen, in) <= 0)
+ if (grecs_getline (&buf, &buflen, in) <= 0)
return;
trim_crlf (buf);
if (debug_level)
logmsg (LOG_DEBUG, "recv: %s", buf);
spool = wydawca_find_spool (buf);
if (!spool)
{
if (all_spool_aliases && grecs_list_locate (all_spool_aliases, buf))
fprintf (out, "+ OK, all spools\r\n");
else
{
fprintf (out, "- Unknown service name\r\n");
free (buf);
return;
}
}
else if (spool->url)
fprintf (out, "+ OK, URL %s\r\n", spool->url);
else
fprintf (out, "+ OK, spool %s\r\n", spool->tag);
- if (getline (&buf, &buflen, in) < 0)
+ if (grecs_getline (&buf, &buflen, in) < 0)
{
logmsg (LOG_ERR, "protocol error");
free (buf);
return;
}
trim_crlf (buf);
if (debug_level)
logmsg (LOG_DEBUG, "recv: %s", buf);
p = strchr (buf, ' ');
if (p)
{
*p++ = 0;
while (*p && (*p == ' ' || *p == '\t'))
p++;
}
else
p = "";
pw = getpwnam (buf);
if (pw)
schedule_job (spool, pw->pw_uid);
else
diff --git a/src/process.c b/src/process.c
index e41709d..200d987 100644
--- a/src/process.c
+++ b/src/process.c
@@ -6,49 +6,49 @@
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
Wydawca is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
struct spool_list
{
struct spool_list *next;
struct spool spool;
};
static struct spool_list *spool_list;
void
register_spool (struct spool *spool)
{
- struct spool_list *sp = xmalloc (sizeof *sp);
+ struct spool_list *sp = grecs_malloc (sizeof *sp);
sp->spool = *spool;
sp->next = spool_list;
spool_list = sp;
}
static int
spool_check_alias (struct spool *spool, const char *name)
{
if (spool->aliases && grecs_list_locate (spool->aliases, (char*) name))
return 1;
return 0;
}
struct spool *
wydawca_find_spool (const char *name)
{
struct spool_list *sp;
for (sp = spool_list; sp; sp = sp->next)
{
if (strcmp (sp->spool.tag, name) == 0
|| spool_check_alias (&sp->spool, name))
return &sp->spool;
}
@@ -92,49 +92,49 @@ file_type_str (enum file_type type)
/* Parse file NAME: determine its type and root name and store this
information in FINFO */
void
parse_file_name (const char *name, struct file_info *finfo)
{
static struct suffix
{
const char *suf;
unsigned len;
enum file_type type;
} suftab[] = {
{ SUF_SIG, SUF_SIG_LEN, file_signature },
{ SUF_DIR, SUF_DIR_LEN, file_directive },
{ "", 0, file_dist }
};
int i;
unsigned len = strlen (name);
for (i = 0; i < sizeof suftab / sizeof suftab[0]; i++)
{
if (len >= suftab[i].len
&& memcmp (name + len - suftab[i].len,
suftab[i].suf, suftab[i].len) == 0)
{
- finfo->name = xstrdup (name);
+ finfo->name = grecs_strdup (name);
finfo->type = suftab[i].type;
finfo->root_len = len - suftab[i].len;
return;
}
}
abort (); /* should not happen */
}
int
match_uid_p (uid_t uid, int uc, uid_t *uv)
{
int i;
if (!uv)
return 1;
for (i = 0; i < uc; i++)
if (uv[i] == uid)
return 1;
return 0;
}
/* Scan upload directory from the DPAIR and register all files found
there, forming triplets when possible */
void
scan_spool_unlocked (const struct spool *spool, int uc, uid_t *uv)
diff --git a/src/sql.c b/src/sql.c
index a4b311e..80eb344 100644
--- a/src/sql.c
+++ b/src/sql.c
@@ -9,49 +9,49 @@
Wydawca is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
#include "sql.h"
/* Singly-linked list of configured MySQL connections. */
struct sql_list
{
struct sql_list *next;
struct sqlconn conn;
};
static struct sql_list *sql_list;
/* Append CONN to the end of sql_list */
void
sql_register_conn (struct sqlconn *conn)
{
- struct sql_list *ent = xmalloc (sizeof *ent);
+ struct sql_list *ent = grecs_malloc (sizeof *ent);
ent->conn = *conn;
ent->next = sql_list;
sql_list = ent;
}
/* Find a configured connection that has the given IDENT */
struct sqlconn *
sql_find_connection (const char *ident)
{
struct sql_list *p;
for (p = sql_list; p; p = p->next)
if (strcmp (p->conn.ident, ident) == 0)
return &p->conn;
return NULL;
}
/* Return true if there exists a connection with the given IDENT */
int
sql_connection_exists_p (const char *ident)
{
return sql_find_connection (ident) != NULL;
}
/* Initialize MySQL dictionary */
@@ -177,31 +177,31 @@ sql_get_dictionary (struct dictionary *dict, void *handle,
if (!conn->result)
return 1;
mysql_data_seek (conn->result, nrow);
row = mysql_fetch_row (conn->result);
if (row[ncol] == NULL)
len = 0;
else
len = trim_length (row[ncol]);
dictionary_copy_result (dict, row[ncol], len);
return 0;
}
int
sql_quote (struct dictionary *dict, void *handle, const char *input,
char **poutput, size_t *psize)
{
struct sqlconn *conn = handle;
size_t len, size;
char *output;
len = strlen (input);
size = 2 * len + 1;
- output = xmalloc (size);
+ output = grecs_malloc (size);
mysql_real_escape_string (&conn->mysql, output, input, len);
*poutput = output;
if (psize)
*psize = strlen (output);
return 0;
}
diff --git a/src/timer.c b/src/timer.c
index 1634462..cece63a 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -1,47 +1,46 @@
/* wydawca - automatic release submission daemon
Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff
Wydawca is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
Wydawca is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include <wydawca.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
-#include <xalloc.h>
struct timer_slot
{
char *name;
double real;
double self_user; /* user time in sec */
double self_system; /* system time in sec */
double children_user; /* user time in sec */
double children_system; /* system time in sec */
struct timeval real_mark;
struct rusage self_mark;
struct rusage children_mark;
};
static struct grecs_symtab *timer_table;
static size_t _timer_count;
static unsigned
hash_string_ci (const char *string, unsigned long n_buckets)
{
size_t value = 0;
unsigned char ch;
for (; (ch = *string); string++)
@@ -161,77 +160,77 @@ timer_format_time (double t)
char *str = NULL;
size_t size = 0;
if (t < 600)
grecs_asprintf (&str, &size, "%0.3f", t);
else
{
long int s, m, h, d;
s = (long int) t;
d = s / (3600 * 24);
s -= d * 3600 * 24;
h = s / 3600;
s -= h * 3600;
m = s / 60;
s -= m * 60;
if (d)
grecs_asprintf (&str, &size, "%ld+%02ld:%02ld:%02ld", d, h, m, s);
else if (h)
grecs_asprintf (&str, &size, "%02ld:%02ld:%02ld", h, m, s);
else
grecs_asprintf (&str, &size, "%02ld:%02ld", m, s);
}
if (!str)
- xalloc_die ();
+ grecs_alloc_die ();
return str;
}
size_t
timer_get_count ()
{
return _timer_count;
}
struct timer_data
{
struct metadef *def;
size_t num;
};
int
_fill_meta (void *sym, void *data)
{
struct timer_slot *slot = sym;
struct timer_data *tp = data;
#define CREATE_DEF(arg) \
if (tp->num) \
{ \
char *buf = NULL; \
size_t size = 0; \
grecs_asprintf (&buf, &size, "timer:%s:%s", slot->name, #arg); \
if (!buf) \
- xalloc_die (); \
+ grecs_alloc_die (); \
tp->def->kw = buf; \
tp->def->storage = timer_format_time (__cat2__(timer_get_,arg) (slot)); \
tp->def->value = tp->def->storage; \
tp->def->expand = NULL; \
tp->def++; \
tp->num--; \
}
CREATE_DEF(system);
CREATE_DEF(real);
CREATE_DEF(user);
return tp->num <= 0;
}
void
timer_fill_meta (struct metadef *def, size_t num)
{
struct timer_data td;
if (!timer_table)
return;
td.def = def;
td.num = num;
grecs_symtab_enumerate (timer_table, _fill_meta, &td);
diff --git a/src/triplet.c b/src/triplet.c
index 3083c64..9dfdf2c 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -39,83 +39,84 @@ hash_triplet_compare (void const *data1, void const *data2)
void
hash_triplet_free (void *data)
{
int i;
struct file_triplet *tp = data;
struct uploader_info *up;
free (tp->name);
for (i = 0; i < FILE_TYPE_COUNT; i++)
{
if (tp->file[i].name)
free (tp->file[i].name);
}
free (tp->directive);
free (tp->blurb);
free (tp->tmp);
txtacc_free (tp->acc);
/* Free uploader list */
for (up = tp->uploader_list; up; )
{
struct uploader_info *next = up->next;
+ free (up->fpr);
free (up);
up = next;
}
free (tp);
}
char *
triplet_strdup (struct file_triplet *tp, const char *str)
{
size_t len = strlen (str);
txtacc_grow (tp->acc, str, len + 1);
return txtacc_finish (tp->acc, 0);
}
/* Register a file in the triplet table */
void
register_file (struct file_info *finfo, const struct spool *spool)
{
struct file_triplet key, *ret;
int install = 1;
if (!triplet_table)
{
triplet_table = grecs_symtab_create (sizeof (struct file_triplet),
hash_triplet_hasher,
hash_triplet_compare,
NULL,
NULL,
hash_triplet_free);
if (!triplet_table)
grecs_alloc_die ();
}
- key.name = xmalloc (finfo->root_len + 1);
+ key.name = grecs_malloc (finfo->root_len + 1);
memcpy (key.name, finfo->name, finfo->root_len);
key.name[finfo->root_len] = 0;
ret = grecs_symtab_lookup_or_install (triplet_table, &key, &install);
if (!ret)
grecs_alloc_die ();
free (key.name);
if (install)
{
ret->spool = spool;
ret->acc = txtacc_create ();
}
ret->file[finfo->type] = *finfo;
}
/* Return true if any part of the triplet TRP was modified more than
TTL seconds ago */
static int
triplet_expired_p (struct file_triplet *trp, time_t ttl)
{
int i;
time_t now = time (NULL);
if (ttl == 0)
@@ -357,117 +358,117 @@ format_file_data (struct file_triplet *trp, enum file_type type, char **pret)
/* MODE OWNER GROUP SIZE MTIME FILE_NAME MD5SUM? */
modes[0] = '-'; /* Only regular files are allowed */
decode_file_mode (info->sb.st_mode, modes + 1);
/* File time */
tm = localtime (&info->sb.st_mtime);
strftime (timebuf, sizeof timebuf, "%Y-%m-%d %H:%M:%S %z", tm);
pw = getpwuid (TRIPLET_UID (trp));
if (!pw)
user_name = "unknown";
else
user_name = pw->pw_name;
grp = getgrgid (TRIPLET_GID (trp));
if (!grp)
group_name = "unknown"; /* should not happen */
else
group_name = grp->gr_name;
/* Size */
if (grecs_asprintf (&sptr, &slen, "%lu", (unsigned long) info->sb.st_size))
- xalloc_die ();
+ grecs_alloc_die ();
/* Figure out padding and format the buffer */
slen = strlen (sptr);
pad = strlen (user_name) + 1 + strlen (group_name) + 1 + slen;
if (pad > ugswidth)
ugswidth = pad;
if (grecs_asprintf (&buf, &size,
"%s %s %s %*s %s %s",
modes, user_name, group_name, ugswidth - pad + slen,
sptr,
timebuf, info->name))
- xalloc_die ();
+ grecs_alloc_die ();
free (sptr);
*pret = buf;
return 0;
}
static const char *
expand_triplet_ls_full (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
char *buf[FILE_TYPE_COUNT] = { NULL, NULL, NULL };
size_t size = 0;
if (format_file_data (trp, file_dist, &buf[file_dist]) == 0)
size += strlen (buf[file_dist]) + 1;
if (format_file_data (trp, file_signature, &buf[file_signature]) == 0)
size += strlen (buf[file_signature]) + 1;
if (format_file_data (trp, file_directive, &buf[file_directive]) == 0)
size += strlen (buf[file_directive]) + 1;
- def->value = def->storage = xmalloc (size + 1);
+ def->value = def->storage = grecs_malloc (size + 1);
def->value[0] = 0;
if (buf[file_dist])
{
strcat (def->value, buf[file_dist]);
strcat (def->value, "\n");
}
if (buf[file_signature])
{
strcat (def->value, buf[file_signature]);
strcat (def->value, "\n");
}
if (buf[file_directive])
{
strcat (def->value, buf[file_directive]);
strcat (def->value, "\n");
}
free (buf[file_dist]);
free (buf[file_signature]);
free (buf[file_directive]);
return def->value;
}
static const char *
expand_triplet_ls_upload (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
char *buf[2] = { NULL, NULL };
size_t size = 0;
if (format_file_data (trp, file_dist, &buf[file_dist]) == 0)
size += strlen (buf[file_dist]) + 1;
if (format_file_data (trp, file_signature, &buf[file_signature]) == 0)
size += strlen (buf[file_signature]) + 1;
- def->value = def->storage = xmalloc (size + 1);
+ def->value = def->storage = grecs_malloc (size + 1);
def->value[0] = 0;
if (buf[file_dist])
{
strcat (def->value, buf[file_dist]);
strcat (def->value, "\n");
}
if (buf[file_signature])
{
strcat (def->value, buf[file_signature]);
strcat (def->value, "\n");
}
free (buf[file_dist]);
free (buf[file_signature]);
return def->value;
}
static const char *
expand_triplet_dist (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->file[file_dist].name;
}
@@ -531,99 +532,99 @@ expand_user_real_name (struct metadef *def, void *data)
return trp->uploader->realname;
def->value = "UNKNOWN";
return def->value;
}
static const char *
expand_user_email (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
if (trp->uploader)
return trp->uploader->email;
def->value = "UNKNOWN";
return def->value;
}
static const char *
expand_email_user (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
if (trp->uploader)
{
size_t size = 0;
if (grecs_asprintf (&def->storage, &size, "\"%s\" <%s>",
trp->uploader->realname, trp->uploader->email))
- xalloc_die ();
+ grecs_alloc_die ();
def->value = def->storage;
}
return def->value;
}
static const char *
expand_report (struct metadef *def, void *data)
{
return report_string;
}
static const char *
expand_comment (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
if (directive_get_value (trp, "comment", (const char**) &def->value))
def->value = "";
return def->value;
}
static const char *
expand_check_diagn (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->check_diag;
}
static const char *
expand_check_result (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
int status = trp->check_result;
if (status == 0)
return def->value = "0";
else if (WIFEXITED (status))
{
size_t size = 0;
def->storage = NULL;
if (grecs_asprintf (&def->storage, &size,
"%d", WEXITSTATUS (status)))
- xalloc_die ();
+ grecs_alloc_die ();
}
else if (WIFSIGNALED (status))
{
size_t size = 0;
def->storage = NULL;
if (grecs_asprintf (&def->storage, &size, "SIG+%d",
WTERMSIG (status)))
- xalloc_die ();
+ grecs_alloc_die ();
}
else
return def->value = "[unrecognized return code]";
return def->value = def->storage;
}
#define DECL_EXPAND_TIMER(what) \
static const char * \
__cat2__(expand_timer_,what) (struct metadef *def, void *data) \
{ \
wydawca_timer_t t = timer_stop ((char*)def->data); \
def->storage = timer_format_time (__cat2__(timer_get_,what) (t)); \
return def->value = def->storage; \
}
DECL_EXPAND_TIMER(real)
DECL_EXPAND_TIMER(user)
DECL_EXPAND_TIMER(system)
#define DECL_TIMER(name,t) \
{ "timer:" #name ":" #t, NULL, __cat2__(expand_timer_,t), NULL, #name }
#define DECL_FULL_TIMER(name) \
DECL_TIMER(name, real), \
DECL_TIMER(name, user), \
diff --git a/src/txtacc.c b/src/txtacc.c
index 91659f6..442e27e 100644
--- a/src/txtacc.c
+++ b/src/txtacc.c
@@ -13,50 +13,50 @@
You should have received a copy of the GNU General Public License along
with wydawca. If not, see <http://www.gnu.org/licenses/>. */
#include "wydawca.h"
struct txtacc_entry
{
char *buf; /* Text buffer */
size_t size; /* Buffer size */
size_t len; /* Actual number of bytes in buffer */
};
#define TXTACC_BUFSIZE 1024
#define txtacc_entry_freesize(e) ((e)->size - (e)->len)
struct txtacc
{
struct grecs_list *cur; /* Current build list */
struct grecs_list *mem; /* List of already allocated elements */
};
static struct txtacc_entry *
txtacc_alloc_entry (struct grecs_list *list, size_t size)
{
- struct txtacc_entry *p = xmalloc (sizeof (*p));
- p->buf = xmalloc (size);
+ struct txtacc_entry *p = grecs_malloc (sizeof (*p));
+ p->buf = grecs_malloc (size);
p->size = size;
p->len = 0;
grecs_list_append (list, p);
return p;
}
static struct txtacc_entry *
txtacc_cur_entry (struct txtacc *acc)
{
struct txtacc_entry *ent;
if (grecs_list_size (acc->cur) == 0)
return txtacc_alloc_entry (acc->cur, TXTACC_BUFSIZE);
ent = acc->cur->tail->data;
if (txtacc_entry_freesize (ent) == 0)
ent = txtacc_alloc_entry (acc->cur, TXTACC_BUFSIZE);
return ent;
}
static void
txtacc_entry_append (struct txtacc_entry *ent, const char *p, size_t size)
{
memcpy (ent->buf + ent->len, p, size);
ent->len += size;
@@ -68,115 +68,117 @@ txtacc_entry_tailor (struct txtacc_entry *ent)
if (ent->size > ent->len)
{
char *p = realloc (ent->buf, ent->len);
if (!p)
return;
ent->buf = p;
ent->size = ent->len;
}
}
static void
txtacc_entry_free (void *p)
{
if (p)
{
struct txtacc_entry *ent = p;
free (ent->buf);
free (ent);
}
}
struct txtacc *
txtacc_create ()
{
- struct txtacc *acc = xmalloc (sizeof (*acc));
+ struct txtacc *acc = grecs_malloc (sizeof (*acc));
acc->cur = grecs_list_create ();
acc->cur->free_entry = txtacc_entry_free;
acc->mem = grecs_list_create ();
acc->mem->free_entry = txtacc_entry_free;
return acc;
}
void
txtacc_free (struct txtacc *acc)
{
grecs_list_free (acc->cur);
grecs_list_free (acc->mem);
free (acc);
}
void
txtacc_grow (struct txtacc *acc, const char *buf, size_t size)
{
while (size)
{
struct txtacc_entry *ent = txtacc_cur_entry (acc);
size_t rest = txtacc_entry_freesize (ent);
if (rest > size)
rest = size;
txtacc_entry_append (ent, buf, rest);
buf += rest;
size -= rest;
}
}
char *
txtacc_finish (struct txtacc *acc, int steal)
{
struct grecs_list_entry *ep;
struct txtacc_entry *txtent;
size_t size;
char *p;
switch (grecs_list_size (acc->cur))
{
case 0:
return NULL;
case 1:
txtent = acc->cur->head->data;
acc->cur->head->data = NULL;
txtacc_entry_tailor (txtent);
+ grecs_list_append (acc->mem, txtent);
break;
default:
size = 0;
for (ep = acc->cur->head; ep; ep = ep->next)
{
txtent = ep->data;
size += txtent->len;
}
txtent = txtacc_alloc_entry (acc->mem, size);
for (ep = acc->cur->head; ep; ep = ep->next)
{
struct txtacc_entry *tp = ep->data;
txtacc_entry_append (txtent, tp->buf, tp->len);
}
}
grecs_list_clear (acc->cur);
p = txtent->buf;
if (steal)
- free (txtent);
- else
- grecs_list_append (acc->mem, txtent);
+ {
+ grecs_list_remove_tail (acc->mem);
+ free (txtent);
+ }
return p;
}
void
txtacc_free_string (struct txtacc *acc, char *str)
{
struct grecs_list_entry *ep;
for (ep = acc->mem->head; ep; ep = ep->next)
{
struct txtacc_entry *tp = ep->data;
if (tp->buf == str)
{
- grecs_list_remove_entry(acc->mem, ep);
+ grecs_list_remove_entry (acc->mem, ep);
free (tp->buf);
return;
}
}
}
diff --git a/src/verify.c b/src/verify.c
index a49983c..c8fef11 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -92,49 +92,49 @@ fill_project_name (struct file_triplet *trp)
{
char *blurb;
size_t size;
FILE *fp;
char *p;
const char *directory;
int rc;
size = trp->file[file_directive].sb.st_size;
if (size <= MSG_BEGIN_MARKER_LEN)
{
logmsg (LOG_ERR, _("too small directive file %s"),
trp->file[file_directive].name);
return 1;
}
fp = fopen (trp->file[file_directive].name, "r");
if (!fp)
{
logmsg (LOG_ERR, _("cannot open file %s: %s"),
trp->file[file_directive].name, strerror (errno));
return 1;
}
- blurb = xmalloc (size + 1);
+ blurb = grecs_malloc (size + 1);
rc = fread (blurb, size, 1, fp);
fclose (fp);
if (rc != 1)
{
logmsg (LOG_ERR, _("error reading file %s: %s"),
trp->file[file_directive].name, strerror (errno));
free (blurb);
return 1;
}
blurb[size] = 0;
if (extract_plaintext (blurb))
{
logmsg (LOG_ERR, _("%s: unrecognized format"),
trp->file[file_directive].name);
free (blurb);
return 1;
}
trp->blurb = blurb;
if (directive_parse (trp))
@@ -161,49 +161,49 @@ fill_project_name (struct file_triplet *trp)
p = strchr (trp->relative_dir, '/');
if (p)
{
size_t len = p - trp->relative_dir;
if (len == 0)
{
logmsg (LOG_ERR, _("%s: empty `directory' directive"),
trp->file[file_directive].name);
return 1;
}
txtacc_grow (trp->acc, trp->relative_dir, len);
txtacc_1grow (trp->acc, 0);
trp->project = txtacc_finish (trp->acc, 0);
}
else
trp->project = trp->relative_dir;
return 0;
}
struct uploader_info *
new_uploader_info (struct uploader_info *src)
{
- struct uploader_info *p = xmalloc (sizeof (*p));
+ struct uploader_info *p = grecs_malloc (sizeof (*p));
p->next = NULL;
p->name = src->name;
p->realname = src->realname;
p->gpg_key = src->gpg_key;
p->email = src->email;
p->fpr = NULL;
return p;
}
struct uploader_info *
uploader_find_frp (struct uploader_info *list, const char *fpr)
{
for (; list; list = list->next)
if (list->fpr && strcmp (list->fpr, fpr) == 0)
break;
return list;
}
int
verify_directive_file (struct file_triplet *trp)
{
char *command;
int rc;
void *md;
diff --git a/src/wydawca.c b/src/wydawca.c
index cc1815b..36aa8b7 100644
--- a/src/wydawca.c
+++ b/src/wydawca.c
@@ -50,49 +50,49 @@ struct grecs_sockaddr listen_sockaddr;
unsigned wydawca_stat[MAX_STAT];
void
initstats ()
{
memset (wydawca_stat, 0, sizeof wydawca_stat);
}
/* Logging */
void
syslog_printer (int prio, const char *fmt, va_list ap)
{
if (syslog_include_prio)
{
static char *fmtbuf;
static size_t fmtsize;
const char *p = mu_syslog_priority_to_string (prio);
size_t size = strlen (p) + 3 + strlen (fmt) + 1;
if (size > fmtsize)
{
fmtsize = size;
- fmtbuf = x2realloc (fmtbuf, &fmtsize);
+ fmtbuf = grecs_realloc (fmtbuf, fmtsize);
}
sprintf (fmtbuf, "[%s] %s", p, fmt);
fmt = fmtbuf;
}
#if HAVE_VSYSLOG
vsyslog (prio, fmt, ap);
#else
char buf[128];
vsnprintf (buf, sizeof buf, fmt, ap);
syslog (prio, "%s", buf);
#endif
}
void
stderr_printer (int prio, const char *fmt, va_list ap)
{
const char *p = mu_syslog_priority_to_string (prio);
fprintf (stderr, "%s: ", program_name);
if (p)
fprintf (stderr, "[%s] ", p);
vfprintf (stderr, fmt, ap);
@@ -158,59 +158,59 @@ static char *stat_kwname[MAX_STAT] = {
"stat:archives",
"stat:symlinks",
"stat:rmsymlinks",
"stat:check-failures"
};
int
stat_mask_p (unsigned long mask)
{
int i;
for (i = 0; i < MAX_STAT; i++)
if (wydawca_stat[i] != 0 && (mask && STAT_MASK (i)))
return 1;
return 0;
}
static const char *
stat_expand (struct metadef *def, void *data)
{
size_t size = 0;
def->storage = NULL;
if (grecs_asprintf (&def->storage, &size, "%u",
wydawca_stat[(int) def->data]))
- xalloc_die ();
+ grecs_alloc_die ();
def->value = def->storage;
return def->value;
}
struct metadef *
make_stat_expansion (size_t count)
{
int i;
struct metadef *def, *p;
- def = xcalloc (MAX_STAT + count + 1, sizeof (def[0]));
+ def = grecs_calloc (MAX_STAT + count + 1, sizeof (def[0]));
p = def + count;
for (i = 0; i < MAX_STAT; i++, p++)
{
p->kw = stat_kwname[i];
p->value = NULL;
p->storage = NULL;
p->expand = stat_expand;
p->data = (void*) i;
}
p->kw = NULL;
return def;
}
void
logstats ()
{
int i;
if (stat_mask_p (print_stats))
{
for (i = 0; i < MAX_STAT; i++)
if (print_stats & STAT_MASK (i))
logmsg (LOG_INFO, "%s: %u", gettext (stat_name[i]), wydawca_stat[i]);
}
@@ -231,49 +231,49 @@ grecs_print_diag (grecs_locus_t *locus, int err, int errcode, const char *msg)
else
logmsg (err ? LOG_ERR : LOG_WARNING, "%s:%lu: %s",
locus->file, (unsigned long)locus->line, msg);
}
else
{
if (errcode)
logmsg (err ? LOG_ERR : LOG_WARNING, "%s: %s", msg,
strerror (errcode));
else
logmsg (err ? LOG_ERR : LOG_WARNING, "%s", msg);
}
}
static int uidc;
static uid_t *uidv;
static void
collect_uids (int argc, char **argv)
{
int i;
uidc = argc;
- uidv = xcalloc (uidc, sizeof (uidv[0]));
+ uidv = grecs_calloc (uidc, sizeof (uidv[0]));
for (i = 0; i < argc; i++)
{
struct passwd *pw = getpwnam (argv[i]);
if (!pw)
{
char *p;
unsigned n = strtoul (argv[i], &p, 10);
if (*p)
{
logmsg (LOG_ERR, _("no such user: %s"), argv[i]);
exit (EX_NOUSER);
}
uidv[i] = n;
}
else
uidv[i] = pw->pw_uid;
}
}
char **x_argv;
extern int reconfigure;
void
diff --git a/src/wydawca.h b/src/wydawca.h
index 2307bad..94b7ee3 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -20,56 +20,55 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <syslog.h>
#include <getopt.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
#include <signal.h>
#include <limits.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <time.h>
#include <sysexits.h>
+#include <fnmatch.h>
+#include <regex.h>
#include <mailutils/types.h>
#include <mailutils/url.h>
#include <mailutils/errno.h>
-#include "error.h"
-#include "xalloc.h"
-#include "backupfile.h"
#include "grecs.h"
#include "wordsplit.h"
#define SP(s) ((s) ? (s) : "NONE")
#define WYDAWCA_EX_AGAIN 1
/* The range of directive versions we accept (major * 100 + minor) */
#define MIN_DIRECTIVE_VERSION 101
#define MAX_DIRECTIVE_VERSION 101
/* Default modes for mkdir and creat commands: rely on the umask value */
#define MKDIR_PERMISSIONS 0777
#define CREAT_PERMISSIONS 0666
#define SUF_SIG ".sig"
#define SUF_SIG_LEN (sizeof (SUF_SIG) - 1)
#define SUF_DIR ".directive.asc"
#define SUF_DIR_LEN (sizeof (SUF_DIR) - 1)
#define __cat2__(a,b) a ## b
#define __cat3__(a,b,c) a ## b ## c
#define NITEMS(a) (sizeof(a)/sizeof((a)[0]))
@@ -89,48 +88,63 @@ enum dictionary_type
dictionary_external /* Invoke an external program */
};
struct dictionary
{
enum dictionary_id id;
enum dictionary_type type; /* Dictionary type */
char *query; /* Query template */
int parmc; /* Number of entries in paramv */
char **parmv; /* Parameters. The semantics differs
depending on type. For SQL:
0 - Identifier of the SQL struct
to use; */
int init_passed; /* Initialization count */
char *result; /* Result storage */
size_t result_size; /* Size of result */
unsigned ncol; /* Number of columns per row */
unsigned nrow; /* Number of rows */
void *storage;
};
+enum backup_type
+ {
+ no_backups, /* Don't make backups */
+ simple_backups, /* Make only simple backups */
+ numbered_existing_backups,/* Make numbered backups for files that already
+ have such backups and simple backups for the
+ rest */
+ numbered_backups, /* Make only numbered backups */
+ };
+
+extern char const *simple_backup_suffix;
+
+char *find_backup_file_name (char const *, enum backup_type);
+
+
/* Archive types */
enum archive_type
{
archive_none, /* No archivation requested */
archive_directory, /* Archive by moving files to a separate directory
hierarchy */
archive_tar /* Archive by appending to a tar file (tar -r) */
};
struct archive_descr
{
enum archive_type type; /* Archivation type */
char *name; /* Directory name if type==archive_directory,
archive file name if type==archive_tar */
enum backup_type backup_type; /* Requested backup type if
type == archive_directory */
};
/* Type of file in a triplet */
enum file_type
{
file_dist, /* Something to be distributed */

Return to:

Send suggestions and report system problems to the System administrator.