home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / net / nntp / nntpclient.java < prev    next >
Text File  |  1995-08-11  |  6KB  |  212 lines

  1. /*
  2.  * @(#)NntpClient.java    1.12 95/05/10 Jonathan Payne, James Gosling
  3.  * 
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for NON-COMMERCIAL purposes and without fee is hereby
  8.  * granted provided that this copyright notice appears in all copies. Please
  9.  * refer to the file "copyright.html" for further important copyright and
  10.  * licensing information.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  15.  * OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
  16.  * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  17.  * ITS DERIVATIVES.
  18.  */
  19.  
  20. package net.nntp;
  21.  
  22. import java.io.*;
  23. import net.*;
  24. import java.util.*;
  25.  
  26. /**
  27.  * This class implements network news clients (NNTP).
  28.  *
  29.  * @version    1.9, 12 Dec 1994
  30.  * @author    Jonathan Payne, James Gosling
  31.  */
  32. public class NntpClient extends TransferProtocolClient {
  33.     String serverName;        /* for re-opening server connections */
  34.     int serverPort;
  35.  
  36.     public NntpClient () {
  37.     }
  38.  
  39.     /** Create new NNTP Client connected to host <i>host</i> */
  40.     public NntpClient (String host) {
  41.     super();
  42.     openServer(host, InetAddress.getPortByName("nntp"));
  43.     }
  44.  
  45.     private void assert(boolean expr) {
  46.     if (!expr)
  47.         throw new Exception("assertion failed");
  48.     }
  49.  
  50.     /**
  51.      * Open a connection to the NNTP server.
  52.      * @exception NntpProtocolException did not get the correct welcome message
  53.      */
  54.     public void openServer(String name, int port) {
  55.     serverName = name;
  56.     serverPort = port;
  57.     super.openServer(name, port);
  58.     if (readServerResponse() >= 300)
  59.         throw new NntpProtocolException("Welcome message");
  60.     }
  61.  
  62.     /** Sends command <i>cmd</i> to the server. */
  63.     public int askServer(String cmd) {
  64.     int code = 503;
  65.     for (int tries = 3; --tries >= 0;) {
  66.         try {
  67.         serverOutput.print(cmd);
  68.         code = readServerResponse();
  69.         if (code < 500)
  70.             return code;
  71.  
  72.         /*
  73.          * errors codes >500 usually result from something happening
  74.          * on the net.  Its usually profitable to disconnect and
  75.          * reconnect
  76.          */
  77.         } catch(Exception e) {
  78.         }
  79.         /* reconnect to the server */
  80.         try {
  81.         serverOutput.close();
  82.         } catch(Exception e2) {
  83.         }
  84.         openServer(serverName, serverPort);
  85.     }
  86.     return code;
  87.     }
  88.  
  89.     InputStream makeStreamRequest(String cmd, int reply) {
  90.     int response;
  91.  
  92.     response = askServer(cmd + "\r\n");
  93.     if (response != reply) {
  94.         String msg = null;
  95.         try {
  96.         for (int i = 0; i < 99; i++) {
  97.             String n = (String) serverResponse.elementAt(i);
  98.             if (msg == null)
  99.             msg = n;
  100.             else
  101.             msg = msg + "\n" + n;
  102.         }
  103.         } catch(Exception e) {
  104.         };
  105.         if (msg == null)
  106.         msg = "Command " + cmd + " yielded " + response + "; expecting " + reply;
  107.         throw new NntpProtocolException(msg);
  108.     }
  109.     switch (response / 100) {
  110.       case 1:
  111.       case 2:
  112.         break;
  113.  
  114.       case 3:
  115.         throw new NntpProtocolException("More input to command expected");
  116.  
  117.       case 4:
  118.         throw new NntpProtocolException("Server error - cmd OK");
  119.  
  120.       case 5:
  121.         throw new NntpProtocolException("Error in command: " + cmd);
  122.     }
  123.     return new NntpInputStream(new TelnetInputStream(serverInput, false));
  124.     }
  125.     String tokenize(String input)[] {
  126.     Vector v = new Vector();
  127.     StringTokenizer t = new StringTokenizer(input);
  128.     String cmd[];
  129.  
  130.     while (t.hasMoreTokens())
  131.         v.addElement(t.nextToken());
  132.     cmd = new String[v.size()];
  133.     for (int i = 0; i < cmd.length; i++)
  134.         cmd[i] = (String) v.elementAt(i);
  135.  
  136.     return cmd;
  137.     }
  138.  
  139.     /**
  140.      * Get information about group <i>name</i>.
  141.      * @exception UnknownNewsgroupException the group name wasn't active.
  142.      * @exception NntpProtocolException received an unexpected reply.
  143.      */
  144.     public NewsgroupInfo getGroup(String name) {
  145.     switch (askServer("group " + name + "\r\n")) {
  146.       case 411:
  147.         throw new UnknownNewsgroupException(name);
  148.  
  149.       default:
  150.         throw new NntpProtocolException("unexpected reply: "
  151.                         + getResponseString());
  152.  
  153.       case 211:
  154.         {
  155.         String tokens[] = tokenize(getResponseString());
  156.         int start;
  157.         int end;
  158.  
  159.         assert(tokens[0].equals("211"));
  160.         assert(tokens.length >= 5);
  161.         start = Integer.parseInt(tokens[2]);
  162.         end = Integer.parseInt(tokens[3]);
  163.         assert(tokens[4].equals(name));
  164.         return new NewsgroupInfo(name, start, end);
  165.         }
  166.     }
  167.     }
  168.  
  169.     /** Set the current group to <i>name</i> */
  170.     public void setGroup(String name) {
  171.     if (askServer("group " + name + "\r\n") != 211)
  172.         throw new UnknownNewsgroupException(name);
  173.     }
  174.  
  175.     /** get article <i>n</i> from the current group. */
  176.     public InputStream getArticle(int n) {
  177.     return makeStreamRequest("article " + n, 220);
  178.     }
  179.  
  180.     /** get article <i>id</i> from the current group. */
  181.     public InputStream getArticle(String id) {
  182.     if (id.charAt(0) != '<')
  183.         id = "<" + id + ">";
  184.     return makeStreamRequest("article " + id, 220);
  185.     }
  186.  
  187.     /** get header of article <i>n</i> from the current group. */
  188.     public InputStream getHeader(int n) {
  189.     return makeStreamRequest("head " + n, 221);
  190.     }
  191.     /** get header of article <i>id</i> from the current group. */
  192.     public InputStream getHeader(String id) {
  193.     if (id.charAt(0) != '<')
  194.         id = "<" + id + ">";
  195.     return makeStreamRequest("head " + id, 221);
  196.     }
  197.     /** Setup to post a message.  It returns a stream
  198.         to which the article should be written.  Returns null if the post
  199.     is disallowed.  The article must have a properly formed RFC850 header
  200.     and end-of-lines must by sent as \r\n.  The Article must end with
  201.     \r\n */
  202.     public PrintStream startPost() {
  203.     return askServer("post\r\n") == 340 ? serverOutput : null;
  204.     }
  205.     /** Finish posting a message.  Must be called after calling startPost
  206.     and writing the article.  Returns true if the article is posted
  207.     successfully. */
  208.     public boolean finishPost() {
  209.     return askServer(".\r\n") == 240;
  210.     }
  211. }
  212.