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

📄 nntpstore.java

📁 WebMail is a server application that allows ISPs to provide a WWW interface for each user to his mai
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * NNTPStore.java * Copyright (C) 1999 dog <dog@dog.net.uk> *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *  * You may retrieve the latest version of this library from * http://www.dog.net.uk/knife/ */package dog.mail.nntp;import java.io.*;import java.net.*;import java.util.*;import javax.mail.*;import javax.mail.event.*;import javax.mail.internet.*;import dog.mail.util.*;import dog.util.*;/** * The storage class implementing the NNTP Usenet news protocol. * * @author dog@dog.net.uk * @version 1.2 */public class NNTPStore extends Store implements StatusSource {	/**	 * The default NNTP port.	 */	public static final int DEFAULT_PORT = 119;		static int fetchsize = 1024;	Socket socket;	CRLFInputStream in;	CRLFOutputStream out;	String hostname;	String response;    static final int HELP = 100;    static final int READY = 200;    static final int READ_ONLY = 201;    static final int STREAMING_OK = 203;    static final int CLOSING = 205;	static final int GROUP_SELECTED = 211; // or list of article numbers follows	static final int LISTING = 215; // list of newsgroups follows	static final int ARTICLE_RETRIEVED_BOTH = 220;	static final int ARTICLE_RETRIEVED_HEAD = 221; // or header follows	static final int ARTICLE_RETRIEVED_BODY = 222;	static final int ARTICLE_RETRIEVED = 223;	static final int LISTING_OVERVIEW = 224;	static final int LISTING_ARTICLES = 230; // list of new articles by message-id follows	static final int LISTING_NEW = 231; // list of new newsgroups follows	static final int ARTICLE_POSTED = 240; // article posted ok	static final int AUTHINFO_OK = 281;	static final int SEND_ARTICLE = 340; // send article to be posted. End with <CR-LF>.<CR-LF>	static final int SEND_AUTHINFOPASS = 381; // send password (response to user name)    static final int SERVICE_DISCONTINUED = 400;	static final int NO_SUCH_GROUP = 411;	static final int NO_GROUP_SELECTED = 412; // no newsgroup has been selected	static final int NO_ARTICLE_SELECTED = 420; // no current article has been selected	static final int NO_SUCH_ARTICLE_IN_GROUP = 423; // no such article number in this group	static final int NO_SUCH_ARTICLE = 430; // no such article found	static final int POSTING_NOT_ALLOWED = 440; // posting not allowed	static final int POSTING_FAILED = 441; // posting failed    static final int COMMAND_NOT_RECOGNIZED = 500;    static final int COMMAND_SYNTAX_ERROR = 501;    static final int PERMISSION_DENIED = 502;    static final int SERVER_ERROR = 503;	boolean postingAllowed = false;    Root root;	Newsgroup current;    Date lastNewGroup;	Hashtable newsgroups = new Hashtable(); // hashtable of newsgroups by name	Hashtable articles = new Hashtable(); // hashtable of articles by message-id	Vector statusListeners = new Vector();		/**	 * Constructor.	 */	public NNTPStore(Session session, URLName urlname) {		super(session, urlname);		String ccs = session.getProperty("mail.nntp.fetchsize");		if (ccs!=null) try { fetchsize = Math.max(Integer.parseInt(ccs), 1024); } catch (NumberFormatException e) {}	}		/**	 * Connects to the NNTP server and authenticates with the specified parameters.	 */	protected boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {		if (port<0) port = DEFAULT_PORT;		if (host==null)			return false;		try {            boolean debug = session.getDebug();						hostname = host;			if (debug)				System.err.println("DEBUG: nntp: opening connection to "+hostname);			socket = new Socket(host, port);			in = new CRLFInputStream(new BufferedInputStream(socket.getInputStream()), fetchsize);			out = new CRLFOutputStream(new BufferedOutputStream(socket.getOutputStream()));						switch (getResponse()) {			case READY:				postingAllowed = true;			case READ_ONLY:				//StringTokenizer st = new StringTokenizer(response);				//if (st.hasMoreTokens()) hostname = st.nextToken();				break;			default:				throw new MessagingException("unexpected server response: "+response);			}						send("MODE READER"); // newsreader extension			switch (getResponse()) {			case READY:				postingAllowed = true;			case READ_ONLY:				break;			}						// NNTP basic authentication			// introduced by Volker Schmidt <vs75@gmx.de>			// NOTE: need to handle multiple varities of authentication (kerberos, etc)			if (username!=null && password!=null) {				send("AUTHINFO USER "+username);				if (getResponse()!=SEND_AUTHINFOPASS)					throw new AuthenticationFailedException(response);				send("AUTHINFO PASS "+password);				if (getResponse()!=AUTHINFO_OK)					throw new AuthenticationFailedException(response);			}			// end authentication				if (debug)				System.err.println("DEBUG: nntp: connected to "+hostname+", posting is "+(postingAllowed ? "" : "not ")+"allowed");			addStore(this);			readNewsrc();						return true;		} catch(UnknownHostException e) {			throw new MessagingException("unknown host", e);		} catch(IOException e) {			throw new MessagingException("I/O error", e);		}	}	/**	 * Closes the connection.	 */	public synchronized void close() throws MessagingException {		if (socket!=null)			try {				boolean debug = session.getDebug();								if (debug)					System.err.println("DEBUG: nntp: closing connection to "+hostname);				send("QUIT");				switch (getResponse()) {				case CLOSING:					break;				case SERVER_ERROR:					if (response.toLowerCase().indexOf("timeout")>-1)						break;				default:					throw new MessagingException("unexpected server response: "+response);				}				removeStore(this);				socket.close();				socket = null;								if (debug)					System.err.println("DEBUG: nntp: closed connection to "+hostname);			} catch (IOException e) {				// socket.close() seems to throw an exception!				//throw new MessagingException("Close failed", e);			}		super.close();	}	/**	 * Returns the hostname of the server.	 */	public String getHostName() { return hostname; }	int getResponse() throws IOException {		response = in.readLine();		boolean debug = session.getDebug();				if (debug)			System.err.println("DEBUG: nntp: <"+response);				if (response==null)			response = SERVER_ERROR+" timeout";		try {			int index = response.indexOf(' ');			if (index>-1) {				int code = Integer.parseInt(response.substring(0, index));				response = response.substring(index+1);				return code;			} else {				int code = Integer.parseInt(response);				return code;			}		} catch (StringIndexOutOfBoundsException e) {			throw new ProtocolException("NNTP protocol exception: "+response);		} catch (NumberFormatException e) {			throw new ProtocolException("NNTP protocol exception: "+response);		}	}	void send(String command) throws IOException {		boolean debug = session.getDebug();				if (debug)			System.err.println("DEBUG: nntp: >"+command);				out.write(command.getBytes());		out.writeln();		out.flush();	}    // Opens a newsgroup.	synchronized void open(Newsgroup group) throws MessagingException {		if (current!=null) {			if (current.equals(group))				return;			else				close(current);		}		String name = group.getName();		try {			send("GROUP "+name);            int r = getResponse();			switch (r) {			  case GROUP_SELECTED:				try {					updateGroup(group, response);					group.open = true;					current = group;				} catch (NumberFormatException e) {					throw new MessagingException("NNTP protocol exception: "+response, e);				}				break;			  case NO_SUCH_GROUP:				throw new MessagingException(response);			  case SERVER_ERROR:				if (response.toLowerCase().indexOf("timeout")>-1) {					close();					connect();					open(group);					break;				}			  default:				throw new MessagingException("unexpected server response ("+r+"): "+response);			}		} catch (IOException e) {			throw new MessagingException("I/O error", e);		}	}    // Updates a newsgroup with the most recent article counts.	void updateGroup(Newsgroup newsgroup, String response) throws IOException {		try {			StringTokenizer st = new StringTokenizer(response, " ");            newsgroup.count = Integer.parseInt(st.nextToken());            newsgroup.first = Integer.parseInt(st.nextToken());			newsgroup.last = Integer.parseInt(st.nextToken());						boolean debug = session.getDebug();						if (debug)				System.err.println("DEBUG: nntp: "+newsgroup.name+": "+newsgroup.count+" articles");				} catch (NumberFormatException e) {			throw new ProtocolException("NNTP protocol exception");		} catch (NoSuchElementException e) {			throw new ProtocolException("NNTP protocol exception");		}	}    // Closes a newsgroup.	synchronized void close(Newsgroup group) throws MessagingException {		if (current!=null && !current.equals(group)) close(current);		group.open = false;	}	    // Returns the (approximate) number of articles in a newsgroup.	synchronized int getMessageCount(Newsgroup group) throws MessagingException {        String name = group.getName();		try {			send("GROUP "+name);			switch (getResponse()) {			  case GROUP_SELECTED:				try {					updateGroup(group, response);					current = group;					return group.count;				} catch(NumberFormatException e) {					throw new MessagingException("NNTP protocol exception: "+response, e);				}			  case NO_SUCH_GROUP:				throw new MessagingException("No such group");			  case SERVER_ERROR:				if (response.toLowerCase().indexOf("timeout")>-1) {					close();					connect();					return getMessageCount(group);				}			  default:				throw new MessagingException("unexpected server response: "+response);			}		} catch (IOException e) {			throw new MessagingException("I/O error", e);		}	}    // Returns the headers for an article.	synchronized InternetHeaders getHeaders(Article article) throws MessagingException {		new Throwable().printStackTrace();		String mid = article.messageId;		if (mid==null) {			Newsgroup group = (Newsgroup)article.getFolder();			if (!current.equals(group)) open(group);			mid = Integer.toString(article.getMessageNumber());		}		try {			send("HEAD "+mid);			switch (getResponse()) {			  case ARTICLE_RETRIEVED_HEAD:				return new InternetHeaders(new MessageInputStream(in));			  case NO_GROUP_SELECTED:				throw new MessagingException("No group selected");			  case NO_ARTICLE_SELECTED:				throw new MessagingException("No article selected");			  case NO_SUCH_ARTICLE_IN_GROUP:				//throw new MessagingException("No such article in group");				return null;			  case NO_SUCH_ARTICLE:				throw new MessagingException("No such article");			  case SERVER_ERROR:				if (response.toLowerCase().indexOf("timeout")>-1) {					close();					connect();					return getHeaders(article);				}			  default:

⌨️ 快捷键说明

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