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