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

📄 news.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:	News 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:	4 September 1991 * Last Edited:	30 January 2007 */#include <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include "mail.h"#include "osdep.h"#include <sys/stat.h>#include <sys/time.h>#include "misc.h"#include "newsrc.h"#include "fdstring.h"/* news_load_message() flags */#define NLM_HEADER 0x1		/* load message text */#define NLM_TEXT 0x2		/* load message text *//* NEWS I/O stream local data */	typedef struct news_local {  unsigned int dirty : 1;	/* disk copy of .newsrc needs updating */  char *dir;			/* spool directory name */  char *name;			/* local mailbox name */  unsigned char buf[CHUNKSIZE];	/* scratch buffer */  unsigned long cachedtexts;	/* total size of all cached texts */} NEWSLOCAL;/* Convenient access to local data */#define LOCAL ((NEWSLOCAL *) stream->local)/* Function prototypes */DRIVER *news_valid (char *name);DRIVER *news_isvalid (char *name,char *mbx);void *news_parameters (long function,void *value);void news_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);void news_list (MAILSTREAM *stream,char *ref,char *pat);void news_lsub (MAILSTREAM *stream,char *ref,char *pat);long news_canonicalize (char *ref,char *pat,char *pattern);long news_subscribe (MAILSTREAM *stream,char *mailbox);long news_unsubscribe (MAILSTREAM *stream,char *mailbox);long news_create (MAILSTREAM *stream,char *mailbox);long news_delete (MAILSTREAM *stream,char *mailbox);long news_rename (MAILSTREAM *stream,char *old,char *newname);MAILSTREAM *news_open (MAILSTREAM *stream);int news_select (struct direct *name);int news_numsort (const void *d1,const void *d2);void news_close (MAILSTREAM *stream,long options);void news_fast (MAILSTREAM *stream,char *sequence,long flags);void news_flags (MAILSTREAM *stream,char *sequence,long flags);void news_load_message (MAILSTREAM *stream,unsigned long msgno,long flags);char *news_header (MAILSTREAM *stream,unsigned long msgno,		   unsigned long *length,long flags);long news_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);void news_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt);long news_ping (MAILSTREAM *stream);void news_check (MAILSTREAM *stream);long news_expunge (MAILSTREAM *stream,char *sequence,long options);long news_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);long news_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);/* News routines *//* Driver dispatch used by MAIL */DRIVER newsdriver = {  "news",			/* driver name */				/* driver flags */  DR_NEWS|DR_READONLY|DR_NOFAST|DR_NAMESPACE|DR_NONEWMAIL|DR_DIRFMT,  (DRIVER *) NIL,		/* next driver */  news_valid,			/* mailbox is valid for us */  news_parameters,		/* manipulate parameters */  news_scan,			/* scan mailboxes */  news_list,			/* find mailboxes */  news_lsub,			/* find subscribed mailboxes */  news_subscribe,		/* subscribe to mailbox */  news_unsubscribe,		/* unsubscribe from mailbox */  news_create,			/* create mailbox */  news_delete,			/* delete mailbox */  news_rename,			/* rename mailbox */  mail_status_default,		/* status of mailbox */  news_open,			/* open mailbox */  news_close,			/* close mailbox */  news_fast,			/* fetch message "fast" attributes */  news_flags,			/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message envelopes */  news_header,			/* fetch message header */  news_text,			/* fetch message body */  NIL,				/* fetch partial message text */  NIL,				/* unique identifier */  NIL,				/* message number */  NIL,				/* modify flags */  news_flagmsg,			/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  news_ping,			/* ping mailbox to see if still alive */  news_check,			/* check for new messages */  news_expunge,			/* expunge deleted messages */  news_copy,			/* copy messages to another mailbox */  news_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM newsproto = {&newsdriver};/* News validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *news_valid (char *name){  int fd;  char *s,*t,*u;  struct stat sbuf;  if ((name[0] == '#') && (name[1] == 'n') && (name[2] == 'e') &&      (name[3] == 'w') && (name[4] == 's') && (name[5] == '.') &&      !strchr (name,'/') &&      !stat ((char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL),&sbuf) &&      ((fd = open ((char *) mail_parameters (NIL,GET_NEWSACTIVE,NIL),O_RDONLY,		   NIL)) >= 0)) {    fstat (fd,&sbuf);		/* get size of active file */				/* slurp in active file */    read (fd,t = s = (char *) fs_get (sbuf.st_size+1),sbuf.st_size);    s[sbuf.st_size] = '\0';	/* tie off file */    close (fd);			/* flush file */    while (*t && (u = strchr (t,' '))) {      *u++ = '\0';		/* tie off at end of name */      if (!strcmp (name+6,t)) {	fs_give ((void **) &s);	/* flush data */	return &newsdriver;      }      t = 1 + strchr (u,'\n');	/* next line */    }    fs_give ((void **) &s);	/* flush data */  }  return NIL;			/* return status */}/* News manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *news_parameters (long function,void *value){  return (function == GET_NEWSRC) ? env_parameters (function,value) : NIL;}/* News scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void news_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  char tmp[MAILTMPLEN];  if (news_canonicalize (ref,pat,tmp))    mm_log ("Scan not valid for news mailboxes",ERROR);}/* News find list of newsgroups * Accepts: mail stream *	    reference *	    pattern to search */void news_list (MAILSTREAM *stream,char *ref,char *pat){  int fd;  int i;  char *s,*t,*u,*r,pattern[MAILTMPLEN],name[MAILTMPLEN];  struct stat sbuf;  if (!pat || !*pat) {		/* empty pattern? */    if (news_canonicalize (ref,"*",pattern)) {				/* tie off name at root */      if (s = strchr (pattern,'.')) *++s = '\0';      else pattern[0] = '\0';      mm_list (stream,'.',pattern,LATT_NOSELECT);    }  }  else if (news_canonicalize (ref,pat,pattern) &&	   !stat ((char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL),&sbuf) &&	   ((fd = open ((char *) mail_parameters (NIL,GET_NEWSACTIVE,NIL),			O_RDONLY,NIL)) >= 0)) {    fstat (fd,&sbuf);		/* get file size and read data */    read (fd,s = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);    close (fd);			/* close file */    s[sbuf.st_size] = '\0';	/* tie off string */    strcpy (name,"#news.");	/* write initial prefix */    i = strlen (pattern);	/* length of pattern */    if (pattern[--i] != '%') i = 0;    if (t = strtok_r (s,"\n",&r)) do if (u = strchr (t,' ')) {      *u = '\0';		/* tie off at end of name */      strcpy (name + 6,t);	/* make full form of name */      if (pmatch_full (name,pattern,'.')) mm_list (stream,'.',name,NIL);      else if (i && (u = strchr (name + i,'.'))) {	*u = '\0';		/* tie off at delimiter, see if matches */	if (pmatch_full (name,pattern,'.'))	  mm_list (stream,'.',name,LATT_NOSELECT);      }    } while (t = strtok_r (NIL,"\n",&r));    fs_give ((void **) &s);  }}/* News find list of subscribed newsgroups * Accepts: mail stream *	    reference *	    pattern to search */void news_lsub (MAILSTREAM *stream,char *ref,char *pat){  char pattern[MAILTMPLEN];				/* return data from newsrc */  if (news_canonicalize (ref,pat,pattern)) newsrc_lsub (stream,pattern);}/* News canonicalize newsgroup name * Accepts: reference *	    pattern *	    returned single pattern * Returns: T on success, NIL on failure */long news_canonicalize (char *ref,char *pat,char *pattern){  unsigned long i;  char *s;  if (ref && *ref) {		/* have a reference */    strcpy (pattern,ref);	/* copy reference to pattern */				/* # overrides mailbox field in reference */    if (*pat == '#') strcpy (pattern,pat);				/* pattern starts, reference ends, with . */    else if ((*pat == '.') && (pattern[strlen (pattern) - 1] == '.'))      strcat (pattern,pat + 1);	/* append, omitting one of the period */    else strcat (pattern,pat);	/* anything else is just appended */  }  else strcpy (pattern,pat);	/* just have basic name */  if ((pattern[0] == '#') && (pattern[1] == 'n') && (pattern[2] == 'e') &&      (pattern[3] == 'w') && (pattern[4] == 's') && (pattern[5] == '.') &&      !strchr (pattern,'/')) {	/* count wildcards */    for (i = 0, s = pattern; *s; *s++) if ((*s == '*') || (*s == '%')) ++i;				/* success if not too many */    if (i <= MAXWILDCARDS) return LONGT;    MM_LOG ("Excessive wildcards in LIST/LSUB",ERROR);  }  return NIL;}/* News subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long news_subscribe (MAILSTREAM *stream,char *mailbox){  return news_valid (mailbox) ? newsrc_update (stream,mailbox+6,':') : NIL;}/* NEWS unsubscribe to mailbox * Accepts: mail stream *	    mailbox to delete from subscription list * Returns: T on success, NIL on failure */long news_unsubscribe (MAILSTREAM *stream,char *mailbox){  return news_valid (mailbox) ? newsrc_update (stream,mailbox+6,'!') : NIL;}/* News create mailbox * Accepts: mail stream *	    mailbox name to create * Returns: T on success, NIL on failure */long news_create (MAILSTREAM *stream,char *mailbox){  return NIL;			/* never valid for News */}/* News delete mailbox *	    mailbox name to delete * Returns: T on success, NIL on failure */long news_delete (MAILSTREAM *stream,char *mailbox){  return NIL;			/* never valid for News */}/* News rename mailbox * Accepts: mail stream *	    old mailbox name *	    new mailbox name * Returns: T on success, NIL on failure */long news_rename (MAILSTREAM *stream,char *old,char *newname){  return NIL;			/* never valid for News */}/* News open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *news_open (MAILSTREAM *stream){  long i,nmsgs;  char *s,tmp[MAILTMPLEN];  struct direct **names = NIL;  				/* return prototype for OP_PROTOTYPE call */  if (!stream) return &newsproto;  if (stream->local) fatal ("news recycle stream");				/* build directory name */  sprintf (s = tmp,"%s/%s",(char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL),	   stream->mailbox + 6);  while (s = strchr (s,'.')) *s = '/';				/* scan directory */  if ((nmsgs = scandir (tmp,&names,news_select,news_numsort)) >= 0) {

⌨️ 快捷键说明

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