1 /* $OpenBSD: forward.c,v 1.14 2009/08/08 00:02:22 gilles Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/tree.h> 22 #include <sys/param.h> 23 #include <sys/socket.h> 24 #include <sys/stat.h> 25 26 #include <ctype.h> 27 #include <errno.h> 28 #include <event.h> 29 #include <pwd.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <unistd.h> 34 35 #include "smtpd.h" 36 37 int 38 forwards_get(int fd, struct aliaseslist *aliases) 39 { 40 FILE *fp; 41 struct alias alias; 42 struct alias *aliasp; 43 char *buf, *lbuf, *p, *cp; 44 size_t len; 45 size_t nbaliases = 0; 46 int quoted; 47 48 fp = fdopen(fd, "r"); 49 if (fp == NULL) 50 return 0; 51 52 lbuf = NULL; 53 while ((buf = fgetln(fp, &len))) { 54 if (buf[len - 1] == '\n') 55 buf[len - 1] = '\0'; 56 else { 57 /* EOF without EOL, copy and add the NUL */ 58 if ((lbuf = malloc(len + 1)) == NULL) 59 fatal("malloc"); 60 memcpy(lbuf, buf, len); 61 lbuf[len] = '\0'; 62 buf = lbuf; 63 } 64 65 /* ignore empty lines and comments */ 66 if (buf[0] == '#' || buf[0] == '\0') 67 continue; 68 69 quoted = 0; 70 cp = buf; 71 do { 72 /* skip whitespace */ 73 while (isspace((int)*cp)) 74 cp++; 75 76 /* parse line */ 77 for (p = cp; *p != '\0'; p++) { 78 if (*p == ',' && !quoted) { 79 *p++ = '\0'; 80 break; 81 } else if (*p == '"') 82 quoted = !quoted; 83 } 84 buf = cp; 85 cp = p; 86 87 log_debug("\tforward: %s", buf); 88 if (! alias_parse(&alias, buf)) { 89 log_debug("bad entry in ~/.forward"); 90 continue; 91 } 92 93 if (alias.type == ALIAS_INCLUDE) { 94 log_debug( 95 "includes are forbidden in ~/.forward"); 96 continue; 97 } 98 99 aliasp = calloc(1, sizeof(struct alias)); 100 if (aliasp == NULL) 101 fatal("calloc"); 102 *aliasp = alias; 103 TAILQ_INSERT_HEAD(aliases, aliasp, entry); 104 nbaliases++; 105 } while (*cp != '\0'); 106 } 107 free(lbuf); 108 fclose(fp); 109 return (nbaliases); 110 } 111