summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jrfonseca@users.sourceforge.net>2003-07-03 18:25:53 +0000
committerJosé Fonseca <jrfonseca@users.sourceforge.net>2003-07-03 18:25:53 +0000
commit15ff73b9843c79c1709f4a521aaa09285105f8bc (patch)
tree207ebddf035d06172746ef77695f4c3de64f357f
parent2867d16bc9bae9764904efbf44cd5131fca1bc9b (diff)
Exit with an error code immediately whenever an error.
Extensive use of xmalloc and friends.
-rw-r--r--lexer.l46
-rw-r--r--local.c59
-rw-r--r--local.h4
-rw-r--r--main.c54
-rw-r--r--message.c116
-rw-r--r--message.h6
-rw-r--r--parser.y13
-rw-r--r--rfc822.c21
-rw-r--r--smtp.c18
-rw-r--r--smtp.h4
-rw-r--r--xmalloc.h56
11 files changed, 172 insertions, 225 deletions
diff --git a/lexer.l b/lexer.l
index a0d2c94..d655807 100644
--- a/lexer.l
+++ b/lexer.l
@@ -1,22 +1,22 @@
%{
-/*
- * lexer.l -- lexer for the rcfile
+/**
+ * \file lexer.l
+ * Lexer for the rcfile.
+ *
+ * \author Adapted from fetchmail's rcfile_l.l by José Fonseca
*/
-/*
- * Adapted from fetchmail's rcfile_l.l by José Fonseca
- */
-
+
#include <stdio.h>
#include <string.h>
#include "parser.h"
+#include "xmalloc.h"
-#define MSGBUFSIZE 8192
int lineno = 1;
-void escapes(const char *tp, char *cp);
+void escapes(const char *tp, char *cp, size_t n);
%}
@@ -25,29 +25,29 @@ void escapes(const char *tp, char *cp);
%%
\"[^\"]*\" {
- char buf[MSGBUFSIZE];
+ char buf[BUFSIZ];
yytext[strlen(yytext)-1] = '\0';
- escapes(yytext+1, buf);
- yylval.sval = (char *) strdup(buf);
+ escapes(yytext+1, buf, BUFSIZ);
+ yylval.sval = xstrdup(buf);
BEGIN(0);
return STRING;
}
\'[^\']*\' {
- char buf[MSGBUFSIZE];
+ char buf[BUFSIZ];
yytext[strlen(yytext)-1] = '\0';
- escapes(yytext+1, buf);
- yylval.sval = (char *) strdup(buf);
+ escapes(yytext+1, buf, BUFSIZ);
+ yylval.sval = xstrdup(buf);
BEGIN(0);
return STRING;
}
<NAME>[^=;, \t\r\n]+ {
- char buf[MSGBUFSIZE];
+ char buf[BUFSIZ];
- escapes(yytext, buf);
- yylval.sval = (char *) strdup(buf);
+ escapes(yytext, buf, BUFSIZ);
+ yylval.sval = xstrdup(buf);
BEGIN(0);
return STRING;
}
@@ -73,10 +73,10 @@ required { return REQUIRED; }
-?[0-9]+/[^a-zA-Z] { yylval.number = atoi(yytext); return NUMBER; }
[^=;:, \t\r\n]+ {
- char buf[MSGBUFSIZE];
+ char buf[BUFSIZ];
- escapes(yytext, buf);
- yylval.sval = (char *) strdup(buf);
+ escapes(yytext, buf, BUFSIZ);
+ yylval.sval = xstrdup(buf);
return STRING;
}
@@ -87,10 +87,11 @@ required { return REQUIRED; }
/* process standard C-style escape sequences in a string */
void escapes(
const char *cp, /* source string with escapes */
- char *tp /* target buffer for digested string */
+ char *tp, /* target buffer for digested string */
+ size_t n
)
{
- while (*cp)
+ while (*cp && --n)
{
int cval = 0;
@@ -126,6 +127,7 @@ void escapes(
else
cval = *cp++;
*tp++ = cval;
+
}
*tp = '\0';
}
diff --git a/local.c b/local.c
index da66ddf..eadfa3a 100644
--- a/local.c
+++ b/local.c
@@ -12,6 +12,7 @@
#include "local.h"
#include "main.h"
+#include "xmalloc.h"
#if 0
@@ -37,29 +38,24 @@ static void sanitize(char *s)
*cp = '_';
}
-#define xmalloc malloc
-#define xstrdup strdup
-
-#define HAVE_SETEUID
/**
* Pipe the message to the MDA for local delivery.
*
* Based on fetchmail's open_mda_sink().
*/
-int local_init(message_t *message)
+void local_init(message_t *message)
{
-#ifdef HAVE_SETEUID
- uid_t orig_uid, uid;
- struct passwd *pw;
-#endif /* HAVE_SETEUID */
struct idlist *idp;
int length = 0, fromlen = 0, nameslen = 0;
char *names = NULL, *before, *after, *from = NULL;
char *user = NULL;
if (!mda)
- return 1;
+ {
+ fprintf(stderr, "local delivery not possible without a MDA");
+ exit(EX_OSFILE);
+ }
length = strlen(mda);
before = xstrdup(mda);
@@ -172,46 +168,20 @@ int local_init(message_t *message)
before = after;
}
-#ifdef HAVE_SETEUID
- /*
- * Arrange to run with user's permissions if we're root.
- * This will initialize the ownership of any files the
- * MDA creates properly. (The seteuid call is available
- * under all BSDs and Linux)
- */
- orig_uid = getuid();
- /* if `user' doesn't name a real local user, try to run as root */
- if ((pw = getpwnam(user)) == (struct passwd *)NULL)
- uid = 0;
- else
- uid = pw->pw_uid; /* for local delivery via MDA */
- seteuid(uid);
-#endif /* HAVE_SETEUID */
-
- mda_fp = popen(before, "w");
-
-#ifdef HAVE_SETEUID
- /* this will fail quietly if we didn't start as root */
- seteuid(orig_uid);
-#endif /* HAVE_SETEUID */
-
- if (!mda_fp)
+
+ if(!(mda_fp = popen(before, "w")))
{
- free(before);
- before = NULL;
fprintf(stderr, "MDA open failed\n");
- return 0;
+ exit(EX_OSERR);
}
-
+
if(verbose)
fprintf(stdout, "Connected to MDA: %s\n", before);
free(before);
- before = NULL;
- return 1;
}
-int local_flush(message_t *message)
+void local_flush(message_t *message)
{
char buffer[BUFSIZ];
size_t n;
@@ -219,10 +189,11 @@ int local_flush(message_t *message)
do {
n = message_read(message, buffer, BUFSIZ);
if(fwrite(buffer, 1, n, mda_fp) != n)
- return 0;
+ {
+ perror(NULL);
+ exit(EX_OSERR);
+ }
} while(n == BUFSIZ);
-
- return 1;
}
void local_cleanup(void)
diff --git a/local.h b/local.h
index 7ce218d..726364a 100644
--- a/local.h
+++ b/local.h
@@ -19,9 +19,9 @@ extern FILE *mda_fp;
int local_address(const char *address);
/** Send a message locally (via a MDA) */
-int local_init(message_t *msg);
+void local_init(message_t *msg);
-int local_flush(message_t *msg);
+void local_flush(message_t *msg);
void local_cleanup(void);
diff --git a/main.c b/main.c
index eddda54..2188542 100644
--- a/main.c
+++ b/main.c
@@ -23,7 +23,6 @@ FILE *log_fp = NULL;
int main (int argc, char **argv)
{
int c;
- int ret;
enum notify_flags notify = Notify_NOTSET;
char *from = NULL;
message_t *message;
@@ -298,73 +297,54 @@ int main (int argc, char **argv)
exit (EX_USAGE);
}
- if(!(message = message_new()))
- goto error;
+ message = message_new();
/** Parse the envelope headers */
if(parse_headers)
- {
if(!message_parse_headers(message))
{
- fprintf(stderr, "Failed to parse headers\n");
- exit(EX_DATAERR);
- }
-
- if(!remote && !local)
- {
fprintf(stderr, "No recipients found\n");
exit(EX_DATAERR);
}
- }
/* Set the reverse path for the mail envelope. */
- if(from && !message_set_reverse_path (message, from))
- goto error;
+ if(from)
+ message_set_reverse_path (message, from);
/* Add remaining program arguments as message recipients. */
- while (optind < argc) {
- if(!message_add_recipient(message, argv[optind++]))
- goto error;
- }
+ while (optind < argc)
+ message_add_recipient(message, argv[optind++]);
local = !list_empty(&message->local_recipients);
remote = !list_empty(&message->remote_recipients);
if(remote && !local)
- ret = smtp_send(message);
+ smtp_send(message);
else if(!remote && local)
{
- if(!local_init(message))
- goto error;
-
- if(!local_flush(message))
- goto error;
-
+ local_init(message);
+ local_flush(message);
local_cleanup();
-
- ret = 0;
}
else
{
- if(!local_init(message))
- goto error;
+ local_init(message);
- ret = smtp_send(message);
+ smtp_send(message);
if(ferror(mda_fp))
- goto error;
+ {
+ perror(NULL);
+ exit(EX_OSERR);
+ }
- if(!message_eof(message) && !local_flush(message))
- goto error;
+ if(!message_eof(message))
+ local_flush(message);
local_cleanup();
}
message_free(message);
- return ret;
-
-error:
- perror(NULL);
- exit(255);
+ exit(EX_OK);
}
diff --git a/message.c b/message.c
index 0454192..1513691 100644
--- a/message.c
+++ b/message.c
@@ -14,14 +14,14 @@
#include "message.h"
#include "local.h"
#include "rfc822.h"
+#include "xmalloc.h"
message_t *message_new(void)
{
message_t *message;
- if(!(message = (message_t *)malloc(sizeof(message_t))))
- return NULL;
+ message = (message_t *)xmalloc(sizeof(message_t));
memset(message, 0, sizeof(message_t));
@@ -71,39 +71,29 @@ void message_free(message_t *message)
free(message);
}
-int message_set_reverse_path(message_t *message, const char *address)
+void message_set_reverse_path(message_t *message, const char *address)
{
if(message->reverse_path)
free(message->reverse_path);
- if(!(message->reverse_path = strdup(address)))
- return 0;
-
- return 1;
+ message->reverse_path = xstrdup(address);
}
-int message_add_recipient(message_t *message, const char *address)
+void message_add_recipient(message_t *message, const char *address)
{
recipient_t *recipient;
- if(!(recipient = (recipient_t *)malloc(sizeof(recipient_t))))
- return 0;
+ recipient = (recipient_t *)xmalloc(sizeof(recipient_t));
- if(!(recipient->address = strdup(address)))
- {
- free(recipient);
- return 0;
- }
+ recipient->address = xstrdup(address);
if(local_address(address))
list_add(&recipient->list, &message->local_recipients);
else
list_add(&recipient->list, &message->remote_recipients);
-
- return 1;
}
-static int message_buffer_alloc(message_t *message)
+static void message_buffer_alloc(message_t *message)
{
char *buffer;
size_t buffer_size;
@@ -113,13 +103,10 @@ static int message_buffer_alloc(message_t *message)
else
buffer_size = message->buffer_size << 1;
- if(!(buffer = (char *)realloc(message->buffer, buffer_size)))
- return 0;
+ buffer = (char *)xrealloc(message->buffer, buffer_size);
message->buffer = buffer;
message->buffer_size = buffer_size;
-
- return 1;
}
static char *message_buffer_readline(message_t *message)
@@ -129,8 +116,8 @@ static char *message_buffer_readline(message_t *message)
while(1)
{
- if(message->buffer_stop >= message->buffer_size - 1 && !message_buffer_alloc(message))
- return NULL;
+ if(message->buffer_stop >= message->buffer_size - 1)
+ message_buffer_alloc(message);
if(!fgets(message->buffer + message->buffer_stop, message->buffer_size - message->buffer_stop, fp))
return NULL;
@@ -218,8 +205,8 @@ size_t message_read(message_t *message, char *ptr, size_t size)
{
size_t count = 0, n;
- if(!message->buffer && !message_buffer_alloc(message))
- return 0;
+ if(!message->buffer)
+ message_buffer_alloc(message);
n = message_buffer_flush(message, ptr, size);
count += n;
@@ -259,8 +246,9 @@ int message_eof(message_t *message)
return feof(fp);
}
-static int message_parse_header(message_t *message, size_t start, size_t stop)
+static unsigned message_parse_header(message_t *message, size_t start, size_t stop)
{
+ unsigned count = 0;
const char *address;
char *header, *next, c;
@@ -273,8 +261,10 @@ static int message_parse_header(message_t *message, size_t start, size_t stop)
if(!strncasecmp("From: ", header, 6))
{
if((address = next_address(header)))
- if(!message_set_reverse_path(message, address))
- return 0;
+ {
+ message_set_reverse_path(message, address);
+ count++;
+ }
}
else if(!strncasecmp("To: ", header, 4) ||
!strncasecmp("Cc: ", header, 4) ||
@@ -283,8 +273,8 @@ static int message_parse_header(message_t *message, size_t start, size_t stop)
address = next_address(header);
while(address)
{
- if(!message_add_recipient(message, address))
- return 0;
+ message_add_recipient(message, address);
+ count++;
address = next_address(NULL);
}
@@ -301,19 +291,19 @@ static int message_parse_header(message_t *message, size_t start, size_t stop)
message->buffer_stop = start + n;
}
- return 1;
+ return count;
}
-int message_parse_headers(message_t *message)
+unsigned message_parse_headers(message_t *message)
{
FILE *fp = message->fp ? message->fp : stdin;
char *line, *header;
size_t start, stop;
+ unsigned count = 0;
assert(!message->buffer);
- if(!message_buffer_alloc(message))
- return 0;
+ message_buffer_alloc(message);
start = 0;
while((line = message_buffer_readline(message)))
@@ -325,62 +315,16 @@ int message_parse_headers(message_t *message)
else
{
stop = line - message->buffer;
- if(stop && !message_parse_header(message, start, stop))
- return 0;
+ if(stop)
+ count += message_parse_header(message, start, stop);
start = stop;
if(line[0] == '\n')
- return 1;
+ return count;
}
}
- return 0;
-}
-
-#ifdef TEST
-int local_address(const char *address)
-{
- return !strchr(address, '@');
-}
-
-int main(int argc, char *argv[])
-{
- message_t *message = message_new();
- const size_t len = 8192;
- size_t n;
- char buf[len];
- unsigned i;
- FILE *fpin, *fpout;
- struct list_head *ptr;
- int ret;
-
- fpin = fopen("test.in", "r");
- fpout = fopen("test.out", "w");
- message->fp = fpin;
- ret = message_parse_headers(message);
- do {
- n = message_read(message, buf, len);
- fwrite(buf, 1, n, fpout);
- } while(n == len);
-
- printf("%d %s\n", ret, message->reverse_path);
- list_for_each(ptr, &message->local_recipients)
- {
- recipient_t *recipient = list_entry(ptr, recipient_t, list);
-
- if(recipient->address)
- printf("%s\n",recipient->address);
- }
- list_for_each(ptr, &message->remote_recipients)
- {
- recipient_t *recipient = list_entry(ptr, recipient_t, list);
-
- if(recipient->address)
- printf("%s\n",recipient->address);
- }
-
- message_free(message);
+ fprintf(stderr, "Failed to parse headers\n");
+ exit(EX_DATAERR);
}
-
-#endif
diff --git a/message.h b/message.h
index 5977be6..52aba01 100644
--- a/message.h
+++ b/message.h
@@ -49,11 +49,11 @@ message_t *message_new(void);
/** Free the resources associated with a message. */
void message_free(message_t *m);
-int message_set_reverse_path(message_t *message, const char *address);
+void message_set_reverse_path(message_t *message, const char *address);
-int message_add_recipient(message_t *message, const char *address);
+void message_add_recipient(message_t *message, const char *address);
-int message_parse_headers(message_t *message);
+unsigned message_parse_headers(message_t *message);
size_t message_read(message_t *message, char *ptr, size_t size);
diff --git a/parser.y b/parser.y
index f142e75..fa786ec 100644
--- a/parser.y
+++ b/parser.y
@@ -17,6 +17,7 @@
#include "main.h"
#include "smtp.h"
#include "local.h"
+#include "xmalloc.h"
/* parser reads these */
@@ -69,7 +70,7 @@ identity : IDENTITY map STRING
{
identity = identity_new();
identity_add(identity);
- identity->address = strdup($3);
+ identity->address = xstrdup($3);
}
;
@@ -78,14 +79,14 @@ statement_list : statement
;
/* future global options should also have the form SET <name> optmap <value> */
-statement : HOSTNAME map STRING { identity->host = strdup($3); }
- | USERNAME map STRING { identity->user = strdup($3); }
- | PASSWORD map STRING { identity->pass = strdup($3); }
+statement : HOSTNAME map STRING { identity->host = xstrdup($3); }
+ | USERNAME map STRING { identity->user = xstrdup($3); }
+ | PASSWORD map STRING { identity->pass = xstrdup($3); }
| STARTTLS map DISABLED { identity->starttls = Starttls_DISABLED; }
| STARTTLS map ENABLED { identity->starttls = Starttls_ENABLED; }
| STARTTLS map REQUIRED { identity->starttls = Starttls_REQUIRED; }
- | CERTIFICATE_PASSPHRASE map STRING { identity->certificate_passphrase = strdup($3); }
- | MDA map STRING { mda = strdup($3); }
+ | CERTIFICATE_PASSPHRASE map STRING { identity->certificate_passphrase = xstrdup($3); }
+ | MDA map STRING { mda = xstrdup($3); }
;
%%
diff --git a/rfc822.c b/rfc822.c
index 5f1cac8..0035ad2 100644
--- a/rfc822.c
+++ b/rfc822.c
@@ -19,14 +19,17 @@
#include <stdlib.h>
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
#define HEADER_END(p) ((p)[0] == '\n' && ((p)[1] != ' ' && (p)[1] != '\t'))
+#define START_HDR 0 /**< before header colon */
+#define SKIP_JUNK 1 /**< skip whitespace, \n, and junk */
+#define BARE_ADDRESS 2 /**< collecting address without delimiters */
+#define INSIDE_DQUOTE 3 /**< inside double quotes */
+#define INSIDE_PARENS 4 /**< inside parentheses */
+#define INSIDE_BRACKETS 5 /**< inside bracketed address */
+#define ENDIT_ALL 6 /**< after last address */
+
/**
* Parse addresses in succession out of a specified RFC822 header.
*
@@ -40,14 +43,6 @@ char *next_address(const char *hdr)
static int state, oldstate;
int parendepth = 0;
-#define START_HDR 0 /* before header colon */
-#define SKIP_JUNK 1 /* skip whitespace, \n, and junk */
-#define BARE_ADDRESS 2 /* collecting address without delimiters */
-#define INSIDE_DQUOTE 3 /* inside double quotes */
-#define INSIDE_PARENS 4 /* inside parentheses */
-#define INSIDE_BRACKETS 5 /* inside bracketed address */
-#define ENDIT_ALL 6 /* after last address */
-
#define NEXTTP() ((tp < sizeof(address)-1) ? tp++ : tp)
if (hdr)
diff --git a/smtp.c b/smtp.c
index 7f472e1..e71b5cd 100644
--- a/smtp.c
+++ b/smtp.c
@@ -20,6 +20,7 @@
#include "smtp.h"
#include "local.h"
#include "main.h"
+#include "xmalloc.h"
/**
@@ -35,8 +36,7 @@ identity_t *identity_new(void)
{
identity_t *identity;
- if(!(identity = (identity_t *)malloc(sizeof(identity_t))))
- return NULL;
+ identity = (identity_t *)xmalloc(sizeof(identity_t));
memset(identity, 0, sizeof(identity_t));
@@ -89,12 +89,9 @@ identity_t *identity_lookup(const char *address)
return default_identity;
}
-int identities_init(void)
+void identities_init(void)
{
- if(!(default_identity = identity_new()))
- return 0;
-
- return 1;
+ default_identity = identity_new();
}
void identities_cleanup(void)
@@ -306,7 +303,7 @@ void print_recipient_status (smtp_recipient_t recipient, const char *mailbox,
fprintf (stderr, "%s: %d %s\n", mailbox, status->code, status->text);
}
-int smtp_send(message_t *msg)
+void smtp_send(message_t *msg)
{
smtp_session_t session;
smtp_message_t message;
@@ -403,7 +400,7 @@ int smtp_send(message_t *msg)
char buf[128];
fprintf (stderr, "SMTP server problem %s\n",
- smtp_strerror (smtp_errno (), buf, sizeof buf));
+ smtp_strerror (smtp_errno (), buf, sizeof(buf)));
ret = EX_UNAVAILABLE;
}
@@ -431,7 +428,8 @@ int smtp_send(message_t *msg)
auth_destroy_context (authctx);
auth_client_exit ();
- return ret;
+ if (ret != EX_OK)
+ exit(ret);
}
/*@}*/
diff --git a/smtp.h b/smtp.h
index da18bc6..233c078 100644
--- a/smtp.h
+++ b/smtp.h
@@ -45,7 +45,7 @@ void identity_add(identity_t *identity);
identity_t *identity_lookup(const char *address);
/** Initialize the identities resources */
-int identities_init(void);
+void identities_init(void);
/** Cleanup the resources associated with the identities */
void identities_cleanup(void);
@@ -54,6 +54,6 @@ void identities_cleanup(void);
/** Send a message via a SMTP server */
-int smtp_send(message_t *msg);
+void smtp_send(message_t *msg);
#endif
diff --git a/xmalloc.h b/xmalloc.h
new file mode 100644
index 0000000..881bcad
--- /dev/null
+++ b/xmalloc.h
@@ -0,0 +1,56 @@
+/**
+ * \file xmalloc.c
+ * Allocate space or die.
+ *
+ * \author Adapted from fetchmail's xmalloc.c by José Fonseca.
+ */
+
+#ifndef _XMALLOC_H
+#define _XMALLOC_H
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "main.h"
+
+
+static inline
+void *xmalloc(size_t size)
+{
+ void *ptr;
+
+ ptr = malloc(size);
+ if (ptr == NULL)
+ {
+ perror(NULL);
+ exit(EX_OSERR);
+ }
+ return(ptr);
+}
+
+static inline
+void *xrealloc(void *ptr, size_t size)
+{
+ if (ptr == 0)
+ return xmalloc(size);
+ ptr = realloc(ptr, size);
+ if (ptr == NULL)
+ {
+ perror(NULL);
+ exit(EX_OSERR);
+ }
+ return ptr;
+}
+
+static inline
+char *xstrdup(const char *s)
+{
+ char *p;
+ p = (char *)xmalloc(strlen(s) + 1);
+ strcpy(p, s);
+ return p;
+}
+
+#endif