diff options
Diffstat (limited to 'modules/mailutils/mailutils.c')
-rw-r--r-- | modules/mailutils/mailutils.c | 180 |
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 @@ | |||
25 | #include <smap/diag.h> | 25 | #include <smap/diag.h> |
26 | #include <smap/module.h> | 26 | #include <smap/module.h> |
27 | #include <smap/parseopt.h> | 27 | #include <smap/parseopt.h> |
28 | #include <smap/wordsplit.h> | ||
28 | 29 | ||
29 | static char *dfl_positive_reply = "OK"; | 30 | static char *dfl_positive_reply = "OK"; |
30 | static char *dfl_negative_reply = "NOTFOUND"; | 31 | static char *dfl_negative_reply = "NOTFOUND"; |
@@ -66,58 +67,97 @@ _mu_smap_db_free(struct _mu_smap_db *db) | |||
66 | free(db); | 67 | free(db); |
67 | } | 68 | } |
68 | 69 | ||
70 | static void | ||
71 | free_env(char **env) | ||
72 | { | ||
73 | int i; | ||
74 | for (i = 0; env[i]; i++) | ||
75 | free(env[i]); | ||
76 | } | ||
77 | |||
69 | static char * | 78 | static char * |
70 | expand_reply_text(const char *arg, struct _mu_smap_result *res) | 79 | mkvar(const char *name, const char *val) |
71 | { | 80 | { |
72 | int rc; | 81 | char *ptr = malloc(strlen(name) + strlen(val) + 2); |
73 | mu_vartab_t vtab; | 82 | if (ptr) { |
74 | char *reply = NULL; | 83 | strcpy(ptr, name); |
75 | char buf[512]; | 84 | strcat(ptr, "="); |
76 | struct mu_auth_data *auth = res->auth; | 85 | strcat(ptr, val); |
86 | } | ||
87 | return ptr; | ||
88 | } | ||
77 | 89 | ||
78 | if (!arg) | 90 | static int |
79 | return NULL; | 91 | mkenv(char **env, struct _mu_smap_result *res) |
80 | mu_vartab_create(&vtab); | 92 | { |
81 | mu_vartab_define(vtab, "db", res->db, 0); | 93 | int i = 0; |
82 | mu_vartab_define(vtab, "key", res->key, 0); | 94 | struct mu_auth_data *auth = res->auth; |
83 | mu_vartab_define(vtab, "map", res->map, 0); | 95 | char buf[512]; |
84 | mu_vartab_define(vtab, MU_AUTH_NAME, auth ? auth->name : "", 0); | 96 | |
85 | mu_vartab_define(vtab, MU_AUTH_PASSWD, auth ? auth->passwd : "", 0); | 97 | #define MKVAR(n, v) \ |
86 | if (!auth) | 98 | do { \ |
87 | strcpy(buf, "-1"); | 99 | if (!(env[i++] = mkvar(n, v))) \ |
88 | else | 100 | return 1; \ |
101 | } while (0) | ||
102 | |||
103 | MKVAR("db", res->db); | ||
104 | MKVAR("key", res->key); | ||
105 | MKVAR("map", res->map); | ||
106 | if (auth) { | ||
107 | MKVAR(MU_AUTH_NAME, auth->name); | ||
108 | MKVAR(MU_AUTH_PASSWD, auth->passwd); | ||
89 | snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->uid); | 109 | snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->uid); |
90 | mu_vartab_define(vtab, MU_AUTH_UID, buf, 0); | 110 | MKVAR(MU_AUTH_UID, buf); |
91 | if (!auth) | ||
92 | strcpy(buf, "-1"); | ||
93 | else | ||
94 | snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->gid); | 111 | snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->gid); |
95 | mu_vartab_define(vtab, MU_AUTH_GID, buf, 0); | 112 | MKVAR(MU_AUTH_GID, buf); |
96 | mu_vartab_define(vtab, MU_AUTH_GECOS, | 113 | MKVAR(MU_AUTH_GECOS, auth->gecos); |
97 | auth ? auth->gecos : "", 0); | 114 | MKVAR(MU_AUTH_DIR, auth->dir); |
98 | mu_vartab_define(vtab, MU_AUTH_DIR, auth ? auth->dir : "", 0); | 115 | MKVAR(MU_AUTH_SHELL, auth->shell); |
99 | mu_vartab_define(vtab, MU_AUTH_SHELL, auth ? auth->shell : "", 0); | 116 | MKVAR(MU_AUTH_MAILBOX, |
100 | mu_vartab_define(vtab, MU_AUTH_MAILBOX, | 117 | auth->mailbox ? auth->mailbox : |
101 | (auth && auth->mailbox) ? auth->mailbox : | 118 | res->url ? mu_url_to_string(res->url) : ""); |
102 | res->url ? mu_url_to_string(res->url) : "", 0); | ||
103 | if (!auth) | ||
104 | strcpy(buf, "NONE"); | ||
105 | else | ||
106 | snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->quota); | 119 | snprintf(buf, sizeof buf, "%lu", (unsigned long) auth->quota); |
107 | mu_vartab_define(vtab, MU_AUTH_QUOTA, buf, 0); | 120 | MKVAR(MU_AUTH_QUOTA, buf); |
108 | snprintf(buf, sizeof buf, "%lu", (unsigned long) res->mbsize); | 121 | snprintf(buf, sizeof buf, "%lu", (unsigned long) res->mbsize); |
109 | mu_vartab_define(vtab, "mbsize", buf, 0); | 122 | MKVAR("mbsize", buf); |
110 | snprintf(buf, sizeof buf, "%lu", (unsigned long) res->msgsize); | 123 | snprintf(buf, sizeof buf, "%lu", (unsigned long) res->msgsize); |
111 | mu_vartab_define(vtab, "msgsize", buf, 0); | 124 | MKVAR("msgsize", buf); |
112 | 125 | } | |
113 | if (res->diag) | 126 | if (res->diag) |
114 | mu_vartab_define(vtab, "diag", res->diag, 1); | 127 | MKVAR("diag", res->diag); |
115 | rc = mu_vartab_expand(vtab, arg, &reply); | 128 | |
129 | env[i] = NULL; | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int | ||
134 | expand_reply_text(const char *arg, struct _mu_smap_result *res, char **repl) | ||
135 | { | ||
136 | int rc; | ||
137 | char *env[16]; | ||
138 | struct wordsplit ws; | ||
139 | |||
140 | if (mkenv(env, res)) { | ||
141 | mu_error("not enough memory"); | ||
142 | free_env(env); | ||
143 | return 1; | ||
144 | } | ||
145 | |||
146 | ws.ws_env = (const char **) env; | ||
147 | ws.ws_error = smap_error; | ||
148 | rc = wordsplit(arg, &ws, | ||
149 | WRDSF_NOSPLIT | | ||
150 | WRDSF_NOCMD | | ||
151 | WRDSF_ENV | | ||
152 | WRDSF_ERROR | | ||
153 | WRDSF_SHOWERR); | ||
154 | free_env(env); | ||
116 | if (rc) | 155 | if (rc) |
117 | mu_error("cannot expand string `%s': %s", | 156 | return 1; |
118 | arg, mu_strerror (rc)); | 157 | *repl = ws.ws_wordv[0]; |
119 | mu_vartab_destroy(&vtab); | 158 | ws.ws_wordv = NULL; |
120 | return reply; | 159 | wordsplit_free(&ws); |
160 | return 0; | ||
121 | } | 161 | } |
122 | 162 | ||
123 | static int | 163 | static int |
@@ -130,7 +170,8 @@ _mu_auth_query(smap_database_t dbp, | |||
130 | struct mu_auth_data *auth = mu_get_auth_by_name(key); | 170 | struct mu_auth_data *auth = mu_get_auth_by_name(key); |
131 | struct _mu_smap_result res; | 171 | struct _mu_smap_result res; |
132 | char *reply; | 172 | char *reply; |
133 | 173 | int rc; | |
174 | |||
134 | res.db = mdb->id; | 175 | res.db = mdb->id; |
135 | res.map = map; | 176 | res.map = map; |
136 | res.key = key; | 177 | res.key = key; |
@@ -140,14 +181,16 @@ _mu_auth_query(smap_database_t dbp, | |||
140 | res.diag = NULL; | 181 | res.diag = NULL; |
141 | res.url = NULL; | 182 | res.url = NULL; |
142 | if (!auth) | 183 | if (!auth) |
143 | reply = expand_reply_text(mdb->negative_reply, &res); | 184 | rc = expand_reply_text(mdb->negative_reply, &res, &reply); |
144 | else { | 185 | else { |
145 | reply = expand_reply_text(mdb->positive_reply, &res); | 186 | rc = expand_reply_text(mdb->positive_reply, &res, &reply); |
146 | mu_auth_data_free(auth); | 187 | mu_auth_data_free(auth); |
147 | } | 188 | } |
148 | smap_stream_printf(ostr, "%s\n", reply); | 189 | if (rc == 0) { |
149 | free(reply); | 190 | smap_stream_printf(ostr, "%s\n", reply); |
150 | return 0; | 191 | free(reply); |
192 | } | ||
193 | return rc; | ||
151 | } | 194 | } |
152 | 195 | ||
153 | static int | 196 | static int |
@@ -181,32 +224,34 @@ switch_user_id(struct mu_auth_data *auth, int user) | |||
181 | return rc; | 224 | return rc; |
182 | } | 225 | } |
183 | 226 | ||
184 | static char * | 227 | static int |
185 | checksize(struct _mu_smap_db *mdb, smap_stream_t ostr, | 228 | checksize(struct _mu_smap_db *mdb, smap_stream_t ostr, |
186 | const char *user, struct _mu_smap_result *res) | 229 | const char *user, struct _mu_smap_result *res, |
230 | char **preply) | ||
187 | { | 231 | { |
188 | struct mu_auth_data *auth; | 232 | struct mu_auth_data *auth; |
189 | mu_mailbox_t mbox; | 233 | mu_mailbox_t mbox; |
190 | int status; | 234 | int status; |
191 | char *reply_txt = NULL; | 235 | |
236 | *preply = NULL; | ||
192 | 237 | ||
193 | auth = mu_get_auth_by_name(user); | 238 | auth = mu_get_auth_by_name(user); |
194 | res->auth = auth; | 239 | res->auth = auth; |
195 | if (!auth) { | 240 | if (!auth) { |
196 | res->diag = "user not found"; | 241 | res->diag = "user not found"; |
197 | smap_debug(dbgid, 1, ("%s: user not found", user)); | 242 | smap_debug(dbgid, 1, ("%s: user not found", user)); |
198 | return NULL; | 243 | return 0; |
199 | } | 244 | } |
200 | if (switch_user_id(auth, 1)) { | 245 | if (switch_user_id(auth, 1)) { |
201 | res->diag = "local system error"; | 246 | res->diag = "local system error"; |
202 | return NULL; | 247 | return 0; |
203 | } | 248 | } |
204 | status = mu_mailbox_create_default(&mbox, auth->mailbox); | 249 | status = mu_mailbox_create_default(&mbox, auth->mailbox); |
205 | if (status) { | 250 | if (status) { |
206 | res->diag = "local system error"; | 251 | res->diag = "local system error"; |
207 | mu_error("could not create mailbox `%s': %s", | 252 | mu_error("could not create mailbox `%s': %s", |