📄 news.c
字号:
/* * 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: 24 January 2000 * * Copyright 2000 by the University of Washington * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * above copyright notice and this permission notice appear in supporting * documentation, and that the name of the University of Washington not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. This software is made * available "as is", and * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */#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 "news.h"#include "misc.h"#include "newsrc.h"/* News routines *//* Driver dispatch used by MAIL */DRIVER newsdriver = { "news", /* driver name */ /* driver flags */ DR_NEWS|DR_READONLY|DR_NOFAST|DR_NAMESPACE, (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 */ NIL, /* 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 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,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); } } 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 (s,"\n")) 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 (NIL,"\n")); 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){ 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 */ return ((pattern[0] == '#') && (pattern[1] == 'n') && (pattern[2] == 'e') && (pattern[3] == 'w') && (pattern[4] == 's') && (pattern[5] == '.') && !strchr (pattern,'/')) ? T : 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 status of mailbox default handler * Accepts: mail stream * mailbox name * status flags * Returns: T on success, NIL on failure */long news_status (MAILSTREAM *stream,char *mbx,long flags){ MAILSTATUS status; unsigned long i; MAILSTREAM *tstream = NIL; /* make temporary stream (unless this mbx) */ if ((!stream || strcmp (stream->mailbox,mbx)) && !(stream = tstream = mail_open (NIL,mbx,OP_READONLY|OP_SILENT))) return NIL; status.flags = flags; /* return status values */ status.messages = stream->nmsgs; status.recent = stream->recent; if (flags & SA_UNSEEN) /* must search to get unseen messages */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -