    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 char[] __buffer = new char[1024];
    064
    065        /***
    066         * The default FingerClient constructor.  Initializes the
    067         * default port to <code> DEFAULT_PORT </code>.
    068         ***/
    069        public FingerClient()
    070        {
    071            setDefaultPort(DEFAULT_PORT);
    072        }
    073
    074
    075        /***
    076         * Fingers a user at the connected host and returns the output
    077         * as a String.  You must first connect to a finger server before
    078         * calling this method, and you should disconnect afterward.
    079         * <p>
    080         * @param longOutput Set to true if long output is requested, false if not.
    081         * @param username  The name of the user to finger.
    082         * @return The result of the finger query.
    083         * @exception IOException If an I/O error occurs while reading the socket.
    084         ***/
    085        public String query(boolean longOutput, String username) throws IOException
    086        {
    087            int read;
    088            StringBuilder result = new StringBuilder(__buffer.length);
    089            BufferedReader input;
    090
    091            input =
    092                new BufferedReader(new InputStreamReader(getInputStream(longOutput,
    093                                   username)));
    094
    095            try {
    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            } finally {
    104                input.close();
    105            }
    106
    107            return result.toString();
    108        }
    109
    110
    111        /***
    112         * Fingers the connected host and returns the output
    113         * as a String.  You must first connect to a finger server before
    114         * calling this method, and you should disconnect afterward.
    115         * This is equivalent to calling <code> query(longOutput, "") </code>.
    116         * <p>
    117         * @param longOutput Set to true if long output is requested, false if not.
    118         * @return The result of the finger query.
    119         * @exception IOException If an I/O error occurs while reading the socket.
    120         ***/
    121        public String query(boolean longOutput) throws IOException
    122        {
    123            return query(longOutput, "");
    124        }
    125
    126
    127        /***
    128         * Fingers a user and returns the input stream from the network connection
    129         * of the finger query.  You must first connect to a finger server before
    130         * calling this method, and you should disconnect after finishing reading
    131         * the stream.
    132         * <p>
    133         * @param longOutput Set to true if long output is requested, false if not.
    134         * @param username  The name of the user to finger.
    135         * @return The InputStream of the network connection of the finger query.
    136         *         Can be read to obtain finger results.
    137         * @exception IOException If an I/O error during the operation.
    138         ***/
    139        public InputStream getInputStream(boolean longOutput, String username)
    140        throws IOException
    141        {
    142            return getInputStream(longOutput, username, null);
    143        }
    144
    145        /***
    146         * Fingers a user and returns the input stream from the network connection
    147         * of the finger query.  You must first connect to a finger server before
    148         * calling this method, and you should disconnect after finishing reading
    149         * the stream.
    150         * <p>
    151         * @param longOutput Set to true if long output is requested, false if not.
    152         * @param username  The name of the user to finger.
    153         * @param encoding the character encoding that should be used for the query,
    154         *        null for the platform's default encoding
    155         * @return The InputStream of the network connection of the finger query.
    156         *         Can be read to obtain finger results.
    157         * @exception IOException If an I/O error during the operation.
    158         ***/
    159        public InputStream getInputStream(boolean longOutput, String username, String encoding)
    160        throws IOException
    161        {
    162            DataOutputStream output;
    163            StringBuilder buffer = new StringBuilder(64);
    164            if (longOutput)
    165                buffer.append(__LONG_FLAG);
    166            buffer.append(username);
    167            buffer.append(SocketClient.NETASCII_EOL);
    168
    169            byte[] encodedQuery =
    170                    (encoding == null ? buffer.toString().getBytes() : buffer.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    }