aboutsummaryrefslogtreecommitdiff
path: root/modules/mailutils/mailutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mailutils/mailutils.c')
-rw-r--r--modules/mailutils/mailutils.c180
1 files changed, 115 insertions, 65 deletions
diff --git a/modules/mailutils/mailutils.c b/modules/mailutils/mailutils.c
index 10018c4..03966c1 100644
--- a/modules/mailutils/mailutils.c
+++ b/modules/mailutils/mailutils.c
@@ -25,6 +25,7 @@
#include <smap/diag.h>
#include <smap/module.h>
#include <smap/parseopt.h>
+#include <smap/wordsplit.h>
static char *dfl_positive_reply = "OK";
static char *dfl_negative_reply = "NOTFOUND";
@@ -66,58 +67,97 @@ _mu_smap_db_free(struct _mu_smap_db *db)
free(db);
}
+static void
+free_env(char **env)
+{
+ int i;
+ for (i = 0; env[i]; i++)
+ free(env[i]);
+}
+
static char *
-expand_reply_text(const char *arg, struct _mu_smap_result *res)
+mkvar(const char *name, const char *val)
{
- int rc;
- mu_vartab_t vtab;
- char *reply = NULL;
- char buf[512];
- struct mu_auth_data *auth = res->auth;
+ char *ptr = malloc(strlen(name) + strlen(val) + 2);
+ if (ptr) {
+ strcpy(ptr, name);
+ strcat(ptr, "=");
+ strcat(ptr, val);
+ }
+ return ptr;
+}
- if (!arg)
- return NULL;
- mu_vartab_create(&vtab);
- mu_vartab_define(vtab, "db", res->db, 0);
- mu_vartab_define(vtab, "key", res->key, 0);
- mu_vartab_define(vtab, "map", res->map, 0);
- mu_vartab_define(vtab, MU_AUTH_NAME, auth ? auth->name : "", 0);
- mu_vartab_define(vtab, MU_AUTH_PASSWD, auth ? auth->passwd : "", 0);
- if (!auth)
- strcpy(buf, "-1");
- else
+static int
+mkenv(char **env, struct _mu_smap_result *res)
+{
+ int i = 0;
+ struct mu_auth_data *auth = res->auth;
+ char buf[512];
+
+#define MKVAR(n, v) \
+ do { \
+ if (!(env[i++] = mkvar(n, v))) \
+ return 1; \
+ } while (0)
+
+ MKVAR("db", res->db);
+ MKVAR("key", res->key);
+ MKVAR("map", res->map);
+ if (auth) {
+ MKVAR(MU_AUTH_NAME, auth->name);
+ MKVAR(MU_AUTH_PASSWD, auth->passwd);
snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->uid);
- mu_vartab_define(vtab, MU_AUTH_UID, buf, 0);
- if (!auth)
- strcpy(buf, "-1");
- else
+ MKVAR(MU_AUTH_UID, buf);
snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->gid);
- mu_vartab_define(vtab, MU_AUTH_GID, buf, 0);
- mu_vartab_define(vtab, MU_AUTH_GECOS,
- auth ? auth->gecos : "", 0);
- mu_vartab_define(vtab, MU_AUTH_DIR, auth ? auth->dir : "", 0);
- mu_vartab_define(vtab, MU_AUTH_SHELL, auth ? auth->shell : "", 0);
- mu_vartab_define(vtab, MU_AUTH_MAILBOX,
- (auth && auth->mailbox) ? auth->mailbox :
- res->url ? mu_url_to_string(res->url) : "", 0);
- if (!auth)
- strcpy(buf, "NONE");
- else
+ MKVAR(MU_AUTH_GID, buf);
+ MKVAR(MU_AUTH_GECOS, auth->gecos);
+ MKVAR(MU_AUTH_DIR, auth->dir);
+ MKVAR(MU_AUTH_SHELL, auth->shell);
+ MKVAR(MU_AUTH_MAILBOX,
+ auth->mailbox ? auth->mailbox :
+ res->url ? mu_url_to_string(res->url) : "");
snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->quota);
- mu_vartab_define(vtab, MU_AUTH_QUOTA, buf, 0);
- snprintf(buf, sizeof buf, "%lu", (unsigned long) res->mbsize);
- mu_vartab_define(vtab, "mbsize", buf, 0);
- snprintf(buf, sizeof buf, "%lu", (unsigned long) res->msgsize);
- mu_vartab_define(vtab, "msgsize", buf, 0);
-
+ MKVAR(MU_AUTH_QUOTA, buf);
+ snprintf(buf, sizeof buf, "%lu", (unsigned long) res->mbsize);
+ MKVAR("mbsize", buf);
+ snprintf(buf, sizeof buf, "%lu", (unsigned long) res->msgsize);
+ MKVAR("msgsize", buf);
+ }
if (res->diag)
- mu_vartab_define(vtab, "diag", res->diag, 1);
- rc = mu_vartab_expand(vtab, arg, &reply);
+ MKVAR("diag", res->diag);
+
+ env[i] = NULL;
+ return 0;
+}
+
+static int
+expand_reply_text(const char *arg, struct _mu_smap_result *res, char **repl)
+{
+ int rc;
+ char *env[16];
+ struct wordsplit ws;
+
+ if (mkenv(env, res)) {
+ mu_error("not enough memory");
+ free_env(env);
+ return 1;
+ }
+
+ ws.ws_env = (const char **) env;
+ ws.ws_error = smap_error;
+ rc = wordsplit(arg, &ws,
+ WRDSF_NOSPLIT |
+ WRDSF_NOCMD |
+ WRDSF_ENV |
+ WRDSF_ERROR |
+ WRDSF_SHOWERR);
+ free_env(env);
if (rc)
- mu_error("cannot expand string `%s': %s",
- arg, mu_strerror (rc));
- mu_vartab_destroy(&vtab);
- return reply;
+ return 1;
+ *repl = ws.ws_wordv[0];
+ ws.ws_wordv = NULL;
+ wordsplit_free(&ws);
+ return 0;
}
static int
@@ -130,7 +170,8 @@ _mu_auth_query(smap_database_t dbp,
struct mu_auth_data *auth = mu_get_auth_by_name(key);
struct _mu_smap_result res;
char *reply;
-
+ int rc;
+
res.db = mdb->id;
res.map = map;
res.key = key;
@@ -140,14 +181,16 @@ _mu_auth_query(smap_database_t dbp,
res.diag = NULL;
res.url = NULL;
if (!auth)
- reply = expand_reply_text(mdb->negative_reply, &res);
+ rc = expand_reply_text(mdb->negative_reply, &res, &reply);
else {
- reply = expand_reply_text(mdb->positive_reply, &res);
+ rc = expand_reply_text(mdb->positive_reply, &res, &reply);
mu_auth_data_free(auth);
}
- smap_stream_printf(ostr, "%s\n", reply);
- free(reply);
- return 0;
+ if (rc == 0) {
+ smap_stream_printf(ostr, "%s\n", reply);
+ free(reply);
+ }
+ return rc;
}
static int
@@ -181,32 +224,34 @@ switch_user_id(struct mu_auth_data *auth, int user)
return rc;
}
-static char *
+static int
checksize(struct _mu_smap_db *mdb, smap_stream_t ostr,
- const char *user, struct _mu_smap_result *res)
+ const char *user, struct _mu_smap_result *res,
+ char **preply)
{
struct mu_auth_data *auth;
mu_mailbox_t mbox;
int status;
- char *reply_txt = NULL;
+
+ *preply = NULL;
auth = mu_get_auth_by_name(user);
res->auth = auth;
if (!auth) {
res->diag = "user not found";
smap_debug(dbgid, 1, ("%s: user not found", user));
- return NULL;
+ return 0;
}
if (switch_user_id(auth, 1)) {
res->diag = "local system error";
- return NULL;
+ return 0;
}
status = mu_mailbox_create_default(&mbox, auth->mailbox);
if (status) {
res->diag = "local system error";
mu_error("could not create mailbox `%s': %s",
auth->mailbox, mu_strerror(status));
- return NULL;
+ return 0;
}
mu_mailbox_get_url(mbox, &res->url);
@@ -245,14 +290,15 @@ checksize(struct _mu_smap_db *mdb, smap_stream_t ostr,
stat = mdb->positive_reply;
res->diag = "QUOTAOK";
}
- reply_txt = expand_reply_text(stat, res);
+ if (expand_reply_text(stat, res, preply))
+ return 1;
}
switch_user_id(auth, 0);
mu_mailbox_close(mbox);
}
mu_mailbox_destroy(&mbox);
mu_auth_data_free(auth);
- return reply_txt;
+ return 0;
}
static int
@@ -267,7 +313,8 @@ _mu_mbq_query(smap_database_t dbp,
size_t len;
struct _mu_smap_result res;
char *reply;
-
+ int rc;
+
memset(&res, 0, sizeof(res));
res.db = mdb->id;
res.map = map;
@@ -290,13 +337,16 @@ _mu_mbq_query(smap_database_t dbp,
("ignoring junk after %s", user + len));
}
- reply = checksize(mdb, ostr, user, &res);
- if (!reply)
- reply = expand_reply_text(mdb->onerror_reply, &res);
- smap_stream_printf(ostr, "%s\n", reply);
- free(reply);
+ rc = checksize(mdb, ostr, user, &res, &reply);
+
+ if (!rc && !reply)
+ rc = expand_reply_text(mdb->onerror_reply, &res, &reply);
+ if (rc == 0) {
+ smap_stream_printf(ostr, "%s\n", reply);
+ free(reply);
+ }
free(user);
- return 0;
+ return rc;
}

Return to:

Send suggestions and report system problems to the System administrator.