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

📄 nntp.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
{  void *sdb = NIL;  char *s,mbx[MAILTMPLEN];				/* return data from newsrc */  if (nntp_canonicalize (ref,pat,mbx,NIL)) newsrc_lsub (stream,mbx);  if (*pat == '{') {		/* if remote pattern, must be NNTP */    if (!nntp_valid (pat)) return;    ref = NIL;			/* good NNTP pattern, punt reference */  }				/* if remote reference, must be valid NNTP */  if (ref && (*ref == '{') && !nntp_valid (ref)) return;				/* kludgy application of reference */  if (ref && *ref) sprintf (mbx,"%s%s",ref,pat);  else strcpy (mbx,pat);  if (s = sm_read (&sdb)) do if (nntp_valid (s) && pmatch (s,mbx))    mm_lsub (stream,NIL,s,NIL);  while (s = sm_read (&sdb));	/* until no more subscriptions */}/* NNTP canonicalize newsgroup name * Accepts: reference *	    pattern *	    returned single pattern *	    returned wildmat pattern * Returns: T on success, NIL on failure */long nntp_canonicalize (char *ref,char *pat,char *pattern,char *wildmat){  char *s;  DRIVER *ret;  if (ref && *ref) {		/* have a reference */    if (!nntp_valid (ref)) return NIL;    strcpy (pattern,ref);	/* copy reference to pattern */				/* # overrides mailbox field in reference */    if (*pat == '#') strcpy (strchr (pattern,'}') + 1,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 ((ret = wildmat ?		/* if valid and wildmat */       nntp_isvalid (pattern,wildmat) : nntp_valid (pattern)) && wildmat) {				/* don't return wildmat if specials present */    if (strpbrk (wildmat,",?![\\]")) wildmat[0] = '\0';				/* replace all % with * */    for (s = wildmat; s = strchr (s,'%'); *s = '*');  }  return ret ? LONGT : NIL;}/* NNTP subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long nntp_subscribe (MAILSTREAM *stream,char *mailbox){  char mbx[MAILTMPLEN];  return nntp_isvalid (mailbox,mbx) ? newsrc_update (stream,mbx,':') : NIL;}/* NNTP unsubscribe to mailbox * Accepts: mail stream *	    mailbox to delete from subscription list * Returns: T on success, NIL on failure */long nntp_unsubscribe (MAILSTREAM *stream,char *mailbox){  char mbx[MAILTMPLEN];  return nntp_isvalid (mailbox,mbx) ? newsrc_update (stream,mbx,'!') : NIL;}/* NNTP create mailbox * Accepts: mail stream *	    mailbox name to create * Returns: T on success, NIL on failure */long nntp_create (MAILSTREAM *stream,char *mailbox){  return NIL;			/* never valid for NNTP */}/* NNTP delete mailbox *	    mailbox name to delete * Returns: T on success, NIL on failure */long nntp_delete (MAILSTREAM *stream,char *mailbox){  return NIL;			/* never valid for NNTP */}/* NNTP rename mailbox * Accepts: mail stream *	    old mailbox name *	    new mailbox name * Returns: T on success, NIL on failure */long nntp_rename (MAILSTREAM *stream,char *old,char *newname){  return NIL;			/* never valid for NNTP */}/* NNTP status * Accepts: mail stream *	    mailbox name *	    status flags * Returns: T on success, NIL on failure */long nntp_status (MAILSTREAM *stream,char *mbx,long flags){  MAILSTATUS status;  NETMBX mb;  unsigned long i,j,k,rnmsgs;  long ret = NIL;  char *s,*name,*state,tmp[MAILTMPLEN];  char *old = (stream && !stream->halfopen) ? LOCAL->name : NIL;  MAILSTREAM *tstream = NIL;  if (!(mail_valid_net_parse (mbx,&mb) && !strcmp (mb.service,"nntp") &&	*mb.mailbox &&	((mb.mailbox[0] != '#') ||	 ((mb.mailbox[1] == 'n') && (mb.mailbox[2] == 'e') &&	  (mb.mailbox[3] == 'w') && (mb.mailbox[4] == 's') &&	  (mb.mailbox[5] == '.'))))) {    sprintf (tmp,"Invalid NNTP name %s",mbx);    mm_log (tmp,ERROR);    return NIL;  }				/* note mailbox name */  name = (*mb.mailbox == '#') ? mb.mailbox+6 : mb.mailbox;				/* stream to reuse? */  if (!(stream && LOCAL->nntpstream &&	mail_usable_network_stream (stream,mbx)) &&      !(tstream = stream =	mail_open (NIL,mbx,OP_HALFOPEN|OP_SILENT|		   ((flags & SA_MULNEWSRC) ? OP_MULNEWSRC : NIL))))    return NIL;			/* can't reuse or make a new one */  if (nntp_send (LOCAL->nntpstream,"GROUP",name) == NNTPGOK) {    status.flags = flags;	/* status validity flags */    k = strtoul (LOCAL->nntpstream->reply + 4,&s,10);    i = strtoul (s,&s,10);	/* first assigned UID */				/* next UID to be assigned */    status.uidnext = (j = strtoul (s,NIL,10)) + 1;				/* maximum number of messages */    rnmsgs = status.messages = (i | j) ? status.uidnext - i : 0;    if (k > status.messages) {	/* check for absurdity */      sprintf (tmp,"NNTP SERVER BUG (impossible message count): %lu > %lu",	       k,status.messages);      mm_log (tmp,WARN);    }				/* restrict article range if needed */    if (nntp_range && (status.messages > nntp_range)) {      i = status.uidnext - (status.messages = nntp_range);      if (k > nntp_range) k = nntp_range;    }				/* initially zero */    status.recent = status.unseen = 0;    if (!status.messages);	/* empty case */				/* use server guesstimate in simple case */    else if (!(flags & (SA_RECENT | SA_UNSEEN))) status.messages = k;				/* have newsrc state? */    else if (state = newsrc_state (stream,name)) {				/* yes, get the UID/sequence map */      if (nntp_getmap (stream,name,i,status.uidnext - 1,rnmsgs,		       status.messages,tmp)) {				/* calculate true count */	for (status.messages = 0;	     (s = net_getline (LOCAL->nntpstream->netstream)) &&	       strcmp (s,"."); ) {				/* only count if in range */	  if (((k = atol (s)) >= i) && (k < status.uidnext)) {	    newsrc_check_uid (state,k,&status.recent,&status.unseen);	    status.messages++;	  }	  fs_give ((void **) &s);	}	if (s) fs_give ((void **) &s);      }				/* assume c-client/NNTP map is entire range */      else while (i < status.uidnext)	newsrc_check_uid (state,i++,&status.recent,&status.unseen);      fs_give ((void **) &state);    }				/* no .newsrc state, all messages new */    else status.recent = status.unseen = status.messages;				/* UID validity is a constant */    status.uidvalidity = stream->uid_validity;				/* pass status to main program */    mm_status (stream,mbx,&status);    ret = T;			/* succes */  }				/* flush temporary stream */  if (tstream) mail_close (tstream);				/* else reopen old newsgroup */  else if (old && nntp_send (LOCAL->nntpstream,"GROUP",old) != NNTPGOK) {    mm_log (LOCAL->nntpstream->reply,ERROR);    stream->halfopen = T;	/* go halfopen */  }  return ret;			/* success */}/* NNTP get map * Accepts: stream *	    newsgroup name *	    first UID in map range *	    last UID in map range *	    reported total number of messages in newsgroup *	    calculated number of messages in range *	    temporary buffer * Returns: T on success, NIL on failure */long nntp_getmap (MAILSTREAM *stream,char *name,		  unsigned long first,unsigned long last,		  unsigned long rnmsgs,unsigned long nmsgs,char *tmp){  short trylistgroup = NIL;  if (rnmsgs > (nmsgs * 8))	/* small subrange? */    trylistgroup = T;		/* yes, can try LISTGROUP if [X]HDR fails */  else switch ((int) nntp_send (LOCAL->nntpstream,"LISTGROUP",name)) {  case NNTPGOK:			/* got data */    return LONGT;  default:			/* else give up if server claims LISTGROUP */    if (EXTENSION.listgroup) return NIL;  }				/* build range */  sprintf (tmp,"%lu-%lu",first,last);  if (EXTENSION.hdr)		/* have HDR extension? */    return (nntp_send (LOCAL->nntpstream,"HDR Date",tmp) == NNTPHEAD) ?      LONGT : NIL;  if (LOCAL->xhdr)		/* try the experimental extension then */    switch ((int) nntp_send (LOCAL->nntpstream,"XHDR Date",tmp)) {    case NNTPHEAD:		/* got an overview? */      return LONGT;    case NNTPBADCMD:		/* unknown command? */      LOCAL->xhdr = NIL;	/* disable future XHDR attempts */    }  if (trylistgroup &&		/* no [X]HDR, maybe do LISTGROUP after all */      (nntp_send (LOCAL->nntpstream,"LISTGROUP",name) == NNTPGOK))    return LONGT;  return NIL;}/* NNTP open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *nntp_mopen (MAILSTREAM *stream){  unsigned long i,j,k,nmsgs,rnmsgs;  char *s,*mbx,tmp[MAILTMPLEN];  FILE *f;  NETMBX mb;  char *newsrc = (char *) mail_parameters (NIL,GET_NEWSRC,NIL);  newsrcquery_t nq = (newsrcquery_t) mail_parameters (NIL,GET_NEWSRCQUERY,NIL);  SENDSTREAM *nstream = NIL;				/* return prototype for OP_PROTOTYPE call */  if (!stream) return &nntpproto;  mail_valid_net_parse (stream->mailbox,&mb);				/* note mailbox anme */  mbx = (*mb.mailbox == '#') ? mb.mailbox+6 : mb.mailbox;  if (LOCAL) {			/* recycle stream */    nstream = LOCAL->nntpstream;/* remember NNTP protocol stream */    sprintf (tmp,"Reusing connection to %s",net_host (nstream->netstream));    if (!stream->silent) mm_log (tmp,(long) NIL);    if (stream->rdonly) mb.readonlyflag = T;    if (LOCAL->tlsflag) mb.tlsflag = T;    if (LOCAL->tlssslv23) mb.tlssslv23 = T;    if (LOCAL->notlsflag) mb.notlsflag = T;    if (LOCAL->sslflag) mb.sslflag = T;    if (LOCAL->novalidate) mb.novalidate = T;    if (LOCAL->nntpstream->loser) mb.loser = T;    if (stream->secure) mb.secflag = T;    LOCAL->nntpstream = NIL;	/* keep nntp_mclose() from punting it */    nntp_mclose (stream,NIL);	/* do close action */    stream->dtb = &nntpdriver;	/* reattach this driver */  }				/* copy flags */  if (mb.dbgflag) stream->debug = T;  if (mb.readonlyflag) stream->rdonly = T;  if (mb.secflag) stream->secure = T;  mb.trysslflag = stream->tryssl = (mb.trysslflag || stream->tryssl) ? T : NIL;  if (!nstream) {		/* open NNTP now if not already open */    char *hostlist[2];    hostlist[0] = strcpy (tmp,mb.host);    if (mb.port || nntp_port)      sprintf (tmp + strlen (tmp),":%lu",mb.port ? mb.port : nntp_port);    if (mb.tlsflag) strcat (tmp,"/tls");    if (mb.tlssslv23) strcat (tmp,"/tls-sslv23");    if (mb.notlsflag) strcat (tmp,"/notls");    if (mb.sslflag) strcat (tmp,"/ssl");    if (mb.novalidate) strcat (tmp,"/novalidate-cert");    if (mb.loser) strcat (tmp,"/loser");    if (mb.secflag) strcat (tmp,"/secure");    if (mb.user[0]) sprintf (tmp + strlen (tmp),"/user=\"%s\"",mb.user);    hostlist[1] = NIL;    if (!(nstream = nntp_open (hostlist,NOP_READONLY |			       (stream->debug ? NOP_DEBUG : NIL)))) return NIL;  }				/* always zero messages if halfopen */  if (stream->halfopen) i = j = k = rnmsgs = nmsgs = 0;				/* otherwise open the newsgroup */  else if (nntp_send (nstream,"GROUP",mbx) == NNTPGOK) {    k = strtoul (nstream->reply + 4,&s,10);    i = strtoul (s,&s,10);    stream->uid_last = j = strtoul (s,&s,10);    rnmsgs = nmsgs = (i | j) ? 1 + j - i : 0;    if (k > nmsgs) {		/* check for absurdity */      sprintf (tmp,"NNTP SERVER BUG (impossible message count): %lu > %lu",	       k,nmsgs);      mm_log (tmp,WARN);    }				/* restrict article range if needed */    if (nntp_range && (nmsgs > nntp_range)) i = 1 + j - (nmsgs = nntp_range);  }  else {			/* no such newsgroup */    mm_log (nstream->reply,ERROR);    nntp_close (nstream);	/* punt stream */    return NIL;  }				/* instantiate local data */  stream->local = memset (fs_get (sizeof (NNTPLOCAL)),0,sizeof (NNTPLOCAL));  LOCAL->nntpstream = nstream;				/* save state for future recycling */  if (mb.tlsflag) LOCAL->tlsflag = T;  if (mb.tlssslv23) LOCAL->tlssslv23 = T;  if (mb.notlsflag) LOCAL->notlsflag = T;  if (mb.sslflag) LOCAL->sslflag = T;  if (mb.novalidate) LOCAL->novalidate = T;  if (mb.loser) LOCAL->nntpstream->loser = T;				/* assume present until proven otherwise */  LOCAL->xhdr = LOCAL->xover = T;  LOCAL->name = cpystr (mbx);	/* copy newsgroup name */  if (stream->mulnewsrc) {	/* want to use multiple .newsrc files? */    strcpy (tmp,newsrc);    s = tmp + strlen (tmp);	/* end of string */    *s++ = '-';			/* hyphen delimiter and host */    lcase (strcpy (s,(long) mail_parameters (NIL,GET_NEWSRCCANONHOST,NIL) ?		   net_host (nstream->netstream) : mb.host));    LOCAL->newsrc = cpystr (nq ? (*nq) (stream,tmp,newsrc) : tmp);  }  else LOCAL->newsrc = cpystr (newsrc);  if (mb.user[0]) LOCAL->user = cpystr (mb.user);  stream->sequence++;		/* bump sequence number */  stream->rdonly = stream->perm_deleted = T;				/* UIDs are always valid */  stream->uid_validity = 0xbeefface;  sprintf (tmp,"{%s:%lu/nntp",(long) mail_parameters (NIL,GET_TRUSTDNS,NIL) ?	   net_host (nstream->netstream) : mb.host,	   net_port (nstream->netstream));  if (LOCAL->tlsflag) strcat (tmp,"/tls");  if (LOCAL->tlssslv23) strcat (tmp,"/tls-sslv23");  if (LOCAL->notlsflag) strcat (tmp,"/notls");  if (LOCAL->sslflag) strcat (tmp,"/ssl");  if (LOCAL->novalidate) strcat (tmp,"/novalidate-cert");  if (LOCAL->nntpstream->loser) strcat (tmp,"/loser");  if (stream->secure) strcat (tmp,"/secure");  if (stream->rdonly) strcat (tmp,"/readonly");  if (LOCAL->user) sprintf (tmp + strlen (tmp),"/user=\"%s\"",LOCAL->user);  if (stream->halfopen) strcat (tmp,"}<no_mailbox>");  else sprintf (tmp + strlen (tmp),"}#news.%s",mbx);  fs_give ((void **) &stream->mailbox);  stream->mailbox = cpystr (tmp);  if (EXTENSION.over &&		/* get overview format if have OVER */      (nntp_send (LOCAL->nntpstream,"LIST","OVERVIEW.FMT") == NNTPGLIST) &&

⌨️ 快捷键说明

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