/*************************************************************************
 * File: $Source: /usr/usrs/xsource/xmfm/RCS/buttoncb.c,v $
 * Author: Jan Newmarch
 * Last modified: $Date: 1992/11/17 00:35:37 $
 * Version: $Revision: 1.9 $
 * Purpose: handle the callback events from various buttons being pressed
 *
 * Revision history:
 *	7 Aug 92	stdin of no-xterm do_commands set to /dev/null
 *	16 Oct 92	caddr_t changed to XtPointer
 *       3 Nov 92       lint-ed
 ************************************************************************/ 

#include "copyright.h"

/*************************************************************************
 * System includes
 ************************************************************************/ 
#include <stdio.h>
#include <Xm/Xm.h>
#include <X11/cursorfont.h>
#include <string.h>
#ifdef vax11c
#include <ctype.h>
#endif /* vax11c */

/*************************************************************************
 * Local includes
 ************************************************************************/ 
#include "const.h"
#include "types.h"
#ifdef RDD
#include "rdd.h"
#endif
#ifdef vax11c
#include "vms_cmd_services.h"
#endif /* vax11c */

/*************************************************************************
 * Functions exported
 ************************************************************************/ 
extern void FileButtonPressedCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);
extern void FileButtonReleasedCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);
extern void FileToolButtonPressedCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);
#ifdef vax11ca
extern void do_command (
#ifdef UseFunctionPrototypes
	char *command, int refresh_dir, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi
#endif
);
#else
extern void do_command (
#ifdef UseFunctionPrototypes
	char *command, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi
#endif
);
#endif /* vax11c */

/*************************************************************************
 * Variables exported
 ************************************************************************/ 

/*************************************************************************
 * Extern functions
 ************************************************************************/ 
extern void builtin_command (
#ifdef UseFunctionPrototypes
	char *command, dir_pane_info *dpi
#endif
);
extern void BusyCursor (
#ifdef UseFunctionPrototypes
	Widget toplevel
#endif
);
extern void UnBusyCursor (
#ifdef UseFunctionPrototypes
	Widget toplevel
#endif
);
extern void PromptDialog (
#ifdef UseFunctionPrototypes
	Widget parent, char *prompt, int modal, char **answer
#endif
);
extern Bool XtChdir (
#ifdef UseFunctionPrototypes
	char *dir
#endif
);

/*************************************************************************
 * Extern variables
 ************************************************************************/ 
extern file_action *actions;
extern XmString empty_string;

/*************************************************************************
 * Forward functions
 ************************************************************************/ 
static void expand_command (
#ifdef UseFunctionPrototypes
	char **command, char **argv, int argc, char *action
#endif
);
#ifdef vax11c
void do_command (
#ifdef UseFunctionPrototypes
	char *command, int refresh_dir, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi
#endif
);
#else
void do_command (
#ifdef UseFunctionPrototypes
	char *command, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi
#endif
);
#endif /* vax11c */
void expand_prompt ();

/*************************************************************************
 * Local variables
 ************************************************************************/ 

#ifdef vax11c
#define XTERM_STR "CREATE/TERM=DECTERM/WINDOW=(TITLE=\""
#define PAUSEME_STR "\")/WAIT "
#define EXEC_STR "\")/WAIT "
#else
#define XTERM_STR "xterm -title '"
#define PAUSEME_STR "' -exec pauseme '"
#define EXEC_STR "' -exec sh -c '"
#endif /* vax11c */

#define COMM_SIZE		4096
#define IS_WHITE_SPACE(c)	((c) == ' ' || (c) == '\t' || (c) == '\n')
#define STRING_LEN_CHECK(size)	if ((int)(new_str + (size) - *command) > COMM_SIZE)\
				{	fprintf (stderr, "action too long\n");\
					*new_str = '\0';\
					return;}

/*************************************************************************
 * Function: invert_colours ()
 * Purpose: swap  the fg and bg of the label and pixmap
 * In parameters: w
 * Out parameters:
 * Side effects: pne_button_info of button has label, pixmap swapped
 *	with inverted versions
 * Precondition:
 * Postcondition: label shows inverted.
 ************************************************************************/ 
void
invert_colours 
#ifdef UseFunctionPrototypes
	(Widget w)
#else
	(w)
	Widget w;

#endif
{	
	pane_button_info *pbi;
	Pixmap tmp_pixmap;
	GC tmp_gc;

	if (w == NULL)
		return;
	XtVaGetValues (w,
		XmNuserData, (XtArgVal) &pbi,
		NULL);
	
	/* swap the gc and pixmap with reversed forms */
	tmp_pixmap = pbi -> pixmap;
	pbi -> pixmap = pbi -> pixmap_reversed;
	pbi -> pixmap_reversed = tmp_pixmap;

	tmp_gc = pbi -> gc;
	pbi -> gc = pbi -> gc_reversed;
	pbi -> gc_reversed = tmp_gc;

	/* set the reversed pixmap in the button */
	XtVaSetValues (w,
		XmNlabelPixmap, (XtArgVal) pbi -> pixmap,
		NULL);
	
	/* and force a redisplay to redraw name */
	XClearArea (XtDisplay (w), XtWindow (w),
			0, 0, 1, 1, True);
}
/*************************************************************************
 * Function: FileButtonPressedCB ()
 * Purpose: handle a button press in any of the panes i.e. a file has
 *          been selected
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition: a button for a file, executable, or 
 *               directory has been pressed
 * Postcondition: toolbar buttons set up to reflect actions for this 
 *               selected file
 * Warning: this function is called by others that set last 2 params
 *	to NULL
 ************************************************************************/ 

/* ARGSUSED */
void
FileButtonPressedCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)
	Widget w;
	XtPointer client_data;
	XtPointer call_data;

#endif
{	
	pane_button_info *pbi;
	tool_button_info *tbi;
	file_action *pfa;
	action_pair *pap;
	XmString xmstr;
	int button;
	Widget tool_button;

#ifdef DEBUG
	fprintf (stderr, "button pressed\n");
#endif
	/* get the user data */
	XtVaGetValues (w,
			XmNuserData, (XtArgVal) &pbi,
			NULL);

	/* set the last selected back to normal and invert this one */
	if (pbi -> dpi -> file_selected != NULL)
		invert_colours (pbi -> dpi -> file_button_selected);
	invert_colours (w);
	
	/* set the file selected */
	pbi -> dpi -> file_selected = pbi -> name;
	pbi -> dpi -> file_button_selected = w;
	pbi -> dpi -> executable_selected = NULL;
	pbi -> dpi -> dir_selected = NULL;

	/* find file pattern matching this name */
	pfa = actions;
	while (pfa != NULL) {
#ifdef vax11c
		char temp_buffer[MAXPATHLEN+1];

		/*
		 *	If this is the "[-]" equivalent to ".." then
		 *	substitue a dummy name to allow the regular expression
		 *	to match to the correct pixmap
		 */
		if (!strcmp (pbi -> name, "[-]"))
			strcpy (temp_buffer, "VMS_UNIX_DIR_HACK.DIR;1");
		else
			strcpy (temp_buffer, pbi -> name);

		if (pfa -> file_type == pbi -> file_type &&
			RegExpMatch (temp_buffer, pfa -> fsm_ptr))
#else
		if (pfa -> file_type == pbi -> file_type &&
			RegExpMatch (pbi -> name, pfa -> fsm_ptr))
#endif /* vax11c */
			break;
		else	pfa = pfa -> next;
	}

	/* description of this file type */
	if (pfa != NULL)
		pbi -> dpi -> description =  pfa -> description; 
	else	pbi -> dpi -> description =  NULL;
	
	button = 0;
	/* set actions in toolbar */
	if (pfa != NULL)
	{
		pap = pfa -> actions;
		while (button < FILES_TOOLBAR_SIZE && pap != NULL)
		{
			tool_button = (pbi -> dpi -> files_toolbar) [button];

			/* set the action label in the button */
			xmstr = XmStringCreateLtoR (pap -> action_label,
					XmSTRING_DEFAULT_CHARSET);
			XtVaSetValues (tool_button,
					XmNlabelString, (XtArgVal) xmstr,
					NULL);
			XmStringFree (xmstr);

			/* set the action in the buttons user data */
			XtVaGetValues (tool_button,
					XmNuserData, (XtArgVal) &tbi,
					NULL);
			tbi -> action = pap -> action;
			tbi -> prompt = pap -> prompt;
			tbi -> run_in_xterm = pap -> run_in_xterm;
			tbi -> pause_after_exec = pap -> pause_after_exec;
			tbi -> has_prompt = pap -> has_prompt;
#ifdef vax11c
			tbi -> refresh_dir = pap -> refresh_dir;
#endif /* vax11c */

			XtSetSensitive (tool_button, True);
			button++;
			pap = pap -> next;
		}
	}
	/* empty out the remaining buttons */
	for ( ; button < FILES_TOOLBAR_SIZE; button++)
	{
		tool_button = (pbi -> dpi -> files_toolbar) [button];
		/* break out as soon as we hit an already insensitive button */
		if (XtIsSensitive (tool_button) == False)
			break;
		XtVaSetValues (tool_button,
				XmNlabelString, (XtArgVal) empty_string,
				NULL);
		XtSetSensitive (tool_button, False);
	}

#ifdef RDD
	/* set the drag cursor */
	{	Window root;
		int x, y;
		unsigned int width, height;
		unsigned int border_width, depth;

		XGetGeometry (XtDisplay (pbi -> dpi -> toplevel),
				pbi -> pixmap,
				&root,
				&x, &y, &width, &height,
				&border_width, &depth);
		rddSetDragPixmap (pbi -> pixmap, width, height);
	}
#endif
}


/*************************************************************************
 * Function: FileButtonReleasedCB ()
 * Purpose: handle a button release in any of the panes i.e. a file has
 *          been selected. Check if it is a multiclick, and if so
 *	    execute default action.
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition: a button for a file, executable, or 
                 directory has been released
 ************************************************************************/ 

/* ARGSUSED */
void
FileButtonReleasedCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)
	Widget w;
	XtPointer client_data;
	XtPointer call_data;

#endif
{	pane_button_info *pbi;
	XmDrawnButtonCallbackStruct *c_data= (XmDrawnButtonCallbackStruct *) call_data;

#ifdef DEBUG
	fprintf (stderr, "button released\n");
#endif
	/* get the user data */
	XtVaGetValues (w,
			XmNuserData, (XtArgVal) &pbi, NULL);
	/* if it was a double click, execute
	   the default action. default action is in
	   the first toolbar button, if sensitive */
	if ((c_data -> click_count) > 1 &&
		XtIsSensitive ((pbi -> dpi -> files_toolbar) [0]))
	{	/* set the busy cursor as a signal that something happens */
		BusyCursor (pbi -> dpi -> toplevel);

		/* fake default action on button */
		FileToolButtonPressedCB ( (pbi -> dpi -> files_toolbar) [0],
					NULL, NULL);
	        UnBusyCursor (pbi -> dpi -> toplevel);
	}
}

/*************************************************************************
 * Function: FileToolbarButtonPressed ()
 * Purpose: handle a button press in the file toolbar
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition: button in toolbar pressed
 * Postcondition: action for that button on selected file executed
 ************************************************************************/ 
void
FileToolButtonPressedCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)
	Widget w;
	XtPointer client_data, call_data;

#endif
{
	tool_button_info *tbi;
	char *command;
	char *argv[10];
	int argc;
	char *prompt_answer;
	int len_arg;

	XtVaGetValues (w,
			XmNuserData, (XtArgVal) &tbi,
			NULL);

#ifdef vax11c
	{
		register char *cp;

		if (tbi -> dpi -> file_selected == NULL)
			argv[0] = NULL;
		else {
			cp = XtMalloc(MAXPATHLEN+1);
			if (!cp)
				argv[0] = NULL;
			else {
				getcwd(cp, MAXPATHLEN);
				/*
				 *	If this is the "[-]" directory, then
				 *	skip doing this garbage
				 */
				if (strcmp (tbi -> dpi -> file_selected, "[-]") == 0)
					argv[0] = tbi -> dpi -> file_selected;
				else {
					len_arg = strlen (tbi -> dpi -> file_selected) +
		 					strlen (cp) + 1;
					argv[0] = XtMalloc(len_arg);
					strcpy (argv[0], cp);
					strcat (argv[0], tbi -> dpi -> file_selected);
				}
				XtFree (cp);
			}
		}
	}
#else
	argv[0] = tbi -> dpi -> file_selected;
#endif /* vax11c */
	if (argv[0] != NULL)
		argc = 1;
	else	argc = 0;
	if (tbi -> has_prompt)
	{	PromptDialog (w, tbi -> prompt, True, &prompt_answer);
		if (prompt_answer == NULL)
			return;
		/* set answer into args array */
		while (*prompt_answer != '\0' && argc < 10)
		{	while (IS_WHITE_SPACE (*prompt_answer))
				prompt_answer++;
			argv[argc] = prompt_answer;
			argc++;
			len_arg = strcspn (prompt_answer, " \t\n");
			if (prompt_answer[len_arg] == '\0')
				break;
			else
			{	prompt_answer[len_arg] = '\0';
				prompt_answer += len_arg + 1;
			}
		}
	}
#ifdef DEBUG
	for (len_arg = 0; len_arg < argc; len_arg++)
		fprintf (stderr, "Arg %d is %s\n", len_arg, argv[len_arg]);
#endif

#ifdef OLD_PATTERN
	/* next step: replace 2nd arg by argv */
	expand_command (&command, tbi -> dpi -> file_selected, tbi -> action);
#else
	expand_command (&command, argv, argc, tbi -> action);
#endif

#ifdef vax11c
	XtFree(argv[0]);
#endif /* vax11c */

#ifdef DEBUG
	fprintf (stderr, "action %s\n", tbi -> action);
	fprintf (stderr, "on file %s\n", tbi -> dpi -> file_selected);
	fprintf (stderr, "new command: %s\n", command);
#endif

	/* make sure we are in the right directory for this pane */
	XtChdir (DirectoryPath (DirectoryMgrDir (tbi -> dpi -> directory_manager)));

#ifdef DEBUG
	{	char path[MAXPATHLEN];
		fprintf (stderr, "changing to directory %s\n",
			DirectoryPath (DirectoryMgrDir (tbi -> dpi -> directory_manager)));

        	getcwd (path, MAXPATHLEN);
		fprintf (stderr, "now in directory %s\n", path);
	}
#endif

	if (*command == '$')
		builtin_command (command, tbi -> dpi);
	else
		do_command (command, 
#ifdef vax11c
				     tbi -> refresh_dir,
#endif /* vax11c */
				     tbi -> run_in_xterm, 
				     tbi -> pause_after_exec,
                                     tbi -> dpi);
	XtFree (command);
}


#ifdef OLD_PATTERN
/*************************************************************************
 * Function: expand_command ()
 * Purpose: this expands out the action into a command
 * 	    it uses the Make patterns of
 *		$$ = $
 *		$* = stem of file name
 *		$@ = file name
 * In parameters: file, action
 * Out parameters: command
 * Precondition: action is a string that can be applied to the file
 * Postcondition: command is the action with filename replaced
 *                according to patterns above
 ************************************************************************/ 
static void
expand_command (command, file, action)
	char **command;
	char *file;
	char *action;
{
	int old_len, new_len;
	int file_len, stem_len;
	char *p;
	char *new_str;
	char *stem;

	/* find some constant lengths */
	old_len = strlen (action);
	file_len = strlen (file);
	for (stem_len = file_len; stem_len > 0; stem_len--)
		if (file[stem_len - 1] == '.')
			break;
	stem_len--;

	/* create the stem string */
	stem = XtMalloc (stem_len + 1);
	strncpy (stem, file, stem_len);
	stem[stem_len + 1] = '\0';

	/* find the length of the new string */
	new_len = 0;
	p = action;
	while (*p != '\0')
	{	if (*p == '$')
		switch ( *(p+1) )
		{	case '$':	new_len++;
					p += 2;
					break;
			case '@':	new_len += file_len;
					p += 2;
					break;
			case '*':	new_len += stem_len;
					p += 2;
					break;
			default:	new_len++;
					p++;
		} else {
			new_len++;
			p++;
		}
	}

	/* create the new string */
	*command = new_str = (char *) XtMalloc (new_len + 1);

	/* and populate it */
	p = action; 
	while (*p != '\0')
	{	if (*p == '$')
		switch ( *(p+1) )
		{	case '$':	*new_str = '$';
					new_str++;
					p += 2;
					break;
			case '@':	strcpy (new_str, file);
					new_str += file_len;
					p += 2;
					break;
			case '*':	strcpy (new_str, stem);
					new_str += stem_len;
					p += 2;
					break;
			default:	*new_str++ = *p++;
					
		} else {
			new_len++;
			*new_str++ = *p++;
		}
	}
	*new_str = '\0';
}
#else /* OLD_PATTERN */
/*************************************************************************
 * Function: expand_command ()
 * Purpose: this expands out the action into a command
 * 	    it uses the ksh patterns of
 *		\c = c
 *		$0 = selected file
 *		$d = n-th parameter in prompt
 *		$* = string of entire prompt 
 *		${d#p} = d-th param less pattern p from front
 *		${d%p} = d-th param less pattern p from end
 * In parameters: argv, argc, action
 * Out parameters: command
 * Precondition: action is a string that can be applied to the file
 * Postcondition: command is the action with patterns replaced
 *                according to params in argv
 ************************************************************************/ 
static void
expand_command 
#ifdef UseFunctionPrototypes
	(char **command, char **argv, int argc, char *action)
#else
	(command, argv, argc, action)
	char **command;
	char **argv;
	int argc;
	char *action;

#endif
{
	char *p;
	char *new_str;
	int digit;
	char *end_brace_pos;
	int arg_len, pat_len;

	/* create the new string, hopefully too big */
	*command = new_str = (char *) XtMalloc (4096);

	/* and populate it */
	p = action; 
	while (*p != '\0')
	{	if (*p == '\\')
		{	/* escape sequence */
			STRING_LEN_CHECK (2);
			p++;
			*new_str++ = *p++;
			continue;
		}
		if (*p == '$')
		{	 p++;
			if (isdigit (*p))
			{	/* $d param subst */
				digit = *p++ - '0';
				if (digit >= argc)
					/* off the end of the argv array */
					continue;
				arg_len = strlen (argv[digit]);
				STRING_LEN_CHECK (arg_len);
				strcpy (new_str, argv[digit]);
				new_str += arg_len;
				continue;
			}
			if (*p == '*')
			{	/* $* all params subst */
				int i;

				for (i = 1; i < argc; i++)
				{	arg_len = strlen (argv[i]);
					STRING_LEN_CHECK (arg_len);
					strcpy (new_str, argv[i]);
					new_str += arg_len;
					if (i < argc - 1)
						/* change \0 to ' ' */
						*new_str++ = ' ';
				}
				p++;
				continue;
			}
			if (*p != '{')
			{	/* pass $ through - not one of our patterns */
				STRING_LEN_CHECK (2);
				*new_str++ = '$';
				*new_str++ = *p++;
				continue;
			}
			/* it's '${' so should end in '}' */
			end_brace_pos = strchr (p, '}');
			if (end_brace_pos == NULL)
			{	/* dunno what to do - no closing brace */
				fprintf (stderr, "no closing } in action!\n");
				continue;
			}
			p++;
			if (!isdigit (*p))
			{	/* pass it through - not a positional param */
				STRING_LEN_CHECK ((int)(end_brace_pos - p) + 2);
				*new_str++ = '$';
				*new_str++ = '{';
				while (p != end_brace_pos + 1)
					*new_str++ = *p++;
			}
			/* its ${d...}. Is ... NULL, %, #? */
			digit = *p - '0';
			STRING_LEN_CHECK (1);
			p++;
			if (p == end_brace_pos)
			{	/* ${d} param subst */
				arg_len = strlen (argv[digit]);
				STRING_LEN_CHECK (arg_len);
				strcpy (new_str, argv[digit]);	 
				new_str += arg_len;
				p++;	/* skip past '}' */
				continue;
			}
			if (*p == '#')
			{	/* ${d#pat} take pattern off the front */
				p++;
				pat_len = (int) (end_brace_pos - p);
				if (strncmp (argv[digit],p,
					pat_len) != 0)
				{	 /* no match, copy whole arg */
					strcpy (new_str, argv[digit]);
					new_str += strlen (argv[digit]);
					p += pat_len + 1;
					continue;
				}
				/* copy part after match */
				strcpy (new_str, argv[digit] + pat_len);
				new_str +=strlen (argv[digit]) - pat_len;
				p += pat_len + 1;
				continue;
			}
			if (*p == '%')
			{	/* ${d%pat} take pattern off the end */
				int stem_len, arg_len;
				char *tail;

				p++;
				pat_len = (int) (end_brace_pos - p);
				arg_len = strlen (argv[digit]);
				stem_len = arg_len - pat_len;

				/* pattern should start at tail */
				tail = argv[digit] + stem_len;
				if (strncmp (tail, p, pat_len) != 0)
				{	/* no match, copy all */
					strcpy (new_str, argv[digit]);
					new_str += arg_len;
					p += pat_len + 1;
					continue;
				}
				/* copy first part only, upto pattern */
				strncpy (new_str, argv[digit], stem_len);
				new_str += stem_len;
				p += pat_len + 1;
				continue;
			}
			/* dunno what it is */
			fprintf (stderr, "unknown pattern %s in action\n",
					p);
			continue;
		}
		/* copy any other char */
		*new_str++ = *p++;
	}
	*new_str = '\0';
}
#endif /* OLD_PATTERN */


#ifdef vax11c
/*************************************************************************
 * Function: do_comand ()
 * Purpose: execute the selected command
 * In parameters: command, run_in_xterm, pause_after_exec
 * Out parameters:
 * Precondition: command is a valid OpenVMS command
 * Postcondition: action specified by command running asynchronously
 ************************************************************************/ 
void
do_command
#ifdef UseFunctionPrototypes
	(char *command, int refresh_dir, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi)
#else
	(command, refresh_dir, run_in_xterm, pause_after_exec, dpi)
	char *command;
	Bool refresh_dir;
	Bool run_in_xterm;
	Bool pause_after_exec;
        dir_pane_info *dpi;

#endif
{
	int len_new_command;
	char *new_command;
        int pid;
	unsigned long int status;

	if (run_in_xterm && pause_after_exec)
	{
		len_new_command = 2 * strlen (command) + 
					strlen (XTERM_STR) +
					strlen (PAUSEME_STR) + 4;
		/* leave space for \0 terminator */
		new_command = XtMalloc (len_new_command + 1);
		strcpy (new_command, XTERM_STR);
		strcat (new_command, command);
		strcat (new_command, PAUSEME_STR);
		strcat (new_command, command);
        }
	else if (run_in_xterm)
	{
		len_new_command = 2 * strlen (command) + 
					strlen (XTERM_STR) + 
					strlen (EXEC_STR) + 4;
		new_command = XtMalloc (len_new_command + 1);
		strcpy (new_command, XTERM_STR);
		strcat (new_command, command);
		strcat (new_command, EXEC_STR);
		strcat (new_command, command);

	}
	else	/* run as an X application, or into existing xterm */
	{
		len_new_command =  strlen (command) + 13;
		new_command = XtMalloc (len_new_command + 1);
		strcpy (new_command, command);
	}

#ifdef DEBUG
	fprintf(stderr, "Running command: \"%s\"\n", new_command);
#endif /* DEBUG */

	status = createProcess (new_command, (refresh_dir ? 1 : 0), dpi);
	if (!(status&1)) lib$signal (status);

}
#else
/*************************************************************************
 * Function: do_comand ()
 * Purpose: execute the selected command
 * In parameters: command, run_in_xterm, pause_after_exec
 * Out parameters:
 * Precondition: command is a valid Unix command
 * Postcondition: action specified by command running asynchronously
 ************************************************************************/ 
void 
do_command 
#ifdef UseFunctionPrototypes
	(char *command, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi)
#else
	(command, run_in_xterm, pause_after_exec, dpi)
	char *command;
	Bool run_in_xterm;
	Bool pause_after_exec;
        dir_pane_info *dpi;

#endif
{
	int len_new_command;
	char *new_command;
        int pid;

	if (run_in_xterm && pause_after_exec)
	{
		len_new_command = 2 * strlen (command) + 
					strlen (XTERM_STR) +
					strlen (PAUSEME_STR) + 4;
		/* leave space for \0 terminator */
		new_command = XtMalloc (len_new_command + 1);
		strcpy (new_command, XTERM_STR);
		strcat (new_command, command);
		strcat (new_command, PAUSEME_STR);
		strcat (new_command, command);
                strcat (new_command, "' ");
        }
	else if (run_in_xterm)
	{
		len_new_command = 2 * strlen (command) + 
					strlen (XTERM_STR) + 
					strlen (EXEC_STR) + 4;
		new_command = XtMalloc (len_new_command + 1);
		strcpy (new_command, XTERM_STR);
		strcat (new_command, command);
		strcat (new_command, EXEC_STR);
		strcat (new_command, command);
                strcat (new_command, "' ");

	}
	else	/* run as an X application, or into existing xterm */
	{
		len_new_command =  strlen (command) + 13;
		new_command = XtMalloc (len_new_command + 1);
		strcpy (new_command, command);
		/* make sure that if it attempts to read from stdin,
		   it fails (eg. an interactive shell not run in an xterm) */
		strcat (new_command, " < /dev/null ");
	}

/*	system (new_command);
	XtFree (new_command);
 */
        if ((pid = fork ()) > 0)
        {        /* parent */
                 add_pid (pid, dpi);
        }
        else     /* child */
        {
                system (new_command);
                XtFree (new_command); 
		exit (0);
        }                
}
#endif /* vax11c */

