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

📄 ipop3d.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ======================================================================== * Copyright 1988-2008 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * *  * ======================================================================== *//* * Program:	IPOP3D - IMAP to POP3 conversion server * * Author:	Mark Crispin *		UW Technology *		University of Washington *		Seattle, WA  98195 *		Internet: MRC@Washington.EDU * * Date:	1 November 1990 * Last Edited:	19 February 2008 *//* Parameter files */#include <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include <signal.h>#include <time.h>#include "c-client.h"#define CRLF PSOUT ("\015\012")	/* primary output terpri *//* Autologout timer */#define KODTIMEOUT 60*5#define LOGINTIMEOUT 60*3#define TIMEOUT 60*10/* Server states */#define AUTHORIZATION 0#define TRANSACTION 1#define UPDATE 2#define LOGOUT 3/* Eudora food */#define STATUS "Status: %s%s\015\012"#define SLEN (sizeof (STATUS)-3)/* Global storage */char *version = "104";		/* edit number of this server */short state = AUTHORIZATION;	/* server state */short critical = NIL;		/* non-zero if in critical code */MAILSTREAM *stream = NIL;	/* mailbox stream */time_t idletime = 0;		/* time we went idle */unsigned long nmsgs = 0;	/* current number of messages */unsigned long ndele = 0;	/* number of deletes */unsigned long nseen = 0;	/* number of mark-seens */unsigned long last = 0;		/* highest message accessed */unsigned long il = 0;		/* initial last message */char challenge[128];		/* challenge */char *host = NIL;		/* remote host name */char *user = NIL;		/* user name */char *pass = NIL;		/* password */char *initial = NIL;		/* initial response */long *msg = NIL;		/* message translation vector */short *flags = NIL;		/* flags */char *logout = "Logout";char *goodbye = "+OK Sayonara\015\012";/* POP3 flags */#define DELE 0x1#define SEEN 0x2/* Function prototypes */int main (int argc,char *argv[]);void sayonara (int status);void clkint ();void kodint ();void hupint ();void trmint ();int pass_login (char *t,int argc,char *argv[]);char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]);char *responder (void *challenge,unsigned long clen,unsigned long *rlen);int mbxopen (char *mailbox);long blat (char *text,long lines,unsigned long size,STRING *st);void rset ();/* Main program */int main (int argc,char *argv[]){  unsigned long i,j,k;  char *s,*t;  char tmp[MAILTMPLEN];  time_t autologouttime;  char *pgmname = (argc && argv[0]) ?    (((s = strrchr (argv[0],'/')) || (s = strrchr (argv[0],'\\'))) ?     s+1 : argv[0]) : "ipop3d";				/* set service name before linkage */  mail_parameters (NIL,SET_SERVICENAME,(void *) "pop");#include "linkage.c"				/* initialize server */  server_init (pgmname,"pop3","pop3s",clkint,kodint,hupint,trmint,NIL);  mail_parameters (NIL,SET_BLOCKENVINIT,VOIDT);  s = myusername_full (&i);	/* get user name and flags */  mail_parameters (NIL,SET_BLOCKENVINIT,NIL);  if (i == MU_LOGGEDIN) {	/* allow EXTERNAL if logged in already */    mail_parameters (NIL,UNHIDE_AUTHENTICATOR,(void *) "EXTERNAL");    mail_parameters (NIL,SET_EXTERNALAUTHID,(void *) s);  }  {				/* set up MD5 challenge */    AUTHENTICATOR *auth = mail_lookup_auth (1);    while (auth && compare_cstring (auth->name,"CRAM-MD5")) auth = auth->next;				/* build challenge -- less than 128 chars */    if (auth && auth->server && !(auth->flags & AU_DISABLE))      sprintf (challenge,"<%lx.%lx@%.64s>",(unsigned long) getpid (),	       (unsigned long) time (0),tcp_serverhost ());    else challenge[0] = '\0';	/* no MD5 authentication */  }  /* There are reports of POP3 clients which get upset if anything appears   * between the "+OK" and the "POP3" in the greeting.   */  PSOUT ("+OK POP3 ");  if (!challenge[0]) {		/* if no MD5 enable, output host name */    PSOUT (tcp_serverhost ());    PBOUT (' ');  }  PSOUT (CCLIENTVERSION);  PBOUT ('.');  PSOUT (version);  PSOUT (" server ready");  if (challenge[0]) {		/* if MD5 enable, output challenge here */    PBOUT (' ');    PSOUT (challenge);  }  CRLF;  PFLUSH ();			/* dump output buffer */  autologouttime = time (0) + LOGINTIMEOUT;				/* command processing loop */  while ((state != UPDATE) && (state != LOGOUT)) {    idletime = time (0);	/* get a command under timeout */    alarm ((state == TRANSACTION) ? TIMEOUT : LOGINTIMEOUT);    clearerr (stdin);		/* clear stdin errors */				/* read command line */    while (!PSIN (tmp,MAILTMPLEN)) {				/* ignore if some interrupt */      if (ferror (stdin) && (errno == EINTR)) clearerr (stdin);      else {	char *e = ferror (stdin) ?	  strerror (errno) : "Unexpected client disconnect";	alarm (0);		/* disable all interrupts */	server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);	sprintf (logout = tmp,"%.80s, while reading line",e);	goodbye = NIL;	rset ();		/* try to gracefully close the stream */	if (state == TRANSACTION) mail_close (stream);	stream = NIL;	state = LOGOUT;	sayonara (1);      }    }    alarm (0);			/* make sure timeout disabled */    idletime = 0;		/* no longer idle */    if (!strchr (tmp,'\012'))	/* find end of line */      PSOUT ("-ERR Command line too long\015\012");    else if (!(s = strtok (tmp," \015\012")))      PSOUT ("-ERR Null command\015\012");    else {			/* dispatch based on command */      ucase (s);		/* canonicalize case */				/* snarf argument */      t = strtok (NIL,"\015\012");				/* QUIT command always valid */      if (!strcmp (s,"QUIT")) state = UPDATE;      else if (!strcmp (s,"CAPA")) {	AUTHENTICATOR *auth;	PSOUT ("+OK Capability list follows:\015\012");	PSOUT ("TOP\015\012LOGIN-DELAY 180\015\012UIDL\015\012");	if (s = ssl_start_tls (NIL)) fs_give ((void **) &s);	else PSOUT ("STLS\015\012");	if (i = !mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL))	  PSOUT ("USER\015\012");				/* display secure server authenticators */	for (auth = mail_lookup_auth (1), s = "SASL"; auth; auth = auth->next)	  if (auth->server && !(auth->flags & AU_DISABLE) &&	      !(auth->flags & AU_HIDE) && (i || (auth->flags & AU_SECURE))) {	    if (s) {	      PSOUT (s);	      s = NIL;	    }	    PBOUT (' ');	    PSOUT (auth->name);	  }	PSOUT (s ? ".\015\012" : "\015\012.\015\012");      }      else switch (state) {	/* else dispatch based on state */      case AUTHORIZATION:	/* waiting to get logged in */	if (!strcmp (s,"AUTH")) {	  if (t && *t) {	/* mechanism given? */	    if (host) fs_give ((void **) &host);	    if (user) fs_give ((void **) &user);	    if (pass) fs_give ((void **) &pass);	    s = strtok (t," ");	/* get mechanism name */				/* get initial response */	    if (initial = strtok (NIL,"\015\012")) {	      if ((*initial == '=') && !initial[1]) ++initial;	      else if (!*initial) initial = NIL;	    }	    if (!(user = cpystr (mail_auth (s,responder,argc,argv)))) {	      PSOUT ("-ERR Bad authentication\015\012");	      syslog (LOG_INFO,"AUTHENTICATE %s failure host=%.80s",s,		      tcp_clienthost ());	    }	    else if ((state = mbxopen ("INBOX")) == TRANSACTION)	      syslog (LOG_INFO,"Auth user=%.80s host=%.80s nmsgs=%lu/%lu",		      user,tcp_clienthost (),nmsgs,stream->nmsgs);	    else syslog (LOG_INFO,"Auth user=%.80s host=%.80s no mailbox",			 user,tcp_clienthost ());	  }	  else {	    AUTHENTICATOR *auth;	    PSOUT ("+OK Supported authentication mechanisms:\015\012");	    i = !mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL);	    for (auth = mail_lookup_auth (1); auth; auth = auth->next)	      if (auth->server && !(auth->flags & AU_DISABLE) &&		  !(auth->flags & AU_HIDE) &&		  (i || (auth->flags & AU_SECURE))) {		PSOUT (auth->name);		CRLF;	      }	    PBOUT ('.');	    CRLF;	  }	}	else if (!strcmp (s,"APOP")) {	  if (challenge[0]) {	/* can do it if have an MD5 challenge */	    if (host) fs_give ((void **) &host);	    if (user) fs_give ((void **) &user);	    if (pass) fs_give ((void **) &pass);				/* get user name */	    if (!(t && *t && (s = strtok (t," ")) && (t = strtok(NIL,"\012"))))	      PSOUT ("-ERR Missing APOP argument\015\012");	    else if (!(user = apop_login (challenge,s,t,argc,argv)))	      PSOUT ("-ERR Bad APOP\015\012");	    else if ((state = mbxopen ("INBOX")) == TRANSACTION)	      syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%lu/%lu",		      user,tcp_clienthost (),nmsgs,stream->nmsgs);	    else syslog (LOG_INFO,"APOP user=%.80s host=%.80s no mailbox",			 user,tcp_clienthost ());	  }	  else PSOUT ("-ERR Not supported\015\012");	}				/* (chuckle) */	else if (!strcmp (s,"RPOP"))	  PSOUT ("-ERR Nice try, bunkie\015\012");	else if (!strcmp (s,"STLS")) {	  if (t = ssl_start_tls (pgmname)) {	    PSOUT ("-ERR STLS failed: ");	    PSOUT (t);	    CRLF;	  }	  else PSOUT ("+OK STLS completed\015\012");	}	else if (!mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL) &&		 !strcmp (s,"USER")) {	  if (host) fs_give ((void **) &host);	  if (user) fs_give ((void **) &user);	  if (pass) fs_give ((void **) &pass);	  if (t && *t) {	/* if user name given */				/* skip leading whitespace (bogus clients!) */	    while (*t == ' ') ++t;				/* remote user name? */	    if (s = strchr (t,':')) {	      *s++ = '\0';	/* tie off host name */	      host = cpystr (t);/* copy host name */	      user = cpystr (s);/* copy user name */	    }				/* local user name */	    else user = cpystr (t);	    PSOUT ("+OK User name accepted, password please\015\012");	  }	  else PSOUT ("-ERR Missing username argument\015\012");	}	else if (!mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL) &&		 user && *user && !strcmp (s,"PASS"))	  state = pass_login (t,argc,argv);	else PSOUT ("-ERR Unknown AUTHORIZATION state command\015\012");	break;      case TRANSACTION:		/* logged in */	if (!strcmp (s,"STAT")) {	  for (i = 1,j = 0,k = 0; i <= nmsgs; i++)				/* message still exists? */	    if (msg[i] && !(flags[i] & DELE)) {	      j++;		/* count one more undeleted message */	      k += mail_elt (stream,msg[i])->rfc822_size + SLEN;	    }	  sprintf (tmp,"+OK %lu %lu\015\012",j,k);	  PSOUT (tmp);	}	else if (!strcmp (s,"LIST")) {	  if (t && *t) {	/* argument do single message */	    if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && msg[i] &&		!(flags[i] & DELE)) {	      sprintf (tmp,"+OK %lu %lu\015\012",i,		       mail_elt(stream,msg[i])->rfc822_size + SLEN);	      PSOUT (tmp);	    }	    else PSOUT ("-ERR No such message\015\012");	  }	  else {		/* entire mailbox */	    PSOUT ("+OK Mailbox scan listing follows\015\012");	    for (i = 1,j = 0,k = 0; i <= nmsgs; i++)	      if (msg[i] && !(flags[i] & DELE)) {		sprintf (tmp,"%lu %lu\015\012",i,			 mail_elt (stream,msg[i])->rfc822_size + SLEN);		PSOUT (tmp);	      }	    PBOUT ('.');	/* end of list */	    CRLF;	  }	}	else if (!strcmp (s,"UIDL")) {	  if (t && *t) {	/* argument do single message */	    if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && msg[i] &&		!(flags[i] & DELE)) {	      sprintf (tmp,"+OK %lu %08lx%08lx\015\012",i,stream->uid_validity,		       mail_uid (stream,msg[i]));	      PSOUT (tmp);	    }	    else PSOUT ("-ERR No such message\015\012");	  }	  else {		/* entire mailbox */	    PSOUT ("+OK Unique-ID listing follows\015\012");	    for (i = 1,j = 0,k = 0; i <= nmsgs; i++)	      if (msg[i] && !(flags[i] & DELE)) {		sprintf (tmp,"%lu %08lx%08lx\015\012",i,stream->uid_validity,			 mail_uid (stream,msg[i]));		PSOUT (tmp);	      }	    PBOUT ('.');	/* end of list */	    CRLF;	  }

⌨️ 快捷键说明

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