diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2002-11-20 12:34:05 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2002-11-20 12:34:05 +0000 |
commit | 977661a0f430d96613265328371c1c4653efda07 (patch) | |
tree | 581d19ab098cba0e38e43e56bfbdcd27d635d551 /mail.local | |
parent | 6f7e5734c0e184d80ff4dc5009368120ad93d29a (diff) | |
download | mailutils-977661a0f430d96613265328371c1c4653efda07.tar.gz mailutils-977661a0f430d96613265328371c1c4653efda07.tar.bz2 |
(make_tmp): Create a message instead
of returning file pointer.
(argp_capa): Added "mailer" capability.
(sieve_test): Second argument.
(mda,deliver): Take message_t as first argument, instead of
FILE*.
Diffstat (limited to 'mail.local')
-rw-r--r-- | mail.local/main.c | 211 |
1 files changed, 130 insertions, 81 deletions
diff --git a/mail.local/main.c b/mail.local/main.c index 79bef09e6..79abfd3d2 100644 --- a/mail.local/main.c +++ b/mail.local/main.c @@ -35,8 +35,8 @@ mu_debug_t mudebug; #define EX_QUOTA() (ex_quota_tempfail ? EX_TEMPFAIL : EX_UNAVAILABLE) void close_fds (); -FILE *make_tmp (const char *from, char **tempfile); -void deliver (FILE *fp, char *name); +int make_tmp __P((const char *from, message_t *msg, char **tempfile)); +void deliver (message_t msg, char *name); void guess_retval (int ec); void mailer_err (char *fmt, ...); void notify_biff (mailbox_t mbox, char *name, size_t size); @@ -99,15 +99,15 @@ static const char *argp_capa[] = { "auth", "common", "license", - "mailbox", "logging", + "mailbox", + "mailer", NULL }; char *from = NULL; char *progfile_pattern = NULL; char *sieve_pattern = NULL; -message_t sieve_msg = NULL; #define D_DEFAULT "9s" @@ -264,8 +264,8 @@ _sieve_parse_error (void *user_name, const char *filename, int lineno, int main (int argc, char *argv[]) { - FILE *fp; char *tempfile = NULL; + message_t message = NULL; int arg_index; /* Preparative work: close inherited fds, force a reasonable umask @@ -324,35 +324,8 @@ main (int argc, char *argv[]) list_append (bookie, smtp_record); } - fp = make_tmp (from, &tempfile); - if (sieve_pattern) - { - stream_t stream; - int status; - - fflush (fp); - file_stream_create (&stream, tempfile, MU_STREAM_RDWR); - if ((status = stream_open (stream))) - { - mu_error ("Opening temporary file failed: %s\n", - mu_errstring (status)); - return EX_TEMPFAIL; - } - - if ((status = message_create (&sieve_msg, NULL))) - { - mu_error ("Can't create temporary message: %s\n", - mu_errstring (status)); - return EX_TEMPFAIL; - } - - if ((status = message_set_stream (sieve_msg, stream, NULL))) - { - mu_error ("Can't assign stream to temporary message: %s\n", - mu_errstring (status)); - return EX_TEMPFAIL; - } - } + if (make_tmp (from, &message, &tempfile)) + exit (exit_code); if (multiple_delivery) multiple_delivery = argc > 1; @@ -363,7 +336,7 @@ main (int argc, char *argv[]) struct mda_data mda_data; memset (&mda_data, 0, sizeof mda_data); - mda_data.fp = fp; + mda_data.msg = message; mda_data.argv = argv; mda_data.progfile_pattern = progfile_pattern; mda_data.tempfile = tempfile; @@ -373,12 +346,12 @@ main (int argc, char *argv[]) unlink (tempfile); for (; *argv; argv++) - mda (fp, *argv); + mda (message, *argv); return exit_code; } int -sieve_test (struct mu_auth_data *auth) +sieve_test (struct mu_auth_data *auth, message_t msg) { int rc = 1; char *progfile; @@ -414,13 +387,13 @@ sieve_test (struct mu_auth_data *auth) { attribute_t attr; - message_get_attribute (sieve_msg, &attr); + message_get_attribute (msg, &attr); attribute_unset_deleted (attr); if (switch_user_id (auth, 1) == 0) { chdir (auth->dir); - rc = sieve_message (mach, sieve_msg); + rc = sieve_message (mach, msg); if (rc == 0) rc = attribute_is_deleted (attr) == 0; @@ -436,9 +409,9 @@ sieve_test (struct mu_auth_data *auth) } int -mda (FILE *fp, char *username) +mda (message_t msg, char *username) { - deliver (fp, username); + deliver (msg, username); if (multiple_delivery) exit_code = EX_OK; @@ -491,24 +464,41 @@ switch_user_id (struct mu_auth_data *auth, int user) return rc; } -FILE * -make_tmp (const char *from, char **tempfile) +static int +tmp_write (stream_t stream, off_t *poffset, char *buf, size_t len) { - time_t t; - FILE *fp; - char *buf = NULL; size_t n = 0; - int line; + int status = stream_write (stream, buf, len, *poffset, &n); + if (status == 0 && n != len) + status = EIO; + *poffset += n; + return status; +} +int +make_tmp (const char *from, message_t *msg, char **tempfile) +{ + stream_t stream; + char *buf = NULL; + size_t n = 0; + off_t offset = 0; + size_t line; + int status; + static char *newline = "\n"; + *tempfile = mu_tempname (NULL); - fp = fopen (*tempfile, "w+"); - - if (fp == NULL) + if ((status = file_stream_create (&stream, *tempfile, MU_STREAM_RDWR))) { - mailer_err ("unable to open temporary file"); + mailer_err ("unable to open temporary file: %s", mu_errstring (status)); exit (exit_code); } + if ((status = stream_open (stream))) + { + mailer_err ("unable to open temporary file: %s", mu_errstring (status)); + exit (exit_code); + } + line = 0; while (getline (&buf, &n, stdin) > 0) { @@ -526,8 +516,13 @@ make_tmp (const char *from, char **tempfile) } if (from) { + time_t t; + char *ptr; + time (&t); - fprintf (fp, "From %s %s", from, ctime (&t)); + asprintf (&ptr, "From %s %s", from, ctime (&t)); + status = tmp_write (stream, &offset, ptr, strlen (ptr)); + free (ptr); } else { @@ -539,35 +534,61 @@ make_tmp (const char *from, char **tempfile) } } else if (!memcmp (buf, "From ", 5)) - fputc ('>', fp); - if (fputs (buf, fp) == EOF) { - mailer_err ("temporary file write error"); - fclose (fp); - return NULL; + static char *escape = ">"; + status = tmp_write (stream, &offset, escape, 1); + } + + if (!status) + status = tmp_write (stream, &offset, buf, strlen (buf)); + + if (status) + { + mailer_err ("temporary file write error: %s", mu_errstring (status)); + stream_destroy (&stream, stream_get_owner (stream)); + return status; } } if (buf && strchr (buf, '\n') == NULL) - putc ('\n', fp); - - putc ('\n', fp); + status = tmp_write (stream, &offset, newline, 1); + + status = tmp_write (stream, &offset, newline, 1); free (buf); + + if (status) + { + errno = status; + mailer_err ("temporary file write error: %s", mu_errstring (status)); + stream_destroy (&stream, stream_get_owner (stream)); + return status; + } + + if ((status = message_create (msg, NULL)) == 0) + status = message_set_stream (*msg, stream, NULL); - return fp; + if (status) + { + errno = status; + mailer_err ("temporary message creation error: %s", + mu_errstring (status)); + stream_destroy (&stream, stream_get_owner (stream)); + return status; + } + + return status; } void -deliver (FILE *fp, char *name) +deliver (message_t msg, char *name) { mailbox_t mbox; char *path; url_t url = NULL; - size_t n = 0; locker_t lock; struct mu_auth_data *auth; int status; - stream_t stream; + stream_t istream, ostream; size_t size; int failed = 0; #if defined(USE_DBM) @@ -582,12 +603,19 @@ deliver (FILE *fp, char *name) return; } - if (!sieve_test (auth)) + if (!sieve_test (auth, msg)) { exit_code = EX_OK; mu_auth_data_free (auth); return; } + + if ((status = message_get_stream (msg, &istream)) != 0) + { + mailer_err ("can't get input message stream: %s", mu_errstring (status)); + mu_auth_data_free (auth); + return; + } if ((status = mailbox_create (&mbox, auth->mailbox)) != 0) { @@ -629,7 +657,7 @@ deliver (FILE *fp, char *name) return; } - if ((status = mailbox_get_stream (mbox, &stream))) + if ((status = mailbox_get_stream (mbox, &ostream))) { mailer_err ("can't get stream for mailbox %s: %s", path, mu_errstring (status)); @@ -637,7 +665,7 @@ deliver (FILE *fp, char *name) return; } - if ((status = stream_size (stream, (off_t *) &size))) + if ((status = stream_size (ostream, (off_t *) &size))) { mailer_err ("can't get stream size (mailbox %s): %s", path, mu_errstring (status)); @@ -656,9 +684,10 @@ deliver (FILE *fp, char *name) case MQUOTA_UNLIMITED: break; default: - if (fstat (fileno (fp), &sb)) + if ((status = stream_size (istream, (off_t *) &isize))) { - mailer_err ("cannot stat tempfile: %s", strerror (errno)); + mailer_err ("can't get stream size (input message): %s", + path, mu_errstring (status)); exit_code = EX_UNAVAILABLE; failed++; } @@ -675,26 +704,46 @@ deliver (FILE *fp, char *name) if (!failed && switch_user_id (auth, 1) == 0) { + off_t ioff = 0; off_t off = size; - size_t nwr; + size_t nwr, nrd; char *buf = NULL; + size_t bufsize = 1024; - n = 0; - status = 0; - fseek (fp, 0, SEEK_SET); - while (getline(&buf, &n, fp) > 0) + stream_size (istream, (off_t *) &bufsize); + for (; (buf = malloc (bufsize)) == NULL && bufsize > 1; bufsize /= 2) + ; + + if (!buf) + { + status = errno = ENOMEM; + failed++; + } + else { - status = stream_write (stream, buf, strlen (buf), off, &nwr); - if (status) + status = 0; + + while ((status = stream_read (istream, buf, bufsize, ioff, &nrd)) + == 0 + && nrd > 0) { - mailer_err ("error writing to mailbox: %s", - mu_errstring (status)); - break; + status = stream_write (ostream, buf, nrd, off, &nwr); + if (status) + break; + ioff += nrd; + off += nwr; } - off += nwr; + + free (buf); } - free (buf); + switch_user_id (auth, 0); + + if (status) + { + mailer_err ("error writing to mailbox: %s", + mu_errstring (status)); + } } if (!failed) |