/*
** $Id: rxrun.c,v 1.1 1999/02/10 23:17:14 tanchs1 Exp $
**
** Runs REXX scripts. Avoids nasty command tail limitations of
** CMD.EXE and 4OS2.EXE.
**
** Copyright (C) 1998  Andreas Huber <ahuber@ping.at>
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; see the file COPYING. If not, write to
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
*/
#define INCL_REXXSAA
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
#include <signal.h>
#include <string.h>

#define EXIT_USAGE	2
#define EXIT_SIGNAL	3

static char const* argv0 = "rxrun";

static ULONG SysGetPPid(
	PCSZ Name,
	ULONG Argc,
	RXSTRING Argv[],
	PCSZ Queuename,
	PRXSTRING Retstr)
{
	if (Argc != 0)
		return 40;
	sprintf((char*)Retstr->strptr, "%d", getppid());
	Retstr->strlength = strlen((char*)Retstr->strptr);
	return 0;
}

static int rexx_start(int argc, char const* argv[], int* status)
{
	size_t i;
	RXSTRING* rexx_argv;
	LONG result;
	SHORT rc;

	if (argc < 1) {
		errno = ENOEXEC;
		return -1;
	}
	if ((rexx_argv = calloc(argc-1, sizeof(RXSTRING))) == NULL) {
		errno = ENOMEM;
		return -1;
	}
	if ((result = RexxRegisterFunctionExe((PCSZ)"SysGetPPid",
			SysGetPPid)) != RXFUNC_OK) {
		free((void*)rexx_argv);
		errno = ENOEXEC;
		return -1;
	}
	for (i = 1; argv[i] != NULL; i++)
		MAKERXSTRING(rexx_argv[i-1], argv[i], strlen(argv[i]));
	result = RexxStart(argc-1, rexx_argv, (PCSZ)argv[0], NULL,
		NULL, RXCOMMAND, NULL, &rc, NULL);
	free((void*)rexx_argv);
	if (result > 0) {
		errno = ENOEXEC;
		return -1;
	}
	*status = result < 0 || rc == 255 ? SIGINT : rc << 8;
	return 0;
}

static void signal_handler(int sig)
{
	fprintf(stderr, "%s: *** [%s] ***\n",
		argv0, sig == SIGINT ? "SIGINT" : "SIGBREAK");
	fflush(stderr);
	exit(EXIT_SIGNAL);
}

int main(int argc, char const* argv[])
{
	int status;

	argv0 = (argv0 = strrchr(argv[0], '\\')) != NULL ||
			(argv0 = strrchr(argv[0], '/')) != NULL ||
			(argv0 = strrchr(argv[0], ':')) != NULL ? argv0+1 : argv[0];
	if (argc < 2) {
		printf("Usage: %s rexx-script [arguments...]\n", argv0);
		exit(EXIT_USAGE);
	}
	(void)signal(SIGINT, signal_handler);
	(void)signal(SIGBREAK, signal_handler);
	status = 0;
	if (rexx_start(argc-1, &argv[1], &status) < 0) {
		perror(argv[1]);
		exit(EXIT_FAILURE);
	}
	if (status == SIGINT)
		raise(SIGINT);
	return status >> 8;
}

