Annotation of embedaddon/strongswan/src/libfast/fast_smtp.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2010 Martin Willi
! 3: * Copyright (C) 2010 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "fast_smtp.h"
! 17:
! 18: #include <unistd.h>
! 19: #include <errno.h>
! 20:
! 21: #include <utils/debug.h>
! 22:
! 23: typedef struct private_fast_smtp_t private_fast_smtp_t;
! 24:
! 25: /**
! 26: * Private data of an fast_smtp_t object.
! 27: */
! 28: struct private_fast_smtp_t {
! 29:
! 30: /**
! 31: * Public fast_smtp_t interface.
! 32: */
! 33: fast_smtp_t public;
! 34:
! 35: /**
! 36: * file stream to SMTP server
! 37: */
! 38: FILE *f;
! 39: };
! 40:
! 41: /**
! 42: * Read the response code from an SMTP server
! 43: */
! 44: static int read_response(private_fast_smtp_t *this)
! 45: {
! 46: char buf[256], *end;
! 47: int res = 0;
! 48:
! 49: while (TRUE)
! 50: {
! 51: if (!fgets(buf, sizeof(buf), this->f))
! 52: {
! 53: return 0;
! 54: }
! 55: res = strtol(buf, &end, 10);
! 56: switch (*end)
! 57: {
! 58: case '-':
! 59: continue;
! 60: case ' ':
! 61: case '\0':
! 62: case '\n':
! 63: break;
! 64: default:
! 65: return 0;
! 66: }
! 67: break;
! 68: }
! 69: return res;
! 70: }
! 71:
! 72: /**
! 73: * write a SMTP command to the server, read response code
! 74: */
! 75: static int write_cmd(private_fast_smtp_t *this, char *fmt, ...)
! 76: {
! 77: char buf[256];
! 78: va_list args;
! 79:
! 80: va_start(args, fmt);
! 81: vsnprintf(buf, sizeof(buf), fmt, args);
! 82: va_end(args);
! 83:
! 84: if (fprintf(this->f, "%s\n", buf) < 1)
! 85: {
! 86: DBG1(DBG_LIB, "sending SMTP command failed");
! 87: return 0;
! 88: }
! 89: return read_response(this);
! 90: }
! 91:
! 92: METHOD(fast_smtp_t, send_mail, bool,
! 93: private_fast_smtp_t *this, char *from, char *to, char *subject, char *fmt, ...)
! 94: {
! 95: va_list args;
! 96:
! 97: if (write_cmd(this, "MAIL FROM:<%s>", from) != 250)
! 98: {
! 99: DBG1(DBG_LIB, "SMTP MAIL FROM failed");
! 100: return FALSE;
! 101: }
! 102: if (write_cmd(this, "RCPT TO:<%s>", to) != 250)
! 103: {
! 104: DBG1(DBG_LIB, "SMTP RCPT TO failed");
! 105: return FALSE;
! 106: }
! 107: if (write_cmd(this, "DATA") != 354)
! 108: {
! 109: DBG1(DBG_LIB, "SMTP DATA failed");
! 110: return FALSE;
! 111: }
! 112:
! 113: fprintf(this->f, "From: %s\n", from);
! 114: fprintf(this->f, "To: %s\n", to);
! 115: fprintf(this->f, "Subject: %s\n", subject);
! 116: fprintf(this->f, "\n");
! 117: va_start(args, fmt);
! 118: vfprintf(this->f, fmt, args);
! 119: va_end(args);
! 120: fprintf(this->f, "\n.\n");
! 121: return read_response(this) == 250;
! 122: }
! 123:
! 124:
! 125: METHOD(fast_smtp_t, destroy, void,
! 126: private_fast_smtp_t *this)
! 127: {
! 128: write_cmd(this, "QUIT");
! 129: fclose(this->f);
! 130: free(this);
! 131: }
! 132:
! 133: /**
! 134: * See header
! 135: */
! 136: fast_smtp_t *fast_smtp_create()
! 137: {
! 138: private_fast_smtp_t *this;
! 139: struct sockaddr_in addr = {
! 140: .sin_family = AF_INET,
! 141: .sin_port = htons(25),
! 142: .sin_addr = {
! 143: .s_addr = htonl(INADDR_LOOPBACK),
! 144: },
! 145: };
! 146: int s;
! 147:
! 148: INIT(this,
! 149: .public = {
! 150: .send_mail = _send_mail,
! 151: .destroy = _destroy,
! 152: },
! 153: );
! 154:
! 155: s = socket(AF_INET, SOCK_STREAM, 0);
! 156: if (s < 0)
! 157: {
! 158: DBG1(DBG_LIB, "opening SMTP socket failed: %s", strerror(errno));
! 159: free(this);
! 160: return NULL;
! 161: }
! 162: if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) < 0)
! 163: {
! 164: DBG1(DBG_LIB, "connecting to SMTP server failed: %s", strerror(errno));
! 165: close(s);
! 166: free(this);
! 167: return NULL;
! 168: }
! 169: this->f = fdopen(s, "a+");
! 170: if (!this->f)
! 171: {
! 172: DBG1(DBG_LIB, "opening stream to SMTP server failed: %s",
! 173: strerror(errno));
! 174: close(s);
! 175: free(this);
! 176: return NULL;
! 177: }
! 178: if (read_response(this) != 220 ||
! 179: write_cmd(this, "EHLO localhost") != 250)
! 180: {
! 181: DBG1(DBG_LIB, "SMTP EHLO failed");
! 182: fclose(this->f);
! 183: free(this);
! 184: return NULL;
! 185: }
! 186: return &this->public;
! 187: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>