1 /* $OpenBSD: forward.c,v 1.20 2009/11/09 23:54:08 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 expandtree *expandtree) 39 { 40 FILE *fp; 41 struct alias alias; 42 char *buf, *lbuf, *p, *cp; 43 size_t len; 44 size_t nbaliases = 0; 45 int quoted; 46 struct expand_node expnode; 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 if (! alias_parse(&alias, buf)) { 88 log_debug("bad entry in ~/.forward"); 89 continue; 90 } 91 92 if (alias.type == EXPAND_INCLUDE) { 93 log_debug( 94 "includes are forbidden in ~/.forward"); 95 continue; 96 } 97 98 bzero(&expnode, sizeof(struct expand_node)); 99 alias_to_expand_node(&expnode, &alias); 100 expandtree_increment_node(expandtree, &expnode); 101 nbaliases++; 102 } while (*cp != '\0'); 103 } 104 free(lbuf); 105 fclose(fp); 106 return (nbaliases); 107 } 108