Remove all uses of vartab, replacing them with wordsplit.
* libmailutils/string/wordsplit.c (mu_wordsplit_init): Call mu_wordsplit_free_words to reclaim the memory. (mu_wordsplit_free_words): New function. (mu_wordsplit_free): Use mu_wordsplit_free_words. * imap4d/imap4d.c (imap4d_session_setup0): Use wordsplit instead of vartab. * imap4d/imap4d.h: Don't include vartab.h. * imap4d/preauth.c (do_preauth_ident): Use mu_str_stripws instead of the static trimcrlf, which is removed. (do_preauth_program): Use wordsplit instead of vartab and mu_prog_stream_create instead of popen. * libmailutils/mailbox/mbx_default.c: Include nls.h Don't include vartab.h (mu_construct_user_mailbox_url): Use wordsplit instead of vartab. * libmailutils/server/acl.c (expand_arg): Use wordsplit instead of vartab. * libmu_auth/ldap.c (_mu_ldap_search):L Likewise. * libmu_auth/radius.c (_expand_query): Likewise. * libmu_auth/sql.c (mu_sql_expand_query): Likewise. * libproto/mailer/prog.c (_expand_sender, _expand_rcpt): Rewrite. (url_to_argv): : Use wordsplit instead of vartab. * po/POTFILES.in: Add more files.
Showing
11 changed files
with
356 additions
and
209 deletions
... | @@ -308,21 +308,34 @@ imap4d_session_setup0 () | ... | @@ -308,21 +308,34 @@ imap4d_session_setup0 () |
308 | 308 | ||
309 | if (modify_homedir) | 309 | if (modify_homedir) |
310 | { | 310 | { |
311 | int rc; | ||
312 | mu_vartab_t vtab; | ||
313 | char *expr = mu_tilde_expansion (modify_homedir, "/", real_homedir); | 311 | char *expr = mu_tilde_expansion (modify_homedir, "/", real_homedir); |
314 | 312 | struct mu_wordsplit ws; | |
315 | mu_vartab_create (&vtab); | 313 | const char *env[3]; |
316 | mu_vartab_define (vtab, "user", auth_data->name, 0); | 314 | |
317 | mu_vartab_define (vtab, "home", real_homedir, 0); | 315 | env[0] = "user"; |
318 | rc = mu_vartab_expand (vtab, expr, &imap4d_homedir); | 316 | env[1] = auth_data->name; |
319 | mu_vartab_destroy (&vtab); | 317 | env[2] = "home"; |
320 | free (expr); | 318 | env[3] = real_homedir; |
321 | if (rc) | 319 | env[4] = NULL; |
320 | |||
321 | ws.ws_env = env; | ||
322 | if (mu_wordsplit (expr, &ws, | ||
323 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | | ||
324 | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) | ||
325 | { | ||
326 | mu_error (_("cannot expand line `%s': %s"), expr, | ||
327 | mu_wordsplit_strerror (&ws)); | ||
328 | return 1; | ||
329 | } | ||
330 | else if (ws.ws_wordc == 0) | ||
331 | { | ||
332 | mu_error (_("expanding %s yields empty string"), expr); | ||
333 | return 1; | ||
334 | } | ||
335 | imap4d_homedir = strdup (ws.ws_wordv[0]); | ||
336 | if (!imap4d_homedir) | ||
322 | { | 337 | { |
323 | free (real_homedir); | 338 | mu_error ("%s", mu_strerror (errno)); |
324 | mu_diag_funcall (MU_DIAG_ERROR, "mu_vartab_expand", | ||
325 | modify_homedir, rc); | ||
326 | return 1; | 339 | return 1; |
327 | } | 340 | } |
328 | } | 341 | } | ... | ... |
... | @@ -100,7 +100,6 @@ | ... | @@ -100,7 +100,6 @@ |
100 | #include <mailutils/server.h> | 100 | #include <mailutils/server.h> |
101 | #include <mailutils/wordsplit.h> | 101 | #include <mailutils/wordsplit.h> |
102 | #include <mailutils/alloc.h> | 102 | #include <mailutils/alloc.h> |
103 | #include <mailutils/vartab.h> | ||
104 | #include <mailutils/cctype.h> | 103 | #include <mailutils/cctype.h> |
105 | #include <mailutils/cstr.h> | 104 | #include <mailutils/cstr.h> |
106 | #include <mailutils/io.h> | 105 | #include <mailutils/io.h> | ... | ... |
... | @@ -61,22 +61,6 @@ ident_extract_username (char *reply) | ... | @@ -61,22 +61,6 @@ ident_extract_username (char *reply) |
61 | } | 61 | } |
62 | 62 | ||
63 | static int | 63 | static int |
64 | trimcrlf (char *buf) | ||
65 | { | ||
66 | int len = strlen (buf); | ||
67 | if (len == 0) | ||
68 | return 0; | ||
69 | if (buf[len-1] == '\n') | ||
70 | { | ||
71 | len--; | ||
72 | if (buf[len-1] == '\r') | ||
73 | len--; | ||
74 | buf[len] = 0; | ||
75 | } | ||
76 | return len; | ||
77 | } | ||
78 | |||
79 | static int | ||
80 | is_des_p (const char *name) | 64 | is_des_p (const char *name) |
81 | { | 65 | { |
82 | int len = strlen (name); | 66 | int len = strlen (name); |
... | @@ -369,8 +353,7 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa) | ... | @@ -369,8 +353,7 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa) |
369 | return NULL; | 353 | return NULL; |
370 | } | 354 | } |
371 | mu_diag_output (MU_DIAG_INFO, "Got %s", buf); | 355 | mu_diag_output (MU_DIAG_INFO, "Got %s", buf); |
372 | trimcrlf (buf); | 356 | name = ident_extract_username (mu_str_stripws (buf)); |
373 | name = ident_extract_username (buf); | ||
374 | if (!name) | 357 | if (!name) |
375 | mu_diag_output (MU_DIAG_INFO, | 358 | mu_diag_output (MU_DIAG_INFO, |
376 | _("malformed IDENT response: `%s', from %s:%d"), | 359 | _("malformed IDENT response: `%s', from %s:%d"), |
... | @@ -405,48 +388,83 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa) | ... | @@ -405,48 +388,83 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa) |
405 | } | 388 | } |
406 | 389 | ||
407 | 390 | ||
391 | #define SEQ(s, n, l) \ | ||
392 | (((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0) | ||
393 | |||
394 | struct preauth_closure | ||
395 | { | ||
396 | struct sockaddr_in *s_clt, *s_srv; | ||
397 | }; | ||
398 | |||
399 | static const char * | ||
400 | preauth_getvar (const char *name, size_t nlen, void *data) | ||
401 | { | ||
402 | struct preauth_closure *clos = data; | ||
403 | |||
404 | if (clos->s_clt && clos->s_clt->sin_family == AF_INET) | ||
405 | { | ||
406 | if (SEQ ("client_address", name, nlen)) | ||
407 | return inet_ntoa (clos->s_clt->sin_addr); | ||
408 | if (SEQ ("client_prot", name, nlen)) | ||
409 | return mu_umaxtostr (0, ntohs (clos->s_clt->sin_port)); | ||
410 | } | ||
411 | if (clos->s_srv && clos->s_srv->sin_family == AF_INET) | ||
412 | { | ||
413 | if (SEQ ("server_address", name, nlen)) | ||
414 | return inet_ntoa (clos->s_srv->sin_addr); | ||
415 | if (SEQ ("server_port", name, nlen)) | ||
416 | return mu_umaxtostr (0, ntohs (clos->s_srv->sin_port)); | ||
417 | } | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
408 | /* External (program) preauth */ | 421 | /* External (program) preauth */ |
409 | static char * | 422 | static char * |
410 | do_preauth_program (struct sockaddr *pcs, struct sockaddr *sa) | 423 | do_preauth_program (struct sockaddr *pcs, struct sockaddr *sa) |
411 | { | 424 | { |
412 | int rc; | 425 | int rc; |
413 | mu_vartab_t vtab; | 426 | mu_stream_t str; |
414 | char *cmd; | ||
415 | FILE *fp; | ||
416 | char *buf = NULL; | 427 | char *buf = NULL; |
417 | size_t size = 0; | 428 | size_t size = 0, n; |
418 | 429 | struct mu_wordsplit ws; | |
419 | mu_vartab_create (&vtab); | 430 | struct preauth_closure clos; |
420 | if (pcs && pcs->sa_family == AF_INET) | 431 | |
432 | clos.s_clt = (struct sockaddr_in *) pcs; | ||
433 | clos.s_srv = (struct sockaddr_in *) sa; | ||
434 | |||
435 | ws.ws_getvar = preauth_getvar; | ||
436 | ws.ws_closure = &clos; | ||
437 | if (mu_wordsplit (preauth_program, &ws, | ||
438 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | | ||
439 | MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE)) | ||
421 | { | 440 | { |
422 | struct sockaddr_in *s_in = (struct sockaddr_in *)pcs; | 441 | mu_error (_("cannot expand line `%s': %s"), preauth_program, |
423 | mu_vartab_define (vtab, "client_address", inet_ntoa (s_in->sin_addr), 0); | 442 | mu_wordsplit_strerror (&ws)); |
424 | mu_vartab_define (vtab, "client_port", | 443 | return NULL; |
425 | mu_umaxtostr (0, ntohs (s_in->sin_port)), 0); | ||
426 | } | 444 | } |
427 | if (sa && sa->sa_family == AF_INET) | 445 | else if (ws.ws_wordc == 0) |
428 | { | 446 | { |
429 | struct sockaddr_in *s_in = (struct sockaddr_in *) sa; | 447 | mu_wordsplit_free (&ws); |
430 | mu_vartab_define (vtab, "server_address", inet_ntoa (s_in->sin_addr), 0); | 448 | mu_error (_("`%s' expands to an empty line"), preauth_program); |
431 | mu_vartab_define (vtab, "server_port", | 449 | return NULL; |
432 | mu_umaxtostr (0, ntohs (s_in->sin_port)), 0); | ||
433 | } | 450 | } |
434 | rc = mu_vartab_expand (vtab, preauth_program, &cmd); | ||
435 | mu_vartab_destroy (&vtab); | ||
436 | if (rc) | ||
437 | return NULL; | ||
438 | 451 | ||
439 | fp = popen (cmd, "r"); | 452 | rc = mu_prog_stream_create (&str, ws.ws_wordv[0], MU_STREAM_READ); |
440 | free (cmd); | 453 | mu_wordsplit_free (&ws); |
441 | rc = getline (&buf, &size, fp); | 454 | if (rc) |
442 | pclose (fp); | ||
443 | if (rc > 0) | ||
444 | { | 455 | { |
445 | if (trimcrlf (buf) == 0) | 456 | mu_error (_("cannot open input pipe from %s"), preauth_program); |
446 | { | 457 | return NULL; |
447 | free (buf); | 458 | } |
448 | return NULL; | 459 | rc = mu_stream_getline (str, &buf, &size, &n); |
449 | } | 460 | mu_stream_destroy (&str); |
461 | if (rc) | ||
462 | { | ||
463 | mu_error (_("read from `%s' failed"), preauth_program); | ||
464 | } | ||
465 | else | ||
466 | { | ||
467 | mu_rtrim_cset (buf, "\r\n"); | ||
450 | return buf; | 468 | return buf; |
451 | } | 469 | } |
452 | return NULL; | 470 | return NULL; | ... | ... |
... | @@ -29,15 +29,16 @@ | ... | @@ -29,15 +29,16 @@ |
29 | 29 | ||
30 | #include <confpaths.h> | 30 | #include <confpaths.h> |
31 | 31 | ||
32 | #include <mailutils/nls.h> | ||
32 | #include <mailutils/mailbox.h> | 33 | #include <mailutils/mailbox.h> |
33 | #include <mailutils/util.h> | 34 | #include <mailutils/util.h> |
34 | #include <mailutils/debug.h> | 35 | #include <mailutils/debug.h> |
35 | #include <mailutils/error.h> | 36 | #include <mailutils/error.h> |
36 | #include <mailutils/errno.h> | 37 | #include <mailutils/errno.h> |
37 | #include <mailutils/mu_auth.h> | 38 | #include <mailutils/mu_auth.h> |
38 | #include <mailutils/vartab.h> | ||
39 | #include <mailutils/folder.h> | 39 | #include <mailutils/folder.h> |
40 | #include <mailutils/auth.h> | 40 | #include <mailutils/auth.h> |
41 | #include <mailutils/wordsplit.h> | ||
41 | 42 | ||
42 | #include <mailutils/sys/mailbox.h> | 43 | #include <mailutils/sys/mailbox.h> |
43 | 44 | ||
... | @@ -137,12 +138,30 @@ mu_construct_user_mailbox_url (char **pout, const char *name) | ... | @@ -137,12 +138,30 @@ mu_construct_user_mailbox_url (char **pout, const char *name) |
137 | { | 138 | { |
138 | int rc; | 139 | int rc; |
139 | const char *pat = mu_mailbox_url (); | 140 | const char *pat = mu_mailbox_url (); |
140 | mu_vartab_t vtab; | 141 | const char *env[3]; |
142 | struct mu_wordsplit ws; | ||
143 | |||
144 | env[0] = "user"; | ||
145 | env[1] = (char*) name; | ||
146 | env[3] = NULL; | ||
147 | ws.ws_env = env; | ||
148 | if (mu_wordsplit (pat, &ws, | ||
149 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | | ||
150 | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) | ||
151 | { | ||
152 | mu_error (_("cannot expand line `%s': %s"), pat, | ||
153 | mu_wordsplit_strerror (&ws)); | ||
154 | return errno; | ||
155 | } | ||
141 | 156 | ||
142 | mu_vartab_create (&vtab); | 157 | if (ws.ws_wordc == 0) |
143 | mu_vartab_define (vtab, "user", name, 1); | 158 | /* FIXME: a special return code maybe? */ |
144 | rc = mu_vartab_expand (vtab, pat, pout); | 159 | *pout = strdup (""); |
145 | mu_vartab_destroy (&vtab); | 160 | else |
161 | *pout = strdup (ws.ws_wordv[0]); | ||
162 | mu_wordsplit_free (&ws); | ||
163 | if (!*pout) | ||
164 | return ENOMEM; | ||
146 | return rc; | 165 | return rc; |
147 | } | 166 | } |
148 | 167 | ... | ... |
... | @@ -36,7 +36,6 @@ | ... | @@ -36,7 +36,6 @@ |
36 | #include <mailutils/error.h> | 36 | #include <mailutils/error.h> |
37 | #include <mailutils/errno.h> | 37 | #include <mailutils/errno.h> |
38 | #include <mailutils/kwd.h> | 38 | #include <mailutils/kwd.h> |
39 | #include <mailutils/vartab.h> | ||
40 | #include <mailutils/io.h> | 39 | #include <mailutils/io.h> |
41 | 40 | ||
42 | struct _mu_acl_entry | 41 | struct _mu_acl_entry |
... | @@ -500,18 +499,12 @@ struct run_closure | ... | @@ -500,18 +499,12 @@ struct run_closure |
500 | unsigned idx; | 499 | unsigned idx; |
501 | mu_debug_t debug; | 500 | mu_debug_t debug; |
502 | struct sockaddr *sa; | 501 | struct sockaddr *sa; |
502 | char *numbuf; | ||
503 | char *portbuf; | ||
503 | int salen; | 504 | int salen; |
504 | mu_acl_result_t *result; | 505 | mu_acl_result_t *result; |
505 | }; | 506 | }; |
506 | 507 | ||
507 | static int | ||
508 | _expand_aclno (const char *name, void *data, char **p) | ||
509 | { | ||
510 | struct run_closure *rp = data; | ||
511 | /*FIXME: memory leak*/ | ||
512 | return mu_asprintf (p, "%u", rp->idx); | ||
513 | } | ||
514 | |||
515 | #if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) | 508 | #if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) |
516 | # define getmaxfd() sysconf (_SC_OPEN_MAX) | 509 | # define getmaxfd() sysconf (_SC_OPEN_MAX) |
517 | #elif defined (HAVE_GETDTABLESIZE) | 510 | #elif defined (HAVE_GETDTABLESIZE) |
... | @@ -520,52 +513,103 @@ _expand_aclno (const char *name, void *data, char **p) | ... | @@ -520,52 +513,103 @@ _expand_aclno (const char *name, void *data, char **p) |
520 | # define getmaxfd() 64 | 513 | # define getmaxfd() 64 |
521 | #endif | 514 | #endif |
522 | 515 | ||
523 | static int | 516 | #define SEQ(s, n, l) \ |
524 | expand_arg (const char *cmdline, struct run_closure *rp, char **s) | 517 | (((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0) |
518 | |||
519 | static const char * | ||
520 | acl_getvar (const char *name, size_t nlen, void *data) | ||
525 | { | 521 | { |
526 | int rc; | 522 | struct run_closure *rp = data; |
527 | mu_vartab_t vtab; | 523 | |
528 | 524 | if (SEQ ("aclno", name, nlen)) | |
529 | MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "Expanding \"%s\" => ", cmdline); | 525 | { |
526 | if (!rp->numbuf && mu_asprintf (&rp->numbuf, "%u", rp->idx)) | ||
527 | return NULL; | ||
528 | return rp->numbuf; | ||
529 | } | ||
530 | 530 | ||
531 | mu_vartab_create (&vtab); | ||
532 | mu_vartab_define_exp (vtab, "aclno", _expand_aclno, NULL, rp); | ||
533 | switch (rp->sa->sa_family) | 531 | switch (rp->sa->sa_family) |
534 | { | 532 | { |
535 | case AF_INET: | 533 | case AF_INET: |
536 | { | 534 | { |
537 | struct sockaddr_in *s_in = (struct sockaddr_in *)rp->sa; | 535 | struct sockaddr_in *s_in = (struct sockaddr_in *)rp->sa; |
538 | struct in_addr addr = s_in->sin_addr; | 536 | |
539 | char *p; | 537 | if (SEQ ("address", name, nlen)) |
538 | { | ||
539 | struct in_addr addr = s_in->sin_addr; | ||
540 | addr.s_addr = htonl (addr.s_addr); | ||
541 | return inet_ntoa (addr); | ||
542 | } | ||
543 | |||
544 | if (SEQ ("port", name, nlen)) | ||
545 | { | ||
546 | if (!rp->portbuf && | ||
547 | mu_asprintf (&rp->portbuf, "%hu", ntohs (s_in->sin_port))) | ||
548 | return NULL; | ||
549 | return rp->portbuf; | ||
550 | } | ||
551 | break; | ||
540 | 552 | ||
541 | mu_vartab_define (vtab, "family", "AF_INET", 1); | 553 | case AF_UNIX: |
542 | addr.s_addr = htonl (addr.s_addr); | 554 | if (SEQ ("address", name, nlen)) |
543 | mu_vartab_define (vtab, "address", inet_ntoa (addr), 0); | ||
544 | if (mu_asprintf (&p, "%hu", ntohs (s_in->sin_port)) == 0) | ||
545 | { | 555 | { |
546 | mu_vartab_define (vtab, "port", p, 0); | 556 | struct sockaddr_un *s_un = (struct sockaddr_un *)rp->sa; |
547 | free (p); | 557 | if (rp->salen == sizeof (s_un->sun_family)) |
558 | return NULL; | ||
559 | else | ||
560 | return s_un->sun_path; | ||
548 | } | 561 | } |
549 | } | 562 | } |
550 | break; | 563 | break; |
551 | 564 | } | |
565 | return NULL; | ||
566 | } | ||
567 | |||
568 | static int | ||
569 | expand_arg (const char *cmdline, struct run_closure *rp, char **s) | ||
570 | { | ||
571 | int rc; | ||
572 | struct mu_wordsplit ws; | ||
573 | const char *env[3]; | ||
574 | |||
575 | MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "Expanding \"%s\" => ", cmdline); | ||
576 | env[0] = "family"; | ||
577 | switch (rp->sa->sa_family) | ||
578 | { | ||
579 | case AF_INET: | ||
580 | env[1] = "AF_INET"; | ||
581 | break; | ||
582 | |||
552 | case AF_UNIX: | 583 | case AF_UNIX: |
553 | { | 584 | env[1] = "AF_UNIX"; |
554 | struct sockaddr_un *s_un = (struct sockaddr_un *)rp->sa; | ||
555 | |||
556 | mu_vartab_define (vtab, "family", "AF_UNIX", 1); | ||
557 | mu_vartab_define (vtab, "address", s_un->sun_path, 1); | ||
558 | } | ||
559 | break; | 585 | break; |
560 | } | 586 | } |
561 | 587 | env[2] = NULL; | |
562 | rc = mu_vartab_expand (vtab, cmdline, s); | 588 | ws.ws_env = env; |
563 | mu_vartab_destroy (&vtab); | 589 | ws.ws_getvar = acl_getvar; |
590 | ws.ws_closure = rp; | ||
591 | rc = mu_wordsplit (cmdline, &ws, | ||
592 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | | ||
593 | MU_WRDSF_ENV | MU_WRDSF_ENV_KV | | ||
594 | MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE); | ||
564 | 595 | ||
565 | if (rc == 0) | 596 | if (rc == 0) |
566 | MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "\"%s\". ", *s); | 597 | { |
598 | *s = strdup (ws.ws_wordv[0]); | ||
599 | mu_wordsplit_free (&ws); | ||
600 | if (!*s) | ||
601 | { | ||
602 | MU_DEBUG (rp->debug, MU_DEBUG_TRACE0, "failed: not enough memory. "); | ||
603 | return ENOMEM; | ||
604 | } | ||
605 | MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "\"%s\". ", *s); | ||
606 | } | ||
567 | else | 607 | else |
568 | MU_DEBUG (rp->debug, MU_DEBUG_TRACE0, "failed. "); | 608 | { |
609 | MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "failed: %s", | ||
610 | mu_wordsplit_strerror (&ws)); | ||
611 | rc = errno; | ||
612 | } | ||
569 | return rc; | 613 | return rc; |
570 | } | 614 | } |
571 | 615 | ||
... | @@ -744,7 +788,10 @@ mu_acl_check_sockaddr (mu_acl_t acl, const struct sockaddr *sa, int salen, | ... | @@ -744,7 +788,10 @@ mu_acl_check_sockaddr (mu_acl_t acl, const struct sockaddr *sa, int salen, |
744 | r.debug = acl->debug; | 788 | r.debug = acl->debug; |
745 | r.result = pres; | 789 | r.result = pres; |
746 | *r.result = mu_acl_result_undefined; | 790 | *r.result = mu_acl_result_undefined; |
791 | r.numbuf = r.portbuf = NULL; | ||
747 | mu_list_do (acl->aclist, _run_entry, &r); | 792 | mu_list_do (acl->aclist, _run_entry, &r); |
793 | free (r.numbuf); | ||
794 | free (r.portbuf); | ||
748 | free (r.sa); | 795 | free (r.sa); |
749 | return 0; | 796 | return 0; |
750 | } | 797 | } | ... | ... |
... | @@ -143,7 +143,7 @@ mu_wordsplit_init (struct mu_wordsplit *wsp, const char *input, size_t len, | ... | @@ -143,7 +143,7 @@ mu_wordsplit_init (struct mu_wordsplit *wsp, const char *input, size_t len, |
143 | if (wsp->ws_flags & MU_WRDSF_REUSE) | 143 | if (wsp->ws_flags & MU_WRDSF_REUSE) |
144 | { | 144 | { |
145 | if (!(wsp->ws_flags & MU_WRDSF_APPEND)) | 145 | if (!(wsp->ws_flags & MU_WRDSF_APPEND)) |
146 | wsp->ws_wordc = 0; | 146 | mu_wordsplit_free_words (wsp); |
147 | } | 147 | } |
148 | else | 148 | else |
149 | { | 149 | { |
... | @@ -1427,7 +1427,7 @@ mu_wordsplit (const char *command, struct mu_wordsplit *ws, int flags) | ... | @@ -1427,7 +1427,7 @@ mu_wordsplit (const char *command, struct mu_wordsplit *ws, int flags) |
1427 | } | 1427 | } |
1428 | 1428 | ||
1429 | void | 1429 | void |
1430 | mu_wordsplit_free (struct mu_wordsplit *ws) | 1430 | mu_wordsplit_free_words (struct mu_wordsplit *ws) |
1431 | { | 1431 | { |
1432 | size_t i; | 1432 | size_t i; |
1433 | 1433 | ||
... | @@ -1435,8 +1435,18 @@ mu_wordsplit_free (struct mu_wordsplit *ws) | ... | @@ -1435,8 +1435,18 @@ mu_wordsplit_free (struct mu_wordsplit *ws) |
1435 | { | 1435 | { |
1436 | char *p = ws->ws_wordv[ws->ws_offs + i]; | 1436 | char *p = ws->ws_wordv[ws->ws_offs + i]; |
1437 | if (p) | 1437 | if (p) |
1438 | free (p); | 1438 | { |
1439 | free (p); | ||
1440 | ws->ws_wordv[ws->ws_offs + i] = NULL; | ||
1441 | } | ||
1439 | } | 1442 | } |
1443 | ws->ws_wordc = 0; | ||
1444 | } | ||
1445 | |||
1446 | void | ||
1447 | mu_wordsplit_free (struct mu_wordsplit *ws) | ||
1448 | { | ||
1449 | mu_wordsplit_free_words (ws); | ||
1440 | free (ws->ws_wordv); | 1450 | free (ws->ws_wordv); |
1441 | ws->ws_wordv = NULL; | 1451 | ws->ws_wordv = NULL; |
1442 | } | 1452 | } | ... | ... |
... | @@ -46,7 +46,6 @@ | ... | @@ -46,7 +46,6 @@ |
46 | #include "mailutils/md5.h" | 46 | #include "mailutils/md5.h" |
47 | #include "mailutils/sha1.h" | 47 | #include "mailutils/sha1.h" |
48 | #include "mailutils/ldap.h" | 48 | #include "mailutils/ldap.h" |
49 | #include "mailutils/vartab.h" | ||
50 | 49 | ||
51 | #include <ldap.h> | 50 | #include <ldap.h> |
52 | #include <lber.h> | 51 | #include <lber.h> |
... | @@ -504,33 +503,43 @@ _mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key, | ... | @@ -504,33 +503,43 @@ _mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key, |
504 | struct mu_auth_data **return_data) | 503 | struct mu_auth_data **return_data) |
505 | { | 504 | { |
506 | int rc; | 505 | int rc; |
507 | char *filter; | ||
508 | char **attrs; | 506 | char **attrs; |
509 | size_t nattrs; | 507 | size_t nattrs; |
510 | LDAPMessage *res, *msg; | 508 | LDAPMessage *res, *msg; |
511 | ber_int_t msgid; | 509 | ber_int_t msgid; |
512 | mu_vartab_t vtab; | 510 | const char *env[3]; |
511 | struct mu_wordsplit ws; | ||
513 | 512 | ||
514 | rc = _construct_attr_array (&nattrs, &attrs); | 513 | rc = _construct_attr_array (&nattrs, &attrs); |
515 | if (rc) | 514 | if (rc) |
516 | return rc; | 515 | return rc; |
517 | 516 | ||
518 | mu_vartab_create (&vtab); | 517 | env[0] = "user"; |
519 | mu_vartab_define (vtab, "user", key, 1); | 518 | env[1] = key; |
520 | mu_vartab_define (vtab, "u", key, 1); | 519 | env[3] = NULL; |
521 | rc = mu_vartab_expand (vtab, filter_pat, &filter); | 520 | |
522 | mu_vartab_destroy (&vtab); | 521 | ws.ws_env = env; |
523 | if (rc) | 522 | if (mu_wordsplit (filter_pat, &ws, |
523 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | | ||
524 | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) | ||
525 | { | ||
526 | mu_error (_("cannot expand line `%s': %s"), filter_pat, | ||
527 | mu_wordsplit_strerror (&ws)); | ||
528 | return MU_ERR_FAILURE; | ||
529 | } | ||
530 | else if (ws.ws_wordc == 0) | ||
524 | { | 531 | { |
532 | mu_error (_("expanding %s yields empty string"), filter_pat); | ||
533 | mu_wordsplit_free (&ws); | ||
525 | mu_argcv_free (nattrs, attrs); | 534 | mu_argcv_free (nattrs, attrs); |
526 | return ENOMEM; | 535 | return MU_ERR_FAILURE; |
527 | } | 536 | } |
528 | 537 | ||
529 | rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE, | 538 | rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE, |
530 | filter, attrs, 0, | 539 | ws.ws_wordv[0], attrs, 0, |
531 | NULL, NULL, NULL, -1, &msgid); | 540 | NULL, NULL, NULL, -1, &msgid); |
541 | mu_wordsplit_free (&ws); | ||
532 | mu_argcv_free (nattrs, attrs); | 542 | mu_argcv_free (nattrs, attrs); |
533 | free (filter); | ||
534 | 543 | ||
535 | if (rc != LDAP_SUCCESS) | 544 | if (rc != LDAP_SUCCESS) |
536 | { | 545 | { | ... | ... |
... | @@ -40,7 +40,6 @@ | ... | @@ -40,7 +40,6 @@ |
40 | #include <mailutils/error.h> | 40 | #include <mailutils/error.h> |
41 | #include <mailutils/errno.h> | 41 | #include <mailutils/errno.h> |
42 | #include <mailutils/nls.h> | 42 | #include <mailutils/nls.h> |
43 | #include <mailutils/vartab.h> | ||
44 | #include <mailutils/io.h> | 43 | #include <mailutils/io.h> |
45 | #include <mailutils/cctype.h> | 44 | #include <mailutils/cctype.h> |
46 | 45 | ||
... | @@ -245,41 +244,38 @@ mu_radius_module_init (enum mu_gocs_op op, void *data) | ... | @@ -245,41 +244,38 @@ mu_radius_module_init (enum mu_gocs_op op, void *data) |
245 | static char * | 244 | static char * |
246 | _expand_query (const char *query, const char *ustr, const char *passwd) | 245 | _expand_query (const char *query, const char *ustr, const char *passwd) |
247 | { | 246 | { |
248 | int rc; | 247 | struct mu_wordsplit ws; |
249 | mu_vartab_t vtab; | 248 | const char *env[2 * 2 + 1]; |
250 | char *str, *ret; | 249 | char *ret; |
251 | 250 | ||
252 | if (!query) | 251 | env[0] = "user"; |
253 | return NULL; | 252 | env[1] = (char*) ustr; |
254 | 253 | env[2] = "passwd"; | |
255 | mu_vartab_create (&vtab); | 254 | env[3] = (char*) passwd; |
256 | if (ustr) | 255 | env[4] = NULL; |
257 | { | 256 | |
258 | mu_vartab_define (vtab, "user", ustr, 1); | 257 | ws.ws_env = env; |
259 | mu_vartab_define (vtab, "u", ustr, 1); | 258 | if (mu_wordsplit (query, &ws, |
260 | } | 259 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | |
261 | 260 | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) | |
262 | if (passwd) | ||
263 | { | 261 | { |
264 | mu_vartab_define (vtab, "passwd", passwd, 1); | 262 | mu_error (_("cannot expand line `%s': %s"), query, |
265 | mu_vartab_define (vtab, "p", passwd, 1); | 263 | mu_wordsplit_strerror (&ws)); |
264 | return NULL; | ||
266 | } | 265 | } |
267 | 266 | else if (ws.ws_wordc == 0) | |
268 | rc = mu_vartab_expand (vtab, query, &str); | ||
269 | if (rc == 0) | ||
270 | { | 267 | { |
271 | ret = grad_emalloc (strlen (str) + 1); | 268 | mu_error (_("expanding %s yields empty string"), query); |
272 | strcpy (ret, str); | 269 | mu_wordsplit_free (&ws); |
273 | free (str); | 270 | return NULL; |
274 | } | 271 | } |
275 | else | 272 | |
276 | ret = NULL; | 273 | ret = grad_emalloc (strlen (ws.ws_wordv[0]) + 1); |
277 | 274 | strcpy (ret, ws.ws_wordv[0]); | |
278 | mu_vartab_destroy (&vtab); | 275 | mu_wordsplit_free (&ws); |
279 | return ret; | 276 | return ret; |
280 | } | 277 | } |
281 | 278 | ||
282 | |||
283 | 279 | ||
284 | static grad_avp_t * | 280 | static grad_avp_t * |
285 | create_request (grad_avp_t *template, const char *ustr, const char *passwd) | 281 | create_request (grad_avp_t *template, const char *ustr, const char *passwd) | ... | ... |
... | @@ -49,7 +49,6 @@ | ... | @@ -49,7 +49,6 @@ |
49 | #include <mailutils/nls.h> | 49 | #include <mailutils/nls.h> |
50 | #include <mailutils/util.h> | 50 | #include <mailutils/util.h> |
51 | #include <mailutils/sql.h> | 51 | #include <mailutils/sql.h> |
52 | #include <mailutils/vartab.h> | ||
53 | #include <mailutils/cstr.h> | 52 | #include <mailutils/cstr.h> |
54 | #include "sql.h" | 53 | #include "sql.h" |
55 | 54 | ||
... | @@ -91,20 +90,34 @@ mu_sql_expand_query (const char *query, const char *ustr) | ... | @@ -91,20 +90,34 @@ mu_sql_expand_query (const char *query, const char *ustr) |
91 | int rc; | 90 | int rc; |
92 | char *res; | 91 | char *res; |
93 | char *esc_ustr; | 92 | char *esc_ustr; |
94 | mu_vartab_t vtab; | 93 | struct mu_wordsplit ws; |
95 | 94 | const char *env[2 + 1]; | |
95 | |||
96 | if (!query) | 96 | if (!query) |
97 | return NULL; | 97 | return NULL; |
98 | 98 | ||
99 | esc_ustr = sql_escape_string (ustr); | 99 | esc_ustr = sql_escape_string (ustr); |
100 | mu_vartab_create (&vtab); | 100 | env[0] = "user"; |
101 | mu_vartab_define (vtab, "user", ustr, 1); | 101 | env[1] = (char*) ustr; |
102 | mu_vartab_define (vtab, "u", ustr, 1); | 102 | env[2] = NULL; |
103 | rc = mu_vartab_expand (vtab, query, &res); | 103 | |
104 | if (rc) | 104 | ws.ws_env = env; |
105 | res = NULL; | 105 | if (mu_wordsplit (query, &ws, |
106 | mu_vartab_destroy (&vtab); | 106 | MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | |
107 | 107 | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) | |
108 | { | ||
109 | mu_error (_("cannot expand line `%s': %s"), query, | ||
110 | mu_wordsplit_strerror (&ws)); | ||
111 | return NULL; | ||
112 | } | ||
113 | else if (ws.ws_wordc == 0) | ||
114 | { | ||
115 | mu_error (_("expanding %s yields empty string"), query); | ||
116 | mu_wordsplit_free (&ws); | ||
117 | return NULL; | ||
118 | } | ||
119 | res = strdup (ws.ws_wordv[0]); | ||
120 | mu_wordsplit_free (&ws); | ||
108 | free (esc_ustr); | 121 | free (esc_ustr); |
109 | return res; | 122 | return res; |
110 | } | 123 | } | ... | ... |
... | @@ -32,7 +32,7 @@ | ... | @@ -32,7 +32,7 @@ |
32 | #include <mailutils/message.h> | 32 | #include <mailutils/message.h> |
33 | #include <mailutils/observer.h> | 33 | #include <mailutils/observer.h> |
34 | #include <mailutils/progmailer.h> | 34 | #include <mailutils/progmailer.h> |
35 | #include <mailutils/vartab.h> | 35 | #include <mailutils/wordsplit.h> |
36 | 36 | ||
37 | #include <mailutils/sys/url.h> | 37 | #include <mailutils/sys/url.h> |
38 | #include <mailutils/sys/mailer.h> | 38 | #include <mailutils/sys/mailer.h> |
... | @@ -140,26 +140,24 @@ prog_close (mu_mailer_t mailer) | ... | @@ -140,26 +140,24 @@ prog_close (mu_mailer_t mailer) |
140 | return mu_progmailer_close (mailer->data); | 140 | return mu_progmailer_close (mailer->data); |
141 | } | 141 | } |
142 | 142 | ||
143 | static int | 143 | struct prog_exp |
144 | _expand_sender (const char *name, void *data, char **p) | ||
145 | { | ||
146 | mu_address_t addr = data; | ||
147 | char *email; | ||
148 | int status = mu_address_aget_email (addr, 1, &email); | ||
149 | |||
150 | if (status != 0) | ||
151 | return status; | ||
152 | *p = email; | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | struct ex_rcpt | ||
157 | { | 144 | { |
158 | mu_message_t msg; | 145 | mu_message_t msg; |
159 | mu_address_t addr; | 146 | mu_address_t sender_addr; |
160 | char *string; | 147 | char *sender_str; |
148 | mu_address_t rcpt_addr; | ||
149 | char *rcpt_str; | ||
161 | }; | 150 | }; |
162 | 151 | ||
152 | static const char * | ||
153 | _expand_sender (struct prog_exp *pe) | ||
154 | { | ||
155 | if (!pe->sender_str && | ||
156 | mu_address_aget_email (pe->sender_addr, 1, &pe->sender_str)) | ||
157 | return NULL; | ||
158 | return pe->sender_str; | ||
159 | } | ||
160 | |||
163 | static int | 161 | static int |
164 | address_add (mu_address_t *paddr, const char *value) | 162 | address_add (mu_address_t *paddr, const char *value) |
165 | { | 163 | { |
... | @@ -206,28 +204,27 @@ message_read_rcpt (mu_message_t msg, mu_address_t *paddr) | ... | @@ -206,28 +204,27 @@ message_read_rcpt (mu_message_t msg, mu_address_t *paddr) |
206 | return 0; | 204 | return 0; |
207 | } | 205 | } |
208 | 206 | ||
209 | static int | 207 | static const char * |
210 | _expand_rcpt (const char *name, void *data, char **p) | 208 | _expand_rcpt (struct prog_exp *pe) |
211 | { | 209 | { |
212 | struct ex_rcpt *exrcpt = data; | ||
213 | int status; | 210 | int status; |
214 | 211 | ||
215 | if (!exrcpt->string) | 212 | if (!pe->rcpt_str) |
216 | { | 213 | { |
217 | size_t i, count = 0; | 214 | size_t i, count = 0; |
218 | size_t len = 0; | 215 | size_t len = 0; |
219 | char *str; | 216 | char *str; |
220 | mu_address_t tmp_addr = NULL, addr; | 217 | mu_address_t tmp_addr = NULL, addr; |
221 | 218 | ||
222 | if (exrcpt->addr) | 219 | if (pe->rcpt_addr) |
223 | addr = exrcpt->addr; | 220 | addr = pe->rcpt_addr; |
224 | else | 221 | else |
225 | { | 222 | { |
226 | status = message_read_rcpt (exrcpt->msg, &tmp_addr); | 223 | status = message_read_rcpt (pe->msg, &tmp_addr); |
227 | if (status) | 224 | if (status) |
228 | { | 225 | { |
229 | mu_address_destroy (&tmp_addr); | 226 | mu_address_destroy (&tmp_addr); |
230 | return status; | 227 | return NULL; |
231 | } | 228 | } |
232 | addr = tmp_addr; | 229 | addr = tmp_addr; |
233 | } | 230 | } |
... | @@ -241,7 +238,7 @@ _expand_rcpt (const char *name, void *data, char **p) | ... | @@ -241,7 +238,7 @@ _expand_rcpt (const char *name, void *data, char **p) |
241 | if ((status = mu_address_sget_email (addr, i, &email)) != 0) | 238 | if ((status = mu_address_sget_email (addr, i, &email)) != 0) |
242 | { | 239 | { |
243 | mu_address_destroy (&tmp_addr); | 240 | mu_address_destroy (&tmp_addr); |
244 | return status; | 241 | return NULL; |
245 | } | 242 | } |
246 | len += strlen (email); | 243 | len += strlen (email); |
247 | } | 244 | } |
... | @@ -250,9 +247,9 @@ _expand_rcpt (const char *name, void *data, char **p) | ... | @@ -250,9 +247,9 @@ _expand_rcpt (const char *name, void *data, char **p) |
250 | if (!str) | 247 | if (!str) |
251 | { | 248 | { |
252 | mu_address_destroy (&tmp_addr); | 249 | mu_address_destroy (&tmp_addr); |
253 | return ENOMEM; | 250 | return NULL; |
254 | } | 251 | } |
255 | exrcpt->string = str; | 252 | pe->rcpt_str = str; |
256 | 253 | ||
257 | for (i = 1; i <= count; i++) | 254 | for (i = 1; i <= count; i++) |
258 | { | 255 | { |
... | @@ -267,14 +264,22 @@ _expand_rcpt (const char *name, void *data, char **p) | ... | @@ -267,14 +264,22 @@ _expand_rcpt (const char *name, void *data, char **p) |
267 | *str = 0; | 264 | *str = 0; |
268 | mu_address_destroy (&tmp_addr); | 265 | mu_address_destroy (&tmp_addr); |
269 | } | 266 | } |
270 | *p = exrcpt->string; | 267 | return pe->rcpt_str; |
271 | return 0; | ||
272 | } | 268 | } |
273 | 269 | ||
274 | void | 270 | #define SEQ(s, n, l) \ |
275 | _free_rcpt (void *data, char *value) | 271 | (((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0) |
272 | |||
273 | static const char * | ||
274 | prog_getvar (const char *name, size_t nlen, void *data) | ||
276 | { | 275 | { |
277 | free (value); | 276 | struct prog_exp *pe = data; |
277 | |||
278 | if (SEQ ("sender", name, nlen)) | ||
279 | return _expand_sender (pe); | ||
280 | if (SEQ ("rcpt", name, nlen)) | ||
281 | return _expand_rcpt (pe); | ||
282 | return NULL; | ||
278 | } | 283 | } |
279 | 284 | ||
280 | static int | 285 | static int |
... | @@ -283,41 +288,58 @@ url_to_argv (mu_url_t url, mu_message_t msg, | ... | @@ -283,41 +288,58 @@ url_to_argv (mu_url_t url, mu_message_t msg, |
283 | int *pargc, char ***pargv) | 288 | int *pargc, char ***pargv) |
284 | { | 289 | { |
285 | int rc; | 290 | int rc; |
286 | mu_vartab_t vtab; | 291 | struct prog_exp pe; |
287 | struct ex_rcpt ex_rcpt; | ||
288 | char **query; | 292 | char **query; |
289 | size_t i; | 293 | size_t i; |
290 | size_t argc; | 294 | size_t argc; |
291 | char **argv; | 295 | char **argv; |
296 | struct mu_wordsplit ws; | ||
297 | int wsflags; | ||
292 | 298 | ||
293 | ex_rcpt.msg = msg; | 299 | pe.msg = msg; |
294 | ex_rcpt.addr = to; | 300 | pe.rcpt_addr = to; |
295 | ex_rcpt.string = NULL; | 301 | pe.sender_addr = from; |
296 | mu_vartab_create (&vtab); | 302 | pe.sender_str = pe.rcpt_str = NULL; |
297 | mu_vartab_define_exp (vtab, "sender", _expand_sender, NULL, from); | 303 | |
298 | mu_vartab_define_exp (vtab, "rcpt", _expand_rcpt, _free_rcpt, &ex_rcpt); | 304 | ws.ws_getvar = prog_getvar; |
305 | ws.ws_closure = &pe; | ||
306 | wsflags = MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | | ||
307 | MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE; | ||
299 | 308 | ||
300 | rc = mu_url_sget_query (url, &argc, &query); | 309 | rc = mu_url_sget_query (url, &argc, &query); |
301 | if (rc) | 310 | if (rc) |
302 | return rc; | 311 | return rc; |
303 | 312 | ||
304 | argv = calloc (argc + 1, sizeof (argv[0])); | 313 | argv = calloc (argc + 2, sizeof (argv[0])); |
305 | if (!argv) | 314 | if (!argv) |
306 | return ENOMEM; | 315 | return ENOMEM; |
307 | 316 | ||
317 | rc = mu_url_aget_path (url, &argv[0]); | ||
318 | if (rc) | ||
319 | { | ||
320 | free (argv); | ||
321 | return rc; | ||
322 | } | ||
323 | |||
308 | for (i = 0; i < argc; i++) | 324 | for (i = 0; i < argc; i++) |
309 | { | 325 | { |
310 | if ((rc = mu_vartab_expand (vtab, query[i], &argv[i]))) | 326 | if (mu_wordsplit (query[i], &ws, wsflags)) |
311 | { | 327 | { |
312 | mu_argcv_free (i, argv); | 328 | mu_argcv_free (i, argv); |
313 | mu_vartab_destroy (&vtab); | 329 | mu_wordsplit_free (&ws); |
314 | return rc; | 330 | return errno; |
315 | } | 331 | } |
332 | if (ws.ws_wordc == 0) | ||
333 | argv[i+1] = strdup (""); | ||
334 | else | ||
335 | argv[i+1] = strdup (ws.ws_wordv[0]); | ||
336 | wsflags |= MU_WRDSF_REUSE; | ||
316 | } | 337 | } |
317 | argv[i] = NULL; | 338 | argv[i+1] = NULL; |
339 | mu_wordsplit_free (&ws); | ||
340 | free (pe.sender_str); | ||
341 | free (pe.rcpt_str); | ||
318 | 342 | ||
319 | mu_vartab_destroy (&vtab); | ||
320 | |||
321 | *pargc = argc; | 343 | *pargc = argc; |
322 | *pargv = argv; | 344 | *pargv = argv; |
323 | return 0; | 345 | return 0; | ... | ... |
... | @@ -140,6 +140,7 @@ libmailutils/server/ipsrv.c | ... | @@ -140,6 +140,7 @@ libmailutils/server/ipsrv.c |
140 | libmailutils/server/msrv.c | 140 | libmailutils/server/msrv.c |
141 | 141 | ||
142 | libmailutils/mailbox/message.c | 142 | libmailutils/mailbox/message.c |
143 | libmailutils/mailbox/mbx_default.c | ||
143 | libmailutils/mailer/mailer.c | 144 | libmailutils/mailer/mailer.c |
144 | libmailutils/mailer/smtp.c | 145 | libmailutils/mailer/smtp.c |
145 | libmailutils/mailer/smtp_gsasl.c | 146 | libmailutils/mailer/smtp_gsasl.c | ... | ... |
-
Please register or sign in to post a comment