package thundernet.afp;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  AFPd.java                          Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  As an AFP server, accepts connections from AFP clients.  Packets that    */
/*      are recieved are responded to as appropriate for the protocol.       */
/*                                                                           */
/*  Public Methods:                                                          */
/*      APFd()                                                               */
/*      main()                                                               */
/*      kill()                                                               */
/*      run()                                                                */
/*      sendPacket()                                                         */
/*                                                                           */
/*  Date      Who  Comment                                                   */
/*  -----------------------------------------------------------------------  */
/*  24mar01   acp  initial creation                                          */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

import  java.io.*;
import  java.net.*;
import  java.util.*;
import  thundernet.afp.*;
import  thundernet.util.*;



public class AFPd
{

    //
    // private instance variables
    private int                 afpPort;
    private Socket              client;
    private Properties          config;
    private boolean             dead;
    private BufferedInputStream in;
    private PrintStream         log;
    private OutputStream        out;
    private AFPpacket           packet;
    private byte[]              mySenderId;
    private ServerSocket        serverSocket;



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  AFPd()                             Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Primary constructor.  Initializes internal data.                         */
/*                                                                           */
/*  args:                                                                    */
/*       none      no comment                                                */
/*                                                                           */
/*  return:                                                                  */
/*       n/a                                                                 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public AFPd() throws java.lang.Exception
{

    dead = false;
    log = System.out;

    //
    // read in the properties file and initialize instance variables
    //
    config = new Properties();
    config.load(new FileInputStream(System.getProperty("CONFIG")));

    afpPort = Integer.parseInt(config.getProperty(AFP.PROP_AFP_LISTENER_PORT));
    serverSocket = new ServerSocket(afpPort);


    mySenderId = new byte[6];
    mySenderId[0] = (byte)0x21;
    mySenderId[1] = (byte)0x21;
    mySenderId[2] = (byte)0x21;
    mySenderId[3] = (byte)0x21;
    mySenderId[4] = (byte)0x21;
    mySenderId[5] = (byte)0x21;

    packet = new AFPpacket();

}   /* end of method AFPd() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  main()                             Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Program entry point.                                                     */
/*                                                                           */
/*  cmd line> java thundernet.afp.AFPd -DCONFIG=<properties-file>            */
/*                                                                           */
/*  args:                                                                    */
/*       args       command line arguments                                   */
/*                                                                           */
/*  return:                                                                  */
/*       none                                                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public static void main(String[] args)
{

    AFPd    afpd;

    //
    // validate the command line before continuing
    //
    if (System.getProperty("CONFIG") == null)
    {
        System.out.println("AFPd: CONFIG property not found");
        System.out.println("Usage: java thundernet.afp.AFPd -DCONFIG=<properties-file>");
        System.exit(101);
    }

    //
    // instantiate the server and off we go
    //
    try
    {
        afpd = new AFPd();
        afpd.run();
    }
    catch (java.lang.Exception e)
    {
        System.err.println(e);
        e.printStackTrace();
    }

}   /* end of method main() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  kill()                             Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Sets the dead flag so the server can die gracefully.                     */
/*                                                                           */
/*  args:                                                                    */
/*       none      no comment                                                */
/*                                                                           */
/*  return:                                                                  */
/*       none                                                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
private void kill()
{

    dead = true;

}   /* end of method kill() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  run()                              Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  main control loop.                                                       */
/*                                                                           */
/*  args:                                                                    */
/*       none      no comment                                                */
/*                                                                           */
/*  return:                                                                  */
/*       none                                                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
private void run()
{

    while (!dead)
    {
        try
        {
            //
            // accept a connection from a client
            //
            client = serverSocket.accept();
            in = new BufferedInputStream(client.getInputStream());
            out = client.getOutputStream();

            packet.clear();
            packet.recv(in);

            switch (packet.cmd)
            {
                case AFPpacket.CMD_AUTHENTICATE:
                    log.println("AFP Authentication packet received");
                    sendPacket(AFPpacket.CMD_OK_TO_SEND, new byte[0]);
                    log.println("AFP OK To Send packet sent");
                    packet.recv(in);
                    if (packet.cmd == AFPpacket.CMD_EDX_MESSAGE)
                    {
                        log.println("AFP Edx packet received");
                        sendPacket(AFPpacket.CMD_ACK, null);
                        log.println("AFP ACK packet sent");
                    }
                    else
                    {
                        log.println("AFP protocol violation ... expecting Edx packet and got something else");
                        log.println(packet);
                        sendPacket(AFPpacket.CMD_NACK, null);
                    }
                    break;

                case AFPpacket.CMD_EDX_MESSAGE:
                    log.println("AFP EDX Message packet received");
                    break;

                case AFPpacket.CMD_QUERY:
                    log.println("AFP Query packet received");
                    break;

                case AFPpacket.CMD_EVENT:
                    log.println("AFP Event packet received");
                    break;

                case AFPpacket.CMD_ACK:
                    log.println("AFP ACK packet received");
                    break;

                case AFPpacket.CMD_NACK:
                    log.println("AFP NACK packet received");
                    break;

                default:
                    log.println("Unexpected AFP packet received");
                    break;
            }

            client.close();
        }
        catch (java.lang.Exception e)
        {
            e.printStackTrace();
            this.kill();
        }
    }

}   /* end of method run() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  sendPacket()                       Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Sends an AFP packet with the given command and body.                     */
/*                                                                           */
/*  args:                                                                    */
/*      argCmd          packet command                                       */
/*      argBody         body of packet                                       */
/*                                                                           */
/*  return:                                                                  */
/*       none                                                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
private void sendPacket(byte argCmd, byte[] argBody) throws java.io.IOException
{

    packet.clear();
    //
    // set up the packet and then send it
    //
    packet.type = AFPpacket.TYPE_EDX_MSG;
    System.arraycopy(mySenderId, 0, packet.ID, 0, packet.ID.length);
    packet.version = AFPpacket.VERSION_1_0;
    packet.cmd = argCmd;
    packet.priority = AFPpacket.PRIORITY_EDX;

        // Since we know this is an Authenticate packet, we
        // know the length and content of the body now.
    packet.length[0] = (byte)0x00;
    packet.length[1] = (byte)0x00;
    packet.length[2] = (byte)0x00;
    packet.length[3] = (byte)0x00;

    if (argBody != null)
    {
        System.arraycopy(tools.int2ByteArray(argBody.length, 1), 0, packet.length, 4, 4);
    }
    else
    {
        packet.length[4] = (byte)0x00;
        packet.length[5] = (byte)0x00;
        packet.length[6] = (byte)0x00;
        packet.length[7] = (byte)0x00;
    }

    packet.body = argBody;
    packet.eot = AFPpacket.EOT;

    packet.send(out);

}   /* end of method sendPacket() */



}   /* end of class AFPd */


  Copyright © Thundernet Development Group Inc., 2003.
All rights reserved.