/* OSSHELL (STD) -- Run Operating System Shell */ /* OSSHELL (STD) -- Betriebssystem-Shell aktivieren */ /* // Copyright (c) 1996-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (091021) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (010709) RELEASED FOR BAE V5.0. // rl (010125) ENHANCEMENT: // Suppressed DOS message for advanced user interface BAE. // rl (000509) RELEASED FOR BAE V4.6. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // mb (970616) ENHANCEMENT: // Applied CAM View User Language support. // mb (960919) RELEASED FOR BAE V3.4. // mb (960722) CHANGE: // Introduced BAE environment check to abort when // running under BAE Windows configuration. // mb (960125) ORIGINAL CODING. // // DESCRIPTION // // The osshell User Language program provides an interface to the // operating system shell. The system User Language function is // utilized for executing operating system commands. Kindly note // the restrictions and limitations regarding the use of the // system User Language function before using this program! // // RESTRICTIONS // // osshell utilizes the system() User Language function. Note that // this function introduces basic multi-processing/multi-tasking // features which are not completely available on PC-based systems, // or may cause some problems on network-based workstation systems // (depending on whichever OS command is to be executed!). // The osshell User Language program does NOT run in Windows-based // BAE systems. // // REQUIREMENTS // // - RUNNING UNDER DOS HOST ENVIRONMENT COMMAND PROCESSOR // Executing (child) processes from within DOS Extender requires // enough conventional memory to be available for running the // executable. Conventional memory must be controlled by use of // Phar Lap's DOS Extender variables, -MINREAL and -MAXREAL. For // running User Language programs using the system() function, // the corresponding User Language Interpreter environments must // be re-configured according to // // cfig386 -maxreal 0ffffh // // where must be set to // // scm.exe // ged.exe // autoplc.exe // neurrut.exe // cam.exe // cerview.exe // [ ced.exe ] // // respectively. // // WARNINGS // // - DOS COMMAND STANDARD OUTPUT // It is strongly recommended to redirect DOS command standard // output to temporary files (and use some file view User Language // function for display), since otherwise DOS standard output will // overwrite the BAE graphic user interface. // // - DOS COMMAND ERROR OUTPUT // Erroneous DOS command calls will cause error output to the screen, // thus overwriting the BAE graphic interface. Due to the fact that // DOS lacks from some substantial standard features such as redirect // error output, this problem can only be solved by refraining and/or // preventing from running erroneous DOS commands, e.g. by pre-checking // the consistency of each DOS command to be called. // // - REDIRECTING STANDARD INPUT / STARTING INTERACTIVE COMMANDS FROM DOS // It is strongly recommended to refrain and/or prevent from calling // interactive DOS commands and/or application software with the // system() function, since otherwise the system will "hang up" due // to the fact that DOS standard input cannot be redirected from the // BAE graphic user interface. It is also strongly recommended to // refrain and/or prevent from DIRECTLY calling UNIX commands which // expect some user input (more, vi, ...); this problem may be solved // by a command cast to background (&) command shell start where the // desired command should be called from (which however might cause a // terminal device connection problem under remote login). // // - RECURSIVE GRAPHIC APPLICATION CALL FROM DOS // Unpredictable results are ensured when recursively calling graphic // applications using the system() function on PC-based systems. */ // Includes #include "pop.ulh" // User Language popup utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages #define DE_UPRLQUIT "Weiter mit [:Abbruch] ? " #define EN_UPRLQUIT "Hit to continue [:Abort] ? " #define DE_HLPDOSSHELL " DOS SHELL : BEENDEN DURCH EINGABE VON 'exit'" #define EN_HLPDOSSHELL " DOS SHELL : ENTER 'exit' TO EXIT" #define DE_HLPUNIXSHELL " UNIX SHELL : BEENDEN DURCH EINGABE VON 'exit'" #define EN_HLPUNIXSHELL " UNIX SHELL : ENTER 'exit' TO EXIT" #define DE_ERRBAEDEMO1 "Bartels AutoEngineer DEMO Software unterstuetzt" #define DE_ERRBAEDEMO2 "die Aktivierung der Betriebssystem-Shell leider" #define DE_ERRBAEDEMO3 "nicht! - Wir bitten um Nachsicht!" #define EN_ERRBAEDEMO1 "Sorry!" #define EN_ERRBAEDEMO2 "Bartels AutoEngineer DEMO software does not" #define EN_ERRBAEDEMO3 "support operating system shell activation!" #define DE_ERRCOMPSTS "? FEHLERSTATUS %d" #define EN_ERRCOMPSTS "? ERROR STATUS %d" string UPRLQUIT = M(DE_UPRLQUIT ,EN_UPRLQUIT ); string HLPDOSSHELL = M(DE_HLPDOSSHELL ,EN_HLPDOSSHELL ); string HLPUNIXSHELL = M(DE_HLPUNIXSHELL,EN_HLPUNIXSHELL); string ERRBAEDEMO1 = M(DE_ERRBAEDEMO1 ,EN_ERRBAEDEMO1 ); string ERRBAEDEMO2 = M(DE_ERRBAEDEMO2 ,EN_ERRBAEDEMO2 ); string ERRBAEDEMO3 = M(DE_ERRBAEDEMO3 ,EN_ERRBAEDEMO3 ); string ERRCOMPSTS = M(DE_ERRCOMPSTS ,EN_ERRCOMPSTS ); static STRINGS DE_wl = { // Warnings "WARNUNGEN", "---------", "Unter MS-DOS erfolgt ein Programmabsturz, wenn nicht zuvor", "CFIG386 in folgender Weise angewendet wurde:", "",cfig386cmd(),"", "Fehlerausgaben ueberschreiben die BAE-Grafikoberflaeche.", "Grafikanwendungen setzen die BAE-Grafikoberflaeche zurueck.", "Eingaben an interaktive Kommandos sind nicht moeglich.", "Die Umlenkung der Ausgabe auf Datei wird nicht unterstuetzt." }; static STRINGS EN_wl = { // Warnings "WARNINGS", "--------", "BAE will crash under MS-DOS, if CFIG386 has not yet been", "applied as in", "",cfig386cmd(),"", "Error output will overwrite the BAE graphic interface.", "Graphic applications will reset the BAE graphic interface.", "Input to interactive commands cannot be redirected.", "Redirection of standard output is not supported." }; #if UILANGDEF==UILANG_DE static STRINGS wl = bae_uilanguage()==UILANG_EN ? EN_wl : DE_wl; #else static STRINGS wl = bae_uilanguage()==UILANG_DE ? DE_wl : EN_wl; #endif #define CFIGCMD " [:BAE\] cfig386 %s -maxreal 0ffffh" #define UINEXIT "x" #define ULINE "___________________________________________________________" // Globals #define OSPROMPT "[OS] " // Operating system prompt #define OSEXIT "exit" // Operating system exit command string TMPFILE = bae_progdir()+"_osshell.tmp" /* Temp. file for redirect stdout */; #define TABWIDTH 8 // Screen tabulator width int MAXCMDL /* Maximum command line length */; int MAXCOL /* Screen maximum column count */; int rows /* Screen row count */; int currow = 0 /* Current screen row */; int newscreen = 1 /* New screen flag */; string uline /* Underline string */; // Main program void main() { string cmd /* OS command string */; int sts /* OS command completion status */; // Abort if BAE Demo if (bae_swconfig(1)==BAE_Demo) popupmessage(-1,-1,-1,ERRBAEDEMO1,ERRBAEDEMO2,ERRBAEDEMO3); // Abort if BAE Windows environment if (bae_swconfig(3)==BAE_WinStd || bae_swconfig(3)==BAE_WinPulldwn) { launch("cmd"); exit(0); } // Get the maximum command length bae_twsize(MAXCMDL,0); MAXCMDL-=strlen(OSPROMPT)+1; // Set the file error mode fseterrmode(0); // Init the screen screeninit(); // Run the OS shell while ((cmd=askstr(OSPROMPT,MAXCMDL))!=OSEXIT && cmd!=UINPOPABORT) { // Echo the command line echo(OSPROMPT+cmd); // Ignore if no command specified if (cmd=="") continue; // Call the command (direct output to temp. file) sts=system(cmd+" >"+TMPFILE); // List the temporary file fileview(TMPFILE); // Remove the temporary file remove(TMPFILE); // Issue message on nonzero completion status if (sts) { sprintf(cmd,ERRCOMPSTS,sts); echo(OSPROMPT+cmd); } } } // File view routines void fileview(string fn) /* // View an ASCII file (display contents in text output screen) // Parameters : // string fn : File name */ { int fh /* Input file handle */; int rowreq /* Row request count */; string curstr /* Current input string */; // Open the input file if ((fh=fopen(fn,0))==(-1)) return; // Init the screen screeninit(); // Get strings from input file while (fgets(curstr,MAXCOL,fh)==0) { // Get the required lines count rowreq=scrstrlines(curstr); // Test if at end of page if ((currow+=rowreq)>=rows) { // Abort on user confirmation if (confirm(UPRLQUIT)) break; // Re-init the text screen bae_prtdialog(""); bae_inittextscreen(); currow=rowreq; // Issue shell header shellheader(); } // Print the current string putstr(curstr); } // Close the input file fclose(fh); } int scrstrlines(string s) /* // Get screen output lines count for given string // Return value : // requested screen line count // Parameters : // string s : Test string */ { int l = 0 /* String length */; int i = 0 /* Loop control variable */; char c /* Character buffer */; // Scan the string characters while ((c=s[i++])!='\0') { // Test the character if (c=='\t') // Perform tabulation l+=TABWIDTH-l%TABWIDTH; else // Increment the string length l++; } // Test if newline char matches right border if (l>0 && l%MAXCOL==0 && s[strlen(s)-1]=='\n') // Return the requested line count return(l/MAXCOL); // Return the requested lines count return(l/MAXCOL+1); } // User interaction routines int confirm(string prompt) /* // Ask user for yes or no // Return value : // nonzero on yes answer, or zero else // Parameters : // string prompt : Prompt string */ { string answer /* Input string */; // Set default mouse klick answer to empty string bae_setmousetext(""); // Get and lowercase the answer strlower(answer=bae_readtext(prompt,1)); // Return the answer code return(answer==UINEXIT || answer==UINPOPABORT); } void echo(string strbuf) /* // Echo a string to the text output screen // Parameters : // string strbuf : Echo string buffer */ { int rowreq /* Row request count */; // Init the screen screeninit(); // Get the required lines count rowreq=scrstrlines(strbuf); // Test if at end of page if ((currow+=rowreq)>=rows) { // Re-init the text screen bae_prtdialog(""); bae_inittextscreen(); currow=rowreq; // Issue shell header shellheader(); } // Print the current string puts(strbuf); } void screeninit() /* // Init the text output screen */ { // Test if new screen required if (newscreen) { // Get the text screen size bae_twsize(MAXCOL,rows); // Build the underline string sprintf(uline,"%.*s",MAXCOL,ULINE+ULINE+ULINE); // Init the text screen bae_inittextscreen(); // Reset current row currow=0; // Reset the new screen flag newscreen=0; // Issue shell header shellheader(); // Issue warnings osshellwarn(); } } void shellheader() /* // Issue shell header */ { // Print OS shell header/help info echo(bae_swconfig(0)==BAE_HighEnd ? HLPUNIXSHELL : HLPDOSSHELL); // Print underline echo(uline); } void osshellwarn() /* // Issue warnings */ { int wn /* Warnings count */; int i /* Loop control variable */; // Do not issue warnings if in BAE HighEnd // or advanced user interface BAE if (bae_swconfig(0)==BAE_HighEnd || bae_swconfig(3)!=BAE_StdScreen) return; // Assume DOS environment; issue warnings for (wn=arylength(wl),i=0;i"); break; } // Return the CFIG386 command string return(s); } // User Language program end