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

📄 nntp.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
	    r->from = adr->mailbox;	    adr->mailbox = NIL;	    mail_free_address (&adr);	  }	  if (v = strchr (t,'\t')) {	    *v++ = '\0';	/* tie off date */	    if (mail_parse_date (&telt,t)) r->date = mail_longdate (&telt);	    if ((v = strchr (v,'\t')) && (v = strchr (++v,'\t')))	      r->size = atol (++v);	  }	}      }      fs_give ((void **) &s);    }    if (s) fs_give ((void **) &s);  }				/* calculate size of sortcache index */  i = pgm->nmsgs * sizeof (SORTCACHE *);				/* instantiate the index */  sc = (SORTCACHE **) memset (fs_get ((size_t) i),0,(size_t) i);				/* see what needs to be loaded */  for (i = 1; !pgm->abort && (i <= stream->nmsgs); i++)    if ((mail_elt (stream,i))->searched) {      sc[pgm->progress.cached++] =	r = (SORTCACHE *) (*mailcache) (stream,i,CH_SORTCACHE);      r->pgm = pgm;	/* note sort program */      r->num = (flags & SE_UID) ? mail_uid (stream,i) : i;      if (!r->date) r->date = r->num;      if (!r->arrival) r->arrival = mail_uid (stream,i);      if (!r->size) r->size = 1;      if (!r->from) r->from = cpystr ("");      if (!r->to) r->to = cpystr ("");      if (!r->cc) r->cc = cpystr ("");      if (!r->subject) r->subject = cpystr ("");    }  return sc;}/* NNTP thread messages * Accepts: mail stream *	    thread type *	    character set *	    search program *	    option flags * Returns: thread node tree */THREADNODE *nntp_thread (MAILSTREAM *stream,char *type,char *charset,			 SEARCHPGM *spg,long flags){  return mail_thread_msgs (stream,type,charset,spg,flags,nntp_sort);}/* NNTP ping mailbox * Accepts: MAIL stream * Returns: T if stream alive, else NIL */long nntp_ping (MAILSTREAM *stream){  return (nntp_send (LOCAL->nntpstream,"STAT",NIL) != NNTPSOFTFATAL);}/* NNTP check mailbox * Accepts: MAIL stream */void nntp_check (MAILSTREAM *stream){				/* never do if no updates */  if (LOCAL->dirty) newsrc_write (LOCAL->name,stream);  LOCAL->dirty = NIL;}/* NNTP expunge mailbox * Accepts: MAIL stream *	    sequence to expunge if non-NIL *	    expunge options * Returns: T if success, NIL if failure */long nntp_expunge (MAILSTREAM *stream,char *sequence,long options){  if (!stream->silent) mm_log ("Expunge ignored on readonly mailbox",NIL);  return LONGT;}/* NNTP copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    option flags * Returns: T if copy successful, else NIL */long nntp_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  mailproxycopy_t pc =    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);  if (pc) return (*pc) (stream,sequence,mailbox,options);  mm_log ("Copy not valid for NNTP",ERROR);  return NIL;}/* NNTP append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */long nntp_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  mm_log ("Append not valid for NNTP",ERROR);  return NIL;}/* NNTP open connection * Accepts: network driver *	    service host list *	    port number *	    service name *	    NNTP open options * Returns: SEND stream on success, NIL on failure */SENDSTREAM *nntp_open_full (NETDRIVER *dv,char **hostlist,char *service,			    unsigned long port,long options){  SENDSTREAM *stream = NIL;  NETSTREAM *netstream = NIL;  NETMBX mb;  char tmp[MAILTMPLEN];  long extok = LONGT;  NETDRIVER *ssld = (NETDRIVER *) mail_parameters (NIL,GET_SSLDRIVER,NIL);  sslstart_t stls = (sslstart_t) mail_parameters (NIL,GET_SSLSTART,NIL);  if (!(hostlist && *hostlist)) mm_log ("Missing NNTP service host",ERROR);  else do {			/* try to open connection */    sprintf (tmp,"{%.200s/%.20s}",*hostlist,service ? service : "nntp");    if (!mail_valid_net_parse (tmp,&mb) || mb.anoflag) {      sprintf (tmp,"Invalid host specifier: %.80s",*hostlist);      mm_log (tmp,ERROR);    }    else {			/* light tryssl flag if requested */      mb.trysslflag = (options & NOP_TRYSSL) ? T : NIL;				/* default port */      if (mb.port) port = mb.port;      else if (!port) port = nntp_port ? nntp_port : NNTPTCPPORT;      if (netstream =		/* try to open ordinary connection */	  net_open (&mb,dv,port,		    (NETDRIVER *) mail_parameters (NIL,GET_SSLDRIVER,NIL),		    "*nntps",nntp_sslport ? nntp_sslport : NNTPSSLPORT)) {	stream = (SENDSTREAM *) fs_get (sizeof (SENDSTREAM));				/* initialize stream */	memset ((void *) stream,0,sizeof (SENDSTREAM));	stream->netstream = netstream;	stream->host = cpystr ((long) mail_parameters (NIL,GET_TRUSTDNS,NIL) ?			       net_host (netstream) : mb.host);	stream->debug = (mb.dbgflag || (options & NOP_DEBUG)) ? T : NIL;	if (mb.loser) stream->loser = T;				/* process greeting */	switch ((int) nntp_reply (stream)) {	case NNTPGREET:		/* allow posting */	  NNTP.post = T;	  mm_notify (NIL,stream->reply + 4,(long) NIL);	  break;	case NNTPGREETNOPOST:	/* posting not allowed, must be readonly */	  NNTP.post = NIL;	  break;	default:	  mm_log (stream->reply,ERROR);	  stream = nntp_close (stream);	  break;	}      }    }  } while (!stream && *++hostlist);				/* get extensions */  if (stream && extok)    extok = nntp_extensions (stream,(mb.secflag ? AU_SECURE : NIL) |			     (mb.authuser[0] ? AU_AUTHUSER : NIL));  if (stream && !dv && stls && NNTP.ext.starttls &&      !mb.sslflag && !mb.notlsflag &&      (nntp_send_work (stream,"STARTTLS",NNTP.ext.multidomain ? mb.host : NIL)       == NNTPTLSSTART)) {    mb.tlsflag = T;		/* TLS OK, get into TLS at this end */    stream->netstream->dtb = ssld;				/* negotiate TLS */    if (stream->netstream->stream =	(*stls) (stream->netstream->stream,mb.host,		 (mb.tlssslv23 ? NIL : NET_TLSCLIENT) |		 (mb.novalidate ? NET_NOVALIDATECERT:NIL)))      extok = nntp_extensions (stream,(mb.secflag ? AU_SECURE : NIL) |			       (mb.authuser[0] ? AU_AUTHUSER : NIL));    else {      sprintf (tmp,"Unable to negotiate TLS with this server: %.80s",mb.host);      mm_log (tmp,ERROR);				/* close without doing QUIT */      if (stream->netstream) net_close (stream->netstream);      stream->netstream = NIL;      stream = nntp_close (stream);    }  }  else if (mb.tlsflag) {	/* user specified /tls but can't do it */    mm_log ("Unable to negotiate TLS with this server",ERROR);    return NIL;  }  if (stream) {			/* have a session? */    if (mb.user[0]) {		/* yes, have user name? */      if ((long) mail_parameters (NIL,GET_TRUSTDNS,NIL)) {				/* remote name for authentication */	strncpy (mb.host,(long) mail_parameters (NIL,GET_SASLUSESPTRNAME,NIL) ?		 net_remotehost (netstream) : net_host (netstream),		 NETMAXHOST-1);	mb.host[NETMAXHOST-1] = '\0';      }      if (!nntp_send_auth_work (stream,&mb,tmp,NIL))	stream = nntp_close (stream);    }				/* authenticate if no-post and not readonly */    else if (!(NNTP.post || (options & NOP_READONLY) ||	       nntp_send_auth (stream,NIL))) stream = nntp_close (stream);  }				/* in case server demands MODE READER */  if (stream) switch ((int) nntp_send_work (stream,"MODE","READER")) {  case NNTPGREET:    NNTP.post = T;    break;  case NNTPGREETNOPOST:    NNTP.post = NIL;    break;  case NNTPWANTAUTH:		/* server wants auth first, do so and retry */  case NNTPWANTAUTH2:		/* remote name for authentication */    if ((long) mail_parameters (NIL,GET_TRUSTDNS,NIL)) {      strncpy (mb.host,(long) mail_parameters (NIL,GET_SASLUSESPTRNAME,NIL) ?	       net_remotehost (netstream) : net_host (netstream),NETMAXHOST-1);      mb.host[NETMAXHOST-1] = '\0';    }    if (nntp_send_auth_work (stream,&mb,tmp,NIL))      switch ((int) nntp_send (stream,"MODE","READER")) {      case NNTPGREET:	NNTP.post = T;	break;      case NNTPGREETNOPOST:	NNTP.post = NIL;	break;      }    else stream = nntp_close (stream);    break;  }  if (stream) {			/* looks like we have a stream? */				/* yes, make sure can post if not readonly */    if (!(NNTP.post || (options & NOP_READONLY))) stream = nntp_close (stream);    else if (extok) nntp_extensions (stream,(mb.secflag ? AU_SECURE : NIL) |				     (mb.authuser[0] ? AU_AUTHUSER : NIL));  }  return stream;}/* NNTP extensions * Accepts: stream *	    authenticator flags * Returns: T on success, NIL on failure */long nntp_extensions (SENDSTREAM *stream,long flags){  unsigned long i;  char *t,*r,*args;				/* zap all old extensions */  memset (&NNTP.ext,0,sizeof (NNTP.ext));  if (stream->loser) return NIL;/* nothing at all for losers */				/* get server extensions */  switch ((int) nntp_send_work (stream,"LIST","EXTENSIONS")) {  case NNTPEXTOK:		/* what NNTP base spec says */  case NNTPGLIST:		/* some servers do this instead */    break;  default:			/* no LIST EXTENSIONS on this server */    return NIL;  }  NNTP.ext.ok = T;		/* server offers extensions */  while ((t = net_getline (stream->netstream)) && (t[1] || (*t != '.'))) {    if (stream->debug) mm_dlog (t);				/* get optional capability arguments */    if (args = strchr (t,' ')) *args++ = '\0';    if (!compare_cstring (t,"LISTGROUP")) NNTP.ext.listgroup = T;    else if (!compare_cstring (t,"OVER")) NNTP.ext.over = T;    else if (!compare_cstring (t,"HDR")) NNTP.ext.hdr = T;    else if (!compare_cstring (t,"PAT")) NNTP.ext.pat = T;    else if (!compare_cstring (t,"STARTTLS")) NNTP.ext.starttls = T;    else if (!compare_cstring (t,"MULTIDOMAIN")) NNTP.ext.multidomain = T;    else if (!compare_cstring (t,"AUTHINFO") && args) {      char *sasl = NIL;      for (args = strtok_r (args," ",&r); args; args = strtok_r (NIL," ",&r)) {	if (!compare_cstring (args,"USER")) NNTP.ext.authuser = T;	else if (((args[0] == 'S') || (args[0] == 's')) &&		 ((args[1] == 'A') || (args[1] == 'a')) &&		 ((args[2] == 'S') || (args[2] == 's')) &&		 ((args[3] == 'L') || (args[3] == 'l')) && (args[4] == ':'))	  sasl = args + 5;      }      if (sasl) {		/* if SASL, look up authenticators */	for (sasl = strtok_r (sasl,",",&r); sasl; sasl = strtok_r (NIL,",",&r))	  if ((i = mail_lookup_auth_name (sasl,flags)) &&	      (--i < MAXAUTHENTICATORS))	    NNTP.ext.sasl |= (1 << i);				/* disable LOGIN if PLAIN also advertised */	if ((i = mail_lookup_auth_name ("PLAIN",NIL)) &&	    (--i < MAXAUTHENTICATORS) && (NNTP.ext.sasl & (1 << i)) &&	    (i = mail_lookup_auth_name ("LOGIN",NIL)) &&	    (--i < MAXAUTHENTICATORS)) NNTP.ext.sasl &= ~(1 << i);      }    }    fs_give ((void **) &t);  }  if (t) {			/* flush end of text indicator */    if (stream->debug) mm_dlog (t);    fs_give ((void **) &t);  }  return LONGT;}/* NNTP close connection * Accepts: SEND stream * Returns: NIL always */SENDSTREAM *nntp_close (SENDSTREAM *stream){  if (stream) {			/* send "QUIT" */    if (stream->netstream) nntp_send (stream,"QUIT",NIL);				/* do close actions */    if (stream->netstream) net_close (stream->netstream);    if (stream->host) fs_give ((void **) &stream->host);    if (stream->reply) fs_give ((void **) &stream->reply);    fs_give ((void **) &stream);/* flush the stream */  }  return NIL;}/* NNTP deliver news * Accepts: SEND stream *	    message envelope *	    message body * Returns: T on success, NIL on failure */long nntp_mail (SENDSTREAM *stream,ENVELOPE *env,BODY *body){  long ret;  RFC822BUFFER buf;  char *s,path[MAILTMPLEN],tmp[SENDBUFLEN+1];  long error = NIL;  long retry = NIL;  buf.f = nntp_soutr;		/* initialize buffer */  buf.s = stream->netstream;  buf.end = (buf.beg = buf.cur = tmp) + SENDBUFLEN;  tmp[SENDBUFLEN] = '\0';	/* must have additional null guard byte */  /* Gabba gabba hey, we need some brain damage to send netnews!!!   *   * First, we give ourselves a frontal lobotomy, and put in some UUCP   *  syntax.  It doesn't matter that it's completely bogus UUCP, and   *  that UUCP has nothing to do with anything we're doing.  It's been   *  alleged that "Path: not-for-mail" is also acceptable, but we won't   *  make assumptions unless the user says so.   *   * Second, we bop ourselves on the head with a ball-peen hammer.  How

⌨️ 快捷键说明

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