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

📄 nntp.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
      (f = netmsg_slurp (LOCAL->nntpstream->netstream,&k,NIL))) {    fread (LOCAL->over_fmt = (char *) fs_get ((size_t) k + 3),	   (size_t) 1,(size_t) k,f);    LOCAL->over_fmt[k] = '\0';    fclose (f);			/* flush temp file */  }  if (nmsgs) {			/* if any messages exist */    short silent = stream->silent;    stream->silent = T;		/* don't notify main program yet */    mail_exists (stream,nmsgs);	/* silently set the cache to the guesstimate */				/* get UID/sequence map, nuke holes */    if (nntp_getmap (stream,mbx,i,j,rnmsgs,nmsgs,tmp)) {      for (nmsgs = 0;		/* calculate true count */	   (s = net_getline (nstream->netstream)) && strcmp (s,"."); ) {	if ((k = atol (s)) > j){/* discard too high article numbers */	  sprintf (tmp,"NNTP SERVER BUG (out of range article ID): %lu > %lu",		   k,j);	  mm_notify (stream,tmp,NIL);	  stream->unhealthy = T;	}	else if (k >= i) {	/* silently ignore too-low article numbers */				/* guard against server returning extra msgs */	  if (nmsgs == stream->nmsgs) mail_exists (stream,nmsgs+1);				/* create elt for this message, set UID */	  mail_elt (stream,++nmsgs)->private.uid = k;	}	fs_give ((void **) &s);      }      if (s) fs_give ((void **) &s);    }				/* assume c-client/NNTP map is entire range */    else for (k = 1; k <= nmsgs; k++) mail_elt (stream,k)->private.uid = i++;    stream->unhealthy = NIL;	/* set healthy */    stream->nmsgs = 0;		/* whack it back down */    stream->silent = silent;	/* restore old silent setting */    mail_exists (stream,nmsgs);	/* notify upper level that messages exist */				/* read .newsrc entries */    mail_recent (stream,newsrc_read (mbx,stream));  }  else {			/* empty newsgroup or halfopen */    if (!(stream->silent || stream->halfopen)) {      sprintf (tmp,"Newsgroup %s is empty",mbx);      mm_log (tmp,WARN);    }    mail_exists (stream,(long) 0);    mail_recent (stream,(long) 0);  }  return stream;		/* return stream to caller */}/* NNTP close * Accepts: MAIL stream *	    option flags */void nntp_mclose (MAILSTREAM *stream,long options){  unsigned long i;  MESSAGECACHE *elt;  if (LOCAL) {			/* only if a file is open */    nntp_check (stream);	/* dump final checkpoint */    if (LOCAL->over_fmt) fs_give ((void **) &LOCAL->over_fmt);    if (LOCAL->name) fs_give ((void **) &LOCAL->name);    if (LOCAL->user) fs_give ((void **) &LOCAL->user);    if (LOCAL->newsrc) fs_give ((void **) &LOCAL->newsrc);    if (LOCAL->txt) fclose (LOCAL->txt);				/* close NNTP connection */    if (LOCAL->nntpstream) nntp_close (LOCAL->nntpstream);    for (i = 1; i <= stream->nmsgs; i++)      if ((elt = mail_elt (stream,i))->private.spare.ptr)	fs_give ((void **) &elt->private.spare.ptr);				/* nuke the local data */    fs_give ((void **) &stream->local);    stream->dtb = NIL;		/* log out the DTB */  }}/* NNTP fetch fast information * Accepts: MAIL stream *	    sequence *	    option flags * This is ugly and slow */void nntp_fetchfast (MAILSTREAM *stream,char *sequence,long flags){  unsigned long i;  MESSAGECACHE *elt;				/* get sequence */  if (stream && LOCAL && ((flags & FT_UID) ?			  mail_uid_sequence (stream,sequence) :			  mail_sequence (stream,sequence)))    for (i = 1; i <= stream->nmsgs; i++) {      if ((elt = mail_elt (stream,i))->sequence && (elt->valid = T) &&	  !(elt->day && elt->rfc822_size)) {	ENVELOPE **env = NIL;	ENVELOPE *e = NIL;	if (!stream->scache) env = &elt->private.msg.env;	else if (stream->msgno == i) env = &stream->env;	else env = &e;	if (!*env || !elt->rfc822_size) {	  STRING bs;	  unsigned long hs;	  char *ht = (*stream->dtb->header) (stream,i,&hs,NIL);				/* need to make an envelope? */	  if (!*env) rfc822_parse_msg (env,NIL,ht,hs,NIL,BADHOST,				       stream->dtb->flags);				/* need message size too, ugh */	  if (!elt->rfc822_size) {	    (*stream->dtb->text) (stream,i,&bs,FT_PEEK);	    elt->rfc822_size = hs + SIZE (&bs) - GETPOS (&bs);	  }	}				/* if need date, have date in envelope? */	if (!elt->day && *env && (*env)->date)	  mail_parse_date (elt,(*env)->date);				/* sigh, fill in bogus default */	if (!elt->day) elt->day = elt->month = 1;	mail_free_envelope (&e);      }    }}/* NNTP fetch flags * Accepts: MAIL stream *	    sequence *	    option flags */void nntp_flags (MAILSTREAM *stream,char *sequence,long flags){  unsigned long i;  if ((flags & FT_UID) ?	/* validate all elts */      mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence))    for (i = 1; i <= stream->nmsgs; i++) mail_elt (stream,i)->valid = T;}/* NNTP fetch overview * Accepts: MAIL stream, sequence bits set *	    overview return function * Returns: T if successful, NIL otherwise */long nntp_overview (MAILSTREAM *stream,overview_t ofn){  unsigned long i,j,k,uid;  char c,*s,*t,*v,tmp[MAILTMPLEN];  MESSAGECACHE *elt;  OVERVIEW ov;  if (!LOCAL->nntpstream->netstream) return NIL;				/* scan sequence to load cache */  for (i = 1; i <= stream->nmsgs; i++)				/* have cached overview yet? */    if ((elt = mail_elt (stream,i))->sequence && !elt->private.spare.ptr) {      for (j = i + 1;		/* no, find end of cache gap range */	   (j <= stream->nmsgs) && (elt = mail_elt (stream,j))->sequence &&	   !elt->private.spare.ptr; j++);				/* make NNTP range */      sprintf (tmp,(i == (j - 1)) ? "%lu" : "%lu-%lu",mail_uid (stream,i),	       mail_uid (stream,j - 1));      i = j;			/* advance beyond gap */				/* ask server for overview data to cache */      if (nntp_over (stream,tmp)) {	while ((s = net_getline (LOCAL->nntpstream->netstream)) &&	       strcmp (s,".")) {				/* death to embedded newlines */	  for (t = v = s; c = *v++;)	    if ((c != '\012') && (c != '\015')) *t++ = c;	  *t++ = '\0';		/* tie off string in case it was shortened */				/* cache the overview if found its sequence */	  if ((uid = atol (s)) && (k = mail_msgno (stream,uid)) &&	      (t = strchr (s,'\t'))) {	    if ((elt = mail_elt (stream,k))->private.spare.ptr)	      fs_give ((void **) &elt->private.spare.ptr);	    elt->private.spare.ptr = cpystr (t + 1);	  }	  else {		/* shouldn't happen, snarl if it does */	    sprintf (tmp,"Server returned data for unknown UID %lu",uid);	    mm_notify (stream,tmp,WARN);	    stream->unhealthy = T;	  }				/* flush the overview */	  fs_give ((void **) &s);	}	stream->unhealthy = NIL;/* set healthy */				/* flush the terminating dot */	if (s) fs_give ((void **) &s);      }      else i = stream->nmsgs;	/* OVER failed, punt cache load */    }				/* now scan sequence to return overviews */  if (ofn) for (i = 1; i <= stream->nmsgs; i++)    if ((elt = mail_elt (stream,i))->sequence) {      uid = mail_uid (stream,i);/* UID for this message */				/* parse cached overview */      if (nntp_parse_overview (&ov,s = (char *) elt->private.spare.ptr,elt))	(*ofn) (stream,uid,&ov,i);      else {			/* parse failed */	(*ofn) (stream,uid,NIL,i);	if (s && *s) {		/* unusable cached entry? */	  sprintf (tmp,"Unable to parse overview for UID %lu: %.500s",uid,s);	  mm_notify (stream,tmp,WARN);	  stream->unhealthy = T;				/* erase it from the cache */	  fs_give ((void **) &s);	}	stream->unhealthy = NIL;/* set healthy */				/* insert empty cached text as necessary */	if (!s) elt->private.spare.ptr = cpystr ("");      }				/* clean up overview data */      if (ov.from) mail_free_address (&ov.from);      if (ov.subject) fs_give ((void **) &ov.subject);    }  return T;}/* Send OVER to NNTP server * Accepts: mail stream *	    sequence to send * Returns: T if success and overviews will follow, else NIL */long nntp_over (MAILSTREAM *stream,char *sequence){  unsigned char *s;				/* test for Netscape Collabra server */  if (EXTENSION.over && LOCAL->xover &&      nntp_send (LOCAL->nntpstream,"OVER","0") == NNTPOVER) {    /* "Netscape-Collabra/3.52 03615 NNTP" responds to the OVER command with     * a bogus "Subject:From:Date:Bytes:Lines" response followed by overviews     * which lack the Message-ID and References:.  This violates the draft     * NNTP specification (draft-ietf-nntpext-base-18.txt as of this writing).     * XOVER works fine.     */    while ((s = net_getline (LOCAL->nntpstream->netstream)) && strcmp (s,".")){      if (!isdigit (*s)) {	/* is it that fetid piece of reptile dung? */	EXTENSION.over = NIL;	/* sure smells like it */	mm_log ("Working around Netscape Collabra bug",WARN);      }      fs_give ((void **) &s);	/* flush the overview */    }    if (s) fs_give ((void **) &s);				/* don't do this test again */    if (EXTENSION.over) LOCAL->xover = NIL;  }  if (EXTENSION.over)		/* have OVER extension? */    return (nntp_send (LOCAL->nntpstream,"OVER",sequence) == NNTPOVER) ?      LONGT : NIL;  if (LOCAL->xover)		/* try the experiment extension then */    switch ((int) nntp_send (LOCAL->nntpstream,"XOVER",sequence)) {    case NNTPOVER:		/* got an overview? */      return LONGT;    case NNTPBADCMD:		/* unknown command? */      LOCAL->xover = NIL;	/* disable future XOVER attempts */    }  return NIL;}/* Parse OVERVIEW struct from cached NNTP OVER response * Accepts: struct to load *	    cached OVER response *	    internaldate * Returns: T if success, NIL if fail */long nntp_parse_overview (OVERVIEW *ov,char *text,MESSAGECACHE *elt){  char *t;				/* nothing in overview yet */  memset ((void *) ov,0,sizeof (OVERVIEW));				/* no cached data */  if (!(text && *text)) return NIL;  ov->subject = cpystr (text);	/* make hackable copy of overview */				/* find end of Subject */  if (t = strchr (ov->subject,'\t')) {    *t++ = '\0';		/* tie off Subject, point to From */				/* find end of From */    if (ov->date = strchr (t,'\t')) {      *ov->date++ = '\0';	/* tie off From, point to Date */				/* load internaldate too */      if (!elt->day) mail_parse_date (elt,ov->date);				/* parse From */      rfc822_parse_adrlist (&ov->from,t,BADHOST);				/* find end of Date */      if (ov->message_id = strchr (ov->date,'\t')) {				/* tie off Date, point to Message-ID */	*ov->message_id++ = '\0';				/* find end of Message-ID */	if (ov->references = strchr (ov->message_id,'\t')) {				/* tie off Message-ID, point to References */	  *ov->references++ = '\0';				/* fine end of References */	  if (t = strchr (ov->references,'\t')) {	    *t++ = '\0';	/* tie off References, point to octet size */				/* parse size of message in octets */	    ov->optional.octets = atol (t);				/* find end of size */	    if (t = strchr (t,'\t')) {				/* parse size of message in lines */	      ov->optional.lines = atol (++t);				/* find Xref */	      if (ov->optional.xref = strchr (t,'\t'))		*ov->optional.xref++ = '\0';	    }	  }	}      }    }  }  return ov->references ? T : NIL;}/* NNTP fetch header as text * Accepts: mail stream *	    message number *	    pointer to return size *	    flags * Returns: header text */char *nntp_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *size,		   long flags){  char tmp[MAILTMPLEN];  MESSAGECACHE *elt;  FILE *f;  *size = 0;  if ((flags & FT_UID) && !(msgno = mail_msgno (stream,msgno))) return "";				/* have header text? */  if (!(elt = mail_elt (stream,msgno))->private.msg.header.text.data) {    sprintf (tmp,"%lu",mail_uid (stream,msgno));				/* get header text */    switch (nntp_send (LOCAL->nntpstream,"HEAD",tmp)) {    case NNTPHEAD:      if (f = netmsg_slurp (LOCAL->nntpstream->netstream,size,NIL)) {	fread (elt->private.msg.header.text.data =	       (unsigned char *) fs_get ((size_t) *size + 3),	       (size_t) 1,(size_t) *size,f);	fclose (f);		/* flush temp file */				/* tie off header with extra CRLF and NUL */	elt->private.msg.header.text.data[*size] = '\015';	elt->private.msg.header.text.data[++*size] = '\012';	elt->private.msg.header.text.data[++*size] = '\0';	elt->private.msg.header.text.size = *size;	elt->valid = T;		/* make elt valid now */	break;      }				/* fall into default case */    default:			/* failed, mark as deleted and empty */      elt->valid = elt->deleted = T;    case NNTPSOFTFATAL:		/* don't mark deleted if stream dead */      *size = elt->private.msg.header.text.size = 0;      break;    }  }				/* just return size of text */  else *size = elt->private.msg.header.text.size;  return elt->private.msg.header.text.data ?    (char *) elt->private.msg.header.text.data : "";}/* NNTP fetch body * Accepts: mail stream *	    message number *	    pointer to stringstruct to initialize *	    flags * Returns: T if successful, else NIL */long nntp_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){  char tmp[MAILTMPLEN];  MESSAGECACHE *elt;  INIT (bs,mail_string,(void *) "",0);  if ((flags & FT_UID) && !(msgno = mail_msgno (stream,msgno))) return NIL;  elt = mail_elt (stream,msgno);				/* different message, flush cache */  if (LOCAL->txt && (LOCAL->msgno != msgno)) {    fclose (LOCAL->txt);

⌨️ 快捷键说明

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