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

📄 nntp.c

📁 SIP 1.5.0源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* 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 */void nntp_expunge (MAILSTREAM *stream){  if (!stream->silent) mm_log ("Expunge ignored on readonly mailbox",NIL);}/* 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;  NETMBX mb;  char tmp[MAILTMPLEN];  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 || mb.secflag ||	mb.authuser[0]) {      sprintf (tmp,"Invalid host specifier: %.80s",*hostlist);      mm_log (tmp,ERROR);    }    else {				/* light tryalt flag if requested */      mb.tryaltflag = (options & OP_TRYALT) ? T : NIL;      if (netstream =		/* try to open ordinary connection */	  net_open (&mb,dv,nntp_port ? nntp_port : port,		    (NETDRIVER *) mail_parameters (NIL,GET_ALTDRIVER,NIL),		    (char *) mail_parameters (NIL,GET_ALTNNTPNAME,NIL),		    (unsigned long)mail_parameters(NIL,GET_ALTNNTPPORT,NIL))) {	stream = (SENDSTREAM *) fs_get (sizeof (SENDSTREAM));				/* initialize stream */	memset ((void *) stream,0,sizeof (SENDSTREAM));	stream->netstream = netstream;	stream->debug = (mb.dbgflag || (options & OP_DEBUG)) ? T : NIL;				/* get server 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 */	  if (options & OP_READONLY) {	    mm_notify (NIL,stream->reply + 4,(long) NIL);	    break;	  }				/* falls through */	default:		/* anything else is an error */	  mm_log (stream->reply,ERROR);	  stream = nntp_close (stream);	}      }    }  } while (!stream && *++hostlist);				/* have a session, log in if have user name */  if (mb.user[0] && !nntp_send_auth_work (stream,&mb,tmp)) {    nntp_close (stream);	/* punt stream */    return NIL;  }				/* in case server demands MODE READER */  if (stream) switch ((int) nntp_send_work (stream,"MODE","READER")) {  case NNTPWANTAUTH:		/* server wants auth first, do so and retry */  case NNTPWANTAUTH2:    if (nntp_send_auth_work(stream,&mb,tmp)) nntp_send(stream,"MODE","READER");    else stream = nntp_close (stream);    break;  default:			/* only authenticate if requested */    if (mb.user[0] && !nntp_send_auth_work (stream,&mb,tmp))      stream = nntp_close (stream);    break;  }  return stream;}/* NNTP close connection * Accepts: SEND stream * Returns: NIL always */SENDSTREAM *nntp_close (SENDSTREAM *stream){  if (stream) {			/* send "QUIT" */    if (stream->netstream) {	/* only if a living stream */      nntp_send (stream,"QUIT",NIL);				/* close NET connection */      net_close (stream->netstream);    }    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;  char *s,path[MAILTMPLEN],tmp[8*MAILTMPLEN];  /* 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 all that's needed, but without   *  proof, it's probably not safe to make assumptions.   *   * Second, we bop ourselves on the head with a ball-peen hammer.  How   *  dare we be so presumptious as to insert a *comment* in a Date:   *  header line.  Why, we were actually trying to be nice to a human   *  by giving a symbolic timezone (such as PST) in addition to a   *  numeric timezone (such as -0800).  But the gods of news transport   *  will have none of this.  Unix weenies, tried and true, rule!!!   *   * Third, Netscape Collabra server doesn't give the NNTPWANTAUTH error   *  until after requesting and receiving the entire message.  So we can't   *  call rely upon nntp_send()'s to do the auth retry.   */				/* RFC-1036 requires this cretinism */  sprintf (path,"Path: %s!%s\015\012",net_localhost (stream->netstream),	   env->sender ? env->sender->mailbox :	   (env->from ? env->from->mailbox : "not-for-mail"));				/* here's another cretinism */  if (s = strstr (env->date," (")) *s = NIL;  do if ((ret = nntp_send_work (stream,"POST",NIL)) == NNTPREADY)				/* output data, return success status */    ret = (net_soutr (stream->netstream,path) &&	   rfc822_output (tmp,env,body,nntp_soutr,stream->netstream,T)) ?	     nntp_send_work (stream,".",NIL) :	       nntp_fake (stream,NNTPSOFTFATAL,			  "NNTP connection broken (message text)");  while (((ret == NNTPWANTAUTH) || (ret == NNTPWANTAUTH2)) &&	 nntp_send_auth (stream));  if (s) *s = ' ';		/* put the comment in the date back */  if (ret == NNTPOK) return LONGT;  else if (ret < 400) {		/* if not an error reply */    sprintf (tmp,"Unexpected NNTP posting reply code %ld",ret);    mm_log (tmp,WARN);		/* so someone looks at this eventually */    if ((ret >= 200) && (ret < 300)) return LONGT;  }  return NIL;}/* NNTP send command * Accepts: SEND stream *	    text * Returns: reply code */long nntp_send (SENDSTREAM *stream,char *command,char *args){  long ret;  switch ((int) (ret = nntp_send_work (stream,command,args))) {  case NNTPWANTAUTH:		/* authenticate and retry */  case NNTPWANTAUTH2:    if (nntp_send_auth (stream)) ret = nntp_send_work (stream,command,args);    else {			/* we're probably hosed, nuke the session */      nntp_send (stream,"QUIT",NIL);				/* close net connection */      net_close (stream->netstream);      stream->netstream = NIL;    }  default:			/* all others just return */    break;  }  return ret;}/* NNTP send command worker routine * Accepts: SEND stream *	    text * Returns: reply code */long nntp_send_work (SENDSTREAM *stream,char *command,char *args){  long ret;  char *s = (char *) fs_get (strlen (command) + (args ? strlen (args) + 1 : 0)			     + 3);				/* build the complete command */  if (args) sprintf (s,"%s %s",command,args);  else strcpy (s,command);  if (stream->debug) mm_dlog (s);  strcat (s,"\015\012");				/* send the command */  ret = net_soutr (stream->netstream,s) ? nntp_reply (stream) :    nntp_fake (stream,NNTPSOFTFATAL,"NNTP connection broken (command)");  fs_give ((void **) &s);  return ret;}/* NNTP send authentication if needed * Accepts: SEND stream * Returns: T if need to redo command, NIL otherwise */long nntp_send_auth (SENDSTREAM *stream){  NETMBX mb;  char tmp[MAILTMPLEN];  sprintf (tmp,"{%.200s/nntp",net_host (stream->netstream));  if (stream->netstream->dtb ==      (NETDRIVER *) mail_parameters (NIL,GET_ALTDRIVER,NIL))    sprintf (tmp + strlen (tmp),"/%.200s",	     (char *) mail_parameters (NIL,GET_ALTDRIVERNAME,NIL));  strcat (tmp,"}<none>");  mail_valid_net_parse (tmp,&mb);  return nntp_send_auth_work (stream,&mb,tmp);}/* NNTP send authentication worker routine * Accepts: SEND stream *	    NETMBX structure *	    temporary buffer * Returns: T if authenticated, NIL otherwise */long nntp_send_auth_work (SENDSTREAM *stream,NETMBX *mb,char *tmp){  long i;  long trial = 0;  do {				/* get user name and password */    mm_login (mb,mb->user,tmp,trial++);    if (!*tmp) {		/* abort if he refused to give password */      mm_log ("Login aborted",ERROR);      break;    }				/* do the authentication */    if ((i = nntp_send_work (stream,"AUTHINFO USER",mb->user)) == NNTPWANTPASS)      i = nntp_send_work (stream,"AUTHINFO PASS",tmp);				/* successful authentication */    if (i == NNTPAUTHED) return T;    mm_log (stream->reply,WARN);  }  while ((i != NNTPSOFTFATAL) && (trial < nntp_maxlogintrials));  mm_log ("Too many NNTP authentication failures",ERROR);  return NIL;			/* authentication failed */}/* NNTP get reply * Accepts: SEND stream * Returns: reply code */long nntp_reply (SENDSTREAM *stream){				/* flush old reply */  if (stream->reply) fs_give ((void **) &stream->reply);  				/* get reply */  if (!(stream->reply = net_getline (stream->netstream)))    return nntp_fake(stream,NNTPSOFTFATAL,"NNTP connection broken (response)");  if (stream->debug) mm_dlog (stream->reply);				/* handle continuation by recursion */  if (stream->reply[3] == '-') return nntp_reply (stream);				/* return response code */  return stream->replycode = atol (stream->reply);}/* NNTP set fake error * Accepts: SEND stream *	    NNTP error code *	    error text * Returns: error code */long nntp_fake (SENDSTREAM *stream,long code,char *text){				/* flush any old reply */  if (stream->reply) fs_give ((void **) &stream->reply);  				/* set up pseudo-reply string */  stream->reply = (char *) fs_get (20+strlen (text));  sprintf (stream->reply,"%ld %s",code,text);  return code;			/* return error code */}/* NNTP filter mail * Accepts: stream *	    string * Returns: T on success, NIL on failure */long nntp_soutr (void *stream,char *s){  char c,*t;				/* "." on first line */  if (s[0] == '.') net_soutr (stream,".");				/* find lines beginning with a "." */  while (t = strstr (s,"\015\012.")) {    c = *(t += 3);		/* remember next character after "." */    *t = '\0';			/* tie off string */				/* output prefix */    if (!net_soutr (stream,s)) return NIL;    *t = c;			/* restore delimiter */    s = t - 1;			/* push pointer up to the "." */  }				/* output remainder of text */  return *s ? net_soutr (stream,s) : T;}

⌨️ 快捷键说明

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