📄 nntp.c
字号:
/* ======================================================================== * Copyright 1988-2007 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * * ======================================================================== *//* * Program: Network News Transfer Protocol (NNTP) routines * * Author: Mark Crispin * Networks and Distributed Computing * Computing & Communications * University of Washington * Administration Building, AG-44 * Seattle, WA 98195 * Internet: MRC@CAC.Washington.EDU * * Date: 10 February 1992 * Last Edited: 6 September 2007 */#include <ctype.h>#include <stdio.h>#include "c-client.h"#include "newsrc.h"#include "netmsg.h"#include "flstring.h"/* Constants */#define NNTPSSLPORT (long) 563 /* assigned SSL TCP contact port */#define NNTPGREET (long) 200 /* NNTP successful greeting */ /* NNTP successful greeting w/o posting priv */#define NNTPGREETNOPOST (long) 201#define NNTPEXTOK (long) 202 /* NNTP extensions OK */#define NNTPGOK (long) 211 /* NNTP group selection OK */#define NNTPGLIST (long) 215 /* NNTP group list being returned */#define NNTPARTICLE (long) 220 /* NNTP article file */#define NNTPHEAD (long) 221 /* NNTP header text */#define NNTPBODY (long) 222 /* NNTP body text */#define NNTPOVER (long) 224 /* NNTP overview text */#define NNTPOK (long) 240 /* NNTP OK code */#define NNTPAUTHED (long) 281 /* NNTP successful authentication */ /* NNTP successful authentication with data */#define NNTPAUTHEDDATA (long) 282#define NNTPREADY (long) 340 /* NNTP ready for data */#define NNTPWANTAUTH2 (long) 380/* NNTP authentication needed (old) */#define NNTPWANTPASS (long) 381 /* NNTP password needed */#define NNTPTLSSTART (long) 382 /* NNTP continue with TLS negotiation */#define NNTPCHALLENGE (long) 383/* NNTP challenge, want response */#define NNTPSOFTFATAL (long) 400/* NNTP soft fatal code */#define NNTPWANTAUTH (long) 480 /* NNTP authentication needed */#define NNTPBADCMD (long) 500 /* NNTP unrecognized command */#define IDLETIMEOUT (long) 3 /* defined in NNTPEXT WG base draft *//* NNTP I/O stream local data */ typedef struct nntp_local { SENDSTREAM *nntpstream; /* NNTP stream for I/O */ unsigned int dirty : 1; /* disk copy of .newsrc needs updating */ unsigned int tlsflag : 1; /* TLS session */ unsigned int tlssslv23 : 1; /* TLS using SSLv23 client method */ unsigned int notlsflag : 1; /* TLS not used in session */ unsigned int sslflag : 1; /* SSL session */ unsigned int novalidate : 1; /* certificate not validated */ unsigned int xover : 1; /* supports XOVER */ unsigned int xhdr : 1; /* supports XHDR */ char *name; /* remote newsgroup name */ char *user; /* mailbox user */ char *newsrc; /* newsrc file */ char *over_fmt; /* overview format */ unsigned long msgno; /* current text message number */ FILE *txt; /* current text */ unsigned long txtsize; /* current text size */} NNTPLOCAL;/* Convenient access to local data */#define LOCAL ((NNTPLOCAL *) stream->local)/* Convenient access to protocol-specific data */#define NNTP stream->protocol.nntp/* Convenient access to extensions */#define EXTENSION LOCAL->nntpstream->protocol.nntp.ext/* Function prototypes */DRIVER *nntp_valid (char *name);DRIVER *nntp_isvalid (char *name,char *mbx);void *nntp_parameters (long function,void *value);void nntp_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);void nntp_list (MAILSTREAM *stream,char *ref,char *pat);void nntp_lsub (MAILSTREAM *stream,char *ref,char *pat);long nntp_canonicalize (char *ref,char *pat,char *pattern,char *wildmat);long nntp_subscribe (MAILSTREAM *stream,char *mailbox);long nntp_unsubscribe (MAILSTREAM *stream,char *mailbox);long nntp_create (MAILSTREAM *stream,char *mailbox);long nntp_delete (MAILSTREAM *stream,char *mailbox);long nntp_rename (MAILSTREAM *stream,char *old,char *newname);long nntp_status (MAILSTREAM *stream,char *mbx,long flags);long nntp_getmap (MAILSTREAM *stream,char *name, unsigned long first,unsigned long last, unsigned long rnmsgs,unsigned long nmsgs,char *tmp);MAILSTREAM *nntp_mopen (MAILSTREAM *stream);void nntp_mclose (MAILSTREAM *stream,long options);void nntp_fetchfast (MAILSTREAM *stream,char *sequence,long flags);void nntp_flags (MAILSTREAM *stream,char *sequence,long flags);long nntp_overview (MAILSTREAM *stream,overview_t ofn);long nntp_parse_overview (OVERVIEW *ov,char *text,MESSAGECACHE *elt);long nntp_over (MAILSTREAM *stream,char *sequence);char *nntp_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *size, long flags);long nntp_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);FILE *nntp_article (MAILSTREAM *stream,char *msgid,unsigned long *size, unsigned long *hsiz);void nntp_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt);long nntp_search (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm,long flags);long nntp_search_msg (MAILSTREAM *stream,unsigned long msgno,SEARCHPGM *pgm, OVERVIEW *ov);unsigned long *nntp_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg, SORTPGM *pgm,long flags);SORTCACHE **nntp_sort_loadcache (MAILSTREAM *stream,SORTPGM *pgm, unsigned long start,unsigned long last, long flags);THREADNODE *nntp_thread (MAILSTREAM *stream,char *type,char *charset, SEARCHPGM *spg,long flags);long nntp_ping (MAILSTREAM *stream);void nntp_check (MAILSTREAM *stream);long nntp_expunge (MAILSTREAM *stream,char *sequence,long options);long nntp_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);long nntp_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);long nntp_extensions (SENDSTREAM *stream,long flags);long nntp_send (SENDSTREAM *stream,char *command,char *args);long nntp_send_work (SENDSTREAM *stream,char *command,char *args);long nntp_send_auth (SENDSTREAM *stream,long flags);long nntp_send_auth_work (SENDSTREAM *stream,NETMBX *mb,char *pwd,long flags);void *nntp_challenge (void *s,unsigned long *len);long nntp_response (void *s,char *response,unsigned long size);long nntp_reply (SENDSTREAM *stream);long nntp_fake (SENDSTREAM *stream,char *text);long nntp_soutr (void *stream,char *s);/* Driver dispatch used by MAIL */DRIVER nntpdriver = { "nntp", /* driver name */ /* driver flags */#ifdef INADEQUATE_MEMORY DR_LOWMEM |#endif DR_NEWS|DR_READONLY|DR_NOFAST|DR_NAMESPACE|DR_CRLF|DR_RECYCLE|DR_XPOINT | DR_NOINTDATE|DR_NONEWMAIL|DR_HALFOPEN, (DRIVER *) NIL, /* next driver */ nntp_valid, /* mailbox is valid for us */ nntp_parameters, /* manipulate parameters */ nntp_scan, /* scan mailboxes */ nntp_list, /* find mailboxes */ nntp_lsub, /* find subscribed mailboxes */ nntp_subscribe, /* subscribe to mailbox */ nntp_unsubscribe, /* unsubscribe from mailbox */ nntp_create, /* create mailbox */ nntp_delete, /* delete mailbox */ nntp_rename, /* rename mailbox */ nntp_status, /* status of mailbox */ nntp_mopen, /* open mailbox */ nntp_mclose, /* close mailbox */ nntp_fetchfast, /* fetch message "fast" attributes */ nntp_flags, /* fetch message flags */ nntp_overview, /* fetch overview */ NIL, /* fetch message structure */ nntp_header, /* fetch message header */ nntp_text, /* fetch message text */ NIL, /* fetch message */ NIL, /* unique identifier */ NIL, /* message number from UID */ NIL, /* modify flags */ nntp_flagmsg, /* per-message modify flags */ nntp_search, /* search for message based on criteria */ nntp_sort, /* sort messages */ nntp_thread, /* thread messages */ nntp_ping, /* ping mailbox to see if still alive */ nntp_check, /* check for new messages */ nntp_expunge, /* expunge deleted messages */ nntp_copy, /* copy messages to another mailbox */ nntp_append, /* append string message to mailbox */ NIL /* garbage collect stream */}; /* prototype stream */MAILSTREAM nntpproto = {&nntpdriver}; /* driver parameters */static unsigned long nntp_maxlogintrials = MAXLOGINTRIALS;static long nntp_port = 0;static long nntp_sslport = 0;static unsigned long nntp_range = 0;static long nntp_hidepath = 0;/* NNTP validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *nntp_valid (char *name){ char tmp[MAILTMPLEN]; return nntp_isvalid (name,tmp);}/* NNTP validate mailbox work routine * Accepts: mailbox name * buffer for returned mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *nntp_isvalid (char *name,char *mbx){ NETMBX mb; if (!mail_valid_net_parse (name,&mb) || strcmp (mb.service,nntpdriver.name)|| mb.anoflag) return NIL; if (mb.mailbox[0] != '#') strcpy (mbx,mb.mailbox); /* namespace format name */ else if ((mb.mailbox[1] == 'n') && (mb.mailbox[2] == 'e') && (mb.mailbox[3] == 'w') && (mb.mailbox[4] == 's') && (mb.mailbox[5] == '.')) strcpy (mbx,mb.mailbox+6); else return NIL; /* bogus name */ return &nntpdriver;}/* News manipulate driver parameters * Accepts: function code * function-dependent value * Returns: function-dependent return value */void *nntp_parameters (long function,void *value){ switch ((int) function) { case SET_MAXLOGINTRIALS: nntp_maxlogintrials = (unsigned long) value; break; case GET_MAXLOGINTRIALS: value = (void *) nntp_maxlogintrials; break; case SET_NNTPPORT: nntp_port = (long) value; break; case GET_NNTPPORT: value = (void *) nntp_port; break; case SET_SSLNNTPPORT: nntp_sslport = (long) value; break; case GET_SSLNNTPPORT: value = (void *) nntp_sslport; break; case SET_NNTPRANGE: nntp_range = (unsigned long) value; break; case GET_NNTPRANGE: value = (void *) nntp_range; break; case SET_NNTPHIDEPATH: nntp_hidepath = (long) value; break; case GET_NNTPHIDEPATH: value = (void *) nntp_hidepath; break; case GET_NEWSRC: if (value) value = (void *) ((NNTPLOCAL *) ((MAILSTREAM *) value)->local)->newsrc; break; case GET_IDLETIMEOUT: value = (void *) IDLETIMEOUT; break; case ENABLE_DEBUG: if (value) ((NNTPLOCAL *) ((MAILSTREAM *) value)->local)->nntpstream->debug = T; break; case DISABLE_DEBUG: if (value) ((NNTPLOCAL *) ((MAILSTREAM *) value)->local)->nntpstream->debug = NIL; break; default: value = NIL; /* error case */ break; } return value;}/* NNTP mail scan mailboxes for string * Accepts: mail stream * reference * pattern to search * string to scan */void nntp_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){ char tmp[MAILTMPLEN]; if (nntp_canonicalize (ref,pat,tmp,NIL)) mm_log ("Scan not valid for NNTP mailboxes",ERROR);}/* NNTP list newsgroups * Accepts: mail stream * reference * pattern to search */void nntp_list (MAILSTREAM *stream,char *ref,char *pat){ MAILSTREAM *st = stream; char *s,*t,*lcl,pattern[MAILTMPLEN],name[MAILTMPLEN],wildmat[MAILTMPLEN]; int showuppers = pat[strlen (pat) - 1] == '%'; if (!*pat) { if (nntp_canonicalize (ref,"*",pattern,NIL)) { /* tie off name at root */ if ((s = strchr (pattern,'}')) && (s = strchr (s+1,'.'))) *++s = '\0'; else pattern[0] = '\0'; mm_list (stream,'.',pattern,NIL); } } /* ask server for open newsgroups */ else if (nntp_canonicalize (ref,pat,pattern,wildmat) && ((stream && LOCAL && LOCAL->nntpstream) || (stream = mail_open (NIL,pattern,OP_HALFOPEN|OP_SILENT))) && ((nntp_send (LOCAL->nntpstream,"LIST ACTIVE", wildmat[0] ? wildmat : NIL) == NNTPGLIST) || (nntp_send (LOCAL->nntpstream,"LIST",NIL) == NNTPGLIST))) { /* namespace format name? */ if (*(lcl = strchr (strcpy (name,pattern),'}') + 1) == '#') lcl += 6; /* process data until we see final dot */ while (s = net_getline (LOCAL->nntpstream->netstream)) { if ((*s == '.') && !s[1]){/* end of text */ fs_give ((void **) &s); break; } if (t = strchr (s,' ')) { /* tie off after newsgroup name */ *t = '\0'; strcpy (lcl,s); /* make full form of name */ /* report if match */ if (pmatch_full (name,pattern,'.')) mm_list (stream,'.',name,NIL); else while (showuppers && (t = strrchr (lcl,'.'))) { *t = '\0'; /* tie off the name */ if (pmatch_full (name,pattern,'.')) mm_list (stream,'.',name,LATT_NOSELECT); } } fs_give ((void **) &s); /* clean up */ } if (stream != st) mail_close (stream); }}/* NNTP list subscribed newsgroups * Accepts: mail stream * reference * pattern to search */void nntp_lsub (MAILSTREAM *stream,char *ref,char *pat)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -