Codebase list fdm / 7735db4
Spaces -> tabs. Nicholas Marriott 9 years ago
43 changed file(s) with 440 addition(s) and 440 deletion(s). Raw diff Collapse all Expand all
3737 if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a)) \
3838 fatalx("size too big"); \
3939 if ((a)->space == 0) { \
40 (a)->space = ARRAY_INITIALSPACE(a); \
40 (a)->space = ARRAY_INITIALSPACE(a); \
4141 (a)->list = xrealloc((a)->list, 1, (a)->space); \
4242 } \
4343 while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \
5555
5656 #define ARRAY_INIT(a) do { \
5757 (a)->num = 0; \
58 (a)->list = NULL; \
58 (a)->list = NULL; \
5959 (a)->space = 0; \
6060 } while (0)
6161 #define ARRAY_CLEAR(a) do { \
7474 #define ARRAY_INSERT(a, i, s) do { \
7575 ARRAY_ENSURE(a, 1); \
7676 if ((i) < (a)->num) { \
77 memmove((a)->list + (i) + 1, (a)->list + (i), \
77 memmove((a)->list + (i) + 1, (a)->list + (i), \
7878 ARRAY_ITEMSIZE(a) * ((a)->num - (i))); \
7979 } \
8080 (a)->list[i] = s; \
8282 } while (0)
8383 #define ARRAY_REMOVE(a, i) do { \
8484 if ((i) < (a)->num - 1) { \
85 memmove((a)->list + (i), (a)->list + (i) + 1, \
85 memmove((a)->list + (i), (a)->list + (i) + 1, \
8686 ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \
8787 } \
8888 (a)->num--; \
9696 } while (0)
9797 #define ARRAY_TRUNC(a, n) do { \
9898 if ((a)->num > n) \
99 (a)->num -= n; \
99 (a)->num -= n; \
100100 else \
101101 ARRAY_FREE(a); \
102102 } while (0)
2222
2323 #include "fdm.h"
2424
25 char *attach_type(struct mail *, char *, const char *, char **);
25 char *attach_type(struct mail *, char *, const char *, char **);
2626 struct attach *attach_get(struct mail *, char **, size_t *, const char *,
2727 int *);
2828
180180 if (ptr == NULL)
181181 break;
182182 if (ptr - hdr == namelen && strncmp(hdr, name, namelen) == 0) {
183 llen -= (ptr - hdr + 1);
183 llen -= (ptr - hdr + 1);
184184 hdr = ptr + 1;
185185
186186 ptr = memchr(hdr, ';', llen);
135135 int flags, status, found = 0;
136136 char *s, *cause, *lbuf, *out, *err, tag[24];
137137 size_t llen;
138 struct cmd *cmd = NULL;
138 struct cmd *cmd = NULL;
139139 struct rmlist rml;
140140 u_int i;
141141
148148 /* Sort out the command. */
149149 s = replacepath(
150150 &cmddata->cmd, m->tags, m, &m->rml, find_tag(m->tags, "home"));
151 if (s == NULL || *s == '\0') {
151 if (s == NULL || *s == '\0') {
152152 log_warnx("%s: empty command", a->name);
153153 goto error;
154 }
154 }
155155
156156 log_debug2("%s: %s: started (ret=%d re=%s)", a->name, s, cmddata->ret,
157157 cmddata->re.str == NULL ? "none" : cmddata->re.str);
183183 log_warnx("%s: %s: %s", a->name, s, cause);
184184 goto error;
185185 }
186 if (status != 0)
186 if (status != 0)
187187 break;
188188 if (err != NULL)
189189 log_warnx("%s: %s: %s", a->name, s, err);
4949 double fetch_time_blocked = 0.0;
5050 #endif
5151
52 struct mail_queue fetch_matchq;
53 struct mail_queue fetch_deliverq;
54
55 u_int fetch_dropped;
56 u_int fetch_kept;
57
58 u_int fetch_queued; /* number of mails queued */
59 u_int fetch_blocked; /* blocked for parent */
52 struct mail_queue fetch_matchq;
53 struct mail_queue fetch_deliverq;
54
55 u_int fetch_dropped;
56 u_int fetch_kept;
57
58 u_int fetch_queued; /* number of mails queued */
59 u_int fetch_blocked; /* blocked for parent */
6060
6161 int
6262 open_cache(struct account *a, struct cache *cache)
9393 child_fetch(struct child *child, struct io *pio)
9494 {
9595 struct child_fetch_data *data = child->data;
96 enum fdmop op = data->op;
97 struct account *a = data->account;
98 struct msg msg;
96 enum fdmop op = data->op;
97 struct account *a = data->account;
98 struct msg msg;
9999 int error, flags;
100100 double tim;
101101
345345 struct msgbuf msgbuf;
346346 struct fetch_ctx fctx;
347347 struct cache *cache;
348 struct iolist iol;
348 struct iolist iol;
349349 int aborted, complete, holding, timeout;
350350
351351 log_debug2("%s: fetching", a->name);
352352
353353 TAILQ_INIT(&fetch_matchq);
354 TAILQ_INIT(&fetch_deliverq);
354 TAILQ_INIT(&fetch_deliverq);
355355 fetch_queued = fetch_dropped = fetch_kept = 0;
356356
357357 if (nflags & FETCH_POLL && a->fetch->total == NULL) {
523523 {
524524 struct mail_ctx *mctx;
525525 char *hdr, rtime[128], *rhost, total[16];
526 u_int n, b;
527 size_t size;
528 int error;
529 struct tm *tm;
530 time_t t;
526 u_int n, b;
527 size_t size;
528 int error;
529 struct tm *tm;
530 time_t t;
531531
532532 /*
533533 * Check for oversize mails. This must be first since there is no
549549 return (0);
550550 }
551551
552 /*
552 /*
553553 * Find the mail body (needed by trim_from). This is probably slower
554554 * than doing it during fetching but it guarantees consistency.
555555 */
556556 m->body = find_body(m);
557557
558 /* Trim "From" line, if any. */
558 /* Trim "From" line, if any. */
559559 trim_from(m);
560560
561561 /* Check for empty mails. */
570570 m->tim = get_time();
571571
572572 /* Add account name tag. */
573 add_tag(&m->tags, "account", "%s", a->name);
573 add_tag(&m->tags, "account", "%s", a->name);
574574
575575 /* Add mail time tags. */
576576 if (mailtime(m, &t) != 0) {
3737
3838 if (!TAILQ_EMPTY(&cleanlist)) {
3939 TAILQ_FOREACH(cent, &cleanlist, entry)
40 log_debug("cleanup: %s", cent->path);
40 log_debug("cleanup: %s", cent->path);
4141 fatalx("list not empty");
4242 }
4343 }
5353 */
5454
5555 saved_errno = errno;
56 TAILQ_FOREACH(cent, &cleanlist, entry) {
56 TAILQ_FOREACH(cent, &cleanlist, entry) {
5757 if (unlink(cent->path) != 0) {
5858 write(STDERR_FILENO, "unlink failed\n", 14);
5959 _exit(1);
116116 struct cleanent *cent;
117117
118118 #if 0
119 log_debug("cleanup_deregister: %s by %ld", path, (long) getpid());
119 log_debug("cleanup_deregister: %s by %ld", path, (long) getpid());
120120 #endif
121121
122122 if (path == NULL || *path == '\0')
126126 if (sigprocmask(SIG_BLOCK, &set, &oset) < 0)
127127 fatal("sigprocmask failed");
128128
129 TAILQ_FOREACH(cent, &cleanlist, entry) {
129 TAILQ_FOREACH(cent, &cleanlist, entry) {
130130 if (strcmp(cent->path, path) == 0) {
131131 TAILQ_REMOVE(&cleanlist, cent, entry);
132132 xfree(cent->path);
3737 cmd_start(const char *s, int flags, const char *buf, size_t len, char **cause)
3838 {
3939 struct cmd *cmd;
40 int fd_in[2], fd_out[2], fd_err[2];
40 int fd_in[2], fd_out[2], fd_err[2];
4141
4242 cmd = xmalloc(sizeof *cmd);
4343 cmd->pid = -1;
116116 close(fd_err[1]);
117117
118118 #ifdef SIGINFO
119 if (signal(SIGINFO, SIG_DFL) == SIG_ERR)
119 if (signal(SIGINFO, SIG_DFL) == SIG_ERR)
120120 fatal("signal failed");
121121 #endif
122 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
123 fatal("signal failed");
124 if (signal(SIGINT, SIG_DFL) == SIG_ERR)
125 fatal("signal failed");
126 if (signal(SIGTERM, SIG_DFL) == SIG_ERR)
127 fatal("signal failed");
128 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR)
129 fatal("signal failed");
130 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
131 fatal("signal failed");
132 if (signal(SIGUSR2, SIG_DFL) == SIG_ERR)
133 fatal("signal failed");
134 if (signal(SIGCHLD, SIG_DFL) == SIG_ERR)
122 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
123 fatal("signal failed");
124 if (signal(SIGINT, SIG_DFL) == SIG_ERR)
125 fatal("signal failed");
126 if (signal(SIGTERM, SIG_DFL) == SIG_ERR)
127 fatal("signal failed");
128 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR)
129 fatal("signal failed");
130 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
131 fatal("signal failed");
132 if (signal(SIGUSR2, SIG_DFL) == SIG_ERR)
133 fatal("signal failed");
134 if (signal(SIGCHLD, SIG_DFL) == SIG_ERR)
135135 fatal("signal failed");
136136
137137 execl(_PATH_BSHELL, "sh", "-c", s, (char *) NULL);
160160 if (fd_in[1] != -1) {
161161 cmd->io_in = io_create(fd_in[1], NULL, IO_LF);
162162 io_writeonly(cmd->io_in);
163 if (cmd->len != 0)
163 if (cmd->len != 0)
164164 cmd->io_in->flags |= IOF_MUSTWR;
165165 }
166166 cmd->io_out = NULL;
224224 int ssl;
225225 const char *port;
226226 } *proxyent, proxylist[] = {
227 { "http://", PROXY_HTTP, 0, "http" },
228 { "https://", PROXY_HTTPS, 1, "https" },
229 { "socks://", PROXY_SOCKS5, 0, "socks" },
230 { "socks5://", PROXY_SOCKS5, 0, "socks" },
231 { NULL, 0, 0, NULL }
227 { "http://", PROXY_HTTP, 0, "http" },
228 { "https://", PROXY_HTTPS, 1, "https" },
229 { "socks://", PROXY_SOCKS5, 0, "socks" },
230 { "socks5://", PROXY_SOCKS5, 0, "socks" },
231 { NULL, 0, 0, NULL }
232232 };
233233
234234 /* Copy the url so we can mangle it. */
356356 getport(char *port)
357357 {
358358 struct servent *sv;
359 int n;
359 int n;
360360 const char *errstr;
361361
362362 sv = getservbyname(port, "tcp");
576576 SSL_CTX_set_options(ctx, SSL_OP_ALL);
577577 else
578578 SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_TLSv1);
579 SSL_CTX_set_default_verify_paths(ctx);
579 SSL_CTX_set_default_verify_paths(ctx);
580580 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
581581
582582 ssl = SSL_new(ctx);
103103 db_print_item(
104104 unused TDB_CONTEXT *tdb, unused TDB_DATA key, TDB_DATA value, void *ptr)
105105 {
106 void (*p)(const char *, ...) = ptr;
106 void (*p)(const char *, ...) = ptr;
107107 struct cacheitem v;
108108 uint64_t tim;
109109
110 if (value.dsize != sizeof v)
110 if (value.dsize != sizeof v)
111111 return (-1);
112112 memcpy(&v, value.dptr, sizeof v);
113113
131131 uint64_t *lim = ptr;
132132 struct cacheitem v;
133133
134 if (value.dsize != sizeof v)
134 if (value.dsize != sizeof v)
135135 return (-1);
136136 memcpy(&v, value.dptr, sizeof v);
137137
158158 int
159159 db_clear_item(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value, unused void *ptr)
160160 {
161 if (value.dsize != sizeof (struct cacheitem))
161 if (value.dsize != sizeof (struct cacheitem))
162162 return (-1);
163163
164164 return (tdb_delete(tdb, key));
169169 struct fetch_ctx fctx;
170170 struct fetch_imap_data fdata;
171171 char *cause, *folder, *ptr, *line;
172 size_t len, maillen;
172 size_t len, maillen;
173173 u_int total, body;
174174
175175 /* Connect to the IMAP server. */
3232 int deliver_maildir_deliver(struct deliver_ctx *, struct actitem *);
3333 void deliver_maildir_desc(struct actitem *, char *, size_t);
3434
35 char *deliver_maildir_host(void);
35 char *deliver_maildir_host(void);
3636 int deliver_maildir_create(struct account *, const char *);
3737
3838 struct deliver deliver_maildir = {
143143 static u_int delivered = 0;
144144 char *host, *name, *path;
145145 char src[MAXPATHLEN], dst[MAXPATHLEN];
146 int fd;
147 ssize_t n;
146 int fd;
147 ssize_t n;
148148
149149 name = NULL;
150150 fd = -1;
168168 do {
169169 if (name != NULL)
170170 xfree(name);
171 xasprintf(&name, "%ld.%ld_%u.%s",
171 xasprintf(&name, "%ld.%ld_%u.%s",
172172 (long) time(NULL), (long) getpid(), delivered, host);
173173
174174 if (ppath(src, sizeof src, "%s/tmp/%s", path, name) != 0) {
7070 struct deliver_mbox_data *data = ti->data;
7171 char *path, *ptr, *lptr, *from = NULL;
7272 const char *msg;
73 size_t len, llen;
74 int fd, saved_errno;
73 size_t len, llen;
74 int fd, saved_errno;
7575 FILE *f;
7676 gzFile gzf;
7777 long long used;
78 sigset_t set, oset;
78 sigset_t set, oset;
7979 struct stat sb;
8080
8181 f = gzf = NULL;
153153 * done.
154154 */
155155 sigemptyset(&set);
156 sigaddset(&set, SIGTERM);
156 sigaddset(&set, SIGTERM);
157157 if (sigprocmask(SIG_BLOCK, &set, &oset) < 0)
158158 fatal("sigprocmask failed");
159159
4242 struct account *a = dctx->account;
4343 struct mail *m = dctx->mail;
4444 struct deliver_pipe_data *data = ti->data;
45 char *s, *cause, *err;
45 char *s, *cause, *err;
4646 int status;
4747 struct cmd *cmd = NULL;
4848 char *lbuf;
4949 size_t llen;
5050
5151 s = replacepath(&data->cmd, m->tags, m, &m->rml, dctx->udata->home);
52 if (s == NULL || *s == '\0') {
52 if (s == NULL || *s == '\0') {
5353 log_warnx("%s: empty command", a->name);
5454 goto error;
55 }
55 }
5656
5757 if (data->pipe) {
5858 log_debug2("%s: piping to \"%s\"", a->name, s);
7575 xfree(lbuf);
7676 goto error_cause;
7777 }
78 if (status == 0 && err != NULL)
78 if (status == 0 && err != NULL)
7979 log_warnx("%s: %s: %s", a->name, s, err);
8080 } while (status == 0);
8181 status--;
3939 struct mail *m = dctx->mail;
4040 struct deliver_remove_header_data *data = ti->data;
4141 char *ptr, *hdr;
42 size_t len, off, wrap;
42 size_t len, off, wrap;
4343 u_int i, j;
4444
4545
4545 struct mail *m = dctx->mail;
4646 struct deliver_rewrite_data *data = ti->data;
4747 struct mail *md = &dctx->wr_mail;
48 char *s, *cause, *out, *err;
49 int status;
48 char *s, *cause, *out, *err;
49 int status;
5050 struct cmd *cmd = NULL;
5151 char *lbuf;
5252 size_t llen;
5353
5454 s = replacepath(&data->cmd, m->tags, m, &m->rml, dctx->udata->home);
55 if (s == NULL || *s == '\0') {
55 if (s == NULL || *s == '\0') {
5656 log_warnx("%s: empty command", a->name);
5757 goto error;
58 }
58 }
5959
6060 log_debug2("%s: rewriting using \"%s\"", a->name, s);
6161
4444 {
4545 char ch;
4646 const char *errstr;
47 int n;
47 int n;
4848 size_t len;
4949
5050 len = strspn(line, "0123456789");
6767 struct account *a = dctx->account;
6868 struct mail *m = dctx->mail;
6969 struct deliver_smtp_data *data = ti->data;
70 int done, code;
70 int done, code;
7171 struct io *io;
7272 char *cause, *to, *from, *line, *ptr, *lbuf;
7373 enum deliver_smtp_state state;
74 size_t len, llen;
74 size_t len, llen;
7575
7676 io = connectproxy(&data->server,
7777 conf.verify_certs, conf.proxy, IO_CRLF, conf.timeout, &cause);
8787 lbuf = xmalloc(llen);
8888
8989 if (conf.host_fqdn != NULL)
90 xasprintf(&ptr, "%s@%s", dctx->udata->name, conf.host_fqdn);
90 xasprintf(&ptr, "%s@%s", dctx->udata->name, conf.host_fqdn);
9191 else
92 xasprintf(&ptr, "%s@%s", dctx->udata->name, conf.host_name);
92 xasprintf(&ptr, "%s@%s", dctx->udata->name, conf.host_name);
9393 if (data->to.str == NULL)
9494 to = xstrdup(ptr);
9595 else {
132132 goto error;
133133 state = SMTP_HELO;
134134 if (conf.host_fqdn != NULL)
135 io_writeline(io, "HELO %s", conf.host_fqdn);
135 io_writeline(io, "HELO %s", conf.host_fqdn);
136136 else
137 io_writeline(io, "HELO %s", conf.host_name);
137 io_writeline(io, "HELO %s", conf.host_name);
138138 break;
139139 case SMTP_HELO:
140140 if (code != 250)
4242 struct account *a = dctx->account;
4343 struct mail *m = dctx->mail;
4444 struct deliver_write_data *data = ti->data;
45 char *path;
46 FILE *f;
45 char *path;
46 FILE *f;
4747
4848 path = replacepath(&data->path, m->tags, m, &m->rml, dctx->udata->home);
49 if (path == NULL || *path == '\0') {
49 if (path == NULL || *path == '\0') {
5050 if (path != NULL)
5151 xfree(path);
5252 log_warnx("%s: empty command", a->name);
53 return (DELIVER_FAILURE);
54 }
53 return (DELIVER_FAILURE);
54 }
5555
5656 if (data->append) {
5757 log_debug2("%s: appending to %s", a->name, path);
6060 log_debug2("%s: writing to %s", a->name, path);
6161 f = fopen(path, "w");
6262 }
63 if (f == NULL) {
63 if (f == NULL) {
6464 log_warn("%s: %s: fopen", a->name, path);
6565 goto error;
6666 }
2424
2525 /* Deliver context. */
2626 struct deliver_ctx {
27 double tim;
27 double tim;
2828
2929 struct action *action;
3030 struct actitem *actitem;
3535
3636 struct userdata *udata;
3737
38 struct mail wr_mail;
38 struct mail wr_mail;
3939
4040 TAILQ_ENTRY(deliver_ctx) entry;
4141 };
5252 const char *name;
5353 enum delivertype type;
5454
55 int (*deliver)(struct deliver_ctx *, struct actitem *);
55 int (*deliver)(struct deliver_ctx *, struct actitem *);
5656 void (*desc)(struct actitem *, char *, size_t);
5757 };
5858
160160 extern struct deliver deliver_tag;
161161
162162 /* deliver-pipe.c */
163 extern struct deliver deliver_pipe;
163 extern struct deliver deliver_pipe;
164164
165165 /* deliver-drop.c */
166 extern struct deliver deliver_drop;
166 extern struct deliver deliver_drop;
167167
168168 /* deliver-keep.c */
169 extern struct deliver deliver_keep;
169 extern struct deliver deliver_keep;
170170
171171 /* deliver-maildir.c */
172 extern struct deliver deliver_maildir;
172 extern struct deliver deliver_maildir;
173173
174174 /* deliver-remove-header.c */
175175 extern struct deliver deliver_remove_header;
178178 extern struct deliver deliver_add_header;
179179
180180 /* deliver-mbox.c */
181 extern struct deliver deliver_mbox;
181 extern struct deliver deliver_mbox;
182182
183183 /* deliver-write.c */
184 extern struct deliver deliver_write;
184 extern struct deliver deliver_write;
185185
186186 /* deliver-rewrite.c */
187 extern struct deliver deliver_rewrite;
187 extern struct deliver deliver_rewrite;
188188
189189 /* deliver-add-to-cache.c */
190 extern struct deliver deliver_add_to_cache;
190 extern struct deliver deliver_add_to_cache;
191191
192192 /* deliver-remove-from-cache.c */
193 extern struct deliver deliver_remove_from_cache;
193 extern struct deliver deliver_remove_from_cache;
194194
195195 #endif
+30
-30
fdm.c less more
267267 fprintf(stderr,
268268 "usage: %s [-hklmnqv] [-a name] [-D name=value] [-f conffile] "
269269 "[-u user] [-x name] [fetch|poll|cache] [arguments]\n", __progname);
270 exit(1);
270 exit(1);
271271 }
272272
273273 int
274274 main(int argc, char **argv)
275275 {
276 int opt, lockfd, status, res;
276 int opt, lockfd, status, res;
277277 u_int i;
278 enum fdmop op = FDMOP_NONE;
278 enum fdmop op = FDMOP_NONE;
279279 const char *proxy = NULL, *s;
280280 char tmp[BUFSIZ], *ptr, *lock = NULL, *user, *home = NULL;
281281 struct utsname un;
287287 pid_t pid;
288288 struct children children, dead_children;
289289 struct child *child;
290 struct io *dead_io;
290 struct io *dead_io;
291291 struct iolist iol;
292292 double tim;
293293 struct sigaction act;
332332 ARRAY_INIT(&conf.excl);
333333
334334 ARRAY_INIT(&macros);
335 while ((opt = getopt(argc, argv, "a:D:f:hklmnqu:vx:")) != -1) {
336 switch (opt) {
335 while ((opt = getopt(argc, argv, "a:D:f:hklmnqu:vx:")) != -1) {
336 switch (opt) {
337337 case 'a':
338338 ARRAY_ADD(&conf.incl, xstrdup(optarg));
339339 break;
340340 case 'D':
341341 ARRAY_ADD(&macros, optarg);
342342 break;
343 case 'f':
343 case 'f':
344344 if (conf.conf_file == NULL)
345345 conf.conf_file = xstrdup(optarg);
346 break;
346 break;
347347 case 'h':
348348 home = getenv("HOME");
349349 break;
363363 if (conf.def_user == NULL)
364364 conf.def_user = xstrdup(optarg);
365365 break;
366 case 'v':
366 case 'v':
367367 if (conf.debug != -1)
368368 conf.debug++;
369 break;
369 break;
370370 case 'q':
371371 conf.debug = -1;
372372 break;
373373 case 'x':
374374 ARRAY_ADD(&conf.excl, xstrdup(optarg));
375375 break;
376 default:
377 usage();
378 }
379 }
376 default:
377 usage();
378 }
379 }
380380 argc -= optind;
381381 argv += optind;
382382 if (conf.check_only) {
425425 log_warnx("unknown user: %lu", (u_long) geteuid());
426426 exit(1);
427427 }
428 user = xstrdup(pw->pw_name);
428 user = xstrdup(pw->pw_name);
429429 if (home != NULL && *home != '\0')
430430 conf.user_home = xstrdup(home);
431431 else
444444 }
445445 log_debug2("loading configuration from %s", conf.conf_file);
446446 if (stat(conf.conf_file, &sb) == -1) {
447 log_warn("%s", conf.conf_file);
447 log_warn("%s", conf.conf_file);
448448 exit(1);
449449 }
450450 if (geteuid() != 0 && (sb.st_mode & (S_IROTH|S_IWOTH)) != 0)
451451 log_warnx("%s: world readable or writable", conf.conf_file);
452 if (parse_conf(conf.conf_file, &macros) != 0) {
453 log_warn("%s", conf.conf_file);
452 if (parse_conf(conf.conf_file, &macros) != 0) {
453 log_warn("%s", conf.conf_file);
454454 exit(1);
455455 }
456456 ARRAY_FREE(&macros);
470470 conf.queue_low = conf.queue_high * 3 / 4;
471471 if (conf.queue_low >= conf.queue_high)
472472 conf.queue_low = conf.queue_high - 1;
473 }
473 }
474474
475475 /* Set the umask. */
476476 umask(conf.file_umask);
618618 /* If -n, bail now, otherwise check there is something to work with. */
619619 if (conf.check_only)
620620 exit(0);
621 if (TAILQ_EMPTY(&conf.accounts)) {
622 log_warnx("no accounts specified");
621 if (TAILQ_EMPTY(&conf.accounts)) {
622 log_warnx("no accounts specified");
623623 exit(1);
624624 }
625 if (op == FDMOP_FETCH && TAILQ_EMPTY(&conf.rules)) {
626 log_warnx("no rules specified");
625 if (op == FDMOP_FETCH && TAILQ_EMPTY(&conf.rules)) {
626 log_warnx("no rules specified");
627627 exit(1);
628628 }
629629
699699 }
700700 conf.lock_file = lock;
701701
702 SSL_library_init();
703 SSL_load_error_strings();
702 SSL_library_init();
703 SSL_load_error_strings();
704704
705705 #ifdef DEBUG
706706 COUNTFDS("parent");
713713 TAILQ_INSERT_HEAD(&actaq, a, active_entry);
714714 }
715715 if (TAILQ_EMPTY(&actaq)) {
716 log_warnx("no accounts found");
716 log_warnx("no accounts found");
717717 res = 1;
718718 goto out;
719719 }
868868 }
869869
870870 tim = get_time() - tim;
871 log_debug2("parent: finished, total time %.3f seconds", tim);
871 log_debug2("parent: finished, total time %.3f seconds", tim);
872872
873873 out:
874874 if (!conf.allow_many && *conf.lock_file != '\0')
882882 if (conf.proxy->user != NULL)
883883 xfree(conf.proxy->user);
884884 if (conf.proxy->pass != NULL)
885 xfree(conf.proxy->pass);
885 xfree(conf.proxy->pass);
886886 if (conf.proxy->server.host != NULL)
887 xfree(conf.proxy->server.host);
887 xfree(conf.proxy->server.host);
888888 if (conf.proxy->server.port != NULL)
889 xfree(conf.proxy->server.port);
889 xfree(conf.proxy->server.port);
890890 xfree(conf.proxy);
891891 }
892892 while (!TAILQ_EMPTY(&conf.caches)) {
+67
-67
fdm.h less more
6161 #define DEFSTRIPCHARS "\\<>$%^&*|{}[]\"'`;"
6262 #define MAXACTIONCHAIN 5
6363 #define DEFTIMEOUT (900 * 1000)
64 #define LOCKSLEEPTIME 10000 /* 0.1 seconds */
64 #define LOCKSLEEPTIME 10000 /* 0.1 seconds */
6565 #define LOCKTOTALTIME 10000000 /* 10 seconds */
6666 #define MAXNAMESIZE 64
6767 #define DEFUMASK (S_IRWXG|S_IRWXO)
121121 /* Convert a file mode for %o%o%o printf. */
122122 #define MODE(m) \
123123 (m & S_IRUSR ? 4 : 0) + (m & S_IWUSR ? 2 : 0) + (m & S_IXUSR ? 1 : 0), \
124 (m & S_IRGRP ? 4 : 0) + (m & S_IWGRP ? 2 : 0) + (m & S_IXGRP ? 1 : 0), \
124 (m & S_IRGRP ? 4 : 0) + (m & S_IWGRP ? 2 : 0) + (m & S_IXGRP ? 1 : 0), \
125125 (m & S_IROTH ? 4 : 0) + (m & S_IWOTH ? 2 : 0) + (m & S_IXOTH ? 1 : 0)
126126
127127 /* Definition to shut gcc up about unused arguments. */
264264 u_int ent_max;
265265
266266 size_t str_used;
267 size_t str_size;
267 size_t str_size;
268268 };
269269
270270 /* Initial string block slots and block size. */
315315
316316 /* Cache data. */
317317 struct cache {
318 TDB_CONTEXT *db;
319
320 char *path;
318 TDB_CONTEXT *db;
319
320 char *path;
321321 uint64_t expire;
322322
323323 TAILQ_ENTRY(cache) entry;
324324 };
325325 struct cacheitem {
326 uint64_t tim;
326 uint64_t tim;
327327 uint32_t pad[4];
328328 } __packed;
329329
344344 char *data;
345345 size_t off;
346346
347 size_t size; /* size of mail */
348 size_t space; /* size of allocated area */
349
350 size_t body; /* offset of body */
347 size_t size; /* size of mail */
348 size_t space; /* size of allocated area */
349
350 size_t body; /* offset of body */
351351
352352 ARRAY_DECL(, size_t) wrapped; /* list of wrapped lines */
353353 char wrapchar; /* wrapped character */
393393
394394 /* An attachment. */
395395 struct attach {
396 u_int idx;
397
398 size_t data;
399 size_t body;
400 size_t size;
396 u_int idx;
397
398 size_t data;
399 size_t body;
400 size_t size;
401401
402402 char *type;
403403 char *name;
418418
419419 /* Privsep message data. */
420420 struct msgdata {
421 int error;
422 struct mail mail;
421 int error;
422 struct mail mail;
423423
424424 /* These only work so long as they aren't moved in either process. */
425425 struct account *account;
427427 struct match_command_data *cmddata;
428428
429429 uid_t uid;
430 gid_t gid;
430 gid_t gid;
431431 };
432432
433433 /* Privsep message buffer. */
473473 void (*hook)(int, struct account *, struct msg *,
474474 struct child_deliver_data *, int *);
475475
476 struct child *child; /* the source of the request */
476 struct child *child; /* the source of the request */
477477
478478 uid_t uid;
479479 gid_t gid;
604604
605605 /* Configuration settings. */
606606 struct conf {
607 int debug;
607 int debug;
608608 int syslog;
609609
610610 uid_t child_uid;
611611 gid_t child_gid;
612612 char *tmp_dir;
613613
614 struct strings incl;
614 struct strings incl;
615615 struct strings excl;
616616
617617 struct proxy *proxy;
644644
645645 size_t max_size;
646646 int timeout;
647 int del_big;
647 int del_big;
648648 u_int lock_types;
649649
650650 char *def_user;
652652
653653 TAILQ_HEAD(, cache) caches;
654654 TAILQ_HEAD(, account) accounts;
655 TAILQ_HEAD(, action) actions;
655 TAILQ_HEAD(, action) actions;
656656 struct rules rules;
657657 };
658658 extern struct conf conf;
659659
660660 /* Command flags. */
661 #define CMD_IN 0x1
661 #define CMD_IN 0x1
662662 #define CMD_OUT 0x2
663663 #define CMD_ONCE 0x4
664664
665665 /* Command data. */
666666 struct cmd {
667 pid_t pid;
667 pid_t pid;
668668 int status;
669669 int flags;
670670
707707
708708 #ifndef HAVE_STRLCPY
709709 /* strlcpy.c */
710 size_t strlcpy(char *, const char *, size_t);
710 size_t strlcpy(char *, const char *, size_t);
711711 #endif
712712
713713 #ifndef HAVE_STRLCAT
714714 /* strlcat.c */
715 size_t strlcat(char *, const char *, size_t);
715 size_t strlcat(char *, const char *, size_t);
716716 #endif
717717
718718 /* shm.c */
719 char *shm_path(struct shm *);
719 char *shm_path(struct shm *);
720720 void *shm_create(struct shm *, size_t);
721721 int shm_owner(struct shm *, uid_t, gid_t);
722722 void shm_destroy(struct shm *);
725725 void *shm_resize(struct shm *, size_t, size_t);
726726
727727 /* lex.c */
728 int yylex(void);
728 int yylex(void);
729729
730730 /* parse.y */
731731 extern struct macros parse_macros;
732 extern struct files parse_filestack;
732 extern struct files parse_filestack;
733733 extern struct file *parse_file;
734734 extern struct strb *parse_tags;
735 int parse_conf(const char *, struct strings *);
735 int parse_conf(const char *, struct strings *);
736736 __dead printflike1 void yyerror(const char *, ...);
737737
738738 /* parse-fn.c */
739739 char *expand_path(const char *, const char *);
740740 char *run_command(const char *, const char *);
741 char *fmt_replstrs(const char *, struct replstrs *);
742 char *fmt_strings(const char *, struct strings *);
741 char *fmt_replstrs(const char *, struct replstrs *);
742 char *fmt_strings(const char *, struct strings *);
743743 int have_accounts(char *);
744744 struct account *find_account(char *);
745 struct action *find_action(char *);
745 struct action *find_action(char *);
746746 struct actions *match_actions(const char *);
747 struct macro *extract_macro(char *);
747 struct macro *extract_macro(char *);
748748 struct macro *find_macro(const char *);
749749 void find_netrc(const char *, char **, char **);
750750 int find_netrc1(const char *, char **, char **, char **);
760760 void print_rule(struct rule *);
761761
762762 /* netrc.c */
763 FILE *netrc_open(const char *, char **);
763 FILE *netrc_open(const char *, char **);
764764 void netrc_close(FILE *);
765765 int netrc_lookup(FILE *, const char *, char **, char **);
766766
771771 double get_time(void);
772772 void dropto(uid_t, gid_t);
773773 int check_incl(const char *);
774 int check_excl(const char *);
774 int check_excl(const char *);
775775 int use_account(struct account *, char **);
776776 void fill_host(void);
777777 __dead void usage(void);
787787 void re_free(struct re *);
788788
789789 /* attach.c */
790 struct attach *attach_visit(struct attach *, u_int *);
790 struct attach *attach_visit(struct attach *, u_int *);
791791 void printflike2 attach_log(struct attach *, const char *, ...);
792 struct attach *attach_build(struct mail *);
792 struct attach *attach_build(struct mail *);
793793 void attach_free(struct attach *);
794794
795795 /* lookup.c */
807807 int privsep_recv(struct io *, struct msg *, struct msgbuf *);
808808
809809 /* command.c */
810 struct cmd *cmd_start(const char *, int, const char *, size_t, char **);
810 struct cmd *cmd_start(const char *, int, const char *, size_t, char **);
811811 int cmd_poll(struct cmd *, char **, char **, char **, size_t *,
812812 int, char **);
813813 void cmd_free(struct cmd *);
815815 /* child.c */
816816 int child_fork(void);
817817 __dead void child_exit(int);
818 struct child *child_start(struct children *, uid_t, gid_t,
819 int (*)(struct child *, struct io *),
820 int (*)(struct child *, struct msg *, struct msgbuf *),
818 struct child *child_start(struct children *, uid_t, gid_t,
819 int (*)(struct child *, struct io *),
820 int (*)(struct child *, struct msg *, struct msgbuf *),
821821 void *, struct child *);
822822
823823 /* child-fetch.c */
827827 /* child-deliver.c */
828828 int child_deliver(struct child *, struct io *);
829829 void child_deliver_action_hook(int, struct account *, struct msg *,
830 struct child_deliver_data *, int *);
830 struct child_deliver_data *, int *);
831831 void child_deliver_cmd_hook(int, struct account *, struct msg *,
832 struct child_deliver_data *, int *);
832 struct child_deliver_data *, int *);
833833
834834 /* parent-fetch.c */
835835 int parent_fetch(struct child *, struct msg *, struct msgbuf *);
843843 void timer_cancel(void);
844844
845845 /* connect.c */
846 char *sslerror(const char *);
846 char *sslerror(const char *);
847847 char *sslerror2(int, const char *);
848848 void getaddrs(const char *, char **, char **);
849 struct proxy *getproxy(const char *);
850 struct io *connectproxy(struct server *, int, struct proxy *,
851 const char *, int, char **);
849 struct proxy *getproxy(const char *);
850 struct io *connectproxy(struct server *, int, struct proxy *,
851 const char *, int, char **);
852852 struct io *connectio(struct server *, int, const char *, int, char **);
853853
854854 /* file.c */
855855 int printflike3 ppath(char *, size_t, const char *, ...);
856856 int vppath(char *, size_t, const char *, va_list);
857 int openlock(const char *, int, u_int);
858 int createlock(const char *, int, uid_t, gid_t, mode_t, u_int);
859 void closelock(int, const char *, u_int);
857 int openlock(const char *, int, u_int);
858 int createlock(const char *, int, uid_t, gid_t, mode_t, u_int);
859 void closelock(int, const char *, u_int);
860860 int locksleep(const char *, const char *, long long *);
861 int xcreate(const char *, int, uid_t, gid_t, mode_t);
861 int xcreate(const char *, int, uid_t, gid_t, mode_t);
862862 int xmkdir(const char *, uid_t, gid_t, mode_t);
863863 int xmkpath(const char *, uid_t, gid_t, mode_t);
864 const char *checkmode(struct stat *, mode_t);
865 const char *checkowner(struct stat *, uid_t);
866 const char *checkgroup(struct stat *, gid_t);
864 const char *checkmode(struct stat *, mode_t);
865 const char *checkowner(struct stat *, uid_t);
866 const char *checkgroup(struct stat *, gid_t);
867867 int safemove(const char *, const char *);
868868
869869 /* mail.c */
884884 int append_line(struct mail *, const char *, size_t);
885885 char *find_address(char *, size_t, size_t *);
886886 void trim_from(struct mail *);
887 char *make_from(struct mail *, char *);
887 char *make_from(struct mail *, char *);
888888 u_int fill_wrapped(struct mail *);
889889 void set_wrapped(struct mail *, char);
890890
911911 void cleanup_check(void);
912912 void cleanup_flush(void);
913913 void cleanup_purge(void);
914 void cleanup_register(const char *);
915 void cleanup_deregister(const char *);
914 void cleanup_register(const char *);
915 void cleanup_deregister(const char *);
916916
917917 /* strb.c */
918918 void strb_create(struct strb **);
919919 void strb_clear(struct strb **);
920920 void strb_destroy(struct strb **);
921921 void strb_dump(struct strb *, const char *,
922 void (*)(const char *, ...));
922 void (*)(const char *, ...));
923923 void printflike3 strb_add(struct strb **, const char *, const char *, ...);
924924 void strb_vadd(struct strb **, const char *, const char *, va_list);
925925 struct strbent *strb_find(struct strb *, const char *);
926 struct strbent *strb_match(struct strb *, const char *);
926 struct strbent *strb_match(struct strb *, const char *);
927927
928928 /* replace.c */
929929 void printflike3 add_tag(struct strb **, const char *, const char *, ...);
932932 void default_tags(struct strb **, const char *);
933933 void update_tags(struct strb **, struct userdata *);
934934 void reset_tags(struct strb **);
935 char *replacestr(struct replstr *, struct strb *, struct mail *,
936 struct rmlist *);
937 char *replacepath(struct replpath *, struct strb *, struct mail *,
935 char *replacestr(struct replstr *, struct strb *, struct mail *,
936 struct rmlist *);
937 char *replacepath(struct replpath *, struct strb *, struct mail *,
938938 struct rmlist *, const char *);
939939
940940 /* log.c */
968968 int printflike3 xsnprintf(char *, size_t, const char *, ...);
969969 int xvsnprintf(char *, size_t, const char *, va_list);
970970 int printflike3 printpath(char *, size_t, const char *, ...);
971 char *xdirname(const char *);
972 char *xbasename(const char *);
971 char *xdirname(const char *);
972 char *xbasename(const char *);
973973
974974 /* xmalloc-debug.c */
975975 #ifdef DEBUG
134134 fetch_maildir_freepaths(struct account *a)
135135 {
136136 struct fetch_maildir_data *data = a->data;
137 u_int i;
137 u_int i;
138138
139139 if (data->paths == NULL)
140140 return;
312312 struct fetch_maildir_data *data = a->data;
313313 char *path;
314314
315 path = ARRAY_ITEM(data->paths, data->index);
315 path = ARRAY_ITEM(data->paths, data->index);
316316
317317 /* Open the directory. */
318318 log_debug2("%s: trying path: %s", a->name, path);
333333 struct mail *m = fctx->mail;
334334 struct fetch_maildir_mail *aux;
335335 struct dirent *dp;
336 char *path, *maildir, name[MAXPATHLEN];
336 char *path, *maildir, name[MAXPATHLEN];
337337 struct stat sb;
338338 uintmax_t size;
339339 int fd;
340340 ssize_t n;
341341
342 path = ARRAY_ITEM(data->paths, data->index);
342 path = ARRAY_ITEM(data->paths, data->index);
343343
344344 restart:
345345 /* Read the next dir entry. */
301301 struct fetch_mbox_data *data = a->data;
302302 struct fetch_mbox_mbox *fmbox;
303303 char *ptr;
304 struct stat sb;
304 struct stat sb;
305305 uintmax_t size;
306306 long long used;
307307
9090 {
9191 char ch;
9292 const char *errstr;
93 int n;
93 int n;
9494 size_t len;
9595
9696 len = strspn(line, "0123456789");
254254 error:
255255 if (f != NULL)
256256 fclose(f);
257 if (fd != -1)
257 if (fd != -1)
258258 closelock(fd, data->path, conf.lock_types);
259259 return (-1);
260260 }
420420 return (FETCH_BLOCK);
421421
422422 if (data->user == NULL || data->pass == NULL) {
423 fctx->state = fetch_nntp_state_group;
423 fctx->state = fetch_nntp_state_group;
424424 return (FETCH_AGAIN);
425425 }
426426
3232
3333 /* Fetch context. */
3434 struct fetch_ctx {
35 int (*state)(struct account *, struct fetch_ctx *);
35 int (*state)(struct account *, struct fetch_ctx *);
3636 int flags;
3737
3838 struct mail *mail;
9090 };
9191
9292 struct fetch_mbox_mbox {
93 char *path;
93 char *path;
9494 u_int reference;
9595 u_int total;
9696
100100 };
101101
102102 struct fetch_mbox_mail {
103 size_t off;
103 size_t off;
104104 size_t size;
105105
106106 struct fetch_mbox_mbox *fmbox;
248248 #define IMAP_CAPA_XYZZY 0x2
249249
250250 /* fetch-maildir.c */
251 extern struct fetch fetch_maildir;
251 extern struct fetch fetch_maildir;
252252
253253 /* fetch-mbx.c */
254 extern struct fetch fetch_mbox;
254 extern struct fetch fetch_mbox;
255255
256256 /* fetch-stdin.c */
257 extern struct fetch fetch_stdin;
257 extern struct fetch fetch_stdin;
258258
259259 /* fetch-nntp.c */
260 extern struct fetch fetch_nntp;
260 extern struct fetch fetch_nntp;
261261
262262 /* fetch-pop3.c */
263 extern struct fetch fetch_pop3;
263 extern struct fetch fetch_pop3;
264264
265265 /* fetch-pop3pipe.c */
266 extern struct fetch fetch_pop3pipe;
266 extern struct fetch fetch_pop3pipe;
267267
268268 /* fetch-imap.c */
269 extern struct fetch fetch_imap;
269 extern struct fetch fetch_imap;
270270 int fetch_imap_putln(struct account *, const char *, va_list);
271271 int fetch_imap_getln(struct account *, struct fetch_ctx *, char **);
272272 int fetch_imap_state_init(struct account *, struct fetch_ctx *);
273273
274274 /* fetch-imappipe.c */
275 extern struct fetch fetch_imappipe;
275 extern struct fetch fetch_imappipe;
276276
277277 /* imap-common.c */
278278 int imap_tag(char *);
243243 xmkpath(const char *path, uid_t uid, gid_t gid, mode_t mode)
244244 {
245245 struct stat sb;
246 char *copy, *ptr, ch;
246 char *copy, *ptr, ch;
247247
248248 copy = ptr = xstrdup(path);
249 do {
250 ptr += strspn(ptr, "/");
251 ptr += strcspn(ptr, "/");
249 do {
250 ptr += strspn(ptr, "/");
251 ptr += strcspn(ptr, "/");
252252 ch = *ptr;
253253
254254 *ptr = '\0';
255 if (stat(copy, &sb) != 0) {
256 if (errno == ENOENT &&
255 if (stat(copy, &sb) != 0) {
256 if (errno == ENOENT &&
257257 xmkdir(copy, uid, gid, mode) != 0 &&
258258 errno != EEXIST)
259259 return (-1);
260 } else if (!S_ISDIR(sb.st_mode)) {
260 } else if (!S_ISDIR(sb.st_mode)) {
261261 errno = ENOTDIR;
262 return (-1);
263 }
262 return (-1);
263 }
264264 *ptr = ch;
265265 } while (ch != '\0');
266266 xfree(copy);
8383 imap_getln(struct account *a, struct fetch_ctx *fctx, int type, char **line)
8484 {
8585 struct fetch_imap_data *data = a->data;
86 int n;
86 int n;
8787
8888 do {
8989 if (data->getln(a, fctx, line) != 0)
175175 int
176176 imap_tag(char *line)
177177 {
178 int tag;
178 int tag;
179179 const char *errstr;
180180 char *ptr;
181181
288288 {
289289 struct fetch_imap_data *data = a->data;
290290
291 ARRAY_INIT(&data->dropped);
292 ARRAY_INIT(&data->kept);
291 ARRAY_INIT(&data->dropped);
292 ARRAY_INIT(&data->kept);
293293 ARRAY_INIT(&data->wanted);
294294
295295 data->tag = 0;
564564 struct fetch_imap_data *data = a->data;
565565 char *line;
566566
567 if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
568 return (FETCH_ERROR);
569 if (line == NULL)
570 return (FETCH_BLOCK);
571 if (!imap_okay(line))
572 return (imap_bad(a, line));
567 if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
568 return (FETCH_ERROR);
569 if (line == NULL)
570 return (FETCH_BLOCK);
571 if (!imap_okay(line))
572 return (imap_bad(a, line));
573573
574574 /* If no mails, stop early. */
575575 if (data->total == 0) {
580580 }
581581
582582 fctx->state = imap_state_search1;
583 return (FETCH_AGAIN);
583 return (FETCH_AGAIN);
584584 }
585585
586586 /* Search state 1. Request list of mail required. */
+14
-14
io.c less more
130130 io_polln(struct io **iop, u_int n, struct io **rio, int timeout, char **cause)
131131 {
132132 struct io *io;
133 struct pollfd *pfds;
133 struct pollfd *pfds;
134134 int error;
135135 u_int i;
136136
177177 /* Check all the ios. */
178178 for (i = 0; i < n; i++) {
179179 io = iop[i];
180 if (rio != NULL)
180 if (rio != NULL)
181181 *rio = io;
182182 if (io_after_poll(io, &pfds[i]) == -1)
183183 goto error;
365365 if (io->dup_fd != -1) {
366366 write(io->dup_fd, "< ", 2);
367367 write(io->dup_fd, BUFFER_IN(io->rd), n);
368 }
368 }
369369
370370 /* Adjust the buffer size. */
371371 buffer_add(io->rd, n);
457457 {
458458 void *buf;
459459
460 IO_DEBUG(io, "in: %zu bytes, rd: used=%zu, free=%zu", len,
460 IO_DEBUG(io, "in: %zu bytes, rd: used=%zu, free=%zu", len,
461461 BUFFER_USED(io->rd), BUFFER_FREE(io->rd));
462462
463463 if (io->error != NULL)
469469 buf = xmalloc(len);
470470 buffer_read(io->rd, buf, len);
471471
472 IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu", len,
472 IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu", len,
473473 BUFFER_USED(io->rd), BUFFER_FREE(io->rd));
474474
475475 return (buf);
482482 if (io->error != NULL)
483483 return (-1);
484484
485 IO_DEBUG(io, "in: %zu bytes, rd: used=%zu, free=%zu", len,
485 IO_DEBUG(io, "in: %zu bytes, rd: used=%zu, free=%zu", len,
486486 BUFFER_USED(io->rd), BUFFER_FREE(io->rd));
487487
488488 if (BUFFER_USED(io->rd) < len)
490490
491491 buffer_read(io->rd, buf, len);
492492
493 IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu", len,
493 IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu", len,
494494 BUFFER_USED(io->rd), BUFFER_FREE(io->rd));
495495
496496 return (0);
503503 if (io->error != NULL)
504504 return;
505505
506 IO_DEBUG(io, "in: %zu bytes, wr: used=%zu, free=%zu", len,
506 IO_DEBUG(io, "in: %zu bytes, wr: used=%zu, free=%zu", len,
507507 BUFFER_USED(io->wr), BUFFER_FREE(io->wr));
508508
509509 buffer_write(io->wr, buf, len);
510510
511 IO_DEBUG(io, "out: %zu bytes, wr: used=%zu, free=%zu", len,
511 IO_DEBUG(io, "out: %zu bytes, wr: used=%zu, free=%zu", len,
512512 BUFFER_USED(io->wr), BUFFER_FREE(io->wr));
513513 }
514514
532532 if (BUFFER_USED(io->rd) < eollen)
533533 return (NULL);
534534
535 IO_DEBUG(io, "in: rd: used=%zu, free=%zu",
535 IO_DEBUG(io, "in: rd: used=%zu, free=%zu",
536536 BUFFER_USED(io->rd), BUFFER_FREE(io->rd));
537537
538538 base = ptr = BUFFER_OUT(io->rd);
597597 /* Discard the EOL from the buffer. */
598598 buffer_remove(io->rd, eollen);
599599
600 IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu",
600 IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu",
601601 size, BUFFER_USED(io->rd), BUFFER_FREE(io->rd));
602602
603603 return (*buf);
646646 if (io->error != NULL)
647647 return;
648648
649 IO_DEBUG(io, "in: wr: used=%zu, free=%zu",
649 IO_DEBUG(io, "in: wr: used=%zu, free=%zu",
650650 BUFFER_USED(io->wr), BUFFER_FREE(io->wr));
651651
652652 if (fmt != NULL) {
655655 va_end(aq);
656656
657657 buffer_ensure(io->wr, n + 1);
658 xvsnprintf(BUFFER_IN(io->wr), n + 1, fmt, ap);
658 xvsnprintf(BUFFER_IN(io->wr), n + 1, fmt, ap);
659659 buffer_add(io->wr, n);
660660 } else
661661 n = 0;
662662 io_write(io, io->eol, strlen(io->eol));
663663
664 IO_DEBUG(io, "out: %zu bytes, wr: used=%zu, free=%zu",
664 IO_DEBUG(io, "out: %zu bytes, wr: used=%zu, free=%zu",
665665 n + strlen(io->eol), BUFFER_USED(io->wr), BUFFER_FREE(io->wr));
666666 }
667667
3838
3939 /* IO line endings. */
4040 #define IO_CRLF "\r\n"
41 #define IO_CR "\r"
42 #define IO_LF "\n"
41 #define IO_CR "\r"
42 #define IO_LF "\n"
4343
4444 /* Initial block size of buffer and minimum amount to try to read. */
4545 #define IO_BLOCKSIZE 16384
8585 ARRAY_DECL(iolist, struct io *);
8686
8787 /* buffer.c */
88 struct buffer *buffer_create(size_t);
88 struct buffer *buffer_create(size_t);
8989 void buffer_destroy(struct buffer *);
9090 void buffer_clear(struct buffer *);
9191 void buffer_ensure(struct buffer *, size_t);
9797 void buffer_delete_range(struct buffer *, size_t, size_t);
9898 void buffer_write(struct buffer *, const void *, size_t);
9999 void buffer_read(struct buffer *, void *, size_t);
100 void buffer_write8(struct buffer *, uint8_t);
101 void buffer_write16(struct buffer *, uint16_t);
100 void buffer_write8(struct buffer *, uint8_t);
101 void buffer_write16(struct buffer *, uint16_t);
102102 uint8_t buffer_read8(struct buffer *);
103 uint16_t buffer_read16(struct buffer *);
103 uint16_t buffer_read16(struct buffer *);
104104
105105 /* io.c */
106106 struct io *io_create(int, SSL *, const char *);
111111 int io_polln(struct io **, u_int, struct io **, int, char **);
112112 int io_poll(struct io *, int, char **);
113113 int io_read2(struct io *, void *, size_t);
114 void *io_read(struct io *, size_t);
114 void *io_read(struct io *, size_t);
115115 void io_write(struct io *, const void *, size_t);
116 char *io_readline2(struct io *, char **, size_t *);
117 char *io_readline(struct io *);
116 char *io_readline2(struct io *, char **, size_t *);
117 char *io_readline(struct io *);
118118 void printflike2 io_writeline(struct io *, const char *, ...);
119119 void io_vwriteline(struct io *, const char *, va_list);
120120 int io_pollline2(struct io *, char **, char **, size_t *, int,
+40
-40
lex.c less more
203203 int
204204 yylex(void)
205205 {
206 int ch, value;
206 int ch, value;
207207 char *path;
208 struct replpath rp;
208 struct replpath rp;
209209
210210 /* Switch to new file. See comment in read_token below. */
211211 if (lex_include) {
335335 {
336336 const struct token *token = ptr;
337337
338 return (strcmp(name, token->name));
338 return (strcmp(name, token->name));
339339 }
340340
341341 int
406406 * can). If we don't do this, there are problems with things
407407 * like:
408408 *
409 * $file = "abc"
410 * include "${file}"
409 * $file = "abc"
410 * include "${file}"
411411 *
412412 * The include token is seen before yacc has matched the
413413 * previous line, so the macro doesn't exist when we try to
419419
420420 ptr = bsearch(token, tokens,
421421 (sizeof tokens)/(sizeof tokens[0]), sizeof tokens[0], cmp_token);
422 if (ptr == NULL)
422 if (ptr == NULL)
423423 yyerror("unknown token: %s", token);
424424 return (ptr->value);
425425 }
429429 {
430430 char number[32];
431431 size_t nlen;
432 const char *errstr;
432 const char *errstr;
433433 long long n;
434434
435435 nlen = 0;
475475 if (nlen == (sizeof name) - 1)
476476 yyerror("macro name too long");
477477 }
478 name[nlen] = '\0';
478 name[nlen] = '\0';
479479 if (!brackets)
480480 lex_ungetc(ch);
481481
495495 char *buf, *s;
496496
497497 len = 24;
498 buf = xmalloc(len + 1);
498 buf = xmalloc(len + 1);
499499
500500 nesting = 0;
501 while ((ch = lex_getc()) != EOF) {
501 while ((ch = lex_getc()) != EOF) {
502502 switch (ch) {
503503 case '(':
504504 nesting++;
530530 buf[pos++] = '\'';
531531 xfree(s);
532532 continue;
533 }
534
535 buf[pos++] = ch;
536 ENSURE_SIZE(buf, len, pos);
537 }
533 }
534
535 buf[pos++] = ch;
536 ENSURE_SIZE(buf, len, pos);
537 }
538538
539539 yyerror("missing )");
540540 }
544544 {
545545 int ch, oldch;
546546 size_t pos, len, slen;
547 char *name, *s, *buf;
547 char *name, *s, *buf;
548548 struct macro *macro;
549549
550550 len = 24;
551 buf = xmalloc(len + 1);
551 buf = xmalloc(len + 1);
552552
553553 pos = 0;
554 while ((ch = lex_getc()) != endch) {
555 switch (ch) {
554 while ((ch = lex_getc()) != endch) {
555 switch (ch) {
556556 case EOF:
557557 yyerror("missing %c", endch);
558 case '\\':
558 case '\\':
559559 if (!esc)
560560 break;
561 switch (ch = lex_getc()) {
561 switch (ch = lex_getc()) {
562562 case EOF:
563563 yyerror("missing %c", endch);
564 case 'r':
565 ch = '\r';
566 break;
567 case 'n':
568 ch = '\n';
569 break;
570 case 't':
571 ch = '\t';
572 break;
573 }
574 break;
564 case 'r':
565 ch = '\r';
566 break;
567 case 'n':
568 ch = '\n';
569 break;
570 case 't':
571 ch = '\t';
572 break;
573 }
574 break;
575575 case '$':
576576 case '%':
577577 if (!esc)
595595 xfree(name);
596596
597597 if (macro->type == MACRO_NUMBER)
598 xasprintf(&s, "%lld", macro->value.num);
598 xasprintf(&s, "%lld", macro->value.num);
599599 else
600600 s = macro->value.str;
601601 slen = strlen(s);
607607 if (macro->type == MACRO_NUMBER)
608608 xfree(s);
609609 continue;
610 }
611
612 buf[pos++] = ch;
613 ENSURE_SIZE(buf, len, pos);
614 }
615
616 buf[pos] = '\0';
610 }
611
612 buf[pos++] = ch;
613 ENSURE_SIZE(buf, len, pos);
614 }
615
616 buf[pos] = '\0';
617617
618618 return (buf);
619619 }
218218 log_vwrite(LOG_CRIT, fmt, ap);
219219 } else {
220220 if (asprintf(&fmt, "fatal: %s", msg) == -1)
221 exit(1);
221 exit(1);
222222 log_vwrite(LOG_CRIT, fmt, ap);
223223 }
224224 free(fmt);
3333 int fill_from_string(struct mail_ctx *, struct rule *,
3434 struct replstr *);
3535 int fill_from_action(struct mail_ctx *, struct rule *,
36 struct action *, struct replstrs *);
36 struct action *, struct replstrs *);
3737
3838 int start_action(struct mail_ctx *, struct deliver_ctx *);
3939 int finish_action(struct deliver_ctx *, struct msg *,
4646 /*
4747 * Number of chained actions. Limit on recursion with things like:
4848 *
49 * action "name" { action "name" }
49 * action "name" { action "name" }
5050 */
5151 u_int chained;
5252
415415 struct deliver_action_data *data;
416416 struct actitem *ti;
417417 struct deliver_ctx *dctx;
418 u_int i;
418 u_int i;
419419 char *user;
420420 struct userdata *udata;
421421
471471 {
472472 struct account *a = dctx->account;
473473 struct action *t = dctx->action;
474 struct actitem *ti = dctx->actitem;
474 struct actitem *ti = dctx->actitem;
475475 struct mail *m = dctx->mail;
476476 struct msg msg;
477477 struct msgbuf msgbuf;
525525 finish_action(struct deliver_ctx *dctx, struct msg *msg, struct msgbuf *msgbuf)
526526 {
527527 struct account *a = dctx->account;
528 struct actitem *ti = dctx->actitem;
528 struct actitem *ti = dctx->actitem;
529529 struct mail *m = dctx->mail;
530530 u_int lines;
531531
3939
4040 if ((m->base = shm_create(&m->shm, m->space)) == NULL)
4141 return (-1);
42 SHM_REGISTER(&m->shm);
42 SHM_REGISTER(&m->shm);
4343
4444 m->off = 0;
4545 m->data = m->base + m->off;
8989 memcpy(m, mm, sizeof *m);
9090 if ((m->base = shm_reopen(&m->shm)) == NULL)
9191 return (-1);
92 SHM_REGISTER(&m->shm);
92 SHM_REGISTER(&m->shm);
9393
9494 m->data = m->base + m->off;
9595 ARRAY_INIT(&m->wrapped);
451451
452452 /*
453453 * Now, look for sections matching:
454 * [< ][A-Za-z0-9._%+-]+@[A-Za-z0-9.\[\]-]+[> ,;].
454 * [< ][A-Za-z0-9._%+-]+@[A-Za-z0-9.\[\]-]+[> ,;].
455455 */
456456 #define isfirst(c) ((c) == '<' || (c) == ' ')
457457 #define islast(c) ((c) == '>' || (c) == ' ' || (c) == ',' || (c) == ';')
537537 from = find_header(m, "from", &fromlen, 1);
538538 if (from != NULL && fromlen > 0)
539539 from = find_address(from, fromlen, &fromlen);
540 if (fromlen > INT_MAX)
540 if (fromlen > INT_MAX)
541541 from = NULL;
542542 if (from == NULL) {
543543 from = user;
559559 fill_wrapped(struct mail *m)
560560 {
561561 char *ptr;
562 size_t end, off;
562 size_t end, off;
563563 u_int n;
564564
565565 if (!ARRAY_EMPTY(&m->wrapped))
161161 match_attachment_desc(struct expritem *ei, char *buf, size_t len)
162162 {
163163 struct match_attachment_data *data = ei->data;
164 const char *cmp = "";
164 const char *cmp = "";
165165
166166 if (data->cmp == CMP_LT)
167167 cmp = "<";
3838 struct account *a = mctx->account;
3939 struct mail *m = mctx->mail;
4040 int res;
41 char *cause;
41 char *cause;
4242 size_t so, eo;
4343
4444 so = 0;
3131 const char *name;
3232
3333 int (*match)(struct mail_ctx *, struct expritem *);
34 void (*desc)(struct expritem *, char *, size_t);
34 void (*desc)(struct expritem *, char *, size_t);
3535 };
3636
3737 /* Match attachment data. */
4444 ATTACHOP_ANYNAME
4545 } op;
4646
47 enum cmp cmp;
47 enum cmp cmp;
4848 union {
4949 size_t size;
5050 long long num;
7878 /* Match string data. */
7979 struct match_string_data {
8080 struct replstr str;
81 struct re re;
81 struct re re;
8282 };
8383
8484 /* Match regexp data. */
8585 struct match_regexp_data {
8686 struct re re;
8787
88 enum area area;
88 enum area area;
8989 };
9090
9191 /* Match command data. */
153153 {
154154 static char token[BUFSIZ];
155155 char *cp;
156 int c;
156 int c;
157157
158158 if (feof(f) || ferror(f))
159159 return (1);
3030
3131 void parent_fetch_error(struct child *, struct msg *);
3232 void parent_fetch_action(struct child *, struct children *,
33 struct deliver_ctx *, struct msg *);
33 struct deliver_ctx *, struct msg *);
3434 void parent_fetch_cmd(struct child *, struct children *, struct mail_ctx *,
3535 struct msg *);
3636
104104 struct mail *m = dctx->mail;
105105 struct mail *md = &dctx->wr_mail;
106106 struct child_deliver_data *data;
107 uid_t uid = msg->data.uid;
107 uid_t uid = msg->data.uid;
108108 gid_t gid = msg->data.gid;
109109
110110 memset(md, 0, sizeof *md);
151151 {
152152 struct mail *m = mctx->mail;
153153 struct child_deliver_data *data;
154 uid_t uid = msg->data.uid;
154 uid_t uid = msg->data.uid;
155155 gid_t gid = msg->data.gid;
156156
157157 data = xmalloc(sizeof *data);
253253 struct actitem *ti;
254254 struct deliver_action_data *data;
255255 char desc[DESCBUFSIZE], *s;
256 size_t off;
256 size_t off;
257257
258258 off = 0;
259259 TAILQ_FOREACH(ti, tl, entry) {
451451
452452 if (a->fetch == &fetch_pop3) {
453453 struct fetch_pop3_data *data = a->data;
454 if (data->path != NULL)
454 if (data->path != NULL)
455455 xfree(data->path);
456456 xfree(data->user);
457457 xfree(data->pass);
461461 freeaddrinfo(data->server.ai);
462462 } else if (a->fetch == &fetch_pop3pipe) {
463463 struct fetch_pop3_data *data = a->data;
464 if (data->path != NULL)
464 if (data->path != NULL)
465465 xfree(data->path);
466466 xfree(data->user);
467467 xfree(data->pass);
471471 xfree(data->user);
472472 xfree(data->pass);
473473 free_strings(data->folders);
474 ARRAY_FREEALL(data->folders);
474 ARRAY_FREEALL(data->folders);
475475 xfree(data->server.host);
476476 xfree(data->server.port);
477477 if (data->server.ai != NULL)
483483 if (data->pass != NULL)
484484 xfree(data->pass);
485485 free_strings(data->folders);
486 ARRAY_FREEALL(data->folders);
486 ARRAY_FREEALL(data->folders);
487487 xfree(data->pipecmd);
488488 } else if (a->fetch == &fetch_maildir) {
489489 struct fetch_maildir_data *data = a->data;
217217 error:
218218 if (f != NULL)
219219 fclose(f);
220 if (fd != -1)
220 if (fd != -1)
221221 closelock(fd, data->path, conf.lock_types);
222222 return (-1);
223223 }
881881 {
882882 struct fetch_pop3_data *data = a->data;
883883 struct mail *m = fctx->mail;
884 struct fetch_pop3_mail *aux = m->auxdata;
884 struct fetch_pop3_mail *aux = m->auxdata;
885885 char *line;
886886
887887 if (pop3_getln(a, fctx, &line) != 0)
2424
2525 #include "fdm.h"
2626
27 #define ALIAS_IDX(ch) /* LINTED */ \
28 (((ch) >= 'a' && (ch) <= 'z') ? (ch) - 'a' : \
27 #define ALIAS_IDX(ch) /* LINTED */ \
28 (((ch) >= 'a' && (ch) <= 'z') ? (ch) - 'a' : \
2929 (((ch) >= 'A' && (ch) <= 'Z') ? 26 + (ch) - 'A' : -1))
3030
3131 static const char *aliases[] = {
32 "account", /* a */
33 NULL, /* b */
34 NULL, /* c */
35 "day", /* d */
36 NULL, /* e */
37 NULL, /* f */
38 NULL, /* g */
39 "home", /* h */
40 NULL, /* i */
41 NULL, /* j */
42 NULL, /* l */
43 NULL, /* l */
44 "month", /* m */
45 "uid", /* n */
46 NULL, /* o */
47 NULL, /* p */
48 NULL, /* q */
49 NULL, /* r */
50 "source", /* s */
51 "action", /* t */
52 "user", /* u */
53 NULL, /* v */
54 NULL, /* w */
55 NULL, /* x */
56 "year", /* y */
57 NULL, /* z */
58
59 NULL, /* A */
60 NULL, /* B */
61 NULL, /* C */
62 NULL, /* D */
63 NULL, /* E */
64 NULL, /* F */
65 NULL, /* G */
66 "hour", /* H */
67 NULL, /* I */
68 NULL, /* J */
69 NULL, /* K */
70 NULL, /* L */
71 "minute", /* M */
72 NULL, /* N */
73 NULL, /* O */
74 NULL, /* P */
32 "account", /* a */
33 NULL, /* b */
34 NULL, /* c */
35 "day", /* d */
36 NULL, /* e */
37 NULL, /* f */
38 NULL, /* g */
39 "home", /* h */
40 NULL, /* i */
41 NULL, /* j */
42 NULL, /* l */
43 NULL, /* l */
44 "month", /* m */
45 "uid", /* n */
46 NULL, /* o */
47 NULL, /* p */
48 NULL, /* q */
49 NULL, /* r */
50 "source", /* s */
51 "action", /* t */
52 "user", /* u */
53 NULL, /* v */
54 NULL, /* w */
55 NULL, /* x */
56 "year", /* y */
57 NULL, /* z */
58
59 NULL, /* A */
60 NULL, /* B */
61 NULL, /* C */
62 NULL, /* D */
63 NULL, /* E */
64 NULL, /* F */
65 NULL, /* G */
66 "hour", /* H */
67 NULL, /* I */
68 NULL, /* J */
69 NULL, /* K */
70 NULL, /* L */
71 "minute", /* M */
72 NULL, /* N */
73 NULL, /* O */
74 NULL, /* P */
7575 "quarter", /* Q */
76 NULL, /* R */
76 NULL, /* R */
7777 "second", /* S */
78 NULL, /* T */
79 NULL, /* U */
80 NULL, /* V */
81 "dayofweek", /* W */
82 NULL, /* X */
83 "dayofyear", /* Y */
84 NULL, /* Z */
78 NULL, /* T */
79 NULL, /* U */
80 NULL, /* V */
81 "dayofweek", /* W */
82 NULL, /* X */
83 "dayofyear", /* Y */
84 NULL, /* Z */
8585 };
8686
8787 char *replace(char *, struct strb *, struct mail *, struct rmlist *);
88 const char *submatch(char, struct mail *, struct rmlist *, size_t *);
88 const char *submatch(char, struct mail *, struct rmlist *, size_t *);
8989
9090 void printflike3
9191 add_tag(struct strb **tags, const char *key, const char *value, ...)
195195 char *s, *t;
196196
197197 s = replace(rp->str, tags, m, rml);
198 if ((t = expand_path(s, home)) == NULL)
198 if ((t = expand_path(s, home)) == NULL)
199199 return (s);
200200 xfree(s);
201201 return (t);
222222 {
223223 const char *tptr, *alias;
224224 char *ptr, *tend, *dst, ch;
225 size_t i, off, len, tlen;
225 size_t i, off, len, tlen;
226226 int strip;
227227
228228 if (src == NULL)
103103 int saved_errno;
104104 char *path;
105105
106 if (size == 0)
107 fatalx("zero size");
106 if (size == 0)
107 fatalx("zero size");
108108
109109 if (ppath(
110110 shm->name, sizeof shm->name, "%s.XXXXXXXXXX", __progname) != 0)
203203 size_t newsize = nmemb * size;
204204
205205 if (size == 0)
206 fatalx("zero size");
207 if (SIZE_MAX / nmemb < size)
208 fatalx("nmemb * size > SIZE_MAX");
206 fatalx("zero size");
207 if (SIZE_MAX / nmemb < size)
208 fatalx("nmemb * size > SIZE_MAX");
209209
210210 #ifndef HAVE_MREMAP
211211 if (munmap(shm->data, shm->size) != 0)
169169 strb_match(struct strb *sb, const char *patt)
170170 {
171171 static struct strbent sbe;
172 u_int i;
172 u_int i;
173173
174174 for (i = 0; i < sb->ent_used; i++) {
175175 memcpy(&sbe, STRB_ENTRY(sb, i), sizeof sbe);
8585 void
8686 xmalloc_clear(void)
8787 {
88 struct xmalloc_blk *blk;
88 struct xmalloc_blk *blk;
8989
9090 xmalloc_allocated = 0;
9191 xmalloc_freed = 0;
105105 void
106106 xmalloc_report(pid_t pid, const char *hdr)
107107 {
108 struct xmalloc_blk *blk;
108 struct xmalloc_blk *blk;
109109 u_char *iptr;
110 char buf[4 * XMALLOC_BYTES + 1], *optr;
111 size_t len;
112 u_int n;
110 char buf[4 * XMALLOC_BYTES + 1], *optr;
111 size_t len;
112 u_int n;
113113 Dl_info info;
114114
115 XMALLOC_PRINT("%s: %ld: allocated=%zu, freed=%zu, difference=%zd, "
115 XMALLOC_PRINT("%s: %ld: allocated=%zu, freed=%zu, difference=%zd, "
116116 "peak=%zu", hdr, (long) pid, xmalloc_allocated, xmalloc_freed,
117117 xmalloc_allocated - xmalloc_freed, xmalloc_peak);
118 XMALLOC_PRINT("%s: %ld: mallocs=%u, reallocs=%u, frees=%u", hdr,
118 XMALLOC_PRINT("%s: %ld: mallocs=%u, reallocs=%u, frees=%u", hdr,
119119 (long) pid, xmalloc_mallocs, xmalloc_reallocs, xmalloc_frees);
120120
121121 n = 0;
203203
204204 SPLAY_REMOVE(xmalloc_tree, &xmalloc_tree, blk);
205205
206 blk->ptr = newptr;
206 blk->ptr = newptr;
207207 blk->size = newsize;
208208
209209 blk->caller = caller;
7777 len = strlen(s) + 1;
7878 ptr = xmalloc(len);
7979
80 return (strncpy(ptr, s, len));
80 return (strncpy(ptr, s, len));
8181 }
8282
8383 void *
8484 xcalloc(size_t nmemb, size_t size)
8585 {
86 void *ptr;
87
88 if (size == 0 || nmemb == 0)
89 fatalx("zero size");
90 if (SIZE_MAX / nmemb < size)
91 fatalx("nmemb * size > SIZE_MAX");
92 if ((ptr = calloc(nmemb, size)) == NULL)
86 void *ptr;
87
88 if (size == 0 || nmemb == 0)
89 fatalx("zero size");
90 if (SIZE_MAX / nmemb < size)
91 fatalx("nmemb * size > SIZE_MAX");
92 if ((ptr = calloc(nmemb, size)) == NULL)
9393 fatal("xcalloc failed");
9494
9595 #ifdef DEBUG
9696 xmalloc_new(xmalloc_caller(), ptr, nmemb * size);
9797 #endif
98 return (ptr);
98 return (ptr);
9999 }
100100
101101 void *
103103 {
104104 void *ptr;
105105
106 if (size == 0)
107 fatalx("zero size");
108 if ((ptr = malloc(size)) == NULL)
106 if (size == 0)
107 fatalx("zero size");
108 if ((ptr = malloc(size)) == NULL)
109109 fatal("xmalloc failed");
110110
111111 #ifdef DEBUG
112112 xmalloc_new(xmalloc_caller(), ptr, size);
113113 #endif
114 return (ptr);
114 return (ptr);
115115 }
116116
117117 void *
121121 void *newptr;
122122
123123 if (newsize == 0)
124 fatalx("zero size");
125 if (SIZE_MAX / nmemb < size)
126 fatalx("nmemb * size > SIZE_MAX");
127 if ((newptr = realloc(oldptr, newsize)) == NULL)
124 fatalx("zero size");
125 if (SIZE_MAX / nmemb < size)
126 fatalx("nmemb * size > SIZE_MAX");
127 if ((newptr = realloc(oldptr, newsize)) == NULL)
128128 fatal("xrealloc failed");
129129
130130 #ifdef DEBUG
131131 xmalloc_change(xmalloc_caller(), oldptr, newptr, nmemb * size);
132132 #endif
133 return (newptr);
133 return (newptr);
134134 }
135135
136136 void
148148 int printflike2
149149 xasprintf(char **ret, const char *fmt, ...)
150150 {
151 va_list ap;
152 int i;
153
154 va_start(ap, fmt);
155 i = xvasprintf(ret, fmt, ap);
156 va_end(ap);
151 va_list ap;
152 int i;
153
154 va_start(ap, fmt);
155 i = xvasprintf(ret, fmt, ap);
156 va_end(ap);
157157
158158 return (i);
159159 }
164164 int i;
165165
166166 i = vasprintf(ret, fmt, ap);
167 if (i < 0 || *ret == NULL)
168 fatal("xvasprintf failed");
167 if (i < 0 || *ret == NULL)
168 fatal("xvasprintf failed");
169169
170170 #ifdef DEBUG
171171 xmalloc_new(xmalloc_caller(), *ret, i + 1);
172172 #endif
173 return (i);
173 return (i);
174174 }
175175
176176 int printflike3
177177 xsnprintf(char *buf, size_t len, const char *fmt, ...)
178178 {
179 va_list ap;
180 int i;
181
182 va_start(ap, fmt);
183 i = xvsnprintf(buf, len, fmt, ap);
184 va_end(ap);
179 va_list ap;
180 int i;
181
182 va_start(ap, fmt);
183 i = xvsnprintf(buf, len, fmt, ap);
184 va_end(ap);
185185
186186 return (i);
187187 }
195195 fatalx("len > INT_MAX");
196196
197197 i = vsnprintf(buf, len, fmt, ap);
198 if (i < 0)
199 fatal("vsnprintf failed");
200
201 return (i);
198 if (i < 0)
199 fatal("vsnprintf failed");
200
201 return (i);
202202 }
203203
204204 /*