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

📄 tmail.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 2 页
字号:
	deliver_safely (ds,&st,mailbox,path,duid,tmp) :	  fail ("unable to resolve INBOX path",EX_CANTCREAT);				/* dummy, empty imputed append path exist? */    if (ibxpath (ds = default_proto (T),&mailbox,path) &&	!lstat (path,&sbuf) && !sbuf.st_size)      return deliver_safely (ds,&st,mailbox,path,duid,tmp);				/* impute path that we will create */    if (!ibxpath (ds = format ? (format->open) (NIL) : default_proto (NIL),		  &mailbox,path))      return fail ("unable to resolve INBOX",EX_CANTCREAT);  }				/* black box, must create, get create proto */  else if (lstat (path,&sbuf)) ds = default_proto (NIL);  else {			/* black box, existing file */				/* empty file, get append prototype */    if (!sbuf.st_size) ds = default_proto (T);				/* non-empty, get prototype from its data */    else if (!(ds = mail_open (NIL,"INBOX",OP_PROTOTYPE)))      fatal ("no INBOX prototype");				/* error if unknown format */    if (!strcmp (ds->dtb->name,"phile"))      return fail ("unknown format INBOX",EX_UNAVAILABLE);				/* otherwise can deliver to it */    return deliver_safely (ds,&st,mailbox,path,duid,tmp);  }  sprintf (tmp,"attempting to create mailbox %.80s path %.80s",mailbox,path);  mm_dlog (tmp);				/* supplicate to the Evil One */  if (!path_create (ds,path)) return fail ("can't create INBOX",EX_CANTCREAT);  sprintf (tmp,"created %.80s",path);  mm_dlog (tmp);				/* deliver the message */  return deliver_safely (ds,&st,mailbox,path,duid,tmp);}/* Resolve INBOX from driver prototype into mailbox name and filesystem path * Accepts: driver prototype * 	    pointer to mailbox name string pointer *	    buffer to return mailbox path * Returns: T if success, NIL if error */long ibxpath (MAILSTREAM *ds,char **mailbox,char *path){  char *s,tmp[MAILTMPLEN];  long ret = T;  if (!ds) ret = NIL;  else if (!strcmp (ds->dtb->name,"unix") || !strcmp (ds->dtb->name,"mmdf"))    strcpy (path,sysinbox ());	/* use system INBOX for unix and MMDF */  else if (!strcmp (ds->dtb->name,"tenex"))    ret = (mailboxfile (path,"mail.txt") == path) ? T : NIL;  else if (!strcmp (ds->dtb->name,"mtx"))    ret = (mailboxfile (path,"INBOX.MTX") == path) ? T : NIL;  else if (!strcmp (ds->dtb->name,"mbox"))    ret = (mailboxfile (path,"mbox") == path) ? T : NIL;				/* better not be a namespace driver */  else if (ds->dtb->flags & DR_NAMESPACE) return NIL;				/* INBOX in home directory */  else ret = ((mailboxfile (path,"&&&&&") == path) &&	      (s = strstr (path,"&&&&&")) && strcpy (s,"INBOX")) ? T : NIL;  if (ret) {			/* don't bother if lossage */    sprintf (tmp,"#driver.%s/INBOX",ds->dtb->name);    *mailbox = cpystr (tmp);	/* name of INBOX in this namespace */  }  return ret;}/* Deliver safely * Accepts: prototype stream to force mailbox format *	    stringstruct of message temporary file *	    mailbox name *	    filesystem path name *	    user id *	    scratch buffer for messages * Returns: NIL if success, else error code */int deliver_safely (MAILSTREAM *prt,STRING *st,char *mailbox,char *path,		    uid_t uid,char *tmp){  struct stat sbuf;  int i = delivery_unsafe (path,uid,&sbuf,tmp);  if (i) return i;		/* give up now if delivery unsafe */				/* directory, not file */  if ((sbuf.st_mode & S_IFMT) == S_IFDIR) {    if (sbuf.st_mode & 0001) {	/* listable directories may be worrisome */      sprintf (tmp,"WARNING: directory %.80s is listable",path);      mm_log (tmp,WARN);    }  }  else {			/* file, not directory */    if (sbuf.st_nlink != 1) {	/* multiple links may be worrisome */      sprintf (tmp,"WARNING: multiple links to file %.80s",path);      mm_log (tmp,WARN);    }    if (sbuf.st_mode & 0111) {	/* executable files may be worrisome */      sprintf (tmp,"WARNING: file %.80s is executable",path);      mm_log (tmp,WARN);    }  }  if (sbuf.st_mode & 0002) {	/* public-write files may be worrisome */    sprintf (tmp,"WARNING: file %.80s is publicly-writable",path);    mm_log (tmp,WARN);  }  if (sbuf.st_mode & 0004) {	/* public-write files may be worrisome */    sprintf (tmp,"WARNING: file %.80s is publicly-readable",path);    mm_log (tmp,WARN);  }				/* check site-written quota procedure */  if (!tmail_quota (st,path,uid,tmp,sender,precedence)) return fail (tmp,-1);				/* so far, so good */  sprintf (tmp,"%s appending to %.80s (%s %.80s)",	   prt ? prt->dtb->name : "default",mailbox,	   ((sbuf.st_mode & S_IFMT) == S_IFDIR) ? "directory" : "file",path);  mm_dlog (tmp);				/* do the append now! */  if (!mail_append (prt,mailbox,st)) {    sprintf (tmp,"message delivery failed to %.80s",path);    return fail (tmp,EX_CANTCREAT);  }				/* note success */  sprintf (tmp,"delivered to %.80s",path);  mm_log (tmp,NIL);				/* make sure nothing evil this way comes */  return delivery_unsafe (path,uid,&sbuf,tmp);}/* Verify that delivery is safe * Accepts: path name *	    user id *	    stat buffer *	    scratch buffer for messages * Returns: NIL if delivery is safe, error code if unsafe */int delivery_unsafe (char *path,uid_t uid,struct stat *sbuf,char *tmp){  u_short type;  sprintf (tmp,"Verifying safe delivery to %.80s by UID %ld",path,(long) uid);  mm_dlog (tmp);				/* prepare message just in case */  sprintf (tmp,"delivery to %.80s unsafe: ",path);				/* unsafe if can't get its status */  if (lstat (path,sbuf)) strcat (tmp,strerror (errno));  else if (sbuf->st_uid != uid)	/* unsafe if UID does not match */    sprintf (tmp + strlen (tmp),"uid mismatch (%ld != %ld)",	     (long) sbuf->st_uid,(long) uid);				/* check file type */  else switch (sbuf->st_mode & S_IFMT) {  case S_IFDIR:			/* directory is always OK */    return NIL;  case S_IFREG:			/* file is unsafe if setuid */    if (sbuf->st_mode & S_ISUID) strcat (tmp,"setuid file");				/* or setgid */    else if (sbuf->st_mode & S_ISGID) strcat (tmp,"setgid file");    else return NIL;		/* otherwise safe */    break;  case S_IFCHR: strcat (tmp,"character special"); break;  case S_IFBLK: strcat (tmp,"block special"); break;  case S_IFLNK: strcat (tmp,"symbolic link"); break;  case S_IFSOCK: strcat (tmp,"socket"); break;  default:    sprintf (tmp + strlen (tmp),"file type %07o",(unsigned int) type);  }  return fail (tmp,EX_CANTCREAT);}/* Report an error * Accepts: string to output */int fail (char *string,int code){  mm_log (string,ERROR);	/* pass up the string */  switch (code) {#if T  case EX_USAGE:  case EX_OSERR:  case EX_SOFTWARE:  case EX_NOUSER:  case EX_CANTCREAT:  case EX_UNAVAILABLE:    code = EX_TEMPFAIL;		/* coerce these to TEMPFAIL */#endif    break;  case -1:			/* quota failure... */    code = EX_CANTCREAT;	/* ...really returns this code */    break;  default:    break;  }  return code;			/* error code to return */}/* Get user name from username+mailbox specifier * Accepts: username/mailbox specifier *	    pointer to return location for mailbox specifier * Returns: user name, mailbox specifier value NIL if INBOX, patches out + */char *getusername (char *s,char **t){  if (*t = strchr (s,'+')) {	/* have a mailbox specifier? */    *(*t)++ = '\0';		/* yes, tie off user name */				/* user+ and user+INBOX same as user */    if (!**t || !compare_cstring ((unsigned char *) *t,"INBOX")) *t = NIL;  }  return s;			/* return user name */}/* Co-routines from MAIL library *//* Message matches a search * Accepts: MAIL stream *	    message number */void mm_searched (MAILSTREAM *stream,unsigned long msgno){  fatal ("mm_searched() call");}/* Message exists (i.e. there are that many messages in the mailbox) * Accepts: MAIL stream *	    message number */void mm_exists (MAILSTREAM *stream,unsigned long number){  fatal ("mm_exists() call");}/* Message expunged * Accepts: MAIL stream *	    message number */void mm_expunged (MAILSTREAM *stream,unsigned long number){  fatal ("mm_expunged() call");}/* Message flags update seen * Accepts: MAIL stream *	    message number */void mm_flags (MAILSTREAM *stream,unsigned long number){}/* Mailbox found * Accepts: MAIL stream *	    delimiter *	    mailbox name *	    mailbox attributes */void mm_list (MAILSTREAM *stream,int delimiter,char *name,long attributes){  fatal ("mm_list() call");}/* Subscribed mailbox found * Accepts: MAIL stream *	    delimiter *	    mailbox name *	    mailbox attributes */void mm_lsub (MAILSTREAM *stream,int delimiter,char *name,long attributes){  fatal ("mm_lsub() call");}/* Mailbox status * Accepts: MAIL stream *	    mailbox name *	    mailbox status */void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status){  fatal ("mm_status() call");}/* Notification event * Accepts: MAIL stream *	    string to log *	    error flag */void mm_notify (MAILSTREAM *stream,char *string,long errflg){  char tmp[MAILTMPLEN];  tmp[11] = '\0';		/* see if TRYCREATE */  if (!strcmp (ucase (strncpy (tmp,string,11)),"[TRYCREATE]")) trycreate = T;  mm_log (string,errflg);	/* just do mm_log action */}/* Log an event for the user to see * Accepts: string to log *	    error flag */void mm_log (char *string,long errflg){  if (trycreate)mm_dlog(string);/* debug logging only if trycreate in effect */  else {			/* ordinary logging */    fprintf (stderr,"%s\n",string);    switch (errflg) {      case NIL:			/* no error */      syslog (LOG_INFO,"%s",string);      break;    case PARSE:			/* parsing problem */    case WARN:			/* warning */      syslog (LOG_WARNING,"%s",string);      break;    case ERROR:			/* error */    default:      syslog (LOG_ERR,"%s",string);      break;    }  }}/* Log an event to debugging telemetry * Accepts: string to log */void mm_dlog (char *string){  if (debug) fprintf (stderr,"%s\n",string);  syslog (LOG_DEBUG,"%s",string);}/* Get user name and password for this host * Accepts: parse of network mailbox name *	    where to return user name *	    where to return password *	    trial count */void mm_login (NETMBX *mb,char *username,char *password,long trial){  fatal ("mm_login() call");}/* About to enter critical code * Accepts: stream */void mm_critical (MAILSTREAM *stream){  critical = T;			/* note in critical code */}/* About to exit critical code * Accepts: stream */void mm_nocritical (MAILSTREAM *stream){  critical = NIL;		/* note not in critical code */}/* Disk error found * Accepts: stream *	    system error code *	    flag indicating that mailbox may be clobbered * Returns: T if user wants to abort */long mm_diskerror (MAILSTREAM *stream,long errcode,long serious){  return T;}/* Log a fatal error event * Accepts: string to log */void mm_fatal (char *string){  printf ("?%s\n",string);	/* shouldn't happen normally */}

⌨️ 快捷键说明

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