/***********************************************************************1* *2* This software is part of the BSD package *3*Copyright (c) 1978-2006 The Regents of the University of California an*4* *5* Redistribution and use in source and binary forms, with or *6* without modification, are permitted provided that the following *7* conditions are met: *8* *9* 1. Redistributions of source code must retain the above *10* copyright notice, this list of conditions and the *11* following disclaimer. *12* *13* 2. Redistributions in binary form must reproduce the above *14* copyright notice, this list of conditions and the *15* following disclaimer in the documentation and/or other *16* materials provided with the distribution. *17* *18* 3. Neither the name of The Regents of the University of California*19* names of its contributors may be used to endorse or *20* promote products derived from this software without *21* specific prior written permission. *22* *23* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *24* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *25* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *26* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *27* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS *28* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *29* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *30* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *31* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *32* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *33* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *34* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *35* POSSIBILITY OF SUCH DAMAGE. *36* *37* Redistribution and use in source and binary forms, with or without *38* modification, are permitted provided that the following conditions *39* are met: *40* 1. Redistributions of source code must retain the above copyright *41* notice, this list of conditions and the following disclaimer. *42* 2. Redistributions in binary form must reproduce the above copyright *43* notice, this list of conditions and the following disclaimer in *44* the documentation and/or other materials provided with the *45* distribution. *46* 3. Neither the name of the University nor the names of its *47* contributors may be used to endorse or promote products derived *48* from this software without specific prior written permission. *49* *50* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" *51* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *52* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *53* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS *54* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *55* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *56* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *57* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *58* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *59* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *60* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *61* SUCH DAMAGE. *62* *63* Kurt Shoens (UCB) *64* gsf *65* *66***********************************************************************/67#pragma prototyped68/*69* IMAP client70*71* Glenn Fowler72* AT&T Research73*/7475#include "mailx.h"7677#if _PACKAGE_ast7879#include <css.h>80#include <tm.h>8182#define SMTP_READY 22083#define SMTP_OK 25084#define SMTP_START 35485#define SMTP_CLOSE 2218687/*88* send the message in fp to the SMTP server on host89* for recipients argv ...90* if original!=0 then it is the size of the message91* and the original sender is retrived from the92* message and preserved93*/9495int96sendsmtp(Sfio_t* fp, char* host, char** argv, off_t original)97{98register char* s;99register char* t;100char* e;101int n;102int fd;103int r;104off_t z;105Sfio_t* sp;106Sfio_t* rp;107char buf[PATH_MAX];108char svc[PATH_MAX];109110/*111* connect to the service112*/113114sfsprintf(svc, sizeof(svc), "/dev/tcp/%s/inet.smtp", host);115if ((fd = csopen(&cs, svc, 0)) < 0)116{117note(SYSTEM, "smtp: %s: cannot connect to service", svc);118return -1;119}120if (!(sp = sfnew(NiL, NiL, SF_UNBOUND, fd, SF_WRITE)) ||121!(rp = sfnew(NiL, NiL, SF_UNBOUND, fd, SF_READ)))122{123if (sp)124sfclose(sp);125else126close(fd);127note(SYSTEM, "smtp: %s: cannot buffer service", svc);128return -1;129}130131/*132* verify133*/134135do136{137if (!(s = sfgetr(rp, '\n', 1)))138goto bad_recv;139if (strtol(s, &e, 10) != SMTP_READY)140goto bad_prot;141} while (*e == '-');142143/*144* identify145*/146147if (!(s = state.var.domain) || !*s)148s = state.var.hostname;149if (sfprintf(sp, "HELO %s\r\n", s) < 0)150goto bad_send;151do152{153if (!(s = sfgetr(rp, '\n', 1)))154goto bad_recv;155if (strtol(s, &e, 10) != SMTP_OK)156goto bad_prot;157} while (*(unsigned char*)e == SMTP_OK);158159/*160* from161*/162163if (original)164{165if (!(s = sfgetr(fp, '\n', 1)) || !strneq(s, "From ", 5))166goto bad_mesg;167for (s += 5; isspace(*s); s++);168for (t = s; *t && !isspace(*t); t++);169if (!(n = t - s))170goto bad_mesg;171z = sfvalue(fp);172if (sfprintf(sp, "MAIL FROM:<%*.*s>\r\n", n, n, s) < 0)173goto bad_send;174}175else176{177z = 0;178if ((state.var.domain ?179sfprintf(sp, "MAIL FROM:<%s@%s>\r\n", state.var.user, state.var.domain) :180sfprintf(sp, "MAIL FROM:<%s>\r\n", state.var.user)) < 0)181goto bad_send;182}183do184{185if (!(s = sfgetr(rp, '\n', 1)))186goto bad_recv;187if (strtol(s, &e, 10) != SMTP_OK)188goto bad_prot;189} while (*e == '-');190191/*192* to193*/194195while (s = *argv++)196{197if ((state.var.domain && !strchr(s, '@') ?198sfprintf(sp, "RCPT TO:<%s@%s>\r\n", s, state.var.domain) :199sfprintf(sp, "RCPT TO:<%s>\r\n", s)) < 0)200goto bad_send;201do202{203if (!(s = sfgetr(rp, '\n', 1)))204goto bad_recv;205if (strtol(s, &e, 10) != SMTP_OK)206goto bad_prot;207} while (*e == '-');208}209210/*211* body212*/213214if (sfprintf(sp, "DATA\r\n") < 0)215goto bad_send;216do217{218if (!(s = sfgetr(rp, '\n', 1)))219goto bad_recv;220if (strtol(s, &e, 10) != SMTP_START)221goto bad_prot;222} while (*e == '-');223tmfmt(buf, sizeof(buf), "%+uDate: %a, %d %b %Y %H:%M:%S UT", NiL);224if (sfputr(sp, buf, '\n') < 0)225goto bad_send;226if (sfprintf(sp, "From: <%s@%s>\n", state.var.user, host) < 0)227goto bad_send;228while (s = sfgetr(fp, '\n', 1))229{230if (sfprintf(sp, "%s%s\r\n", *s == '.' ? "." : "", s) < 0)231goto bad_send;232if (original && (z += sfvalue(fp)) >= original)233break;234}235if (sfprintf(sp, ".\r\n") < 0)236goto bad_send;237do238{239if (!(s = sfgetr(rp, '\n', 1)))240goto bad_recv;241if (strtol(s, &e, 10) != SMTP_OK)242goto bad_prot;243} while (*e == '-');244245/*246* quit247*/248249if (sfprintf(sp, "QUIT\r\n") < 0)250goto bad_send;251do252{253if (!(s = sfgetr(rp, '\n', 1)))254goto bad_recv;255if (strtol(s, &e, 10) != SMTP_CLOSE)256goto bad_prot;257} while (*e == '-');258r = 0;259goto done;260bad_mesg:261note(0, "smtp: bad message -- no From header");262goto bad;263bad_prot:264if ((n = strlen(e)) > 0 && e[n - 1] == '\r')265e[n - 1] = 0;266note(0, "smtp: %s: service error:%s", svc, e);267goto bad;268bad_send:269note(SYSTEM, "smtp: %s: service write error", svc);270goto bad;271bad_recv:272note(SYSTEM, "smtp: %s: service read error", svc);273bad:274r = -1;275done:276sfclose(sp);277sfclose(rp);278return r;279}280281#else282283int284sendsmtp(FILE* fp, char** argv)285{286note(0, "smtp: support not enabled");287return -1;288}289290#endif291292293