Category : Alternate Operating Systems - Quarterdeck DesqView, CP/M, etc
Archive   : PCCAPP.ZIP
Filename : DEMO.CC

 
Output of file : DEMO.CC contained in archive : PCCAPP.ZIP
/*
* This file is part of the Choices Operating System
* Developed by: The TAPESTRY Parallel Computing Laboratory
* University of Illinois at Urbana-Champaign
* Department of Computer Science
* 1304 W. Springfield Ave.
* Urbana, IL 61801
*
* Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992
* The University of Illinois Board of Trustees.
* All Rights Reserved.
*
* Author: Lee Lup Yuen ([email protected])
* Project Manager and Principal Investigator: Roy Campbell ([email protected])
*
* Funded by: NSF TAPESTRY Grant No. 1-5-30035, NASA ICLASS Grant
* No. 1-5-25469 and No. NSG1471 and AT&T Metronet Grant No. 1-5-37411.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for educational, research, and non-profit purposes
* is hereby granted provided that the above copyright notice, the
* original authors names, and this permission notice appear in all such
* copies and supporting documentation; that no charge be made for such
* copies; and that the name of the University of Illinois not be used
* in advertising or publicity pertaining to distribution of the
* software without specific prior written permission. Any entity
* desiring permission to incorporate this software into commercial
* products should contact the Computing Research Laboratory, Department
* of Computer Science, University of Illinois, 1304 W. Springfield
* Avenue, Urbana, IL 61801. The University of Illinois makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/

#include "OutputStream.h"
#include "InputStream.h"
#include "NameServer.h"
#include "ApplicationDispatcher.h"
#include "Process.h"
#include "ThisProcess.h"
#include "Semaphore.h"
#include "FileSystemInterface.h"
#include "ReadFileStream.h"
#include "ReadFileStreamStar.h"
#include "VirtualPCInterface.h"
#include "VirtualPCArgs.h"
#include "String.h"
#include "Assert.h"

static VirtualPCInterface *virtualPC;
const pathCount = 1000;
char *path [pathCount];

class BufferedReadFileStream
{
/* A BufferedReadFileStream provides buffering for a ReadFileStream. */
public:
BufferedReadFileStream (ReadFileStream *stream);
~BufferedReadFileStream ();
int inError (); // Works like ferror.
char readChar (int &err); // Works like getc.
int read (char *str, int count); // See ReadFileStream.
char *readLine (char *buf, int size); // Works like fgets.
int readBackChar (char ch); // Works like ungetc.
int setOffset (long offset, int origin); // Works like fseek.
long offset (); // Works like ftell.
private:
void flush (); // Empty the buffers.
int errorCode;
ReadFileStreamStar readFileStream;
enum {bufferedReadFileStreamBufferSize = 8192};
// buffer is the buffer for the file stream; readBackBuffer is for
// storing characters pushed back by readBackChar.
char buffer [bufferedReadFileStreamBufferSize];
char readBackBuffer [bufferedReadFileStreamBufferSize];
int bufferIndex;
int bufferSize;
int readBackBufferIndex;
};

void executeScriptLoop (const char *filename);
int checkUserAction ();
int executeCommandLine (char *buffer);
void showVariables ();
void showHelp ();
void setVariable (char *buffer, int equalPos);
void parseCommandLine (char *buffer, int &argc, char *argv[], int &background);
void runFile (char *filename, int argc, char **argv, int background);
void trim (char *str);
void translatePathname (char *path);

int main (int argc, char **argv)
{
// "demo scriptfile" executes all the shell commands in scriptfile
// repeatedly until "q" is pressed. Command execution may be suspended
// by pressing Space, and pressing it again to resume execution.
if (argc != 2)
{
*StandardOutput << "Usage: demo scriptfile\n"
"demo executes all the shell commands in scriptfile repeatedly\n"
"until 'q' is pressed. Command execution may be suspended by\n"
"pressing Space, and pressing it again to resume execution.\n"
<< eor;
return 1;
}
if (argv [1][0] == 0) return 0;
virtualPC = (VirtualPCInterface *) StandardNameServer -> lookup
("virtualPCInterface", "VirtualPCInterface");
Assert (virtualPC != 0);
*StandardOutput << "Starting demo. Press 'q' to quit, Space to pause.\n"
<< eor;
executeScriptLoop (argv [1]);
*StandardOutput << "\ndemo done\n" << eor;
return 0;
}

void executeScriptLoop (const char *filename)
{
// Execute the commands in filename until "q" is pressed. Space pauses
// the command execution.
int done = 0;
do
{
int err;
ReadFileStreamStar rfs = (ReadFileStreamStar)
StandardFileSystemInterface -> open (filename,
ReadFileStreamClass, err);
if (err || rfs == 0) return;
BufferedReadFileStream *brfs = new BufferedReadFileStream (rfs);
Assert (brfs != 0);
static char buffer [1000];
while (brfs -> readLine (buffer, 1000) != 0)
{
int bufferLength = strlen (buffer);
if (bufferLength >= 1) buffer [--bufferLength] = 0;
if (bufferLength >= 1 && buffer [bufferLength - 1] == 13)
buffer [--bufferLength] = 0;
done = executeCommandLine (buffer);
if (done) break;
done = checkUserAction ();
if (done) break;
}
delete brfs;
} while (!done);
}

int checkUserAction ()
{
// Return 1 if user pressed 'q', otherwise return 0. Pause if user
// pressed Space.
// Was there a key pressed?
VirtualPCArgs args;
args.set (rAX, 0x0100);
virtualPC -> executeVector (KeyboardBIOSVector, &args);
// If so, read the key.
if ((args.get (rFlags) & 64) == 0)
{
char c;
StandardInput -> read (&c, 1);
// If 'q', then quit.
if (c == 'q') return 1;
// If Space, then wait for Space again.
else if (c == ' ')
{
*StandardOutput << "\ndemo suspended, press Space to continue: "
<< eor;
StandardInput -> read (&c, 1);
*StandardOutput << "\n" << eor;
}
}
return 0;
}

int executeCommandLine (char *buffer)
{
// Process the command line in buffer. Return non-zero if the exit
// command was encountered.
trim (buffer);
if (buffer [0] == 0) return 0;
else if (buffer [0] == '#')
{ *StandardOutput << buffer << "\n" << eor; return 0; }
else if (strcmp (buffer, "exit") == 0) return 1;
else if (strcmp (buffer, "set") == 0) { showVariables (); return 0; }
else if (strcmp (buffer, "help") == 0) { showHelp (); return 0; }
// Look for "=" in the command line.
int equalPos = -1;
for (int i = 0; buffer [i] != 0; i++)
if (buffer [i] == '=') { equalPos = i; break; }
// If found, must be a variable assignment.
if (equalPos != -1) setVariable (buffer, equalPos);
else
{
// Otherwise it's a file to be executed.
*StandardOutput << "Executing " << buffer << "...\n" << eor;
int argc, background; char *argv [1000];
parseCommandLine (buffer, argc, argv, background);
runFile (argv [0], argc, argv, background);
}
return 0;
}

void showVariables ()
{
// Show all environment variables (eg. PATH).
*StandardOutput << "PATH=";
for (int i = 0; path [i] != 0 && i < pathCount; i++)
{
if (i > 0) *StandardOutput << ";";
*StandardOutput << path [i];
}
*StandardOutput << "\n" << eor;
}

const char helpMessage [] =
"The Choices Command Shell (Chocs) is for running Choices applications.\n"
"These are the commands:\n"
" exit - Exit the command shell.\n"
" help - Display this message.\n"
" set - Display all environment variables.\n"
" VAR=VALUE - Set the environment variable VAR to VALUE.\n"
" (Only the variable PATH can be set.)\n"
" # comment - This is a comment; do not execute.\n"
"To execute a program, enter its name and the arguments. To execute the\n"
"program in the background, type & at the end of the line. PATH\n"
"is a semicolon-separated list of paths which are used to find the\n"
"program. The file named \"profile\" contains commands to be executed\n"
"when the shell is started.\n";

void showHelp ()
{
// Display the help message.
*StandardOutput << helpMessage << eor;
}

void setVariable (char *buffer, int equalPos)
{
// Process the variable assignment command in buffer. equalPos is the
// position of the "=" in buffer. buffer contains a string of the
// format "VAR=VALUE", with optional spaces around the "=".
if (equalPos == 0) { *StandardOutput << "Bad assignment\n" < buffer [equalPos] = 0;
char *var = buffer;
char *value = buffer + equalPos + 1;
trim (var); trim (value);
if (var [0] == 0) { *StandardOutput << "Bad assignment\n" << eor; return; }
if (strcmp (var, "PATH") == 0)
{
char *p = value;
for (int i = 0; i < pathCount; i++)
{
if (path [i] != 0) delete path [i];
if (*p == 0) { path [i] = 0; break; }
char *pNew = p;
while (*pNew != 0 && *pNew != ';') pNew++;
if (*pNew == ';') { *pNew = 0; pNew++; }
path [i] = new char [strlen (p) + 1];
strcpy (path [i], p);
p = pNew;
}
}
else
*StandardOutput << "Bad variable for assignment: only PATH allowed\n"
<< eor;
}

void parseCommandLine (char *buffer, int &argc, char *argv [], int
&background)
{
// Parse command line in buffer and set argc, argv accordingly.
// Set background to 1 if command line ends with &.
background = 0;
int bufferLength = strlen (buffer);
if (buffer [bufferLength - 1] == '&')
{ background = 1; buffer [bufferLength - 1] = 0; }
argc = 1;
argv [0] = buffer;
for (; *buffer != 0; buffer++)
if (*buffer == ' ')
{
while (*buffer == ' ') { *buffer = 0; buffer++; }
argv [argc++] = buffer;
}
}

void runFile (char *filename, int argc, char **argv, int background)
{
// Run filename with arguments argc and argv. If background is true,
// then don't wait for the program to finish.
translatePathname (filename);
int err;
ProcessStar process = ApplicationDispatcher :: buildApplicationProcess
(filename, argc, argv, err);
if (err || process == 0)
{
// The file wasn't executable. Try prepending the PATHs.
static char filename2 [1000];
for (int i = 0; path [i] != 0 && i < pathCount; i++)
{
strcpy (filename2, path [i]); strcat (filename2, "/");
strcat (filename2, filename);
translatePathname (filename2);
process = ApplicationDispatcher :: buildApplicationProcess
(filename2, argc, argv, err);
if (!err && process != 0) break;
}
if (err || process == 0)
{ *StandardOutput << "No such program\n" << eor; return; }
}
if (background)
process -> ready ();
else
{
SemaphoreStar done = new BinarySemaphore (0);
process -> notifyUponCompletion (done);
process -> ready ();
done -> P ();
}
}

void trim (char *str)
{
// Remove leading and trailing spaces from str.
char *src = str, *dest = str;
for (; *src == ' '; src++) {}
for (;;)
{
if (*src == 0) { *dest = 0; break; }
else { *dest = *src; src++; dest++; }
}
dest--;
for (; dest >= str && *dest == ' '; dest--) *dest = 0;
}

void translatePathname (char *path)
{
// Change all '/' in path to '\'.
for (char *s = path; *s != 0; s++)
if (*s == '/') *s = '\\';
}

BufferedReadFileStream :: BufferedReadFileStream (ReadFileStream *stream)
{
errorCode = 0;
readFileStream = stream;
bufferIndex = 0;
bufferSize = 0;
readBackBufferIndex = 0;
}

BufferedReadFileStream :: ~BufferedReadFileStream ()
{
readFileStream = 0;
}

int BufferedReadFileStream :: inError ()
{
return errorCode;
}

char BufferedReadFileStream :: readChar (int &err)
{
if (readBackBufferIndex > 0)
{
err = 0;
return readBackBuffer [readBackBufferIndex--];
}
else if (bufferIndex >= bufferSize)
{
bufferIndex = 0;
bufferSize = readFileStream -> read (buffer,
bufferedReadFileStreamBufferSize);
if (bufferSize == 0)
{
err = 1;
return 0;
}
}

err = 0;
return buffer [bufferIndex++];
}

int BufferedReadFileStream :: read (char *str, int count)
{
for (int i = 0; i <= count - 1; i++)
{
int err;
str [i] = readChar (err);
if (err) break;
}
return i;
}

char *BufferedReadFileStream :: readLine (char *buf, int size)
{
int err;
for (int i = 0; i <= size - 2; i++)
{
buf [i] = readChar (err);
if (err) return 0;
if (buf [i] == '\n')
{
i++;
break;
}
}
buf [i] = 0;
return buf;
}

int BufferedReadFileStream :: readBackChar (char ch)
{
if (readBackBufferIndex == bufferedReadFileStreamBufferSize - 1)
return -1;
else
{
readBackBuffer [++readBackBufferIndex] = ch;
return ch;
}
}

void BufferedReadFileStream :: flush ()
{
bufferSize = 0;
bufferIndex = 0;
readBackBufferIndex = 0;
}

int BufferedReadFileStream :: setOffset (long offset, int origin)
{
flush ();
return readFileStream -> setOffset (offset, origin);
}

long BufferedReadFileStream :: offset ()
{
int charsInBuffer = bufferSize - bufferIndex;
if (charsInBuffer < 0) charsInBuffer = 0;
return readFileStream -> offset () - charsInBuffer - readBackBufferIndex;
}


  3 Responses to “Category : Alternate Operating Systems - Quarterdeck DesqView, CP/M, etc
Archive   : PCCAPP.ZIP
Filename : DEMO.CC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/