⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mail2.c

📁 嵌入式linux下液晶编程院代码, 可以在LINUX2.4内核下运行
💻 C
字号:
/* $Id: mail2.c,v 1.8 2003/02/22 07:53:10 reinelt Exp $ * * mail: pop3, imap, news functions * * Copyright 2001 by Leopold T鰐sch (lt@toetsch.at) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * $Log: mail2.c,v $ * Revision 1.8  2003/02/22 07:53:10  reinelt * cfg_get(key,defval) * * Revision 1.7  2002/12/05 19:23:01  reinelt * fixed undefined operations found by gcc3 * * Revision 1.6  2001/09/12 06:17:22  reinelt * *** empty log message *** * * Revision 1.5  2001/09/12 05:58:16  reinelt * fixed bug in mail2.c * * Revision 1.4  2001/03/16 09:28:08  ltoetsch * bugfixes * * Revision 1.3  2001/03/15 14:25:05  ltoetsch * added unread/total news * * Revision 1.2  2001/03/15 11:10:53  ltoetsch * added quit/logout to pop/imap * * Revision 1.1  2001/03/14 13:19:29  ltoetsch * Added pop3/imap4 mail support * * * Exported Functions: * * int Mail_pop_imap_news(char *mbox, int *total_mails, int *unseen); *     returns -1 on error, 0 on success * */#include <string.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <malloc.h>#include <errno.h>#include "debug.h"#include "cfg.h"#include "socket.h"#define PROTO_UNKNOWN -1#define PROTO_POP3 110#define PROTO_NNTP 119#define PROTO_IMAP4 143/* * parse_proto() * * parse a MailboxN entry in 's' as * * proto:[user[:pass]@]machine[:port][/dir] * * 's' get's destroyed * returns 0 on success, -1 on error * */static int parse_proto(char *s, int *proto, char **user, char **pass,		       char **machine, int *port, char **dir){  struct    {      char *prefix;      int proto;    }  protos[] =    {	{ "pop3:", PROTO_POP3 },	{ "nntp:", PROTO_NNTP },	{ "imap4:", PROTO_IMAP4 },    };  int i;  char *p, *q;  static char empty[] = "";  static char INBOX[] = "INBOX";  *proto = *port = PROTO_UNKNOWN;  for (i=0; i< sizeof(protos)/sizeof(protos[0]); i++)    {      if (memcmp(s, protos[i].prefix, strlen(protos[i].prefix)) == 0)	{	  *proto = *port = protos[i].proto;	  break;	}    }  if (*proto == PROTO_UNKNOWN)    return -1;  p = s + strlen(protos[i].prefix);  /*   * this might fail if user or pass contains a '/'   *    */  if ((q = strchr(p, '/')) != NULL)    {      /* /dir */      *dir = q + 1;      *q = '\0';    }  else    *dir = empty;  if ((q = strchr(p, '@')) != NULL)    {      /* user, pass is present */      *machine = q + 1;      *q = '\0';      *user = p;      if ((q = strchr(p, ':')) != NULL)	{	  /* user[:pass] */	  *q = '\0';	  *pass = q+1;	}      else	*pass = empty;    }  else    {      *machine = p;      *user = *pass = empty;    }  if ((q = strchr(*machine, ':')) != NULL)    {      /* machine[:pass] */      *q = '\0';      *port = atoi(q+1);      if (*port <= 0 || *port >= 0xffff)	return -1;    }  if (!**machine)    return -1;  if (*proto == PROTO_POP3 && **dir)    return -1;  if (*proto == PROTO_IMAP4 && !**dir)    *dir = INBOX;  return 0;}/* write buffer, compare with match */#define BUFLEN 256static int wr_rd(int fd, char *buf, char *match, 		 char *err, char *machine, int port){  int n;  n = write_socket(fd, buf);  if (n <= 0)    {      error("Couldn't write to %s:%d (%s)", machine, port, strerror(errno));      close(fd);      return -1;    }  n = read_socket_match(fd, buf, BUFLEN-1, match);  if (n <= 0)    {      error("%s %s:%d (%s)", err, machine, port, strerror(errno));      close(fd);      return -1;    }  return n;}static int check_nntp(char *user, char *pass, char *machine,		       int port, char *dir, int *total, int *unseen){  int fd;  int n;  char buf[BUFLEN];  char line[BUFLEN];  FILE *fp;  int groups;  int err;  int totg, unsg;  int first;    *total = 0;  *unseen = 0;    strcpy(buf, cfg_get("Newsrc",".newsrc"));  if (*buf == 0 || ((fp = fopen(buf, "r")) == NULL)) {    error("Couldn't open .newsrc-file '%s'", buf);    return -1;  }  fd = open_socket(machine, port);  if (fd < 0)    {      error("Couldn't connect to %s:%d (%s)", machine, port, strerror(errno));      fclose(fp);      return -1;    }  n = read_socket_match(fd, buf, BUFLEN-1, "20"); /* server ready */  if (n <= 0) {    error("Server doesn't respond %s:%d (%s)", machine, port, strerror(errno));    close(fd);    return -1;  }  /* do auth if necessary, this is NOT TESTED */  if (*user) {    sprintf(buf, "AUTHINFO USER %s\r\n", user);    if (wr_rd(fd, buf, "381", "No AUTH required?", machine, port) <= 0)      return -1;    if (*pass)      {        sprintf(buf, "AUTHINFO PASS %s\r\n", pass);      if (wr_rd(fd, buf, "281", "Wrong PASS?", machine, port) <= 0)	return -1;      }  }  // Fixme: this is badbadbadbad  sleep(2);  /* wait for newsserver to read groupinfo */  groups = 0;  err = 0;  totg = unsg = 0; /* total, unseen */      while (fgets(line, sizeof(line)-1, fp) && err < 5) {    char group[256];    char *p;    int smin, smax, lmin, lmax;        if (sscanf(line, "%255[^:]:", group) != 1) {      error("Couldn't read group in '%s'", line);      err++;      continue;    }    if ((p=strchr(group,':')) != NULL)      *p='\0';				          /* check dir if it matches group */    if (*dir && strcmp(dir, group))      continue;        sprintf(buf, "GROUP %s\r\n", group);    if (wr_rd(fd, buf, "211", "Wrong Group", machine, port) <= 0) {      err++;      continue;    }    /* answer 211 total smin smax group: */    sscanf(buf, "211 %*d %d %d", &smin, &smax);    debug("nntp: %s: smin=%d smax=%d", group, smin, smax);    totg += smax-smin-1;    p = strchr(line, ':');    p++;    first = 1;    while (1) {      lmin = strtol(p, &p, 10);      if (*p == '-') 	lmax = strtol(p+1, &p, 10);      else	lmax=lmin;      debug("nntp: %s: lmin=%d lmax=%d", group, lmin, lmax);      if (smax >= lmax) { /* server has more articles */	if (first)	  unsg += smax - lmax;	else	  unsg -= lmax-lmin+1;	first = 0;      }      else	/* local has higher article ??? */        break;      if (*p == ',')	p++;      else	break;    }  } /* while fp */  fclose(fp);      strcpy(buf, "QUIT\r\n");  wr_rd(fd, buf, "2", "Quit", machine, port);  close(fd);  *unseen = unsg;  *total = totg;  return 0;}      static int check_imap4(char *user, char *pass, char *machine,		       int port, char *dir, int *total, int *unseen){  int fd = open_socket(machine, port);  int n;  char buf[BUFLEN];  char *p;  *total=0;  *unseen = 0;  if (fd < 0)    {      error("Couldn't connect to %s:%d (%s)", machine, port, strerror(errno));      return -1;    }  n = read_socket_match(fd, buf, BUFLEN-1, "* OK");  if (n <= 0) {    error("Server doesn't respond %s:%d (%s)", machine, port, strerror(errno));    close(fd);    return -1;  }  sprintf(buf, ". LOGIN %s %s\r\n", user, pass);  if (wr_rd(fd, buf, ". OK", "Wrong User/PASS?", machine, port) <= 0)    return -1;  sprintf(buf, ". STATUS %s (MESSAGES UNSEEN)\r\n", dir);  if (wr_rd(fd, buf, "*", "Wrong dir?", machine, port) <= 0)    return -1;  if ((p = strstr(buf, "MESSAGES")) != NULL)    sscanf(p, "%*s %d", total);  else {    error("Server doesn't provide MESSAGES (%s)", machine, port, strerror(errno));    close(fd);    return -1;  }  if ((p = strstr(buf, "UNSEEN")) != NULL)    sscanf(p, "%*s %d", unseen);  else {    error("Server doesn't provide UNSEEN (%s)", machine, port, strerror(errno));    close(fd);    return -1;  }  strcpy(buf,". LOGOUT\r\n");  wr_rd(fd, buf, "", "LOGOUT", machine, port);  close(fd);  return 0;}static int check_pop3(char *user, char *pass, char *machine,		      int port, int *total, int *unseen){  int fd = open_socket(machine, port);  int n;  char buf[BUFLEN];  *total=0;  *unseen=0;  if (fd < 0)    {      error("Couldn't connect to %s:%d (%s)", machine, port, strerror(errno));      return -1;    }  n = read_socket_match(fd, buf, BUFLEN-1, "+OK");  if (n <= 0) {    error("Server doesn't respond %s:%d (%s)", machine, port, strerror(errno));    close(fd);    return -1;  }  if (*user)    {      sprintf(buf, "USER %s\r\n", user);      if (wr_rd(fd, buf, "+OK", "Wrong USER?", machine, port) <= 0)	return -1;    }  if (*pass)    {      sprintf(buf, "PASS %s\r\n", pass);      if (wr_rd(fd, buf, "+OK", "Wrong PASS?", machine, port) <= 0)	return -1;    }  sprintf(buf, "STAT\r\n");  if (wr_rd(fd, buf, "+OK", "Wrong STAT answer?", machine, port) <= 0)    return -1;  sscanf(buf, "+OK %d", total);  if (*total) {    sprintf(buf, "LAST\r\n");    if (wr_rd(fd, buf, "+OK", "Wrong LAST answer?", machine, port) <= 0)      return -1;    sscanf(buf, "+OK %d", unseen);    *unseen = *total - *unseen;  }  strcpy(buf, "QUIT\r\n");  wr_rd(fd, buf, "+OK", "Quit", machine, port);  close(fd);  return 0;}int Mail_pop_imap_news(char *s, int *total, int *unseen){  int proto, port, ret;  char *user, *pass, *machine, *dir, *ds;    ds = strdup(s);  if (ds == NULL)    {      error("Out of mem");      return -1;    }  ret = parse_proto(ds, &proto, &user, &pass,		    &machine, &port, &dir)  ;  if (ret < 0)    error("Not a pop3/imap4 mailbox");  else    ret = (proto == PROTO_POP3) ?      check_pop3(user, pass, machine, port, total, unseen) :    (proto == PROTO_NNTP) ?    check_nntp(user, pass, machine, port, dir, total, unseen) :    check_imap4(user, pass, machine, port, dir, total, unseen);  free(ds);  return ret;}#ifdef STANDALONE/* * test parse_proto with some garbage * */int foreground = 1;int debugging = 3;/* * for STANDALONE tests, disable Text driver and *  * cc -DSTANDALONE mail2.c socket.c debug.c -g -Wall -o mail2 *  */ #ifdef CHECK_PARSERstatic int test(char *s){  int ret;  int proto, port;  char *user, *pass, *machine, *dir, *ds;  ds = strdup(s);  ret = parse_proto(ds, &proto, &user, &pass,		    &machine, &port, &dir)  ;  printf("parse_proto(%s) ret=%d\n", s, ret);  if (!ret)    printf(	   "\tproto='%d'\n"	   "\tuser='%s'\n"	   "\tpass='%s'\n"	   "\tmachine='%s'\n"	   "\tport='%d'\n"	   "\tdir='%s'\n",	   proto,user,pass,machine,port,dir);  free(ds);  return ret;}#endifint main(int argc, char *argv[]){#ifdef CHECK_PARSER  int i, ret;  /* proto:[user[:pass]@]machine[:port][/dir] */  char *t[] =    {      "pop3:sepp:Geheim@Rechner:123",	"pop3:sepp@Rechner",	"pop3:Rechner:123",	"imap4:sepp:Geheim@Rechner/dir@/:pfad",	"imap4:sepp:Geheim@Rechner",	"imap4sepp:Geheim@Rechner/dir@/:pfad",	"imap4:sepp:Geheim/Rechner/dir@/:pfad",	"pop3:sepp@:",	0    };  ret = 0;  if (argc > 1)    ret |= test(argv[1]);  else    for (i = 0; t[i]; i++)      ret |= test(t[i]);  return ret;# else  int total = -1, unseen = -1;  char *mbx = "imap4:user:pass@server/folder/file";  int ret = Mail_pop_imap(mbx, &total, &unseen);  printf("ret = %d, total = %d unseen = %d\n", ret, total, unseen);  return ret;  # endif}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -