|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5440 (0x1540)
Types: TextFile
Notes: UNIX file
Names: »xqt.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »unimenu/src/menu/xqt.c«
/*
#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]);
}