• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/maloc/src/vsh/vsh.c

00001 /*
00002  * ***************************************************************************
00003  * MALOC = < Minimal Abstraction Layer for Object-oriented C >
00004  * Copyright (C) 1994--2008 Michael Holst
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019  *
00020  * rcsid="$Id: vsh.c,v 1.26 2008/03/12 05:13:58 fetk Exp $"
00021  * ***************************************************************************
00022  */
00023 
00024 /*
00025  * ***************************************************************************
00026  * File:     vsh.c
00027  *
00028  * Purpose:  Class Vsh: methods.
00029  *
00030  * Author:   Michael Holst
00031  * ***************************************************************************
00032  */
00033 
00034 #include "vsh_p.h"
00035 #include "vpup.h"
00036 
00037 VEMBED(rcsid="$Id: vsh.c,v 1.26 2008/03/12 05:13:58 fetk Exp $")
00038 
00039 /* use lex/yacc or not */
00040 #define VSH_LEX_YACC_NOT 1
00041 
00042 /* lex/yacc support */
00043 VPUBLIC int cmdKey = 0;
00044 VPUBLIC Vsh *Vsh_thee = VNULL;
00045 VPUBLIC COMMAND *global_command = VNULL;
00046 
00047 /* command structure */
00048 typedef enum VSH_command {
00049     vshcom_none,
00050     vshcom_clear,
00051     vshcom_help,
00052     vshcom_pause,
00053     vshcom_delay,
00054     vshcom_set,
00055     vshcom_penv,
00056     vshcom_pinfo,
00057     vshcom_cd,
00058     vshcom_cdw,
00059     vshcom_io,
00060     vshcom_noio,
00061     vshcom_exit,
00062     vshcom_dot,
00063     vshcom_sockg,
00064     vshcom_sockm,
00065     vshcom_sockk,
00066     vshcom_sorry
00067 } VSH_command;
00068 
00069 VPRIVATE void Vsh_publishVars(Vsh *thee, int argc, char **argv);
00070 VPRIVATE void Vsh_readlineReset(void);
00071 
00072 /*
00073  * ***************************************************************************
00074  * Class Vsh: Inlineable methods
00075  * ***************************************************************************
00076  */
00077 #if !defined(VINLINE_MALOC)
00078 #endif /* if !defined(VINLINE_MALOC) */
00079 
00080 /*
00081  * ***************************************************************************
00082  * Class Vsh: Non-inlineable methods
00083  * ***************************************************************************
00084  */
00085 
00086 /*
00087  * ***************************************************************************
00088  * Routine:  Vsh_ctor
00089  *
00090  * Purpose:  Create the shell.
00091  *
00092  * Author:   Michael Holst
00093  * ***************************************************************************
00094  */
00095 VPUBLIC Vsh* Vsh_ctor(Vmem *vmem, int argc, char **argv)
00096 {
00097     Vsh *thee = VNULL;
00098 
00099     VDEBUGIO("Vsh_ctor: CREATING object..");
00100 
00101     thee = Vmem_malloc( VNULL, 1, sizeof(Vsh) );
00102     if (vmem == VNULL) {
00103         thee->vmem = Vmem_ctor( "Vsh" );
00104         thee->iMadeVmem = 1;
00105     } else {
00106         thee->vmem = vmem;
00107         thee->iMadeVmem = 0;
00108     }
00109 
00110     VDEBUGIO("..done.\n");
00111 
00112     /* start i/o layer */
00113     Vio_start();
00114 
00115     /* initialization */
00116     thee->processArgs = 1;
00117     thee->inUnit      = VNULL;
00118     thee->scUnit      = VNULL;
00119     thee->clUnit      = VNULL;
00120     thee->cinUnit     = VNULL;
00121     thee->cinName[0]  = '\0';
00122     thee->PR[0]       = '\0';
00123     thee->PR_PATH[0]  = '\0';
00124     strcpy(thee->PR_EXIT,"exit");
00125     thee->envValuLen = 0;
00126     thee->envInfoLen = 0;
00127     thee->envValu = Vmem_malloc(thee->vmem,1,sizeof(char*));
00128     thee->envInfo = Vmem_malloc(thee->vmem,1,sizeof(char*));
00129     thee->envValu[0] = VNULL;
00130     thee->envInfo[0] = VNULL;
00131     thee->buf        = VNULL;
00132     thee->bufsize    = 0;
00133 
00134     /* set the builtin/thee pointers */
00135     thee->Ext_thee    = VNULL;
00136     thee->Ext_builtin = VNULL;
00137     Vsh_thee = thee;
00138 
00139     /* publish other variables */
00140     Vsh_publishVars(thee, argc, argv);
00141 
00142     /* return the object */
00143     return thee;
00144 }
00145 
00146 /*
00147  * ***************************************************************************
00148  * Routine:  Vsh_dtor
00149  *
00150  * Purpose:  Destroy the shell.
00151  *
00152  * Author:   Michael Holst
00153  * ***************************************************************************
00154  */
00155 VPUBLIC void Vsh_dtor(Vsh **thee)
00156 {
00157     VASSERT( (*thee) != VNULL );
00158     if ((*thee) != VNULL) {
00159 
00160         /* wipe the environment */
00161         Vsh_wipe( (*thee) );
00162 
00163         /* stop i/o layer */
00164         Vio_stop();
00165 
00166         VDEBUGIO("Vsh_dtor: DESTROYING object..");
00167         if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
00168         Vmem_free( VNULL, 1, sizeof(Vsh), (void**)thee );
00169         VDEBUGIO("..done.\n");
00170 
00171         (*thee) = VNULL;
00172     }
00173 }
00174 
00175 /*
00176  * ***************************************************************************
00177  * Routine:  Vsh_publishVars
00178  *
00179  * Purpose:  Publish environment variables.
00180  *
00181  * Author:   Michael Holst
00182  * ***************************************************************************
00183  */
00184 VPRIVATE void Vsh_publishVars(Vsh *thee, int argc, char **argv)
00185 {
00186     char homeDirectory[VMAX_ARGLEN];
00187     char workDirectory[VMAX_ARGLEN];
00188     char userName[VMAX_ARGLEN];
00189     char hostName[VMAX_ARGLEN];
00190     char osName[VMAX_ARGLEN];
00191     char configFile[VMAX_ARGLEN];
00192     char buf1[VMAX_ARGLEN], buf2[VMAX_ARGLEN];
00193     char *term, *cterm;
00194     int i, numVars = 11;
00195     typedef struct vshVars {
00196         char envi[VMAX_ARGLEN];
00197         char valu[VMAX_ARGLEN];
00198         char info[VMAX_ARGLEN];
00199     } vshVars;
00200     vshVars envVars[] = {
00201         /* --------   -----       ----------- */
00202         /* VARIABLE   VALUE       EXPLANATION */
00203         /* --------   -----       ----------- */
00204         /* ===[ SOCKET=1 ]=== */
00205         { "GVLO",     "2x1",
00206             "socket layout (1x1,...,4x1,1x1s,...,4x1s)" },
00207 
00208         /* ===[ INPUTDEV=5 ]=== */
00209         { "ISKEY",    "file",
00210             "VIO INPUT DEV type (sdio,file,buff,unix,inet)" },
00211         { "ISFMT",    "asc",
00212             "VIO INPUT DEV format (asc,xdr)" },
00213         { "IFNAM",    "mcin.m",
00214             "VIO INPUT DEV file (filename for file I/O)" },
00215         { "ISNAM",    "0",
00216             "VIO INPUT DEV name ([ buff | unix | inet ] number)" },
00217         { "IHVAL",    "localhost",
00218             "VIO INPUT DEV host (INET hostname or IP address)" },
00219 
00220         /* ===[ OUTPUTDEV=5 ]=== */
00221         { "OSKEY",    "inet",
00222             "VIO OUTPUT DEV type (sdio,file,buff,unix,inet)" },
00223         { "OSFMT",    "asc",
00224             "VIO OUTPUT DEV format (asc,xdr)" },
00225         { "OFNAM",    "mcout.m",
00226             "VIO OUTPUT DEV file (filename for file I/O)" },
00227         { "OSNAM",    "1",
00228             "VIO OUTPUT DEV name ([ buff | unix | inet ] number)" },
00229         { "OHVAL",    "localhost",
00230             "VIO OUTPUT DEV host (INET hostname or IP address)" },
00231     };
00232 
00233     /* get username, hostname, and osname */
00234     VASSERT( Vnm_getuser(userName,sizeof(userName)) );
00235     VASSERT( Vnm_gethost(hostName,sizeof(hostName)) );
00236     VASSERT( Vnm_getos(osName,sizeof(osName)) );
00237 
00238     /* get the home directory */
00239     /*
00240      * NOTES: the first call to Vnm_gethome fixes the home directory
00241      *        for all time, regardless of who makes the call.
00242      */
00243     VASSERT( Vnm_gethome(homeDirectory,sizeof(homeDirectory)) );
00244 
00245     /* get the working directory */
00246     /*
00247      * NOTES: each call to Vnm_getcwd may return a different value;
00248      *        it returns the current working directory, which may be
00249      *        modified by calls to Vnm_chdir.
00250      */
00251     VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
00252 
00253     /* get some other stuff (may be null) */
00254     term  = getenv("TERM");
00255     cterm = getenv("COLORTERM");
00256 
00257     /* config file */
00258     sprintf(configFile,"%s/%s",homeDirectory,"rc.mcsh");
00259 
00260     /* export to the variables */
00261     VASSERT( Vsh_putenv(     thee, "USER",      userName               )
00262           && Vsh_putenvInfo( thee, "USER",      "user name"            ) );
00263     VASSERT( Vsh_putenv(     thee, "HOSTNAME",  hostName               )
00264           && Vsh_putenvInfo( thee, "HOSTNAME",  "host name"            ) );
00265     VASSERT( Vsh_putenv(     thee, "OSTYPE",    osName                 )
00266           && Vsh_putenvInfo( thee, "OSTYPE",    "operating system"     ) );
00267     VASSERT( Vsh_putenv(     thee, "HOME",      homeDirectory          )
00268           && Vsh_putenvInfo( thee, "HOME",      "home directory"       ) );
00269     VASSERT( Vsh_putenv(     thee, "CWD",       workDirectory          )
00270           && Vsh_putenvInfo( thee, "CWD",       "working directory"    ) );
00271     VASSERT( Vsh_putenv(     thee, "TERM",      term                   )
00272           && Vsh_putenvInfo( thee, "TERM",      "terminal type"        ) );
00273     VASSERT( Vsh_putenv(     thee, "COLORTERM", cterm                  )
00274           && Vsh_putenvInfo( thee, "COLORTERM", "color terminal type"  ) );
00275 
00276     /* init file name, shell name, prompt */
00277     VASSERT( Vsh_putenv(     thee, "ENV",       configFile             )
00278           && Vsh_putenvInfo( thee, "ENV",       "environ file"         ) );
00279     VASSERT( Vsh_putenv(     thee, "SHELL",     thee->PR               )
00280           && Vsh_putenvInfo( thee, "SHELL",     "command shell"        ) );
00281     VASSERT( Vsh_putenv(     thee, "PROMPT",    thee->PR_PATH          )
00282           && Vsh_putenvInfo( thee, "PROMPT",    "command shell prompt" ) );
00283 
00284     /* publish remaining variables */
00285     for (i=0; i<numVars; i++) {
00286         VASSERT( Vsh_putenv(     thee, envVars[i].envi, envVars[i].valu )
00287               && Vsh_putenvInfo( thee, envVars[i].envi, envVars[i].info ) );
00288     }
00289 
00290     /* publish argc/argv variables */
00291     VASSERT( Vsh_putenvInt(thee,"ARGC",argc)
00292           && Vsh_putenvInfo(thee,"ARGC","Number of command line parameters") );
00293     for (i=0; i<argc; i++) {
00294         sprintf(buf1,"ARG%d",i);
00295         sprintf(buf2,"Command line parameter <%d>",i);
00296         VASSERT( Vsh_putenv(     thee, buf1, argv[i] )
00297               && Vsh_putenvInfo( thee, buf1, buf2    ) );
00298     }
00299 }
00300 
00301 /*
00302  * ***************************************************************************
00303  * Routine:  Vsh_trace
00304  *
00305  * Purpose:  Trace of token stream.
00306  *
00307  * Author:   Michael Holst
00308  * ***************************************************************************
00309  */
00310 VPUBLIC void Vsh_trace(char *from, char *arg) {
00311 #if defined(VSH_TRACE)
00312 #   if defined(VSH_LEX_YACC)
00313         fprintf(stderr, "%s token=<%s>, yytext=<%s>\n", from, arg, yytext);
00314 #   else
00315         fprintf(stderr, "%s token=<%s>\n", from, arg);
00316 #   endif
00317 #endif
00318 }
00319 
00320 /*
00321  * ***************************************************************************
00322  * Routine:  Vsh_isInteractive
00323  *
00324  * Purpose:  Is this an interactive shell.
00325  *
00326  * Author:   Michael Holst
00327  * ***************************************************************************
00328  */
00329 VPUBLIC int Vsh_isInteractive(Vsh *thee) {
00330     return ((thee->cinUnit == stdin) && isatty(fileno(stdin)));
00331 }
00332 
00333 /*
00334  * ***************************************************************************
00335  * Routine:  Vsh_findVar
00336  *
00337  * Purpose:  Find a variable in the environment.
00338  *
00339  * Notes:    The parameters are:
00340  *
00341  *               env    --> the environment variable array
00342  *               envLen --> the environment variable array length
00343  *               var    --> the variable we are looking for
00344  *               term   --> the character terminator (usually "=" or ":")
00345  *
00346  * Author:   Michael Holst
00347  * ***************************************************************************
00348  */
00349 VPUBLIC int Vsh_findVar(char **env, int envLen,
00350     const char *var, const char term)
00351 {
00352     int i, j, len, ifnd, foundEq;
00353     char varBuf[VMAX_BUFSIZE];
00354 
00355     /* look for variable in the environment */
00356     ifnd = -1;
00357     i = 0;
00358     while ((ifnd < 0) && (i<envLen)) {
00359 
00360         /* grab the complete string */
00361         strcpy(varBuf,env[i]);
00362 
00363         /* strip out the variable and the value */
00364         len = strlen(varBuf);
00365         foundEq = 0;
00366         for (j=0; j<len; j++) {
00367             if (!foundEq) {
00368                 if (varBuf[j] == term) {
00369                     varBuf[j] = '\0';
00370                     foundEq = 1;
00371                 }
00372             } else {
00373                varBuf[j] = '\0';
00374             }
00375         }
00376 
00377         /* now check for match */
00378         if (!strcmp(varBuf,var)) {
00379             ifnd = i;
00380         }
00381         
00382         /* next iteration */
00383         i++;
00384     }
00385 
00386     return ifnd;
00387 }
00388 
00389 /*
00390  * ***************************************************************************
00391  * Routine:  Vsh_putenv
00392  *
00393  * Purpose:  Place a variable with a value in the environment.
00394  *
00395  * Author:   Michael Holst
00396  * ***************************************************************************
00397  */
00398 VPUBLIC int Vsh_putenv(Vsh *thee, const char *envi, const char *valu)
00399 {
00400     int i, len, ifnd;
00401     char *newValu, **newValuList, valuLoc[VMAX_BUFSIZE];
00402 
00403     VASSERT( envi != VNULL );
00404     if (valu == VNULL ) {
00405         valuLoc[0] = '\0';
00406     } else {
00407         strcpy(valuLoc,valu);
00408     }
00409 
00410     /* make the variable=value string */
00411     len = strlen(envi) + 1 + strlen(valuLoc) + 1;
00412     newValu = Vmem_malloc(thee->vmem,len,sizeof(char));
00413     sprintf(newValu,"%s=%s",envi,valuLoc);
00414 
00415     /* look for variable in the environment */
00416     ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
00417 
00418     /* if variable exists, just change it */
00419     if (ifnd >= 0) {
00420 
00421         if (valuLoc[0] != '\0') {
00422 
00423             /* free old VALU */
00424             len = strlen(thee->envValu[ifnd]) + 1;
00425             Vmem_free(thee->vmem,len,sizeof(char),
00426                 (void**)&(thee->envValu[ifnd]) );
00427 
00428             /* point to new VALU */
00429             thee->envValu[ifnd] = newValu;
00430         }
00431 
00432     /* variable doesn't exist; must create it */
00433     } else {
00434 
00435         /* expand the environment */
00436         thee->envValuLen++;
00437 
00438         /* make a new VALU list with one more slot */
00439         len = thee->envValuLen + 1;
00440         newValuList = Vmem_malloc(thee->vmem,len,sizeof(char*));
00441 
00442         /* copy the old VALU list into the new VALU list */
00443         for (i=0; i<thee->envValuLen-1; i++) {
00444             newValuList[i] = thee->envValu[i];
00445         }
00446         newValuList[thee->envValuLen-1] = newValu;
00447         newValuList[thee->envValuLen] = VNULL;
00448 
00449         /* free old VALU list */
00450         len = thee->envValuLen;
00451         Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envValu) );
00452 
00453         /* setup the new VALU list */
00454         thee->envValu = newValuList;
00455     }
00456 
00457     return 1;
00458 }
00459 
00460 /*
00461  * ***************************************************************************
00462  * Routine:  Vsh_putenvInfo
00463  *
00464  * Purpose:  Place a variable with an info string in the environment.
00465  *
00466  * Author:   Michael Holst
00467  * ***************************************************************************
00468  */
00469 VPUBLIC int Vsh_putenvInfo(Vsh *thee, const char *envi, const char *info)
00470 {
00471     int i, len, ifnd;
00472     char *newInfo, **newInfoList, infoLoc[VMAX_BUFSIZE];
00473 
00474     VASSERT( envi != VNULL );
00475     if (info == VNULL ) {
00476         infoLoc[0] = '\0';
00477     } else {
00478         strcpy(infoLoc,info);
00479     }
00480 
00481     /* make the variable=info string */
00482     len = strlen(envi) + 2 + strlen(infoLoc) + 1;
00483     newInfo = Vmem_malloc(thee->vmem,len,sizeof(char));
00484     sprintf(newInfo,"%s: %s",envi,infoLoc);
00485 
00486     /* look for variable in the environment */
00487     ifnd = Vsh_findVar(thee->envInfo,thee->envInfoLen,envi,':');
00488 
00489     /* if variable exists, just change it */
00490     if (ifnd >= 0) {
00491 
00492         if (infoLoc[0] != '\0') {
00493 
00494             /* free old INFO */
00495             len = strlen(thee->envInfo[ifnd]) + 1;
00496             Vmem_free(thee->vmem,len,sizeof(char),
00497                 (void**)&(thee->envInfo[ifnd]) );
00498 
00499             /* point to new INFO */
00500             thee->envInfo[ifnd] = newInfo;
00501         }
00502 
00503     /* variable doesn't exist; must create it */
00504     } else {
00505 
00506         /* expand the environment */
00507         thee->envInfoLen++;
00508 
00509         /* make a new INFO list with one more slot */
00510         len = thee->envInfoLen + 1;
00511         newInfoList = Vmem_malloc(thee->vmem,len,sizeof(char*));
00512 
00513         /* copy the old INFO list into the new INFO list */
00514         for (i=0; i<thee->envInfoLen-1; i++) {
00515             newInfoList[i] = thee->envInfo[i];
00516         }
00517         newInfoList[thee->envInfoLen-1] = newInfo;
00518         newInfoList[thee->envInfoLen] = VNULL;
00519 
00520         /* free old INFO list */
00521         len = thee->envInfoLen;
00522         Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envInfo) );
00523 
00524         /* setup the new INFO list */
00525         thee->envInfo = newInfoList;
00526     }
00527 
00528     return 1;
00529 }
00530 
00531 /*
00532  * ***************************************************************************
00533  * Routine:  Vsh_putenvInt
00534  *
00535  * Purpose:  Place a variable with a value (integer) in the environment.
00536  *
00537  * Author:   Michael Holst
00538  * ***************************************************************************
00539  */
00540 VPUBLIC int Vsh_putenvInt(Vsh *thee, const char *envi, const int valu)
00541 {
00542     char buf[VMAX_BUFSIZE];
00543 
00544     sprintf(buf,"%d",valu);
00545     Vsh_putenv(thee,envi,buf);
00546 
00547     return 1;
00548 }
00549 
00550 /*
00551  * ***************************************************************************
00552  * Routine:  Vsh_putenvReal
00553  *
00554  * Purpose:  Place a variable with a value (real) in the environment.
00555  *
00556  * Author:   Michael Holst
00557  * ***************************************************************************
00558  */
00559 VPUBLIC int Vsh_putenvReal(Vsh *thee, const char *envi, const double valu)
00560 {
00561     char buf[VMAX_BUFSIZE];
00562 
00563     sprintf(buf,"%e",valu);
00564     Vsh_putenv(thee,envi,buf);
00565 
00566     return 1;
00567 }
00568 
00569 
00570 /*
00571  * ***************************************************************************
00572  * Routine:  Vsh_getenv
00573  *
00574  * Purpose:  Get a value of variable in the environment.
00575  *
00576  * Author:   Michael Holst
00577  * ***************************************************************************
00578  */
00579 VPUBLIC char* Vsh_getenv(Vsh *thee, const char *envi)
00580 {
00581     int ifnd;
00582 
00583     ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
00584     if (ifnd >= 0) {
00585         return (thee->envValu[ifnd]+strlen(envi)+1);
00586     } else {
00587         return VNULL;
00588     }
00589 }
00590 
00591 /*
00592  * ***************************************************************************
00593  * Routine:  Vsh_getenvInfo
00594  *
00595  * Purpose:  Get info associated with a variable in the environment.
00596  *
00597  * Author:   Michael Holst
00598  * ***************************************************************************
00599  */
00600 VPUBLIC char* Vsh_getenvInfo(Vsh *thee, const char *envi)
00601 {
00602     int ifnd;
00603 
00604     ifnd = Vsh_findVar(thee->envInfo,thee->envInfoLen,envi,':');
00605     if (ifnd >= 0) {
00606         return (thee->envInfo[ifnd]+strlen(envi)+2);
00607     } else {
00608         return VNULL;
00609     }
00610 }
00611 
00612 /*
00613  * ***************************************************************************
00614  * Routine:  Vsh_getenvInt
00615  *
00616  * Purpose:  Get a value of variable in the environment as an integer.
00617  *
00618  * Author:   Michael Holst
00619  * ***************************************************************************
00620  */
00621 VPUBLIC int Vsh_getenvInt(Vsh *thee, const char *envi)
00622 {
00623     int ifnd;
00624 
00625     ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
00626     if (ifnd >= 0) {
00627         return atoi(thee->envValu[ifnd]+strlen(envi)+1);
00628     } else {
00629         return 0;
00630     }
00631 }
00632 
00633 /*
00634  * ***************************************************************************
00635  * Routine:  Vsh_getenvReal
00636  *
00637  * Purpose:  Get a value of variable in the environment as a real.
00638  *
00639  * Author:   Michael Holst
00640  * ***************************************************************************
00641  */
00642 VPUBLIC double Vsh_getenvReal(Vsh *thee, const char *envi)
00643 {
00644     int ifnd;
00645 
00646     ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
00647     if (ifnd >= 0) {
00648         return atof(thee->envValu[ifnd]+strlen(envi)+1);
00649     } else {
00650         return 0.0;
00651     }
00652 }
00653 
00654 /*
00655  * ***************************************************************************
00656  * Routine:  Vsh_remove
00657  *
00658  * Purpose:  Remove a variable from the environment.
00659  *
00660  * Author:   Michael Holst
00661  * ***************************************************************************
00662  */
00663 VPUBLIC void Vsh_remove(Vsh *thee, const char *envi)
00664 {
00665     /* unsetenv(envi); */
00666 }
00667 
00668 /*
00669  * ***************************************************************************
00670  * Routine:  Vsh_wipe
00671  *
00672  * Purpose:  Wipe the environment.
00673  *
00674  * Author:   Michael Holst
00675  * ***************************************************************************
00676  */
00677 VPUBLIC void Vsh_wipe(Vsh *thee)
00678 {
00679     int i, len;
00680 
00681     VASSERT( thee->envValu != VNULL );
00682 
00683     /* wipe the entire environment */
00684     for (i=0; i<thee->envValuLen; i++) {
00685         len = strlen(thee->envValu[i]) + 1;
00686         Vmem_free(thee->vmem,len,sizeof(char), (void**)&(thee->envValu[i]) );
00687     }
00688     len = thee->envValuLen + 1;
00689     Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envValu) );
00690     for (i=0; i<thee->envInfoLen; i++) {
00691         len = strlen(thee->envInfo[i]) + 1;
00692         Vmem_free(thee->vmem,len,sizeof(char), (void**)&(thee->envInfo[i]) );
00693     }
00694     len = thee->envInfoLen + 1;
00695     Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envInfo) );
00696 }
00697 
00698 /*
00699  * ***************************************************************************
00700  * Routine:  Vsh_printenv
00701  *
00702  * Purpose:  Print the environment.
00703  *
00704  * Author:   Michael Holst
00705  * ***************************************************************************
00706  */
00707 VPUBLIC void Vsh_printenv(Vsh *thee)
00708 {
00709     int i;
00710 
00711     for (i=0; i<thee->envValuLen; i++) {
00712         Vnm_print(1,"%s\n",thee->envValu[i]);
00713     }
00714 }
00715 
00716 /*
00717  * ***************************************************************************
00718  * Routine:  Vsh_printenvInfo
00719  *
00720  * Purpose:  Print the environment info.
00721  *
00722  * Author:   Michael Holst
00723  * ***************************************************************************
00724  */
00725 VPUBLIC void Vsh_printenvInfo(Vsh *thee)
00726 {
00727     int i;
00728 
00729     for (i=0; i<thee->envInfoLen; i++) {
00730         Vnm_print(1,"%s\n",thee->envInfo[i]);
00731     }
00732 }
00733 
00734 /*
00735  * ***************************************************************************
00736  * Routine:  Vsh_completion
00737  *
00738  * Purpose:  Command completion action.
00739  *
00740  * Notes:    The return type and argument list is mandated by readline:
00741  *
00742  *               int func(int count, int key)
00743  *
00744  *           Useful tips: the readline library uses the following conventions
00745  *           for simplifying the notation for function pointers:
00746  *          
00747  *               typedef int IFunction ();
00748  *               typedef void VFunction ();
00749  *               typedef char *CPFunction ();
00750  *               typedef char **CPPFunction ();
00751  *
00752  *           This allows one to replace something like:
00753  *
00754  *               int (*)()func;
00755  *
00756  *           with simply:
00757  *
00758  *               IFunction *func;
00759  *
00760  * Author:   Michael Holst
00761  * ***************************************************************************
00762  */
00763 #if defined(HAVE_READLINE_READLINE_H)
00764 VPRIVATE int Vsh_completion(int count, int key)
00765 {
00766     int cargc = 1; 
00767     char *cargv[2] = { "help", VNULL }; 
00768 
00769     Vnm_print(1,"\n");
00770     Vsh_builtIn(Vsh_thee, cargc, cargv);
00771     Vnm_print(1,"%s",Vsh_thee->PR_PATH);
00772 
00773     Vsh_readlineReset();
00774 
00775     return 0;
00776 }
00777 #endif
00778 
00779 /*
00780  * ***************************************************************************
00781  * Routine:  Vsh_readlineInit
00782  *
00783  * Purpose:  Initialize the readline library.
00784  *
00785  * Author:   Michael Holst
00786  * ***************************************************************************
00787  */
00788 VPRIVATE void Vsh_readlineInit(void)
00789 {
00790     static int init=0;
00791 
00792     if (!init) {
00793         init = 1;
00794 
00795 #if defined(HAVE_READLINE_READLINE_H)
00796 #if 0
00797         rl_catch_signals = 0;
00798         rl_catch_sigwinch = 0;
00799 #endif
00800         rl_bind_key(9, &Vsh_completion);
00801 #endif
00802     }
00803 }
00804 
00805 /*
00806  * ***************************************************************************
00807  * Routine:  Vsh_readlineReset
00808  *
00809  * Purpose:  Reset the readline library (e.g. free partial input string).
00810  *
00811  * Author:   Michael Holst
00812  * ***************************************************************************
00813  */
00814 VPRIVATE void Vsh_readlineReset(void)
00815 {
00816     Vsh_readlineInit();
00817 
00818 #if defined(HAVE_READLINE_READLINE_H)
00819 #if 0
00820     rl_free_line_state();
00821     rl_resize_terminal();
00822 #endif
00823 #endif
00824 }
00825 
00826 /*
00827  * ***************************************************************************
00828  * Routine:  Vsh_addhist
00829  *
00830  * Purpose:  Put an input line into the history list.
00831  *
00832  * Author:   Michael Holst
00833  * ***************************************************************************
00834  */
00835 VPUBLIC void Vsh_addhist(char *buf, int buflen)
00836 {
00837     Vsh_readlineInit();
00838 
00839 #if defined(HAVE_READLINE_HISTORY_H)
00840     add_history(buf);
00841 #endif
00842 }
00843 
00844 /*
00845  * ***************************************************************************
00846  * Routine:  Vsh_readline
00847  *
00848  * Purpose:  Get an input line.
00849  *
00850  * Author:   Michael Holst
00851  * ***************************************************************************
00852  */
00853 VPUBLIC char *Vsh_readline(char *prompt, char *buf, int buflen, FILE *stream)
00854 {
00855     char *key;
00856 
00857     if (stream != stdin) {
00858         key = fgets(buf, buflen, stream);
00859     } else {
00860 
00861 #if defined(HAVE_READLINE_READLINE_H)
00862         Vsh_readlineInit();
00863         key = readline(prompt);
00864         if (key == VNULL) {
00865             buf[0] = '\n';
00866             buf[1] = '\0';
00867         } else if (key[0] == '\0') {
00868             buf[0] = '\n';
00869             buf[1] = '\0';
00870             free(key);
00871         } else {
00872             strncpy(buf,key,buflen);
00873             free(key);
00874         }
00875 #else
00876         Vnm_print(1,"%s",prompt);
00877         key = fgets(buf, buflen, stream);
00878 #endif
00879 
00880     }
00881 
00882     return key;
00883 }
00884 
00885 /*
00886  * ***************************************************************************
00887  * Routine:  Vsh_shell
00888  *
00889  * Purpose:  A bash-like shell with user-definable extensions.
00890  *
00891  * Author:   Michael Holst
00892  * ***************************************************************************
00893  */
00894 VPUBLIC int Vsh_shell(Vsh *thee, char *pPR, void *pthee,
00895     int (*builtin)(void *thee, int argc, char **argv))
00896 {
00897     int i, argc, offset;
00898     char **argvPtr, buf[VMAX_ARGLEN];
00899     char *argvNULL = "\0";
00900     struct stat fInfo;
00901  
00902     /* we will need argc and argv[] */
00903     argc = Vsh_getenvInt(thee, "ARGC");
00904     argvPtr = Vmem_malloc(thee->vmem, VMAX_ARGLEN, sizeof(char*));
00905     for (i=0; i<argc; i++) {
00906         sprintf(buf,"ARG%d",i);
00907         argvPtr[i] = Vsh_getenv(thee, buf);
00908     }
00909     argvPtr[argc] = argvNULL;
00910 
00911     /* paranoia: check type sizes on the machine */
00912     Vnm_typeChk();
00913 
00914     /* the externally supplied builtin object pointer and function */
00915     thee->Ext_thee    = pthee;
00916     thee->Ext_builtin = builtin;
00917 
00918     /* construct a reasonable shell command prompt if not given as argument */
00919     if (pPR != VNULL) {
00920         if (pPR[0] != '\0') {
00921             sprintf(thee->PR,"%s",pPR);
00922         }
00923     }
00924     if (thee->PR[0] == '\0') {
00925         VASSERT( argc > 0 );
00926         strncpy(buf,argvPtr[0],VMAX_ARGLEN);
00927         offset = 0;
00928         if (strlen(buf) >= 2) {
00929             /* remove the "./" if it is there */
00930             if ((buf[0] == '.') && (buf[1] == '/')) {
00931                 offset = 2;
00932             /* remove "-" if there; happens when vsh is a login shell */
00933             } else if (buf[0] == '-') {
00934                 offset = 1;
00935             }
00936         }
00937         sprintf(thee->PR,"%s",buf+offset);
00938     }
00939     Vsh_putenv(thee,"SHELL",thee->PR);
00940 
00941     /*
00942      * if filename given on command line, try to take input from there.
00943      */
00944     thee->inUnit = stdin;
00945     if (thee->processArgs) {
00946         for (i=1; i<argc; i++) {
00947 
00948             /* is the argument the "-h" option */
00949             if (!strcmp(argvPtr[i],"-h")) {
00950                 VJMPERR1(1);
00951 
00952             /* is the argument the "-io" option */
00953             } else if (!strcmp(argvPtr[i],"-io")) {
00954                 Vnm_redirect(0);
00955 
00956             /* is the argument the "-noio" option */
00957             } else if (!strcmp(argvPtr[i],"-noio")) {
00958                 Vnm_redirect(1);
00959 
00960             /* try to open the argument as a script file */
00961             } else {
00962                 thee->clUnit = fopen(argvPtr[i], "r");
00963                 if (thee->clUnit == VNULL) {
00964                     Vnm_print(2,"%s: Problem opening file <%s>\n",
00965                         thee->PR, argvPtr[i]);
00966                     thee->inUnit = stdin;
00967                     VJMPERR1(1);
00968                 } else thee->inUnit = thee->clUnit;
00969             }
00970         }
00971     }
00972 
00973     /* the current input unit starts out as stdin or a script */
00974     thee->cinUnit = thee->inUnit;
00975 
00976     /* we first execute the user's configuration file */
00977     if ( !stat(Vsh_getenv(thee,"ENV"), &fInfo) ) {
00978         if (VS_ISREG(fInfo.st_mode)) {
00979             thee->scUnit = fopen(Vsh_getenv(thee,"ENV"), "r");
00980             if (thee->scUnit != VNULL) {
00981                 thee->cinUnit = thee->scUnit;
00982                 strncpy(thee->cinName,Vsh_getenv(thee,"ENV"),VMAX_ARGLEN);
00983                 Vnm_print(0,"Starting <%s> script named <%s>\n",
00984                     thee->PR,thee->cinName);
00985             }
00986         }
00987     }
00988 
00989     /* start the command shell parsing loop */
00990     cmdKey = 0;
00991     while (cmdKey != 2) {
00992 
00993         /*
00994          * Parse a single input unit.
00995          * An input unit is a complete shell statement
00996          * (e.g. one-line command, if-then-else, while, case, etc)
00997          * which may span multiple lines of input.
00998          */
00999 #if defined(VSH_LEX_YACC)
01000         yyparse();  /* for complex Bourne-shell compatible input units */
01001         Vsh_yyexecute(global_command);
01002 #else
01003         Vsh_parse();  /* for simple one-line commands only */
01004         Vsh_execute();
01005 #endif
01006 
01007     }
01008 
01009     /* close the input unit for a command-line file if we had one */
01010     if (thee->clUnit != VNULL) VASSERT( !fclose(thee->clUnit) );
01011 
01012     /* free the argv storage */
01013     Vmem_free( thee->vmem, VMAX_ARGLEN, sizeof(char*), (void**)&argvPtr );
01014 
01015     /* no error */
01016     return 1;
01017 
01018   VERROR1:
01019     /* close the input unit for a command-line file if we had one */
01020     if (thee->clUnit != VNULL) VASSERT( !fclose(thee->clUnit) );
01021 
01022     /* free the argv storage */
01023     Vmem_free( thee->vmem, VMAX_ARGLEN, sizeof(char*), (void**)argvPtr );
01024 
01025     /* print a usage menu */
01026     Vnm_print(2,"usage: ./%s [ -h | -io | -noio ]"
01027                 " [ shellScriptFile ]\n",thee->PR);
01028 
01029     /* error, but not fatal */
01030     return 1;
01031 }
01032 
01033 /*
01034  * ***************************************************************************
01035  * Routine:  Vsh_input
01036  *
01037  * Purpose:  Read a single newline-terminated line of input.
01038  *
01039  * Notes:    We output a prompt if appropriate to do so.
01040  *           We catch any SIGINTs generated during input just like
01041  *           any normal command shell.  If one is caught, we jump
01042  *           back to the input prompt via setjmp/longjmp.
01043  *           We also handle killing of scripts via SIGINT, and
01044  *           correctly handle prompt output on redirection.
01045  *
01046  *           This routine is used with the following macro:
01047  *
01048  *               define VSH_INPUT(buf,result,max_size) { \  
01049  *                   result = Vsh_input(buf,max_size); \  
01050  *               }
01051  *
01052  *           which has exactly the same functionality as the YY_INPUT
01053  *           macro used by LEX.  Forcing LEX to use VSH_INPUT in place
01054  *           of YY_INPUT allows all of the above to work for a
01055  *           LEX/YACC-generated command shell parser.
01056  *
01057  * Input:    buf[0..buflen-1] = character buffer to read in to
01058  *           buflen           = length of buf
01059  *
01060  * Output:   returned = number of characters actually read in.
01061  *
01062  * Author:   Michael Holst
01063  * ***************************************************************************
01064  */
01065 VPUBLIC int Vsh_input(char *buf, int buflen)
01066 {
01067     int numRead;
01068     char *key, currDirectory[VMAX_ARGLEN];
01069     jmp_buf *jbuf;
01070 
01071     /* setup for the jump */
01072     jbuf = Vnm_signalInit();
01073     if (setjmp(*jbuf)) {
01074 
01075         /* FIRST: kill any script that may have been executing */
01076         Vsh_thee->cinUnit = Vsh_thee->inUnit;
01077 
01078         /* SECOND: reset the readline input buffer */
01079         Vsh_readlineReset();
01080 
01081         /* THIRD: restart lex on the (possibly) new input unit */
01082 #if defined(VSH_LEX_YACC)
01083             yyrestart(Vsh_thee->cinUnit);
01084 #endif
01085 
01086         /* FOURTH: print a newline if we are in interactive mode */
01087         if (Vsh_isInteractive(Vsh_thee)) {
01088             Vnm_print(1,"%s",VNEWLINE_STRING);
01089         }
01090     }
01091 
01092     /* close script unit if open -- must have killed it */
01093     if ( ((Vsh_thee->cinUnit != Vsh_thee->scUnit) 
01094          || feof(Vsh_thee->scUnit)) && (Vsh_thee->scUnit != VNULL) ) {
01095         VASSERT( !fclose(Vsh_thee->scUnit) );
01096         Vsh_thee->scUnit = VNULL;
01097         Vnm_print(0,"Stopping <%s> script named <%s>\n",
01098             Vsh_thee->PR,Vsh_thee->cinName);
01099         strncpy(Vsh_thee->cinName," ",VMAX_ARGLEN);
01100     }
01101 
01102     /* OKAY-TO-JUMP back to the input prompt now */
01103     Vnm_jmpOkSet();
01104 
01105     /* deal with different I/O units */
01106     if (Vsh_isInteractive(Vsh_thee)) {
01107         VASSERT( Vnm_getcwd(currDirectory,sizeof(currDirectory)) );
01108         sprintf(Vsh_thee->PR_PATH,"%s@%s<%s+%s>%% ",
01109             Vsh_getenv(Vsh_thee,"USER"),
01110             Vsh_getenv(Vsh_thee,"HOSTNAME"),
01111             Vsh_getenv(Vsh_thee,"OSTYPE"),
01112             Vsh_thee->PR);
01113         Vsh_putenv(Vsh_thee,"PROMPT",Vsh_thee->PR_PATH);
01114     }
01115 
01116     /* get the input line */
01117     memset(buf, VNULL_SYMBOL, buflen);
01118     key = Vsh_readline(Vsh_thee->PR_PATH, buf, buflen, Vsh_thee->cinUnit);
01119     if ((key == VNULL) && (Vsh_thee->cinUnit==Vsh_thee->scUnit)) {
01120 
01121         /* shut down the script handling */
01122         VASSERT( Vsh_thee->scUnit != VNULL );
01123         VASSERT( feof(Vsh_thee->scUnit) );
01124         VASSERT( !fclose(Vsh_thee->scUnit) );
01125         Vsh_thee->scUnit = VNULL;
01126         Vnm_print(0,"Stopping <%s> script named <%s>\n",
01127             Vsh_thee->PR,Vsh_thee->cinName);
01128         strncpy(Vsh_thee->cinName," ",VMAX_ARGLEN);
01129 
01130         /* deal with different I/O units */
01131         Vsh_thee->cinUnit = Vsh_thee->inUnit;
01132         if (Vsh_isInteractive(Vsh_thee)) {
01133             VASSERT( Vnm_getcwd(currDirectory,sizeof(currDirectory)) );
01134             sprintf(Vsh_thee->PR_PATH,"%s@%s<%s+%s>%% ",
01135                 Vsh_getenv(Vsh_thee,"USER"),
01136                 Vsh_getenv(Vsh_thee,"HOSTNAME"),
01137                 Vsh_getenv(Vsh_thee,"OSTYPE"),
01138                 Vsh_thee->PR);
01139             Vsh_putenv(Vsh_thee,"PROMPT",Vsh_thee->PR_PATH);
01140         }
01141 
01142         /* get the input line */
01143         memset(buf, VNULL_SYMBOL, buflen);
01144         key = Vsh_readline(Vsh_thee->PR_PATH,
01145             buf, buflen, Vsh_thee->cinUnit);
01146     }
01147 
01148     /* calculate the number of characters actually read */
01149     if (key == VNULL) {
01150         numRead = 0;
01151     } else {
01152         numRead = strlen(buf);
01153     }
01154     VASSERT( numRead <= buflen );
01155 
01156     /* NOT-OKAY-TO-JUMP back to the input prompt now */
01157     Vnm_jmpOkClear();
01158 
01159     /* clear the numerical loop signal before executing the command */
01160     Vnm_sigIntClear();
01161 
01162     /* return num chars read */
01163     return numRead;
01164 }
01165 
01166 /*
01167  * ***************************************************************************
01168  * Routine:  Vsh_getCmd
01169  *
01170  * Purpose:  Decode the input string into a legal command.
01171  *
01172  * Author:   Michael Holst
01173  * ***************************************************************************
01174  */
01175 VPRIVATE VSH_command Vsh_getCmd(int argc, char **argv)
01176 {
01177     VSH_command theCmd = vshcom_none;
01178     if (!strcmp(argv[0],"")) {
01179         theCmd = vshcom_none;
01180     } else if ( (!strcmp(argv[0],"c")) || (!strcmp(argv[0],"clear")) ) { 
01181         theCmd = vshcom_clear;
01182     } else if (!strcmp(argv[0],"help")) { 
01183         theCmd = vshcom_help;
01184     } else if (!strcmp(argv[0],"pause")) {
01185         theCmd = vshcom_pause;
01186     } else if (!strcmp(argv[0],"delay")) {
01187         theCmd = vshcom_delay;
01188     } else if (!strcmp(argv[0],"set")) {
01189         theCmd = vshcom_set;
01190     } else if (!strcmp(argv[0],"penv")) {
01191         theCmd = vshcom_penv;
01192     } else if (!strcmp(argv[0],"pinfo")) {
01193         theCmd = vshcom_pinfo;
01194     } else if (!strcmp(argv[0],"cd")) {
01195         theCmd = vshcom_cd;
01196     } else if (!strcmp(argv[0],"cdw")) {
01197         theCmd = vshcom_cdw;
01198     } else if (!strcmp(argv[0],"io")) {
01199         theCmd = vshcom_io;
01200     } else if (!strcmp(argv[0],"noio")) {
01201         theCmd = vshcom_noio;
01202     } else if (!strcmp(argv[0],"exit")) {
01203         theCmd = vshcom_exit;
01204     } else if (!strcmp(argv[0],".")) {
01205         theCmd = vshcom_dot;
01206     } else if (!strcmp(argv[0],"sockg")) {
01207         theCmd = vshcom_sockg;
01208     } else if (!strcmp(argv[0],"sockm")) {
01209         theCmd = vshcom_sockm;
01210     } else if (!strcmp(argv[0],"sockk")) {
01211         theCmd = vshcom_sockk;
01212     } else {
01213         theCmd = vshcom_none;
01214     }
01215     return theCmd;
01216 }
01217 
01218 /*
01219  * ***************************************************************************
01220  * Routine:  Vsh_execCmd
01221  *
01222  * Purpose:  Fork a child to exec a command, wait for child to finish.
01223  *
01224  * Author:   Michael Holst
01225  * ***************************************************************************
01226  */
01227 VPUBLIC void Vsh_execCmd(const char *PR, int argc, char **argv, char *inbuf)
01228 {
01229     /* fork a child to do the work (real shell behavior) */
01230 #if !defined(HAVE_WINSOCK_H)
01231 
01232     static pid_t child_pid;
01233     char PR_TMP[VMAX_ARGLEN];
01234 
01235     VASSERT( argc > 0 );
01236     sprintf(PR_TMP,"%s: %s",PR,argv[0]);
01237 
01238     if ((child_pid=fork()) == 0) {
01239         /* NOTE: child should NOT return except on error */
01240         Vpup_execCmd(PR_TMP,argc,argv,inbuf);
01241         perror(PR_TMP);
01242         exit(1);
01243     } else if (child_pid > 0) {
01244         wait(VNULL);
01245     } else {
01246         perror(PR_TMP);
01247     }
01248 
01249     /* fork() does not exist on Win32 */
01250     /* (also fork() is BROKEN in Linux 2.1.85 believe it or not...) */
01251     /* SO, we fake it by passing command to underlying shell -- bummer! */
01252 #else
01253 
01254     Vnm_system(inbuf);
01255 
01256 #endif
01257 }
01258 
01259 /*
01260  * ***************************************************************************
01261  * Routine:  Vsh_memChk
01262  *
01263  * Purpose:  Print the exact current malloc usage.
01264  *
01265  * Author:   Michael Holst
01266  * ***************************************************************************
01267  */
01268 VPUBLIC void Vsh_memChk(Vsh *thee)
01269 {
01270     if (thee->iMadeVmem) Vmem_print(thee->vmem);
01271 }
01272 
01273 /*
01274  * ***************************************************************************
01275  * Routine:  Vsh_killSockets
01276  *
01277  * Purpose:  Kill any socket graphics.
01278  *
01279  * Author:   Michael Holst
01280  * ***************************************************************************
01281  */
01282 VPRIVATE void Vsh_killSockets(Vsh *thee)
01283 {
01284     Vnm_systemKill("gvx");
01285     Vnm_systemKill("mcsg");
01286     Vnm_systemKill("mcbridge");
01287     Vnm_system("sleep 1");
01288 }
01289 
01290 /*
01291  * ***************************************************************************
01292  * Routine:  Vsh_builtIn
01293  *
01294  * Purpose:  Vsh_shell built-in commands.
01295  *
01296  * Author:   Michael Holst
01297  * ***************************************************************************
01298  */
01299 VPUBLIC int Vsh_builtIn(Vsh *thee, int argc, char **argv)
01300 {
01301     int i, rc;
01302     VSH_command theCmd;
01303     struct stat fInfo;
01304     jmp_buf *jbuf;
01305 
01306     char sysc[VMAX_BUFSIZE];
01307     char sofmt[VMAX_ARGLEN], sokey[VMAX_ARGLEN];
01308 
01309     static int  init=0;
01310     static char buf[VMAX_BUFSIZE], workDirectory[VMAX_ARGLEN];
01311     static char PR_TMP[VMAX_ARGLEN];
01312     static char env[VMAX_BUFSIZE], com[VMAX_BUFSIZE];
01313     static char sock[VMAX_BUFSIZE];
01314     const char *stmp;
01315 
01316     /* one-time intialization */
01317     if (!init) {
01318         init=1;
01319 
01320         /* make the env message (%s slots = 12) */
01321         stmp =
01322           "%s: Execution environment, directories, and files:\n"
01323           "    Shell                --> <%s>\n"
01324           "    User name            --> <%s>\n"
01325           "    Host name            --> <%s>\n"
01326           "    Operating system     --> <%s>\n"
01327           "    Home directory       --> <%s>\n"
01328           "    Work directory       --> <%s>\n"
01329           "    Startup script       --> <%s/%s>\n"
01330           "    Command history file --> <%s/%s>\n"
01331           "    I/O capture file     --> <%s/%s>\n";
01332         sprintf(env,stmp,thee->PR,
01333             thee->PR,
01334             Vsh_getenv(thee,"USER"),
01335             Vsh_getenv(thee,"HOSTNAME"),
01336             Vsh_getenv(thee,"OSTYPE"),
01337             Vsh_getenv(thee,"HOME"),
01338             Vsh_getenv(thee,"CWD"),
01339             Vsh_getenv(thee,"HOME"),"rc.mcsh",
01340             Vsh_getenv(thee,"HOME"),"hist.mcsh",
01341             Vsh_getenv(thee,"HOME"),"io.mc");
01342 
01343         /* make the com message (%s slots = 2) */
01344         stmp =
01345           "%s: Shell interaction commands: \n"
01346           "    help [ env|com|sock ] --> print help messages\n"
01347           "    c | clear                 --> clear the screen\n"
01348           "    pause                     --> pause until carriage return\n"
01349           "    delay                     --> delay for three seconds\n"
01350           "    cd | cdw                  --> cd to home or work directory\n";
01351         sprintf(com,stmp,thee->PR);
01352         stmp =
01353           "    io | noio                 --> display extra io or not\n"
01354           "    set [var [val]]           --> set or print variables\n"
01355           "    penv [var]                --> print variable\n"
01356           "    pinfo [var]               --> print variable information\n"
01357           "    . scriptfile              --> execute an vsh scriptfile\n"
01358           "    exit | CTRL-D             --> exit the <%s> shell\n";
01359         sprintf(buf,stmp,thee->PR);
01360         strcat(com,buf);
01361 
01362         /* make the socket message (%s slots = 1) */
01363         stmp = "%s: Socket Graphics manipulation commands: \n"
01364             "    sockk --> kill all socket graphics processes\n"
01365             "    sockg --> start geomview socket displays\n"
01366             "    sockm --> start mcsg socket displays\n";
01367         sprintf(sock,stmp,thee->PR);
01368     }
01369 
01370     /* the user-defined shell gets first shot at the command */
01371     if (thee->Ext_builtin != VNULL) {
01372         rc = (*(thee->Ext_builtin))(thee->Ext_thee,argc,argv);
01373         if (rc != 0) return rc;
01374     }
01375 
01376     /* now it is our turn; set default return code (success) */
01377     rc = 1;
01378 
01379     /* get the command */
01380     theCmd = Vsh_getCmd(argc, argv);
01381 
01382     /* decode and execute the command */
01383     switch (theCmd) {
01384 
01385       case vshcom_pause:
01386         sprintf(PR_TMP,"%s: Press <return> to continue..", thee->PR);
01387         memset(buf, VNULL_SYMBOL, sizeof(buf));
01388 
01389         /* setup for the jump */
01390         jbuf = Vnm_signalInit();
01391         if (setjmp(*jbuf)) {
01392 
01393             /* FIRST: kill any script that may have been executing */
01394             thee->cinUnit = thee->inUnit;
01395 
01396             /* SECOND: reset the readline input buffer */
01397             Vsh_readlineReset();
01398 
01399             /* THIRD: restart lex on the (possibly) new input unit */
01400 #if defined(VSH_LEX_YACC)
01401                 yyrestart(thee->cinUnit);
01402 #endif
01403 
01404             /* FOURTH: print a newline if we are in interactive mode */
01405             if (Vsh_isInteractive(thee)) {
01406                 Vnm_print(1,"%s",VNEWLINE_STRING);
01407             }
01408 
01409             Vnm_jmpOkClear();
01410             Vnm_sigIntClear();
01411         } else {
01412             Vnm_jmpOkSet();
01413             Vsh_readline(PR_TMP, buf, sizeof(buf), stdin);
01414             Vnm_jmpOkClear();
01415             Vnm_sigIntClear();
01416         }
01417         rc = 1;
01418         break;
01419 
01420       case vshcom_delay:
01421         Vnm_sleep(3000000);
01422         break;
01423 
01424       case vshcom_clear:
01425         memset(buf, VNULL_SYMBOL, sizeof(buf));
01426 #if !defined(HAVE_WINSOCK_H)
01427         strcpy(buf,"clear");
01428 #else
01429         strcpy(buf,"cls");
01430 #endif
01431         Vnm_system(buf);
01432         break;
01433 
01434       case vshcom_help:
01435         if (argc==1) {
01436             Vnm_print(1,"%s: Vsh-layer Help Menu:\n",thee->PR);
01437             Vnm_print(1,"    help env  --> Help on %s environment\n",
01438                 thee->PR);
01439             Vnm_print(1,"    help com  --> Help on %s shell commands\n",
01440                 thee->PR);
01441             Vnm_print(1,"    help sock --> Help on %s socket graphics\n",
01442                 thee->PR);
01443         } else {
01444             if (!strcmp(argv[1],"env")) { 
01445                 Vnm_print(1, "%s", env);
01446             } else if (!strcmp(argv[1],"com")) { 
01447                 Vnm_print(1, "%s", com);
01448             } else if (!strcmp(argv[1],"sock")) { 
01449                 Vnm_print(1, "%s", sock);
01450             } else {
01451                 /* we are the last shell layer; nothing to defer to */
01452             }
01453         }
01454         break;
01455 
01456       case vshcom_set:
01457         if (argc <= 1) {
01458             Vsh_printenv(thee);
01459         } else if (argc == 2) {
01460             Vnm_print(2,"%s: %s=%s\n",
01461                 thee->PR,argv[1],Vsh_getenv(thee,argv[1]));
01462         } else if (argc == 3) {
01463             Vsh_putenv(thee,argv[1],argv[2]);
01464         } else if (argc > 3) {
01465             Vsh_putenv(thee,argv[1],argv[2]);
01466             buf[0] = '\0';
01467             for (i=3; i<argc; i++) {
01468                 if (i>3) strcat(buf," ");
01469                 strcat(buf,argv[i]);
01470             }
01471             Vsh_putenvInfo(thee,argv[1],buf);
01472         } else VASSERT(0);
01473         break;
01474 
01475       case vshcom_penv:
01476         if (argc <= 1) {
01477             Vsh_printenv(thee);
01478         } else if (argc == 2) {
01479             Vnm_print(2,"%s: %s=%s\n",
01480                 thee->PR,argv[1],Vsh_getenv(thee,argv[1]));
01481         } else Vnm_print(2,"%s: %s: Too many arguments\n",thee->PR,argv[0]);
01482         break;
01483 
01484       case vshcom_pinfo:
01485         if (argc <= 1) {
01486             Vsh_printenvInfo(thee);
01487         } else if (argc == 2) {
01488             Vnm_print(2,"%s: %s: %s\n",
01489                 thee->PR,argv[1],Vsh_getenvInfo(thee,argv[1]));
01490         } else Vnm_print(2,"%s: %s: Too many arguments\n",thee->PR,argv[0]);
01491         break;
01492 
01493       case vshcom_cd:
01494         if (argc==1) {
01495             if (Vnm_chdir(Vsh_getenv(thee,"HOME")) == -1) {
01496                 Vnm_print(2,"%s: %s: %s: No such directory\n",
01497                     thee->PR, argv[0], Vsh_getenv(thee,"HOME"));
01498             }
01499             VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
01500             Vsh_putenv(thee,"CWD", workDirectory);
01501         } else {
01502             if (Vnm_chdir(argv[1]) == -1) {
01503                 Vnm_print(2,"%s: %s: %s: No such directory\n",
01504                     thee->PR, argv[0], argv[1]);
01505             }
01506             VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
01507             Vsh_putenv(thee,"CWD", workDirectory);
01508         }
01509         break;
01510 
01511       case vshcom_cdw:
01512         if (argc==1) {
01513             if (Vnm_chdir(Vsh_getenv(thee,"MCSH_HOME")) == -1) {
01514                 Vnm_print(2,"%s: %s: %s: No such directory\n",
01515                     thee->PR, argv[0], Vsh_getenv(thee,"MCSH_HOME"));
01516             }
01517             VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
01518             Vsh_putenv(thee,"CWD", workDirectory);
01519         } else {
01520             if (Vnm_chdir(argv[1]) == -1) {
01521                 Vnm_print(2,"%s: %s: %s: No such directory\n",
01522                     thee->PR, argv[0], argv[1]);
01523             }
01524             VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
01525             Vsh_putenv(thee,"CWD", workDirectory);
01526         }
01527         break;
01528 
01529       case vshcom_io:
01530         Vnm_redirect(0);
01531         break;
01532 
01533       case vshcom_noio:
01534         Vnm_redirect(1);
01535         break;
01536 
01537       case vshcom_exit:
01538         if (Vnm_chdir(Vsh_getenv(thee,"HOME")) == -1)
01539             Vnm_print(2,"%s: %s: %s: No such directory\n",
01540                 thee->PR, "cd", Vsh_getenv(thee,"HOME"));
01541         rc = 2;                                                           
01542         break;
01543 
01544       case vshcom_dot:
01545         if (argc <= 1) {
01546             Vnm_print(2,"%s: Filename argument required\n", thee->PR);
01547         } else if ( !stat(argv[1], &fInfo) ) {
01548             if (VS_ISREG(fInfo.st_mode)) {
01549                 thee->scUnit = fopen(argv[1], "r");
01550                 if (thee->scUnit != VNULL) {
01551                     thee->cinUnit = thee->scUnit;
01552                     strncpy(thee->cinName,argv[1],VMAX_ARGLEN);
01553                     Vnm_print(0,"Starting <%s> script named <%s>\n",
01554                         thee->PR,thee->cinName);
01555                 } else {
01556                     Vnm_print(2,"%s: Problem opening <%s>\n",
01557                         thee->PR,argv[1]);
01558                 }
01559             } else {
01560                 Vnm_print(2,"%s: File <%s> not normal\n",
01561                     thee->PR,argv[1]);
01562             }
01563         } else {
01564             Vnm_print(2,"%s: File <%s> not found\n",thee->PR,argv[1]);
01565         }
01566         break;
01567 
01568       case vshcom_sockg:
01569         Vsh_killSockets(thee);
01570         strncpy(sofmt,Vsh_getenv(thee,"OSFMT"),VMAX_ARGLEN);
01571         if (!strcmp("unix",Vsh_getenv(thee,"OSKEY"))) {
01572             strncpy(sokey,"Mcs",VMAX_ARGLEN);
01573         } else if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01574             strncpy(sokey,"Mcs",VMAX_ARGLEN);
01575         } else {
01576             strncpy(sokey,"Mcs",VMAX_ARGLEN);
01577         }
01578         if (!strcmp("1x1",Vsh_getenv(thee,"GVLO"))) {
01579             sprintf(sysc,"geomview -nopanels -wpos 436,445@55,520 -%s 0",sokey);
01580             Vnm_systemBack(sysc);
01581             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01582                 Vnm_systemBack("mcbridge -i2u 0 0");
01583             }
01584         } else if (!strcmp("2x1",Vsh_getenv(thee,"GVLO"))) {
01585             sprintf(sysc,"geomview -nopanels -wpos 436,445@55,520 -%s 0",sokey);
01586             Vnm_systemBack(sysc);
01587             sprintf(sysc,"geomview -nopanels -wpos 436,445@55,50  -%s 1",sokey);
01588             Vnm_systemBack(sysc);
01589             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01590                 Vnm_systemBack("mcbridge -i2u 0 0");
01591                 Vnm_systemBack("mcbridge -i2u 1 1");
01592             }
01593         } else if (!strcmp("3x1",Vsh_getenv(thee,"GVLO"))) {
01594             sprintf(sysc,"geomview -nopanels -wpos 436,287@55,684 -%s 0",sokey);
01595             Vnm_systemBack(sysc);
01596             sprintf(sysc,"geomview -nopanels -wpos 436,287@55,367 -%s 1",sokey);
01597             Vnm_systemBack(sysc);
01598             sprintf(sysc,"geomview -nopanels -wpos 436,287@55,50  -%s 2",sokey);
01599             Vnm_systemBack(sysc);
01600             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01601                 Vnm_systemBack("mcbridge -i2u 0 0");
01602                 Vnm_systemBack("mcbridge -i2u 1 1");
01603                 Vnm_systemBack("mcbridge -i2u 2 2");
01604             }
01605         } else if (!strcmp("4x1",Vsh_getenv(thee,"GVLO"))) {
01606             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 0",sokey);
01607             Vnm_systemBack(sysc);
01608             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 1",sokey);
01609             Vnm_systemBack(sysc);
01610             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 2",sokey);
01611             Vnm_systemBack(sysc);
01612             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 3",sokey);
01613             Vnm_systemBack(sysc);
01614             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01615                 Vnm_systemBack("mcbridge -i2u 0 0");
01616                 Vnm_systemBack("mcbridge -i2u 1 1");
01617                 Vnm_systemBack("mcbridge -i2u 2 2");
01618                 Vnm_systemBack("mcbridge -i2u 3 3");
01619             }
01620         } else if (!strcmp("1x1s",Vsh_getenv(thee,"GVLO"))) {
01621             sprintf(sysc,"geomview -nopanels -wpos 282,245 -%s 0",sokey);
01622             Vnm_systemBack(sysc);
01623             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01624                 Vnm_systemBack("mcbridge -i2u 0 0");
01625             }
01626         } else if (!strcmp("2x1s",Vsh_getenv(thee,"GVLO"))) {
01627             sprintf(sysc,"geomview -nopanels -wpos 282,245 -%s 0",sokey);
01628             Vnm_systemBack(sysc);
01629             sprintf(sysc,"geomview -nopanels -wpos 282,245 -%s 1",sokey);
01630             Vnm_systemBack(sysc);
01631             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01632                 Vnm_systemBack("mcbridge -i2u 0 0");
01633                 Vnm_systemBack("mcbridge -i2u 1 1");
01634             }
01635         } else if (!strcmp("3x1s",Vsh_getenv(thee,"GVLO"))) {
01636             sprintf(sysc,"geomview -nopanels -wpos 282,152 -%s 0",sokey);
01637             Vnm_systemBack(sysc);
01638             sprintf(sysc,"geomview -nopanels -wpos 282,152 -%s 1",sokey);
01639             Vnm_systemBack(sysc);
01640             sprintf(sysc,"geomview -nopanels -wpos 282,152 -%s 2",sokey);
01641             Vnm_systemBack(sysc);
01642             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01643                 Vnm_systemBack("mcbridge -i2u 0 0");
01644                 Vnm_systemBack("mcbridge -i2u 1 1");
01645                 Vnm_systemBack("mcbridge -i2u 2 2");
01646             }
01647         } else if (!strcmp("4x1s",Vsh_getenv(thee,"GVLO"))) {
01648             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 0",sokey);
01649             Vnm_systemBack(sysc);
01650             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 1",sokey);
01651             Vnm_systemBack(sysc);
01652             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 2",sokey);
01653             Vnm_systemBack(sysc);
01654             sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 3",sokey);
01655             Vnm_systemBack(sysc);
01656             if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01657                 Vnm_systemBack("mcbridge -i2u 0 0");
01658                 Vnm_systemBack("mcbridge -i2u 1 1");
01659                 Vnm_systemBack("mcbridge -i2u 2 2");
01660                 Vnm_systemBack("mcbridge -i2u 3 3");
01661             }
01662         } else {
01663             Vnm_print(2,"%s: %s: Incorrect argument <%s>\n",
01664                 thee->PR,"GVLO",Vsh_getenv(thee,"GVLO"));
01665         }
01666         Vnm_system("sleep 3");
01667         break;
01668 
01669       case vshcom_sockm:
01670         Vsh_killSockets(thee);
01671         strncpy(sofmt,Vsh_getenv(thee,"OSFMT"),VMAX_ARGLEN);
01672         if (!strcmp("unix",Vsh_getenv(thee,"OSKEY"))) {
01673             strncpy(sokey,"Mcs",VMAX_ARGLEN);
01674         } else if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01675             strncpy(sokey,"Mci",VMAX_ARGLEN);
01676         } else {
01677             strncpy(sokey,"Mci",VMAX_ARGLEN);
01678         }
01679         if (!strcmp("1x1",Vsh_getenv(thee,"GVLO"))) {
01680             sprintf(sysc,"mcsg -%s -wpos 436,445@55,520 -%s 0",sofmt,sokey);
01681             Vnm_systemBack(sysc);
01682         } else if (!strcmp("2x1",Vsh_getenv(thee,"GVLO"))) {
01683             sprintf(sysc,"mcsg -%s -wpos 436,445@55,520 -%s 0",sofmt,sokey);
01684             Vnm_systemBack(sysc);
01685             sprintf(sysc,"mcsg -%s -wpos 436,445@55,50  -%s 1",sofmt,sokey);
01686             Vnm_systemBack(sysc);
01687         } else if (!strcmp("3x1",Vsh_getenv(thee,"GVLO"))) {
01688             sprintf(sysc,"mcsg -%s -wpos 436,287@55,684 -%s 0",sofmt,sokey);
01689             Vnm_systemBack(sysc);
01690             sprintf(sysc,"mcsg -%s -wpos 436,287@55,367 -%s 1",sofmt,sokey);
01691             Vnm_systemBack(sysc);
01692             sprintf(sysc,"mcsg -%s -wpos 436,287@55,50  -%s 2",sofmt,sokey);
01693             Vnm_systemBack(sysc);
01694         } else if (!strcmp("4x1",Vsh_getenv(thee,"GVLO"))) {
01695             sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 0",sofmt,sokey);
01696             Vnm_systemBack(sysc);
01697             sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 1",sofmt,sokey);
01698             Vnm_systemBack(sysc);
01699             sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 2",sofmt,sokey);
01700             Vnm_systemBack(sysc);
01701             sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 3",sofmt,sokey);
01702             Vnm_systemBack(sysc);
01703         } else if (!strcmp("1x1s",Vsh_getenv(thee,"GVLO"))) {
01704             sprintf(sysc,"mcsg -%s -wpos 282,245 -%s 0",sofmt,sokey);
01705             Vnm_systemBack(sysc);
01706         } else if (!strcmp("2x1s",Vsh_getenv(thee,"GVLO"))) {
01707             sprintf(sysc,"mcsg -%s -wpos 282,245 -%s 0",sofmt,sokey);
01708             Vnm_systemBack(sysc);
01709             sprintf(sysc,"mcsg -%s -wpos 282,245 -%s 1",sofmt,sokey);
01710             Vnm_systemBack(sysc);
01711         } else if (!strcmp("3x1s",Vsh_getenv(thee,"GVLO"))) {
01712             sprintf(sysc,"mcsg -%s -wpos 282,152 -%s 0",sofmt,sokey);
01713             Vnm_systemBack(sysc);
01714             sprintf(sysc,"mcsg -%s -wpos 282,152 -%s 1",sofmt,sokey);
01715             Vnm_systemBack(sysc);
01716             sprintf(sysc,"mcsg -%s -wpos 282,152 -%s 2",sofmt,sokey);
01717             Vnm_systemBack(sysc);
01718         } else if (!strcmp("4x1s",Vsh_getenv(thee,"GVLO"))) {
01719             sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 0",sofmt,sokey);
01720             Vnm_systemBack(sysc);
01721             sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 1",sofmt,sokey);
01722             Vnm_systemBack(sysc);
01723             sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 2",sofmt,sokey);
01724             Vnm_systemBack(sysc);
01725             sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 3",sofmt,sokey);
01726             Vnm_systemBack(sysc);
01727         } else if (!strcmp("2x1r",Vsh_getenv(thee,"GVLO"))) {
01728             sprintf(sysc,"mcsg -%s -wpos 425,345@55,0 -%s 0",sofmt,sokey);
01729             Vnm_systemBack(sysc);
01730             sprintf(sysc,"mcsg -%s -wpos 425,345@55,369 -%s 1",sofmt,sokey);
01731             Vnm_systemBack(sysc);
01732         } else {
01733             Vnm_print(2,"%s: %s: Incorrect argument <%s>\n",
01734                 thee->PR,"GVLO",Vsh_getenv(thee,"GVLO"));
01735         }
01736         Vnm_system("sleep 3");
01737         break;
01738 
01739       case vshcom_sockk:
01740         Vsh_killSockets(thee);
01741         break;
01742 
01743       case vshcom_sorry:
01744         Vnm_system("play sorry.au");
01745         break;
01746 
01747       default:
01748         rc = 0;
01749         break;
01750     }
01751     return rc;
01752 }
01753 
01754 /*
01755  * ***************************************************************************
01756  * Routine:  Vsh_ioSetup
01757  *
01758  * Purpose:  Setup for an I/O command.
01759  *
01760  * Author:   Michael Holst
01761  * ***************************************************************************
01762  */
01763 VPUBLIC Vio *Vsh_ioSetup(Vsh *thee, char *key)
01764 {
01765     char iodev[VMAX_BUFSIZE], iofmt[VMAX_BUFSIZE];
01766     char iohost[VMAX_BUFSIZE], iofile[VMAX_BUFSIZE];
01767     Vio *sock;
01768 
01769     /* setup for a read */
01770     if (!strcmp("r",key)) {
01771 
01772         strncpy(iohost,Vsh_getenv(thee,"IHVAL"),VMAX_BUFSIZE);
01773 
01774         if (!strcmp("sdio",Vsh_getenv(thee,"ISKEY"))) {
01775             strncpy(iodev,"SDIO",VMAX_BUFSIZE);
01776             strncpy(iofile,"console",VMAX_BUFSIZE);
01777         } else if (!strcmp("file",Vsh_getenv(thee,"ISKEY"))) {
01778             strncpy(iodev,"FILE",VMAX_BUFSIZE);
01779             strncpy(iofile,Vsh_getenv(thee,"IFNAM"),VMAX_BUFSIZE);
01780         } else if (!strcmp("buff",Vsh_getenv(thee,"ISKEY"))) {
01781             strncpy(iodev,"BUFF",VMAX_BUFSIZE);
01782             strncpy(iofile,Vsh_getenv(thee,"ISNAM"),VMAX_BUFSIZE);
01783         } else if (!strcmp("unix",Vsh_getenv(thee,"ISKEY"))) {
01784             strncpy(iodev,"UNIX",VMAX_BUFSIZE);
01785             strncpy(iofile,Vsh_getenv(thee,"ISNAM"),VMAX_BUFSIZE);
01786         } else if (!strcmp("inet",Vsh_getenv(thee,"ISKEY"))) {
01787             strncpy(iodev,"INET",VMAX_BUFSIZE);
01788             strncpy(iofile,Vsh_getenv(thee,"ISNAM"),VMAX_BUFSIZE);
01789         } else {
01790             Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
01791             VJMPERR1( 0 );
01792         }
01793 
01794         if (!strcmp("asc",Vsh_getenv(thee,"ISFMT"))) {
01795             strncpy(iofmt,"ASC", VMAX_BUFSIZE);
01796         } else if (!strcmp("xdr",Vsh_getenv(thee,"ISFMT"))) {
01797             strncpy(iofmt,"XDR", VMAX_BUFSIZE);
01798         } else {
01799             Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
01800             VJMPERR1( 0 );
01801         }
01802 
01803     /* setup for a write */
01804     } else if (!strcmp("w",key)) {
01805 
01806         strncpy(iohost,Vsh_getenv(thee,"OHVAL"),VMAX_BUFSIZE);
01807 
01808         if (!strcmp("sdio",Vsh_getenv(thee,"OSKEY"))) {
01809             strncpy(iodev,"SDIO",VMAX_BUFSIZE);
01810             strncpy(iofile,"console",VMAX_BUFSIZE);
01811         } else if (!strcmp("file",Vsh_getenv(thee,"OSKEY"))) {
01812             strncpy(iodev,"FILE",VMAX_BUFSIZE);
01813             strncpy(iofile,Vsh_getenv(thee,"OFNAM"),VMAX_BUFSIZE);
01814         } else if (!strcmp("buff",Vsh_getenv(thee,"OSKEY"))) {
01815             strncpy(iodev,"BUFF",VMAX_BUFSIZE);
01816             strncpy(iofile,Vsh_getenv(thee,"OSNAM"),VMAX_BUFSIZE);
01817         } else if (!strcmp("unix",Vsh_getenv(thee,"OSKEY"))) {
01818             strncpy(iodev,"UNIX",VMAX_BUFSIZE);
01819             strncpy(iofile,Vsh_getenv(thee,"OSNAM"),VMAX_BUFSIZE);
01820         } else if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
01821             strncpy(iodev,"INET",VMAX_BUFSIZE);
01822             strncpy(iofile,Vsh_getenv(thee,"OSNAM"),VMAX_BUFSIZE);
01823         } else {
01824             Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
01825             VJMPERR1( 0 );
01826         }
01827 
01828         if (!strcmp("asc",Vsh_getenv(thee,"OSFMT"))) {
01829             strncpy(iofmt,"ASC", VMAX_BUFSIZE);
01830         } else if (!strcmp("xdr",Vsh_getenv(thee,"OSFMT"))) {
01831             strncpy(iofmt,"XDR", VMAX_BUFSIZE);
01832         } else {
01833             Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
01834             VJMPERR1( 0 );
01835         }
01836 
01837     } else {
01838         Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
01839         VJMPERR1( 0 );
01840     }
01841 
01842     /* create socket and associate the buffer */
01843     VJMPERR1( VNULL != (sock=Vio_socketOpen(key,iodev,iofmt,iohost,iofile)) );
01844     Vio_bufTake(sock, thee->buf, thee->bufsize);
01845     thee->bufsize = 0;
01846     thee->buf     = VNULL;
01847 
01848     /* return without error */
01849     return sock;
01850 
01851   VERROR1: 
01852     Vnm_print(2,"Vsh_ioSetup: bailing out.\n");
01853     return VNULL;
01854 }
01855 
01856 /*
01857  * ***************************************************************************
01858  * Routine:  Vsh_ioCleanup
01859  *
01860  * Purpose:  Cleanup an I/O command.
01861  *
01862  * Author:   Michael Holst
01863  * ***************************************************************************
01864  */
01865 VPUBLIC void Vsh_ioCleanup(Vsh *thee, Vio **sock)
01866 {
01867     VJMPERR1( VNULL != thee );
01868     VJMPERR1( VNULL != *sock );
01869 
01870     /* snag the buffer before destroying the socket */
01871     thee->bufsize = Vio_bufSize(*sock);
01872     thee->buf     = Vio_bufGive(*sock);
01873 
01874     /* return without error */
01875     Vio_socketClose( sock );
01876     return;
01877 
01878   VERROR1: 
01879     Vnm_print(2,"Vsh_ioCleanup: bailing out.\n");
01880     return; 
01881 }
01882 

Generated on Wed Oct 20 2010 11:12:15 for APBS by  doxygen 1.7.2