/* This command was contributed by Mike Dixon <mdixon@parc.xerox.com>
 * cc -o performService -s -O performService.m -lNeXT_s
 * cc -arch m68k -arch i386 -o performService -s -O performService.m -lNeXT_s
 * cc -arch m68k -arch i386 -arch hppa -o performService -s -O performService.m -lNeXT_s
 */
#import <stdlib.h>
#import <stdio.h>
#import <libc.h>
#import <strings.h>
#import <appkit/appkit.h>

#define STDIN 0
#define STDOUT 1
#define STDERR 2

char *use =
"Use: performService <service> {-stdin | -input 'foo' | -empty} <inType> <outType>*\n";

id pb = 0;

void die (char *msg)
{
    write(STDERR, msg, strlen(msg));
    if (pb)
	[pb freeGlobally];
    exit(-1);
}

void main (int argc, char **argv) {
    const char *serviceName, *sendTypes[2], **recvTypes, *const *rcvdTypes, *const *p;
    char *sendBuf, *recvBuf;
    int nextArg, allocSize, bytesRead, sendLen, numRecvType, recvLen, i;

    if (argc < 4)
	die(use);

    serviceName = argv[1];
    nextArg = 2;

    if (! strcmp(argv[nextArg], "-stdin")) {
	allocSize = 15000;
	sendBuf = malloc(allocSize);
	sendLen = bytesRead = read(STDIN, sendBuf, allocSize);
	while (bytesRead>0) {
	    allocSize += allocSize;
	    sendBuf = realloc(sendBuf, sendLen + allocSize);
	    bytesRead = read(STDIN, sendBuf+sendLen, allocSize);
	    sendLen += bytesRead;
	}
	++nextArg;
    } else if (! strcmp(argv[nextArg], "-input")) {
	sendBuf = argv[nextArg+1];
	sendLen = strlen(sendBuf);
	nextArg += 2;
    } else if (! strcmp(argv[nextArg], "-empty")) {
	sendBuf = "";
	sendLen = 0;
	++nextArg;
    } else
	die(use);

    if (argc <= nextArg)
	die(use);

    sendTypes[0] = argv[nextArg];
    sendTypes[1] = 0;
    ++nextArg;

    numRecvType = argc - nextArg;
    recvTypes = &argv[nextArg];

    pb = [Pasteboard newUnique];
    NXApp=[Application new];
    [pb declareTypes: sendTypes num: 1 owner: NULL];

    if (! [pb writeType: sendTypes[0] data: sendBuf length: sendLen])
	die("Couldn't write my pasteboard.\n");

    if (! NXPerformService(serviceName, pb))
	die("No such service.\n");
    
    if (numRecvType == 0) {
	sleep( 10);
	[pb freeGlobally];
	exit(0);
    }

    rcvdTypes = [pb types];
    for (i = 0; i < numRecvType; i++)
	for (p = rcvdTypes; *p; p++)
	    if (! strcmp(recvTypes[i], *p)) {
		if ([pb readType: *p data: &recvBuf length: &recvLen]) {
		    write(STDOUT, recvBuf, recvLen);
		    [pb freeGlobally];
		    exit(0);
		}
		die("Error reading service reply.\n");
	    }
    die("No reply of the requested type received from service.\n");
}
