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

📄 ipop2d.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ======================================================================== * 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:	IPOP2D - IMAP to POP2 conversion server * * Author:	Mark Crispin *		UW Technology *		University of Washington *		Seattle, WA  98195 *		Internet: MRC@Washington.EDU * * Date:	28 October 1990 * Last Edited:	13 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"/* Autologout timer */#define KODTIMEOUT 60*5#define LOGINTIMEOUT 60*3#define TIMEOUT 60*30/* Size of temporary buffers */#define TMPLEN 1024/* Server states */#define LISN 0#define AUTH 1#define MBOX 2#define ITEM 3#define NEXT 4#define DONE 5/* Global storage */char *version = "75";		/* edit number of this server */short state = LISN;		/* 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;	/* number of messages */unsigned long current = 1;	/* current message number */unsigned long size = 0;		/* size of current message */char status[MAILTMPLEN];	/* space for status string */char *user = "";		/* user name */char *pass = "";		/* password */unsigned long *msg = NIL;	/* message translation vector */char *logout = "Logout";char *goodbye = "+ Sayonara\015\012";/* Function prototypes */int main (int argc,char *argv[]);void sayonara (int status);void clkint ();void kodint ();void hupint ();void trmint ();short c_helo (char *t,int argc,char *argv[]);short c_fold (char *t);short c_read (char *t);short c_retr (char *t);short c_acks (char *t);short c_ackd (char *t);short c_nack (char *t);/* Main program */int main (int argc,char *argv[]){  char *s,*t;  char cmdbuf[TMPLEN];  char *pgmname = (argc && argv[0]) ?    (((s = strrchr (argv[0],'/')) || (s = strrchr (argv[0],'\\'))) ?     s+1 : argv[0]) : "ipop2d";				/* set service name before linkage */  mail_parameters (NIL,SET_SERVICENAME,(void *) "pop");#include "linkage.c"  if (mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL)) {    goodbye = "- POP2 server disabled on this system\015\012";    sayonara (1);  }				/* initialize server */  server_init (pgmname,"pop",NIL,clkint,kodint,hupint,trmint,NIL);  /* There are reports of POP2 clients which get upset if anything appears   * between the "+" and the "POP2" in the greeting.   */  printf ("+ POP2 %s %s.%s server ready\015\012",tcp_serverhost (),	  CCLIENTVERSION,version);  fflush (stdout);		/* dump output buffer */  state = AUTH;			/* initial server state */  while (state != DONE) {	/* command processing loop */    idletime = time (0);	/* get a command under timeout */    alarm ((state != AUTH) ? TIMEOUT : LOGINTIMEOUT);    clearerr (stdin);		/* clear stdin errors */    while (!fgets (cmdbuf,TMPLEN-1,stdin)) {      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 = cmdbuf,"%.80s while reading line",e);	state = DONE;	stream = mail_close (stream);	goodbye = NIL;	sayonara (1);      }    }    alarm (0);			/* make sure timeout disabled */    idletime = 0;		/* no longer idle */				/* find end of line */    if (!strchr (cmdbuf,'\012')) {      server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);      logout = "- Command line too long\015\012";      state = DONE;    }    else if (!(s = strtok (cmdbuf," \015\012"))) {      server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);      goodbye = "- Missing or null command\015\012";      state = DONE;    }    else {			/* dispatch based on command */      ucase (s);		/* canonicalize case */				/* snarf argument */      t = strtok (NIL,"\015\012");      if ((state == AUTH) && !strcmp (s,"HELO")) state = c_helo (t,argc,argv);      else if ((state == MBOX || state == ITEM) && !strcmp (s,"FOLD")) 	state = c_fold (t);      else if ((state == MBOX || state == ITEM) && !strcmp (s,"READ"))	state = c_read (t);      else if ((state == ITEM) && !strcmp (s,"RETR")) state = c_retr (t);      else if ((state == NEXT) && !strcmp (s,"ACKS")) state = c_acks (t);      else if ((state == NEXT) && !strcmp (s,"ACKD")) state = c_ackd (t);      else if ((state == NEXT) && !strcmp (s,"NACK")) state = c_nack (t);      else if ((state == AUTH || state == MBOX || state == ITEM) &&	       !strcmp (s,"QUIT")) {	server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);	state = DONE;		/* done in either case */	if (t) goodbye = "- Bogus argument given to QUIT\015\012";	else {			/* expunge the stream */	  if (stream && nmsgs) stream = mail_close_full (stream,CL_EXPUNGE);	  stream = NIL;		/* don't repeat it */	}      }      else {			/* some other or inappropriate command */	server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);	goodbye = "- Bogus or out of sequence command\015\012";	state = DONE;      }    }    fflush (stdout);		/* make sure output blatted */  }				/* clean up the stream */  if (stream) mail_close (stream);  sayonara (0);  return 0;			/* stupid compilers */}/* Say goodbye * Accepts: exit status * * Does not return */void sayonara (int status){  logouthook_t lgoh = (logouthook_t) mail_parameters (NIL,GET_LOGOUTHOOK,NIL);  if (goodbye) {		/* have a goodbye message? */    fputs (goodbye,stdout);    fflush (stdout);		/* make sure blatted */  }  syslog (LOG_INFO,"%s user=%.80s host=%.80s",logout,	  user ? (char *) user : "???",tcp_clienthost ());				/* do logout hook if needed */  if (lgoh) (*lgoh) (mail_parameters (NIL,GET_LOGOUTDATA,NIL));  _exit (status);		/* all done */}/* Clock interrupt */void clkint (){  alarm (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  goodbye = "- Autologout; idle for too long\015\012";  logout = "Autologout";  state = DONE;			/* mark state done in either case */  if (!critical) {		/* badly host if in critical code */    if (stream && !stream->lock) mail_close (stream);    stream = NIL;    sayonara (1);		/* die die die */  }}/* Kiss Of Death interrupt */void kodint (){				/* only if in command wait */  if (idletime && ((time (0) - idletime) > KODTIMEOUT)) {    alarm (0);		/* disable all interrupts */    server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);    goodbye = "- Killed (lost mailbox lock)\015\012";    logout = "Killed (lost mailbox lock)";    state = DONE;		/* mark state done in either case */    if (!critical) {		/* badly host if in critical code */      if (stream && !stream->lock) mail_close (stream);      stream = NIL;      sayonara (1);		/* die die die */    }  }}/* Hangup interrupt */void hupint (){  alarm (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  goodbye = NIL;  logout = "Hangup";  state = DONE;			/* mark state done in either case */  if (!critical) {		/* badly host if in critical code */    if (stream && !stream->lock) mail_close (stream);    stream = NIL;    sayonara (1);		/* die die die */  }}/* Termination interrupt */void trmint (){  alarm (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  goodbye = "- Killed (terminated)\015\012";  logout = "Killed (terminated)";  if (critical) state = DONE;	/* mark state done in either case */  /* Make no attempt at graceful closure since a shutdown may be in   * progress, and we won't have any time to do mail_close() actions.   */  else sayonara (1);		/* die die die */}/* Parse HELO command * Accepts: pointer to command argument * Returns: new state */short c_helo (char *t,int argc,char *argv[]){  char *s,*u,*p;  char tmp[TMPLEN];  if ((!(t && *t && (u = strtok (t," ")) && (p = strtok (NIL,"\015\012")))) ||      (strlen (p) >= TMPLEN)) {	/* get user name and password */    fputs ("- Missing user or password\015\012",stdout);    return DONE;  }				/* copy password, handle quoting */  for (s = tmp; *p; p++) *s++ = (*p == '\\') ? *++p : *p;  *s = '\0';			/* tie off string */  pass = cpystr (tmp);  if (!(s = strchr (u,':'))) {	/* want remote mailbox? */				/* no, delimit user from possible admin */    if (s = strchr (u,'*')) *s++ = '\0';    if (server_login (user = cpystr (u),pass,s,argc,argv)) {      syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s",s ? "Admin " : "",	      user,tcp_clienthost ());      return c_fold ("INBOX");	/* local; select INBOX */    }  }#ifndef DISABLE_POP_PROXY				/* can't do if can't log in as anonymous */  else if (anonymous_login (argc,argv)) {    *s++ = '\0';		/* separate host name from user name */    user = cpystr (s);		/* note user name */    syslog (LOG_INFO,"IMAP login to host=%.80s user=%.80s host=%.80s",u,user,	    tcp_clienthost ());				/* initially remote INBOX */    sprintf (tmp,"{%.128s/user=%.128s}INBOX",u,user);				/* disable rimap just in case */    mail_parameters (NIL,SET_RSHTIMEOUT,0);    return c_fold (tmp);  }#endif  fputs ("- Bad login\015\012",stdout);  return DONE;}/* Parse FOLD command * Accepts: pointer to command argument * Returns: new state */short c_fold (char *t){  unsigned long i,j,flags;  char *s = NIL,tmp[2*TMPLEN];  NETMBX mb;  if (!(t && *t)) {		/* make sure there's an argument */    fputs ("- Missing mailbox name\015\012",stdout);    return DONE;  }  myusername_full (&flags);	/* get user type flags */				/* expunge old stream */  if (stream && nmsgs) mail_expunge (stream);  nmsgs = 0;			/* no more messages */  if (msg) fs_give ((void **) &msg);#ifndef DISABLE_POP_PROXY  if (flags == MU_ANONYMOUS) {	/* don't permit proxy to leave IMAP */    if (stream) {		/* not first time */      if (!(stream->mailbox && (s = strchr (stream->mailbox,'}'))))	fatal ("bad previous mailbox name");      strncpy (tmp,stream->mailbox,i = (++s - stream->mailbox));      if (i >= TMPLEN) fatal ("ridiculous network prefix");      strcpy (tmp+i,t);		/* append mailbox to initial spec */      t = tmp;    }				/* must be net name first time */    else if (!mail_valid_net_parse (t,&mb)) fatal ("anonymous folder bogon");  }#endif

⌨️ 快捷键说明

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