001    /*
002     * Copyright 2001-2005 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.net;
017    
018    import java.io.BufferedReader;
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.io.InputStreamReader;
022    import java.io.BufferedOutputStream;
023    import java.io.DataOutputStream;
024    
025    /***
026     * The FingerClient class implements the client side of the Internet Finger
027     * Protocol defined in RFC 1288.  To finger a host you create a
028     * FingerClient instance, connect to the host, query the host, and finally
029     * disconnect from the host.  If the finger service you want to query is on
030     * a non-standard port, connect to the host at that port.
031     * Here's a sample use:
032     * <pre>
033     *    FingerClient finger;
034     *
035     *    finger = new FingerClient();
036     *
037     *    try {
038     *      finger.connect("foo.bar.com");
039     *      System.out.println(finger.query("foobar", false));
040     *      finger.disconnect();
041     *    } catch(IOException e) {
042     *      System.err.println("Error I/O exception: " + e.getMessage());
043     *      return;
044     *    }
045     * </pre>
046     * <p>
047     * <p>
048     * @author Daniel F. Savarese
049     ***/
050    
051    public class FingerClient extends SocketClient
052    {
053        /***
054         * The default FINGER port.  Set to 79 according to RFC 1288.
055         ***/
056        public static final int DEFAULT_PORT = 79;
057    
058        private static final String __LONG_FLAG = "/W ";
059    
060        private transient StringBuffer __query = new StringBuffer(64);
061        private transient char[] __buffer = new char[1024];
062    
063        /***
064         * The default FingerClient constructor.  Initializes the
065         * default port to <code> DEFAULT_PORT </code>.
066         ***/
067        public FingerClient()
068        {
069            setDefaultPort(DEFAULT_PORT);
070        }
071    
072    
073        /***
074         * Fingers a user at the connected host and returns the output
075         * as a String.  You must first connect to a finger server before
076         * calling this method, and you should disconnect afterward.
077         * <p>
078         * @param longOutput Set to true if long output is requested, false if not.
079         * @param username  The name of the user to finger.
080         * @return The result of the finger query.
081         * @exception IOException If an I/O error occurs while reading the socket.
082         ***/
083        public String query(boolean longOutput, String username) throws IOException
084        {
085            int read;
086            StringBuffer result = new StringBuffer(__buffer.length);
087            BufferedReader input;
088    
089            input =
090                new BufferedReader(new InputStreamReader(getInputStream(longOutput,
091                                   username)));
092    
093            while (true)
094            {
095                read = input.read(__buffer, 0, __buffer.length);
096                if (read <= 0)
097                    break;
098                result.append(__buffer, 0, read);
099            }
100    
101            input.close();
102    
103            return result.toString();
104        }
105    
106    
107        /***
108         * Fingers the connected host and returns the output
109         * as a String.  You must first connect to a finger server before
110         * calling this method, and you should disconnect afterward.
111         * This is equivalent to calling <code> query(longOutput, "") </code>.
112         * <p>
113         * @param longOutput Set to true if long output is requested, false if not.
114         * @return The result of the finger query.
115         * @exception IOException If an I/O error occurs while reading the socket.
116         ***/
117        public String query(boolean longOutput) throws IOException
118        {
119            return query(longOutput, "");
120        }
121    
122    
123        /***
124         * Fingers a user and returns the input stream from the network connection
125         * of the finger query.  You must first connect to a finger server before
126         * calling this method, and you should disconnect after finishing reading
127         * the stream.
128         * <p>
129         * @param longOutput Set to true if long output is requested, false if not.
130         * @param username  The name of the user to finger.
131         * @return The InputStream of the network connection of the finger query.
132         *         Can be read to obtain finger results.
133         * @exception IOException If an I/O error during the operation.
134         ***/
135        public InputStream getInputStream(boolean longOutput, String username)
136        throws IOException
137        {
138            DataOutputStream output;
139    
140            __query.setLength(0);
141            if (longOutput)
142                __query.append(__LONG_FLAG);
143            __query.append(username);
144            __query.append(SocketClient.NETASCII_EOL);
145    
146            output =
147              new DataOutputStream(new BufferedOutputStream(_output_, 1024));
148            output.writeBytes(__query.toString());
149            output.flush();
150    
151            return _input_;
152        }
153    
154    
155        /***
156         * Fingers the connected host and returns the input stream from
157         * the network connection of the finger query.  This is equivalent to
158         * calling getInputStream(longOutput, "").  You must first connect to a
159         * finger server before calling this method, and you should disconnect
160         * after finishing reading the stream.
161         * <p>
162         * @param longOutput Set to true if long output is requested, false if not.
163         * @return The InputStream of the network connection of the finger query.
164         *         Can be read to obtain finger results.
165         * @exception IOException If an I/O error during the operation.
166         ***/
167        public InputStream getInputStream(boolean longOutput) throws IOException
168        {
169            return getInputStream(longOutput, "");
170        }
171    
172    }