// Copyright 1997, Omni Development Inc.  All Rights Reserved.

#import <Foundation/Foundation.h>
#import <OmniNetworking/OmniNetworking.h>

volatile void usage(const char *pgm)
{
    fprintf(stderr,
            "usage: %s [-send | -receive] multicast-address multicast-port\n",
            pgm);
    exit(1);
}

static void _sendLoop(ONPortAddress *portAddress);
static void _receiveLoop(ONHostAddress *hostAddress, unsigned short port);

int main (int argc, const char *argv[])
{
    NSAutoreleasePool *pool;
    BOOL               isSending = NO;
    NSString          *hostName;
    unsigned short     hostPort;
    ONHostAddress     *hostAddress;
    ONPortAddress     *portAddress;
    ONHost            *host;
    
    pool = [[NSAutoreleasePool alloc] init];

    if (argc != 4)
        usage(argv[0]);

    if (!strcmp("-send", argv[1]))
        isSending = YES;
    else if (!strcmp("-receive", argv[1]))
        isSending = NO;
    else
        usage(argv[0]);

    hostName = [[NSString alloc] initWithCString: argv[2]];
    hostPort   = atoi(argv[3]);

    
    host = [ONHost hostForHostname: hostName];
    if (![[host addresses] count]) {
        fprintf(stderr, "Cannot determine an address for %s\n", argv[2]);
        exit(1);
    }

    hostAddress = [[host addresses] objectAtIndex: 0];
    portAddress = [[ONPortAddress alloc] initWithHostAddress: hostAddress
                                                  portNumber: hostPort];

    if (isSending)
        _sendLoop(portAddress);
    else
        _receiveLoop(hostAddress, hostPort);
    
    [pool release];
    exit(0);       // insure the process exit status is 0
    return 0;      // ...and make main fit the ANSI spec.
}

static void _sendLoop(ONPortAddress *portAddress)
{
    NSFileHandle      *stdinHandle;
    NSData            *data;
    ONMulticastSocket *multicastSocket;

    multicastSocket = (ONMulticastSocket *)[ONMulticastSocket socket];
    stdinHandle = [NSFileHandle fileHandleWithStandardInput];

    while ((data = [stdinHandle availableData]))
        [multicastSocket writeBytes: [data length]
                         fromBuffer: [data bytes]
                      toPortAddress: portAddress];
}

static void _receiveLoop(ONHostAddress *hostAddress, unsigned short port)
{
    NSFileHandle      *stdoutHandle;
    NSMutableData     *data;
    ONMulticastSocket *multicastSocket;

    multicastSocket = (ONMulticastSocket *)[ONMulticastSocket socket];
    [multicastSocket setLocalPortNumber: port allowingAddressReuse: YES];

    [multicastSocket joinReceiveGroup: hostAddress];
    
    data = [NSMutableData dataWithLength: 256];
    stdoutHandle = [NSFileHandle fileHandleWithStandardOutput];
    while (YES) {
        unsigned int length;

        length = [multicastSocket readBytes: 256
                                 intoBuffer: [data mutableBytes]];
        [data setLength: length];
        
        [stdoutHandle writeData: data];
    }
}
