DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦91c553378⟧ TextFile

    Length: 5440 (0x1540)
    Types: TextFile
    Notes: UNIX file
    Names: »xqt.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »unimenu/src/menu/xqt.c« 

TextFile

/*
#define DEBUG
*/

/*
 *			Copyright (c) 1984
 *		    LANTECH Systems, Incoroporated
 *
 *		     Portions Copyright (c) 1985
 *			Five Paces Software
 *
 *			All rights reserved
 */

/*
 * File:	xqt.c
 *
 * Contents:	contains all the stuff to execute a command.
 *		(execute and it's subs.)
 */

/*
 * Function:	execute(menu)
 *
 * Purpose:	Parse an "Exec:" spec and execute the task.
 *
 * Passed:	A menu pointer.
 *
 * Returns:	A valid menu pointer.  Either the one we are called with
 *		or one we created. (N.b.  THIS MUST RETURN A POINTER TO
 *		A VALID MENU. main(){main.c} EXPECTS IT.
 *
 * Called by:	main
 *
 * Calls:	List to be compiled.
 *
 * History:	Original code June 84, Robert Adams.
 *		Mod to eat opening white space July 84.
 *		Change to return value July 84.
 *		Added running programs in another window Mar 85, drm
 */

#include "defs.h"
#include <signal.h>

int	Ls = 0;
int	Pcur = 0;
char	Curdir[82] = {0};

struct menu_f  *execute (mp)
struct menu_f  *mp;
{
int	pid;
char	*cmd;
char	*expand();
char	*strcpy();
int	(*signal())();

	/* 
	 * Like the man says,
	 * "Fail early and often!"
	 */
	if (mp == NULL || (cmd = mp -> m_current) == NULL || *cmd == EOS)
		return mp;

	for (; *cmd == SPACE || *cmd == TAB; cmd++)
		;

	cmd = expand (cmd);		/* expand {Query?} references */
	if ( !cmd )			/* canceled or nothing more to do */
		return (mp);

	if (*cmd == '@')		/* check to see if we want a new menu */
	{
		switch (pid=fork ())
		{
			case -1: 
				printf ("Fork failed.\n");
				printf ("ERROR\n");
				return mp;

			case 0: 		/* child */
				{
					struct menu_f  *init ();
					struct menu_f  *mp2;

					deinit (mp);
					mp2 = init (cmd + 1);
					if (mp2 == NULL)
					{
						CRblk((char *)0);
						_exit (0);
					}
					/* else */

					return mp2;
				}
			default: 		/* parent */
			{
				int (*f)();	/* old signal vaule */
				int dip;	/* possible pid */

				f = signal(SIGINT,SIG_IGN);
				while ( (dip = wait((int *)0)) != -1 )
				{
					if ( pid == dip )
						break;
				}
#ifdef DEBUG
printf("return from child");
read(0, &pid, 1);
#endif
				signal(SIGINT,f);
				return mp;
			}
		}
	}
	
	cls();
	pcurs(24, 1);
	if ( !strncmp(cmd,"cd ",3) )	 	/* chdir done internally */
		cd(cmd + 2);  			/* jump over command */
	else
		system(cmd);

	CRblk((char *)0);
	return mp;
}

/* 
 * change directory - cannot use exec because current directory 
 * is local to the current process
 */
cd(cmd) 
char *cmd;
{
char	*getenv();

	while( *cmd == ' ' || *cmd == '\t' )	/* hop over white spaces */
		cmd++;	

	if ( !(*cmd) )	 			/* if there is no pathname */
	{
		cmd = getenv("HOME");
		if ( !cmd )
			cmd = "/";
	}

	if ( chdir(cmd) )
		printf("Can't change directory to %s\n", cmd);
	else
		printf("Directory changed to %s\n", cmd);
}

/*
 * Function:	char *expand(str)
 *
 * Action:	Copy the string pointed to by "str" to the buffer
 *		the pointer to which is returned.  Additionally,
 *		if "str" contains "{PROMPT}", then PROMPT will be
 *		displayed and the entire {} construct will be replaced
 *		a line of user input.
 *		If "str" contains "!cmd!", the command is executed.
 *		If "str" contains "[file]", then that file is printed.
 *
 * Returns:	A pointer to a static string, you must copy it if you
 *		want to call expand() twice.
 *
 * History:	Original Coding June 84, Robert Adams
 *
 * Algorithm:	Spin the argument pointer down the buffer to which it
 *		points. If the pointed-to char is a `{', then start eating
 *		chars into a seperate buffer, and use it to prompt the
 *		user latOr.  The prompt ends with a `}'.
 * Addition:	"[]" is just like "{}" except the stuff inside is executed.
 *		e.g.  Exec: [/usr/plx/ls] {Which files? }
 *		Many thanks to Mcm and Rfw.
 *
 * 		Added "%...%" to go to a new window. - drm
 */

char   *expand (s)
char   *s;
{
static char     retbuf[256];
char	*retp;
char	*tp;
char	c;
char	close;
char	tbuf[80];
char	*inqwin();
char	*inquire();

	retp = retbuf;
	tp = tbuf;
	Ls = 0;

	/* 
	 * Operational loop.  Just keep on pointin'.
	 */
#ifdef DEBUG
printf("\nin expand: %s\n", s);
#endif
	while ( *s )
	{
		c = *s++;
		/* 
		 * If c is "normal" then just pass it on through.
		 * but if it's an open character we process it 
		 */
		switch(c)
		{
			case '{': close='}'; break;
			case '[': close=']'; break;
			case '!': close='!'; break;
			case '%': close='%'; break;
			case '^': close='^'; break;
			default: 
				*retp++ = c;
				continue;
		}

		tp = &tbuf[0];		/* move the prompt into tbuf */
		while ( (c = *s++) && (c != close) )
			*tp++ = c;
		*tp = EOS;

		switch(close)
		{
			case '!':		/* exec a command */
				if ( !strncmp(tbuf,"cd ",3) )
					cd (&tbuf[2]);
#ifdef PWDS
				else if ( !strncmp(tbuf, "pwd", 3) )
				{
					pwd(Curdir);
					Pcur = 1;
				}
#endif
				else
					system (tbuf);
				continue;

			case ']':		/* cat a file */
				cat(tbuf);
				continue;

			case '%' :		/* set the new window */
				tp = inqwin(tbuf);
				break;

			case '^' : Ls = 1;	/* query with directory list */
			case '}':		/* query */
				tp = inquire(tbuf);
				Ls = 0;
				Pcur = 0;
				break;

			default :		/* close not found */
				tp = tbuf;
				break;
		}

		if ( !tp )			/* Esc pressed */
			return ( NULL );

		if ( *tp )			/* copy the response over */
		{
			while ( *tp )		/* don't copy the null */
				*retp++ = *tp++;
		}
	}

	*retp = EOS;
#ifdef DEBUG
printf("expand: leaving with %s\n", retbuf);
#endif
	return (&retbuf[0]);
}