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

📄 nntp.c

📁 mgcp协议源代码。支持多种编码:g711
💻 C
📖 第 1 页 / 共 4 页
字号:
	  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 open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *nntp_mopen (MAILSTREAM *stream){  unsigned long i,j,k,nmsgs;  char *s,*mbx,tmp[MAILTMPLEN];  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 */    sprintf (tmp,"Reusing connection to %s",LOCAL->host);    if (!stream->silent) mm_log (tmp,(long) NIL);    nstream = LOCAL->nntpstream;    LOCAL->nntpstream = NIL;	/* keep nntp_mclose() from punting it */    nntp_mclose (stream,NIL);	/* do close action */    stream->dtb = &nntpdriver;	/* reattach this driver */  }				/* in case /debug switch given */  if (mb.dbgflag) stream->debug = T;  mb.tryaltflag = stream->tryalt;  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.altflag) sprintf (tmp + strlen (tmp),"/%s",(char *)			     mail_parameters (NIL,GET_ALTDRIVERNAME,NIL));    if (mb.altopt) sprintf (tmp + strlen (tmp),"/%s",(char *)			    mail_parameters (NIL,GET_ALTOPTIONNAME,NIL));    if (mb.user[0]) sprintf (tmp + strlen (tmp),"/user=\"%s\"",mb.user);    hostlist[1] = NIL;    nstream = nntp_open (hostlist,OP_READONLY+(stream->debug ? OP_DEBUG:NIL));  }  if (!nstream) return NIL;	/* didn't get an NNTP session */				/* always zero messages if halfopen */  if (stream->halfopen) i = j = k = 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);    nmsgs = (i | j) ? 1 + j - i : 0;  }  else {			/* no such newsgroup */    mm_log (nstream->reply,ERROR);    nntp_close (nstream);	/* punt stream */    return NIL;  }				/* newsgroup open, instantiate local data */  stream->local = memset (fs_get (sizeof (NNTPLOCAL)),0,sizeof (NNTPLOCAL));  LOCAL->nntpstream = nstream;  LOCAL->name = cpystr (mbx);	/* copy newsgroup name */				/* copy host name */  LOCAL->host = cpystr (net_host (nstream->netstream));  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,LOCAL->host));    LOCAL->newsrc = cpystr (nq ? (*nq) (stream,tmp,newsrc) : newsrc);  }  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",LOCAL->host,net_port (nstream->netstream));  if (mb.altflag) sprintf (tmp + strlen (tmp),"/%s",(char *)			   mail_parameters (NIL,GET_ALTDRIVERNAME,NIL));  if (mb.altopt) sprintf (tmp + strlen (tmp),"/%s",(char *)			  mail_parameters (NIL,GET_ALTOPTIONNAME,NIL));  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 (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 */    sprintf (tmp,"%lu-%lu",i,j);/* in case have to do XHDR Date */    if ((k < nmsgs) &&	/* only bother if there appear to be holes */	((nntp_send (nstream,"LISTGROUP",mbx) == NNTPGOK) ||	 (nntp_send (nstream,"XHDR Date",tmp) == NNTPHEAD))) {      nmsgs = 0;		/* have holes, calculate true count */      while ((s = net_getline (nstream->netstream)) && strcmp (s,".")) {	mail_elt (stream,++nmsgs)->private.uid = atol (s);	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->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->name) fs_give ((void **) &LOCAL->name);    if (LOCAL->host) fs_give ((void **) &LOCAL->host);    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.data)	fs_give ((void **) &elt->private.data);				/* 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->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 *	    UID sequence (may be NIL for nntp_search() call) *	    overview return function * Returns: T if successful, NIL otherwise */long nntp_overview (MAILSTREAM *stream,char *sequence,overview_t ofn){  unsigned long i,j,k,uid;  char c,*s,*t,*v,tmp[MAILTMPLEN];  MESSAGECACHE *elt;  OVERVIEW ov;				/* parse the sequence */  if (!sequence || mail_uid_sequence (stream,sequence)) {				/* 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.data) {	for (j = i + 1;		/* no, find end of cache gap range */	     (j <= stream->nmsgs) && (elt = mail_elt (stream,j))->sequence &&	     !elt->private.data; 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_send (LOCAL->nntpstream,"XOVER",tmp) == NNTPOVER) {	  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.data)		fs_give ((void **) &elt->private.data);	      elt->private.data = (unsigned long) cpystr (t + 1);	    }	    else {		/* shouldn't happen, snarl if it does */	      sprintf (tmp,"Server returned data for unknown UID %lu",uid);	      mm_log (tmp,WARN);	    }				/* flush the overview */	    fs_give ((void **) &s);	  }				/* flush the terminating dot */	  if (s) fs_give ((void **) &s);	}	else i = stream->nmsgs;	/* XOVER 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 for this message */	uid = mail_uid (stream,i);				/* parse cached overview */	if (nntp_parse_overview (&ov,s = (char *) elt->private.data))	  (*ofn) (stream,uid,&ov);	else {			/* parse failed */	  (*ofn) (stream,uid,NIL);	  if (s && *s) {	/* unusable cached entry? */	    sprintf (tmp,"Unable to parse overview for UID %lu: %.500s",uid,s);	    mm_log (tmp,WARN);				/* erase it from the cache */	    fs_give ((void **) &s);	  }				/* insert empty cached text as necessary */	  if (!s) elt->private.data = (unsigned long) cpystr ("");	}				/* clean up overview data */	if (ov.from) mail_free_address (&ov.from);	if (ov.subject) fs_give ((void **) &ov.subject);      }  }  return T;}/* Parse OVERVIEW struct from cached NNTP XOVER response * Accepts: struct to load *	    cached XOVER response * Returns: T if success, NIL if fail */long nntp_parse_overview (OVERVIEW *ov,char *text){  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 */				/* 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;  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 */    if ((nntp_send (LOCAL->nntpstream,"HEAD",tmp) == NNTPHEAD) &&	(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 */    }    else {			/* failed, mark as deleted and empty */      elt->valid = elt->deleted = T;      *size = elt->private.msg.header.text.size = 0;    }  }				/* 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

⌨️ 快捷键说明

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