a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
a20af62000-09-26Fredrik Hübinette (Hubbe) 
bb02cc1997-09-15Fredrik Hübinette (Hubbe) class protocol { // Maybe this should be the other way around?
5946a21998-04-29Fredrik Noring  inherit .NNTP.protocol;
bb02cc1997-09-15Fredrik Hübinette (Hubbe) } class client { inherit protocol;
cc1c0e1998-03-07Fredrik Noring  constant reply_codes = ([ 211:"System status, or system help reply", 214:"Help message", 220:"<host> Service ready", 221:"<host> Service closing transmission channel", 250:"Requested mail action okay, completed", 251:"User not local; will forward to <forward-path>", 354:"Start mail input; end with <CRLF>.<CRLF>", 421:"<host> Service not available, closing transmission channel " "[This may be a reply to any command if the service knows it " "must shut down]", 450:"Requested mail action not taken: mailbox unavailable " "[E.g., mailbox busy]", 451:"Requested action aborted: local error in processing", 452:"Requested action not taken: insufficient system storage", 500:"Syntax error, command unrecognized " "[This may include errors such as command line too long]", 501:"Syntax error in parameters or arguments", 502:"Command not implemented", 503:"Bad sequence of commands", 504:"Command parameter not implemented", 550:"Requested action not taken: mailbox unavailable " "[E.g., mailbox not found, no access]", 551:"User not local; please try <forward-path>", 552:"Requested mail action aborted: exceeded storage allocation", 553:"Requested action not taken: mailbox name not allowed " "[E.g., mailbox syntax incorrect]", 554:"Transaction failed" ]); static private int cmd(string c, string|void comment) { int r = command(c); switch(r) { case 200..399: break; default: throw(({"SMTP: "+c+"\n"+(comment?"SMTP: "+comment+"\n":"")+ "SMTP: "+reply_codes[r]+"\n", backtrace()})); } return r; }
98fe341998-05-26David Hedbor  void create(void|string server, int|void port)
bb02cc1997-09-15Fredrik Hübinette (Hubbe)  { if(!server) { // Lookup MX record here (Using DNS.pmod) object dns=master()->resolv("Protocols")["DNS"]->client(); server=dns->get_primary_mx(gethostname()); }
98fe341998-05-26David Hedbor  if(!port) port = 25;
c936351999-06-02Fredrik Noring  if(!server || !connect(server, port))
bb02cc1997-09-15Fredrik Hübinette (Hubbe)  {
5fcb231998-04-19Niels Möller  throw(({"Failed to connect to mail server.\n",backtrace()}));
bb02cc1997-09-15Fredrik Hübinette (Hubbe)  } if(readreturncode()/100 != 2) throw(({"Connection refused by SMTP server.\n",backtrace()}));
cc1c0e1998-03-07Fredrik Noring  if(catch(cmd("EHLO "+gethostname()))) cmd("HELO "+gethostname(), "greeting failed."); }
6b0af52000-02-18Martin Nilsson  void send_message(string from, array(string) to, string body)
cc1c0e1998-03-07Fredrik Noring  {
76cd3d1999-06-29Henrik Grubbström (Grubba)  cmd("MAIL FROM: <" + from + ">"); foreach(to, string t) { cmd("RCPT TO: <" + t + ">"); }
cc1c0e1998-03-07Fredrik Noring  cmd("DATA"); cmd(body+"\r\n."); cmd("QUIT");
bb02cc1997-09-15Fredrik Hübinette (Hubbe)  }
76cd3d1999-06-29Henrik Grubbström (Grubba)  static string parse_addr(string addr) {
8cd5331999-07-07Fredrik Hübinette (Hubbe)  array(string|int) tokens = replace(MIME.tokenize(addr), '@', "@");
76cd3d1999-06-29Henrik Grubbström (Grubba)  int i; tokens = tokens[search(tokens, '<') + 1..]; if ((i = search(tokens, '>')) != -1) { tokens = tokens[..i-1]; } return tokens*""; }
cc1c0e1998-03-07Fredrik Noring  void simple_mail(string to, string subject, string from, string msg)
bb02cc1997-09-15Fredrik Hübinette (Hubbe)  {
76cd3d1999-06-29Henrik Grubbström (Grubba)  send_message(parse_addr(from), ({ parse_addr(to) }),
baa6a61998-05-12Marcus Comstedt  (string)MIME.Message(msg, (["mime-version":"1.0", "subject":subject, "from":from, "to":to, "content-type": "text/plain;charset=iso-8859-1", "content-transfer-encoding": "8bit"])));
bb02cc1997-09-15Fredrik Hübinette (Hubbe)  }
1d1ac72000-05-18Mirar (Pontus Hagland)  array(int|string) verify(string addr) { return ({command("VRFY "+addr),rest}); }
bb02cc1997-09-15Fredrik Hübinette (Hubbe) }