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

📄 dummy.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ======================================================================== * Copyright 1988-2007 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:	Dummy routines * * Author:	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	9 May 1991 * Last Edited:	1 June 2007 */#include <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include "mail.h"#include "osdep.h"#include <pwd.h>#include <sys/stat.h>#include "dummy.h"#include "misc.h"/* Function prototypes */DRIVER *dummy_valid (char *name);void *dummy_parameters (long function,void *value);void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents,		      long level);long dummy_listed (MAILSTREAM *stream,char delimiter,char *name,		   long attributes,char *contents);long dummy_subscribe (MAILSTREAM *stream,char *mailbox);MAILSTREAM *dummy_open (MAILSTREAM *stream);void dummy_close (MAILSTREAM *stream,long options);long dummy_ping (MAILSTREAM *stream);void dummy_check (MAILSTREAM *stream);long dummy_expunge (MAILSTREAM *stream,char *sequence,long options);long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);long dummy_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);/* Dummy routines *//* Driver dispatch used by MAIL */DRIVER dummydriver = {  "dummy",			/* driver name */  DR_LOCAL|DR_MAIL,		/* driver flags */  (DRIVER *) NIL,		/* next driver */  dummy_valid,			/* mailbox is valid for us */  dummy_parameters,		/* manipulate parameters */  dummy_scan,			/* scan mailboxes */  dummy_list,			/* list mailboxes */  dummy_lsub,			/* list subscribed mailboxes */  dummy_subscribe,		/* subscribe to mailbox */  NIL,				/* unsubscribe from mailbox */  dummy_create,			/* create mailbox */  dummy_delete,			/* delete mailbox */  dummy_rename,			/* rename mailbox */  mail_status_default,		/* status of mailbox */  dummy_open,			/* open mailbox */  dummy_close,			/* close mailbox */  NIL,				/* fetch message "fast" attributes */  NIL,				/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message structure */  NIL,				/* fetch header */  NIL,				/* fetch text */  NIL,				/* fetch message data */  NIL,				/* unique identifier */  NIL,				/* message number from UID */  NIL,				/* modify flags */  NIL,				/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  dummy_ping,			/* ping mailbox to see if still alive */  dummy_check,			/* check for new messages */  dummy_expunge,		/* expunge deleted messages */  dummy_copy,			/* copy messages to another mailbox */  dummy_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM dummyproto = {&dummydriver};/* Dummy validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *dummy_valid (char *name){  char *s,tmp[MAILTMPLEN];  struct stat sbuf;				/* must be valid local mailbox */  if (name && *name && (*name != '{') && (s = mailboxfile (tmp,name))) {				/* indeterminate clearbox INBOX */    if (!*s) return &dummydriver;    else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {    case S_IFREG:    case S_IFDIR:      return &dummydriver;    }				/* blackbox INBOX does not exist yet */    else if (!compare_cstring (name,"INBOX")) return &dummydriver;  }  return NIL;}/* Dummy manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *dummy_parameters (long function,void *value){  void *ret = NIL;  switch ((int) function) {  case GET_INBOXPATH:    if (value) ret = dummy_file ((char *) value,"INBOX");    break;  }  return ret;}/* Dummy scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void dummy_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  DRIVER *drivers;  char *s,test[MAILTMPLEN],file[MAILTMPLEN];  long i;  if (!pat || !*pat) {		/* empty pattern? */    if (dummy_canonicalize (test,ref,"*")) {				/* tie off name at root */      if (s = strchr (test,'/')) *++s = '\0';      else test[0] = '\0';      dummy_listed (stream,'/',test,LATT_NOSELECT,NIL);    }  }				/* get canonical form of name */  else if (dummy_canonicalize (test,ref,pat)) {				/* found any wildcards? */    if (s = strpbrk (test,"%*")) {				/* yes, copy name up to that point */      strncpy (file,test,i = s - test);      file[i] = '\0';		/* tie off */    }    else strcpy (file,test);	/* use just that name then */    if (s = strrchr (file,'/')){/* find directory name */      *++s = '\0';		/* found, tie off at that point */      s = file;    }				/* silly case */    else if ((file[0] == '~') || (file[0] == '#')) s = file;				/* do the work */    dummy_list_work (stream,s,test,contents,0);				/* always an INBOX */    if (pmatch ("INBOX",ucase (test))) {				/* done if have a dirfmt INBOX */      for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL);	   drivers && !(!(drivers->flags & DR_DISABLE) &&			(drivers->flags & DR_DIRFMT) &&			(*drivers->valid) ("INBOX")); drivers = drivers->next);				/* list INBOX appropriately */      dummy_listed (stream,drivers ? '/' : NIL,"INBOX",		    drivers ? NIL : LATT_NOINFERIORS,contents);    }  }}/* Dummy list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void dummy_list (MAILSTREAM *stream,char *ref,char *pat){  dummy_scan (stream,ref,pat,NIL);}/* Dummy list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void dummy_lsub (MAILSTREAM *stream,char *ref,char *pat){  void *sdb = NIL;  char *s,*t,test[MAILTMPLEN],tmp[MAILTMPLEN];  int showuppers = pat[strlen (pat) - 1] == '%';				/* get canonical form of name */  if (dummy_canonicalize (test,ref,pat) && (s = sm_read (&sdb))) do    if (*s != '{') {      if (!compare_cstring (s,"INBOX") &&	  pmatch ("INBOX",ucase (strcpy (tmp,test))))	mm_lsub (stream,NIL,s,LATT_NOINFERIORS);      else if (pmatch_full (s,test,'/')) mm_lsub (stream,'/',s,NIL);      else while (showuppers && (t = strrchr (s,'/'))) {	*t = '\0';		/* tie off the name */	if (pmatch_full (s,test,'/')) mm_lsub (stream,'/',s,LATT_NOSELECT);      }    }  while (s = sm_read (&sdb));	/* until no more subscriptions */}/* Dummy subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long dummy_subscribe (MAILSTREAM *stream,char *mailbox){  char *s,tmp[MAILTMPLEN];  struct stat sbuf;				/* must be valid local mailbox */  if ((s = mailboxfile (tmp,mailbox)) && *s && !stat (s,&sbuf))    switch (sbuf.st_mode & S_IFMT) {    case S_IFDIR:		/* allow but snarl */      sprintf (tmp,"CLIENT BUG DETECTED: subscribe of non-mailbox directory %.80s",	       mailbox);      MM_NOTIFY (stream,tmp,WARN);    case S_IFREG:      return sm_subscribe (mailbox);    }  sprintf (tmp,"Can't subscribe %.80s: not a mailbox",mailbox);  MM_LOG (tmp,ERROR);  return NIL;}/* Dummy list mailboxes worker routine * Accepts: mail stream *	    directory name to search *	    search pattern *	    string to scan *	    search level */void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents,		      long level){  DRIVER *drivers;  dirfmttest_t dt;  DIR *dp;  struct direct *d;  struct stat sbuf;  char tmp[MAILTMPLEN],path[MAILTMPLEN];  size_t len = 0;				/* punt if bogus name */  if (!mailboxdir (tmp,dir,NIL)) return;  if (dp = opendir (tmp)) {	/* do nothing if can't open directory */				/* see if a non-namespace directory format */    for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL), dt = NIL;	 dir && !dt && drivers; drivers = drivers->next)      if (!(drivers->flags & DR_DISABLE) && (drivers->flags & DR_DIRFMT) &&	  (*drivers->valid) (dir))	dt = mail_parameters ((*drivers->open) (NIL),GET_DIRFMTTEST,NIL);				/* list it if at top-level */    if (!level && dir && pmatch_full (dir,pat,'/') && !pmatch (dir,"INBOX"))      dummy_listed (stream,'/',dir,dt ? NIL : LATT_NOSELECT,contents);				/* scan directory, ignore . and .. */    if (!dir || dir[(len = strlen (dir)) - 1] == '/') while (d = readdir (dp))      if ((!(dt && (*dt) (d->d_name))) &&	  ((d->d_name[0] != '.') ||	   (((long) mail_parameters (NIL,GET_HIDEDOTFILES,NIL)) ? NIL :	    (d->d_name[1] && (((d->d_name[1] != '.') || d->d_name[2]))))) &&	  ((len + strlen (d->d_name)) <= NETMAXMBX)) {				/* see if name is useful */	if (dir) sprintf (tmp,"%s%s",dir,d->d_name);	else strcpy (tmp,d->d_name);				/* make sure useful and can get info */	if ((pmatch_full (strcpy (path,tmp),pat,'/') ||	     pmatch_full (strcat (path,"/"),pat,'/') ||	     dmatch (path,pat,'/')) &&	    mailboxdir (path,dir,"x") && (len = strlen (path)) &&	    strcpy (path+len-1,d->d_name) && !stat (path,&sbuf)) {				/* only interested in file type */	  switch (sbuf.st_mode & S_IFMT) {	  case S_IFDIR:		/* directory? */				/* form with trailing / */	    sprintf (path,"%s/",tmp);				/* skip listing if INBOX */	    if (!pmatch (tmp,"INBOX")) {	      if (pmatch_full (tmp,pat,'/')) {		if (!dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))		  break;	      }				/* try again with trailing / */	      else if (pmatch_full (path,pat,'/') &&		       !dummy_listed (stream,'/',path,LATT_NOSELECT,contents))		break;	    }	    if (dmatch (path,pat,'/') &&		(level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL)))	      dummy_list_work (stream,path,pat,contents,level+1);	    break;	  case S_IFREG:		/* ordinary name */	    /* Must use ctime for systems that don't update mtime properly */	    if (pmatch_full (tmp,pat,'/') && compare_cstring (tmp,"INBOX"))	      dummy_listed (stream,'/',tmp,LATT_NOINFERIORS +			    ((sbuf.st_size && (sbuf.st_atime < sbuf.st_ctime))?			     LATT_MARKED : LATT_UNMARKED),contents);	    break;	  }	}      }    closedir (dp);		/* all done, flush directory */  }}/* Scan file for contents * Accepts: driver to use *	    file name *	    desired contents *	    length of contents *	    size of file * Returns: NIL if contents not found, T if found */long scan_contents (DRIVER *dtb,char *name,char *contents,		    unsigned long csiz,unsigned long fsiz){  scancontents_t sc = dtb ?    (scancontents_t) (*dtb->parameters) (GET_SCANCONTENTS,NIL) : NIL;  return (*(sc ? sc : dummy_scan_contents)) (name,contents,csiz,fsiz);}/* Scan file for contents * Accepts: file name *	    desired contents *	    length of contents *	    size of file * Returns: NIL if contents not found, T if found */#define BUFSIZE 4*MAILTMPLENlong dummy_scan_contents (char *name,char *contents,unsigned long csiz,			  unsigned long fsiz){  int fd;  unsigned long ssiz,bsiz;  char *buf;				/* forget it if can't select or open */  if ((fd = open (name,O_RDONLY,NIL)) >= 0) {				/* get buffer including slop */        buf = (char *) fs_get (BUFSIZE + (ssiz = 4 * ((csiz / 4) + 1)) + 1);    memset (buf,'\0',ssiz);	/* no slop area the first time */    while (fsiz) {		/* until end of file */      read (fd,buf+ssiz,bsiz = min (fsiz,BUFSIZE));      if (search ((unsigned char *) buf,bsiz+ssiz,		  (unsigned char *) contents,csiz)) break;      memcpy (buf,buf+BUFSIZE,ssiz);      fsiz -= bsiz;		/* note that we read that much */    }    fs_give ((void **) &buf);	/* flush buffer */    close (fd);			/* finished with file */    if (fsiz) return T;		/* found */  }  return NIL;			/* not found */}/* Mailbox found * Accepts: MAIL stream *	    hierarchy delimiter *	    mailbox name *	    attributes *	    contents to search before calling mm_list() * Returns: NIL if should abort hierarchy search, else T (currently always) */long dummy_listed (MAILSTREAM *stream,char delimiter,char *name,

⌨️ 快捷键说明

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