/* * Copyright (c) 2004 David Parsons. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * * This product includes software developed by David Parsons * (orc@pell.chi.il.us) * * 4. My name may not be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY DAVID PARSONS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID * PARSONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * The licence and distribution terms for any publically available * version or derivative of this code cannot be changed. i.e. this * code cannot simply be copied and put under another distribution * licence [including the GNU Public Licence.] */ #include #include #include #include #include #include #include "smtp.h" say(char *fmt, ...) { int written; va_list ptr; va_start(ptr, fmt); written = vfprintf(stderr, fmt, ptr); va_end(ptr); putc('\n', stderr); } void chat(SMTP *srv, int wanted, char *fmt, ...) { static char bfr[2000]; va_list ptr; int ret; va_start(ptr, fmt); vsprintf(bfr, fmt, ptr); va_end(ptr); nwriteline(srv, bfr); if ( ((ret=nreply(srv))/100) != wanted) { say("Access denied (%d).", ret); nfree(srv); exit(1); } } extern int getopt(); extern char *optarg; extern int optind; extern int opterr; main(int argc, char **argv) { SMTP *f; int opt, code, eof; char *server = "localhost"; char *domain = 0; char *from; char *data; char *host; int d_flag = 0, v_flag = 0; struct passwd *me = getpwuid(getuid()); struct utsname sys; if (me == 0) { fprintf(stderr, "forward: Who Are You?\n"); exit(1); } from = strdup(me->pw_name); opterr = 1; while ( (opt = getopt(argc, argv, "dVD:S:o:f:")) != EOF) { switch (opt) { case 'S': server = optarg; break; case 'D': domain = optarg; break; case 'd': d_flag = 1; break; case 'V': v_flag = 1; break; case 'o': break; case 'f': free(from); from = optarg; break; default: say("Usage: forward -D -S -f -V -o TO [...]"); exit(1); } } if (d_flag) { fprintf(stderr, "["); for (opt=0; opt < argc; opt++) fprintf(stderr, " %s", argv[opt]); fprintf(stderr, " ]\n"); } argc -= optind; argv += optind; if (argc < 1) { say("Usage: forward -D -S -f -V -o TO [...]"); exit(1); } unless (f = smtp(server)) exit(1); if (d_flag) setndbg(f); if (v_flag) setnverbose(f); code = nreply(f); unless ( (code/100) == 2) { say("Access denied(%d).", code); exit(1); } host = "localhost"; if (uname(&sys) > 0) { if (strlen(sys.nodename) > 0) host = sys.nodename; else if (strlen(sys.sysname) > 0) host = sys.sysname; } chat(f, 2, "HELO %s", host); if ( (domain == 0) || strchr(from, '@') != 0) chat(f, 2, "MAIL FROM: <%s>", from); else chat(f, 2, "MAIL FROM: <%s@%s>", from, domain); for (opt = 0; opt < argc; opt++) if ((domain == 0) || strchr(argv[opt], '@') != 0) chat(f, 2, "RCPT TO: <%s>", argv[opt]); else chat(f, 2, "RCPT TO: <%s@%s>", argv[opt], domain); chat(f, 3, "DATA"); while ( (data = readline(0, &eof)) && (eof == 0) ) { if (strcmp(data, ".") == 0) nwriteline(f, ".."); else nwriteline(f, data); } if (data == 0) { /* oops */ nfree(f); exit(1); } chat(f, 2, "."); exit(0); }