1 /*
2 * ***************************************************************************
3 * MALOC = < Minimal Abstraction Layer for Object-oriented C >
4 * Copyright (C) 1994-- Michael Holst
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * rcsid="$Id: vsh.c,v 1.27 2010/08/12 05:40:27 fetk Exp $"
21 * ***************************************************************************
22 */
23
24 /*
25 * ***************************************************************************
26 * File: vsh.c
27 *
28 * Purpose: Class Vsh: methods.
29 *
30 * Author: Michael Holst
31 * ***************************************************************************
32 */
33
34 #include "vsh_p.h"
35 #include "vpup.h"
36
37 VEMBED(rcsid="$Id: vsh.c,v 1.27 2010/08/12 05:40:27 fetk Exp $")
38
39 /* use lex/yacc or not */
40 #define VSH_LEX_YACC_NOT 1
41
42 /* lex/yacc support */
43 VPUBLIC int cmdKey = 0;
44 VPUBLIC Vsh *Vsh_thee = VNULL;
45 VPUBLIC COMMAND *global_command = VNULL;
46
47 /* command structure */
48 typedef enum VSH_command {
49 vshcom_none,
50 vshcom_clear,
51 vshcom_help,
52 vshcom_pause,
53 vshcom_delay,
54 vshcom_set,
55 vshcom_penv,
56 vshcom_pinfo,
57 vshcom_cd,
58 vshcom_cdw,
59 vshcom_io,
60 vshcom_noio,
61 vshcom_exit,
62 vshcom_dot,
63 vshcom_sockg,
64 vshcom_sockm,
65 vshcom_sockk,
66 vshcom_sorry
67 } VSH_command;
68
69 VPRIVATE void Vsh_publishVars(Vsh *thee, int argc, char **argv);
70 VPRIVATE void Vsh_readlineReset(void);
71
72 /*
73 * ***************************************************************************
74 * Class Vsh: Inlineable methods
75 * ***************************************************************************
76 */
77 #if !defined(VINLINE_MALOC)
78 #endif /* if !defined(VINLINE_MALOC) */
79
80 /*
81 * ***************************************************************************
82 * Class Vsh: Non-inlineable methods
83 * ***************************************************************************
84 */
85
86 /*
87 * ***************************************************************************
88 * Routine: Vsh_ctor
89 *
90 * Purpose: Create the shell.
91 *
92 * Author: Michael Holst
93 * ***************************************************************************
94 */
Vsh_ctor(Vmem * vmem,int argc,char ** argv)95 VPUBLIC Vsh* Vsh_ctor(Vmem *vmem, int argc, char **argv)
96 {
97 Vsh *thee = VNULL;
98
99 VDEBUGIO("Vsh_ctor: CREATING object..");
100
101 thee = Vmem_malloc( VNULL, 1, sizeof(Vsh) );
102 if (vmem == VNULL) {
103 thee->vmem = Vmem_ctor( "Vsh" );
104 thee->iMadeVmem = 1;
105 } else {
106 thee->vmem = vmem;
107 thee->iMadeVmem = 0;
108 }
109
110 VDEBUGIO("..done.\n");
111
112 /* start i/o layer */
113 Vio_start();
114
115 /* initialization */
116 thee->processArgs = 1;
117 thee->inUnit = VNULL;
118 thee->scUnit = VNULL;
119 thee->clUnit = VNULL;
120 thee->cinUnit = VNULL;
121 thee->cinName[0] = '\0';
122 thee->PR[0] = '\0';
123 thee->PR_PATH[0] = '\0';
124 strcpy(thee->PR_EXIT,"exit");
125 thee->envValuLen = 0;
126 thee->envInfoLen = 0;
127 thee->envValu = Vmem_malloc(thee->vmem,1,sizeof(char*));
128 thee->envInfo = Vmem_malloc(thee->vmem,1,sizeof(char*));
129 thee->envValu[0] = VNULL;
130 thee->envInfo[0] = VNULL;
131 thee->buf = VNULL;
132 thee->bufsize = 0;
133
134 /* set the builtin/thee pointers */
135 thee->Ext_thee = VNULL;
136 thee->Ext_builtin = VNULL;
137 Vsh_thee = thee;
138
139 /* publish other variables */
140 Vsh_publishVars(thee, argc, argv);
141
142 /* return the object */
143 return thee;
144 }
145
146 /*
147 * ***************************************************************************
148 * Routine: Vsh_dtor
149 *
150 * Purpose: Destroy the shell.
151 *
152 * Author: Michael Holst
153 * ***************************************************************************
154 */
Vsh_dtor(Vsh ** thee)155 VPUBLIC void Vsh_dtor(Vsh **thee)
156 {
157 VASSERT( (*thee) != VNULL );
158 if ((*thee) != VNULL) {
159
160 /* wipe the environment */
161 Vsh_wipe( (*thee) );
162
163 /* stop i/o layer */
164 Vio_stop();
165
166 VDEBUGIO("Vsh_dtor: DESTROYING object..");
167 if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
168 Vmem_free( VNULL, 1, sizeof(Vsh), (void**)thee );
169 VDEBUGIO("..done.\n");
170
171 (*thee) = VNULL;
172 }
173 }
174
175 /*
176 * ***************************************************************************
177 * Routine: Vsh_publishVars
178 *
179 * Purpose: Publish environment variables.
180 *
181 * Author: Michael Holst
182 * ***************************************************************************
183 */
Vsh_publishVars(Vsh * thee,int argc,char ** argv)184 VPRIVATE void Vsh_publishVars(Vsh *thee, int argc, char **argv)
185 {
186 char homeDirectory[VMAX_ARGLEN];
187 char workDirectory[VMAX_ARGLEN];
188 char userName[VMAX_ARGLEN];
189 char hostName[VMAX_ARGLEN];
190 char osName[VMAX_ARGLEN];
191 char configFile[VMAX_ARGLEN];
192 char buf1[VMAX_ARGLEN], buf2[VMAX_ARGLEN];
193 char *term, *cterm;
194 int i, numVars = 11;
195 typedef struct vshVars {
196 char envi[VMAX_ARGLEN];
197 char valu[VMAX_ARGLEN];
198 char info[VMAX_ARGLEN];
199 } vshVars;
200 vshVars envVars[] = {
201 /* -------- ----- ----------- */
202 /* VARIABLE VALUE EXPLANATION */
203 /* -------- ----- ----------- */
204 /* ===[ SOCKET=1 ]=== */
205 { "GVLO", "2x1",
206 "socket layout (1x1,...,4x1,1x1s,...,4x1s)" },
207
208 /* ===[ INPUTDEV=5 ]=== */
209 { "ISKEY", "file",
210 "VIO INPUT DEV type (sdio,file,buff,unix,inet)" },
211 { "ISFMT", "asc",
212 "VIO INPUT DEV format (asc,xdr)" },
213 { "IFNAM", "mcin.m",
214 "VIO INPUT DEV file (filename for file I/O)" },
215 { "ISNAM", "0",
216 "VIO INPUT DEV name ([ buff | unix | inet ] number)" },
217 { "IHVAL", "localhost",
218 "VIO INPUT DEV host (INET hostname or IP address)" },
219
220 /* ===[ OUTPUTDEV=5 ]=== */
221 { "OSKEY", "inet",
222 "VIO OUTPUT DEV type (sdio,file,buff,unix,inet)" },
223 { "OSFMT", "asc",
224 "VIO OUTPUT DEV format (asc,xdr)" },
225 { "OFNAM", "mcout.m",
226 "VIO OUTPUT DEV file (filename for file I/O)" },
227 { "OSNAM", "1",
228 "VIO OUTPUT DEV name ([ buff | unix | inet ] number)" },
229 { "OHVAL", "localhost",
230 "VIO OUTPUT DEV host (INET hostname or IP address)" },
231 };
232
233 /* get username, hostname, and osname */
234 VASSERT( Vnm_getuser(userName,sizeof(userName)) );
235 VASSERT( Vnm_gethost(hostName,sizeof(hostName)) );
236 VASSERT( Vnm_getos(osName,sizeof(osName)) );
237
238 /* get the home directory */
239 /*
240 * NOTES: the first call to Vnm_gethome fixes the home directory
241 * for all time, regardless of who makes the call.
242 */
243 VASSERT( Vnm_gethome(homeDirectory,sizeof(homeDirectory)) );
244
245 /* get the working directory */
246 /*
247 * NOTES: each call to Vnm_getcwd may return a different value;
248 * it returns the current working directory, which may be
249 * modified by calls to Vnm_chdir.
250 */
251 VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
252
253 /* get some other stuff (may be null) */
254 term = getenv("TERM");
255 cterm = getenv("COLORTERM");
256
257 /* config file */
258 sprintf(configFile,"%s/%s",homeDirectory,"rc.mcsh");
259
260 /* export to the variables */
261 VASSERT( Vsh_putenv( thee, "USER", userName )
262 && Vsh_putenvInfo( thee, "USER", "user name" ) );
263 VASSERT( Vsh_putenv( thee, "HOSTNAME", hostName )
264 && Vsh_putenvInfo( thee, "HOSTNAME", "host name" ) );
265 VASSERT( Vsh_putenv( thee, "OSTYPE", osName )
266 && Vsh_putenvInfo( thee, "OSTYPE", "operating system" ) );
267 VASSERT( Vsh_putenv( thee, "HOME", homeDirectory )
268 && Vsh_putenvInfo( thee, "HOME", "home directory" ) );
269 VASSERT( Vsh_putenv( thee, "CWD", workDirectory )
270 && Vsh_putenvInfo( thee, "CWD", "working directory" ) );
271 VASSERT( Vsh_putenv( thee, "TERM", term )
272 && Vsh_putenvInfo( thee, "TERM", "terminal type" ) );
273 VASSERT( Vsh_putenv( thee, "COLORTERM", cterm )
274 && Vsh_putenvInfo( thee, "COLORTERM", "color terminal type" ) );
275
276 /* init file name, shell name, prompt */
277 VASSERT( Vsh_putenv( thee, "ENV", configFile )
278 && Vsh_putenvInfo( thee, "ENV", "environ file" ) );
279 VASSERT( Vsh_putenv( thee, "SHELL", thee->PR )
280 && Vsh_putenvInfo( thee, "SHELL", "command shell" ) );
281 VASSERT( Vsh_putenv( thee, "PROMPT", thee->PR_PATH )
282 && Vsh_putenvInfo( thee, "PROMPT", "command shell prompt" ) );
283
284 /* publish remaining variables */
285 for (i=0; i<numVars; i++) {
286 VASSERT( Vsh_putenv( thee, envVars[i].envi, envVars[i].valu )
287 && Vsh_putenvInfo( thee, envVars[i].envi, envVars[i].info ) );
288 }
289
290 /* publish argc/argv variables */
291 VASSERT( Vsh_putenvInt(thee,"ARGC",argc)
292 && Vsh_putenvInfo(thee,"ARGC","Number of command line parameters") );
293 for (i=0; i<argc; i++) {
294 sprintf(buf1,"ARG%d",i);
295 sprintf(buf2,"Command line parameter <%d>",i);
296 VASSERT( Vsh_putenv( thee, buf1, argv[i] )
297 && Vsh_putenvInfo( thee, buf1, buf2 ) );
298 }
299 }
300
301 /*
302 * ***************************************************************************
303 * Routine: Vsh_trace
304 *
305 * Purpose: Trace of token stream.
306 *
307 * Author: Michael Holst
308 * ***************************************************************************
309 */
Vsh_trace(char * from,char * arg)310 VPUBLIC void Vsh_trace(char *from, char *arg) {
311 #if defined(VSH_TRACE)
312 # if defined(VSH_LEX_YACC)
313 fprintf(stderr, "%s token=<%s>, yytext=<%s>\n", from, arg, yytext);
314 # else
315 fprintf(stderr, "%s token=<%s>\n", from, arg);
316 # endif
317 #endif
318 }
319
320 /*
321 * ***************************************************************************
322 * Routine: Vsh_isInteractive
323 *
324 * Purpose: Is this an interactive shell.
325 *
326 * Author: Michael Holst
327 * ***************************************************************************
328 */
Vsh_isInteractive(Vsh * thee)329 VPUBLIC int Vsh_isInteractive(Vsh *thee) {
330 return ((thee->cinUnit == stdin) && isatty(fileno(stdin)));
331 }
332
333 /*
334 * ***************************************************************************
335 * Routine: Vsh_findVar
336 *
337 * Purpose: Find a variable in the environment.
338 *
339 * Notes: The parameters are:
340 *
341 * env --> the environment variable array
342 * envLen --> the environment variable array length
343 * var --> the variable we are looking for
344 * term --> the character terminator (usually "=" or ":")
345 *
346 * Author: Michael Holst
347 * ***************************************************************************
348 */
Vsh_findVar(char ** env,int envLen,const char * var,const char term)349 VPUBLIC int Vsh_findVar(char **env, int envLen,
350 const char *var, const char term)
351 {
352 int i, j, len, ifnd, foundEq;
353 char varBuf[VMAX_BUFSIZE];
354
355 /* look for variable in the environment */
356 ifnd = -1;
357 i = 0;
358 while ((ifnd < 0) && (i<envLen)) {
359
360 /* grab the complete string */
361 strcpy(varBuf,env[i]);
362
363 /* strip out the variable and the value */
364 len = strlen(varBuf);
365 foundEq = 0;
366 for (j=0; j<len; j++) {
367 if (!foundEq) {
368 if (varBuf[j] == term) {
369 varBuf[j] = '\0';
370 foundEq = 1;
371 }
372 } else {
373 varBuf[j] = '\0';
374 }
375 }
376
377 /* now check for match */
378 if (!strcmp(varBuf,var)) {
379 ifnd = i;
380 }
381
382 /* next iteration */
383 i++;
384 }
385
386 return ifnd;
387 }
388
389 /*
390 * ***************************************************************************
391 * Routine: Vsh_putenv
392 *
393 * Purpose: Place a variable with a value in the environment.
394 *
395 * Author: Michael Holst
396 * ***************************************************************************
397 */
Vsh_putenv(Vsh * thee,const char * envi,const char * valu)398 VPUBLIC int Vsh_putenv(Vsh *thee, const char *envi, const char *valu)
399 {
400 int i, len, ifnd;
401 char *newValu, **newValuList, valuLoc[VMAX_BUFSIZE];
402
403 VASSERT( envi != VNULL );
404 if (valu == VNULL ) {
405 valuLoc[0] = '\0';
406 } else {
407 strcpy(valuLoc,valu);
408 }
409
410 /* make the variable=value string */
411 len = strlen(envi) + 1 + strlen(valuLoc) + 1;
412 newValu = Vmem_malloc(thee->vmem,len,sizeof(char));
413 sprintf(newValu,"%s=%s",envi,valuLoc);
414
415 /* look for variable in the environment */
416 ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
417
418 /* if variable exists, just change it */
419 if (ifnd >= 0) {
420
421 if (valuLoc[0] != '\0') {
422
423 /* free old VALU */
424 len = strlen(thee->envValu[ifnd]) + 1;
425 Vmem_free(thee->vmem,len,sizeof(char),
426 (void**)&(thee->envValu[ifnd]) );
427
428 /* point to new VALU */
429 thee->envValu[ifnd] = newValu;
430 }
431
432 /* variable doesn't exist; must create it */
433 } else {
434
435 /* expand the environment */
436 thee->envValuLen++;
437
438 /* make a new VALU list with one more slot */
439 len = thee->envValuLen + 1;
440 newValuList = Vmem_malloc(thee->vmem,len,sizeof(char*));
441
442 /* copy the old VALU list into the new VALU list */
443 for (i=0; i<thee->envValuLen-1; i++) {
444 newValuList[i] = thee->envValu[i];
445 }
446 newValuList[thee->envValuLen-1] = newValu;
447 newValuList[thee->envValuLen] = VNULL;
448
449 /* free old VALU list */
450 len = thee->envValuLen;
451 Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envValu) );
452
453 /* setup the new VALU list */
454 thee->envValu = newValuList;
455 }
456
457 return 1;
458 }
459
460 /*
461 * ***************************************************************************
462 * Routine: Vsh_putenvInfo
463 *
464 * Purpose: Place a variable with an info string in the environment.
465 *
466 * Author: Michael Holst
467 * ***************************************************************************
468 */
Vsh_putenvInfo(Vsh * thee,const char * envi,const char * info)469 VPUBLIC int Vsh_putenvInfo(Vsh *thee, const char *envi, const char *info)
470 {
471 int i, len, ifnd;
472 char *newInfo, **newInfoList, infoLoc[VMAX_BUFSIZE];
473
474 VASSERT( envi != VNULL );
475 if (info == VNULL ) {
476 infoLoc[0] = '\0';
477 } else {
478 strcpy(infoLoc,info);
479 }
480
481 /* make the variable=info string */
482 len = strlen(envi) + 2 + strlen(infoLoc) + 1;
483 newInfo = Vmem_malloc(thee->vmem,len,sizeof(char));
484 sprintf(newInfo,"%s: %s",envi,infoLoc);
485
486 /* look for variable in the environment */
487 ifnd = Vsh_findVar(thee->envInfo,thee->envInfoLen,envi,':');
488
489 /* if variable exists, just change it */
490 if (ifnd >= 0) {
491
492 if (infoLoc[0] != '\0') {
493
494 /* free old INFO */
495 len = strlen(thee->envInfo[ifnd]) + 1;
496 Vmem_free(thee->vmem,len,sizeof(char),
497 (void**)&(thee->envInfo[ifnd]) );
498
499 /* point to new INFO */
500 thee->envInfo[ifnd] = newInfo;
501 }
502
503 /* variable doesn't exist; must create it */
504 } else {
505
506 /* expand the environment */
507 thee->envInfoLen++;
508
509 /* make a new INFO list with one more slot */
510 len = thee->envInfoLen + 1;
511 newInfoList = Vmem_malloc(thee->vmem,len,sizeof(char*));
512
513 /* copy the old INFO list into the new INFO list */
514 for (i=0; i<thee->envInfoLen-1; i++) {
515 newInfoList[i] = thee->envInfo[i];
516 }
517 newInfoList[thee->envInfoLen-1] = newInfo;
518 newInfoList[thee->envInfoLen] = VNULL;
519
520 /* free old INFO list */
521 len = thee->envInfoLen;
522 Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envInfo) );
523
524 /* setup the new INFO list */
525 thee->envInfo = newInfoList;
526 }
527
528 return 1;
529 }
530
531 /*
532 * ***************************************************************************
533 * Routine: Vsh_putenvInt
534 *
535 * Purpose: Place a variable with a value (integer) in the environment.
536 *
537 * Author: Michael Holst
538 * ***************************************************************************
539 */
Vsh_putenvInt(Vsh * thee,const char * envi,const int valu)540 VPUBLIC int Vsh_putenvInt(Vsh *thee, const char *envi, const int valu)
541 {
542 char buf[VMAX_BUFSIZE];
543
544 sprintf(buf,"%d",valu);
545 Vsh_putenv(thee,envi,buf);
546
547 return 1;
548 }
549
550 /*
551 * ***************************************************************************
552 * Routine: Vsh_putenvReal
553 *
554 * Purpose: Place a variable with a value (real) in the environment.
555 *
556 * Author: Michael Holst
557 * ***************************************************************************
558 */
Vsh_putenvReal(Vsh * thee,const char * envi,const double valu)559 VPUBLIC int Vsh_putenvReal(Vsh *thee, const char *envi, const double valu)
560 {
561 char buf[VMAX_BUFSIZE];
562
563 sprintf(buf,"%e",valu);
564 Vsh_putenv(thee,envi,buf);
565
566 return 1;
567 }
568
569
570 /*
571 * ***************************************************************************
572 * Routine: Vsh_getenv
573 *
574 * Purpose: Get a value of variable in the environment.
575 *
576 * Author: Michael Holst
577 * ***************************************************************************
578 */
Vsh_getenv(Vsh * thee,const char * envi)579 VPUBLIC char* Vsh_getenv(Vsh *thee, const char *envi)
580 {
581 int ifnd;
582
583 ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
584 if (ifnd >= 0) {
585 return (thee->envValu[ifnd]+strlen(envi)+1);
586 } else {
587 return VNULL;
588 }
589 }
590
591 /*
592 * ***************************************************************************
593 * Routine: Vsh_getenvInfo
594 *
595 * Purpose: Get info associated with a variable in the environment.
596 *
597 * Author: Michael Holst
598 * ***************************************************************************
599 */
Vsh_getenvInfo(Vsh * thee,const char * envi)600 VPUBLIC char* Vsh_getenvInfo(Vsh *thee, const char *envi)
601 {
602 int ifnd;
603
604 ifnd = Vsh_findVar(thee->envInfo,thee->envInfoLen,envi,':');
605 if (ifnd >= 0) {
606 return (thee->envInfo[ifnd]+strlen(envi)+2);
607 } else {
608 return VNULL;
609 }
610 }
611
612 /*
613 * ***************************************************************************
614 * Routine: Vsh_getenvInt
615 *
616 * Purpose: Get a value of variable in the environment as an integer.
617 *
618 * Author: Michael Holst
619 * ***************************************************************************
620 */
Vsh_getenvInt(Vsh * thee,const char * envi)621 VPUBLIC int Vsh_getenvInt(Vsh *thee, const char *envi)
622 {
623 int ifnd;
624
625 ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
626 if (ifnd >= 0) {
627 return atoi(thee->envValu[ifnd]+strlen(envi)+1);
628 } else {
629 return 0;
630 }
631 }
632
633 /*
634 * ***************************************************************************
635 * Routine: Vsh_getenvReal
636 *
637 * Purpose: Get a value of variable in the environment as a real.
638 *
639 * Author: Michael Holst
640 * ***************************************************************************
641 */
Vsh_getenvReal(Vsh * thee,const char * envi)642 VPUBLIC double Vsh_getenvReal(Vsh *thee, const char *envi)
643 {
644 int ifnd;
645
646 ifnd = Vsh_findVar(thee->envValu,thee->envValuLen,envi,'=');
647 if (ifnd >= 0) {
648 return atof(thee->envValu[ifnd]+strlen(envi)+1);
649 } else {
650 return 0.0;
651 }
652 }
653
654 /*
655 * ***************************************************************************
656 * Routine: Vsh_remove
657 *
658 * Purpose: Remove a variable from the environment.
659 *
660 * Author: Michael Holst
661 * ***************************************************************************
662 */
Vsh_remove(Vsh * thee,const char * envi)663 VPUBLIC void Vsh_remove(Vsh *thee, const char *envi)
664 {
665 /* unsetenv(envi); */
666 }
667
668 /*
669 * ***************************************************************************
670 * Routine: Vsh_wipe
671 *
672 * Purpose: Wipe the environment.
673 *
674 * Author: Michael Holst
675 * ***************************************************************************
676 */
Vsh_wipe(Vsh * thee)677 VPUBLIC void Vsh_wipe(Vsh *thee)
678 {
679 int i, len;
680
681 VASSERT( thee->envValu != VNULL );
682
683 /* wipe the entire environment */
684 for (i=0; i<thee->envValuLen; i++) {
685 len = strlen(thee->envValu[i]) + 1;
686 Vmem_free(thee->vmem,len,sizeof(char), (void**)&(thee->envValu[i]) );
687 }
688 len = thee->envValuLen + 1;
689 Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envValu) );
690 for (i=0; i<thee->envInfoLen; i++) {
691 len = strlen(thee->envInfo[i]) + 1;
692 Vmem_free(thee->vmem,len,sizeof(char), (void**)&(thee->envInfo[i]) );
693 }
694 len = thee->envInfoLen + 1;
695 Vmem_free(thee->vmem,len,sizeof(char*), (void**)&(thee->envInfo) );
696 }
697
698 /*
699 * ***************************************************************************
700 * Routine: Vsh_printenv
701 *
702 * Purpose: Print the environment.
703 *
704 * Author: Michael Holst
705 * ***************************************************************************
706 */
Vsh_printenv(Vsh * thee)707 VPUBLIC void Vsh_printenv(Vsh *thee)
708 {
709 int i;
710
711 for (i=0; i<thee->envValuLen; i++) {
712 Vnm_print(1,"%s\n",thee->envValu[i]);
713 }
714 }
715
716 /*
717 * ***************************************************************************
718 * Routine: Vsh_printenvInfo
719 *
720 * Purpose: Print the environment info.
721 *
722 * Author: Michael Holst
723 * ***************************************************************************
724 */
Vsh_printenvInfo(Vsh * thee)725 VPUBLIC void Vsh_printenvInfo(Vsh *thee)
726 {
727 int i;
728
729 for (i=0; i<thee->envInfoLen; i++) {
730 Vnm_print(1,"%s\n",thee->envInfo[i]);
731 }
732 }
733
734 /*
735 * ***************************************************************************
736 * Routine: Vsh_completion
737 *
738 * Purpose: Command completion action.
739 *
740 * Notes: The return type and argument list is mandated by readline:
741 *
742 * int func(int count, int key)
743 *
744 * Useful tips: the readline library uses the following conventions
745 * for simplifying the notation for function pointers:
746 *
747 * typedef int IFunction ();
748 * typedef void VFunction ();
749 * typedef char *CPFunction ();
750 * typedef char **CPPFunction ();
751 *
752 * This allows one to replace something like:
753 *
754 * int (*)()func;
755 *
756 * with simply:
757 *
758 * IFunction *func;
759 *
760 * Author: Michael Holst
761 * ***************************************************************************
762 */
763 #if defined(HAVE_READLINE_READLINE_H)
Vsh_completion(int count,int key)764 VPRIVATE int Vsh_completion(int count, int key)
765 {
766 int cargc = 1;
767 char *cargv[2] = { "help", VNULL };
768
769 Vnm_print(1,"\n");
770 Vsh_builtIn(Vsh_thee, cargc, cargv);
771 Vnm_print(1,"%s",Vsh_thee->PR_PATH);
772
773 Vsh_readlineReset();
774
775 return 0;
776 }
777 #endif
778
779 /*
780 * ***************************************************************************
781 * Routine: Vsh_readlineInit
782 *
783 * Purpose: Initialize the readline library.
784 *
785 * Author: Michael Holst
786 * ***************************************************************************
787 */
Vsh_readlineInit(void)788 VPRIVATE void Vsh_readlineInit(void)
789 {
790 static int init=0;
791
792 if (!init) {
793 init = 1;
794
795 #if defined(HAVE_READLINE_READLINE_H)
796 #if 0
797 rl_catch_signals = 0;
798 rl_catch_sigwinch = 0;
799 #endif
800 rl_bind_key(9, &Vsh_completion);
801 #endif
802 }
803 }
804
805 /*
806 * ***************************************************************************
807 * Routine: Vsh_readlineReset
808 *
809 * Purpose: Reset the readline library (e.g. free partial input string).
810 *
811 * Author: Michael Holst
812 * ***************************************************************************
813 */
Vsh_readlineReset(void)814 VPRIVATE void Vsh_readlineReset(void)
815 {
816 Vsh_readlineInit();
817
818 #if defined(HAVE_READLINE_READLINE_H)
819 #if 0
820 rl_free_line_state();
821 rl_resize_terminal();
822 #endif
823 #endif
824 }
825
826 /*
827 * ***************************************************************************
828 * Routine: Vsh_addhist
829 *
830 * Purpose: Put an input line into the history list.
831 *
832 * Author: Michael Holst
833 * ***************************************************************************
834 */
Vsh_addhist(char * buf,int buflen)835 VPUBLIC void Vsh_addhist(char *buf, int buflen)
836 {
837 Vsh_readlineInit();
838
839 #if defined(HAVE_READLINE_HISTORY_H)
840 add_history(buf);
841 #endif
842 }
843
844 /*
845 * ***************************************************************************
846 * Routine: Vsh_readline
847 *
848 * Purpose: Get an input line.
849 *
850 * Author: Michael Holst
851 * ***************************************************************************
852 */
Vsh_readline(char * prompt,char * buf,int buflen,FILE * stream)853 VPUBLIC char *Vsh_readline(char *prompt, char *buf, int buflen, FILE *stream)
854 {
855 char *key;
856
857 if (stream != stdin) {
858 key = fgets(buf, buflen, stream);
859 } else {
860
861 #if defined(HAVE_READLINE_READLINE_H)
862 Vsh_readlineInit();
863 key = readline(prompt);
864 if (key == VNULL) {
865 buf[0] = '\n';
866 buf[1] = '\0';
867 } else if (key[0] == '\0') {
868 buf[0] = '\n';
869 buf[1] = '\0';
870 free(key);
871 } else {
872 strncpy(buf,key,buflen);
873 free(key);
874 }
875 #else
876 Vnm_print(1,"%s",prompt);
877 key = fgets(buf, buflen, stream);
878 #endif
879
880 }
881
882 return key;
883 }
884
885 /*
886 * ***************************************************************************
887 * Routine: Vsh_shell
888 *
889 * Purpose: A bash-like shell with user-definable extensions.
890 *
891 * Author: Michael Holst
892 * ***************************************************************************
893 */
Vsh_shell(Vsh * thee,char * pPR,void * pthee,int (* builtin)(void * thee,int argc,char ** argv))894 VPUBLIC int Vsh_shell(Vsh *thee, char *pPR, void *pthee,
895 int (*builtin)(void *thee, int argc, char **argv))
896 {
897 int i, argc, offset;
898 char **argvPtr, buf[VMAX_ARGLEN];
899 char *argvNULL = "\0";
900 struct stat fInfo;
901
902 /* we will need argc and argv[] */
903 argc = Vsh_getenvInt(thee, "ARGC");
904 argvPtr = Vmem_malloc(thee->vmem, VMAX_ARGLEN, sizeof(char*));
905 for (i=0; i<argc; i++) {
906 sprintf(buf,"ARG%d",i);
907 argvPtr[i] = Vsh_getenv(thee, buf);
908 }
909 argvPtr[argc] = argvNULL;
910
911 /* paranoia: check type sizes on the machine */
912 Vnm_typeChk();
913
914 /* the externally supplied builtin object pointer and function */
915 thee->Ext_thee = pthee;
916 thee->Ext_builtin = builtin;
917
918 /* construct a reasonable shell command prompt if not given as argument */
919 if (pPR != VNULL) {
920 if (pPR[0] != '\0') {
921 sprintf(thee->PR,"%s",pPR);
922 }
923 }
924 if (thee->PR[0] == '\0') {
925 VASSERT( argc > 0 );
926 strncpy(buf,argvPtr[0],VMAX_ARGLEN);
927 offset = 0;
928 if (strlen(buf) >= 2) {
929 /* remove the "./" if it is there */
930 if ((buf[0] == '.') && (buf[1] == '/')) {
931 offset = 2;
932 /* remove "-" if there; happens when vsh is a login shell */
933 } else if (buf[0] == '-') {
934 offset = 1;
935 }
936 }
937 sprintf(thee->PR,"%s",buf+offset);
938 }
939 Vsh_putenv(thee,"SHELL",thee->PR);
940
941 /*
942 * if filename given on command line, try to take input from there.
943 */
944 thee->inUnit = stdin;
945 if (thee->processArgs) {
946 for (i=1; i<argc; i++) {
947
948 /* is the argument the "-h" option */
949 if (!strcmp(argvPtr[i],"-h")) {
950 VJMPERR1(1);
951
952 /* is the argument the "-io" option */
953 } else if (!strcmp(argvPtr[i],"-io")) {
954 Vnm_redirect(0);
955
956 /* is the argument the "-noio" option */
957 } else if (!strcmp(argvPtr[i],"-noio")) {
958 Vnm_redirect(1);
959
960 /* try to open the argument as a script file */
961 } else {
962 thee->clUnit = fopen(argvPtr[i], "r");
963 if (thee->clUnit == VNULL) {
964 Vnm_print(2,"%s: Problem opening file <%s>\n",
965 thee->PR, argvPtr[i]);
966 thee->inUnit = stdin;
967 VJMPERR1(1);
968 } else thee->inUnit = thee->clUnit;
969 }
970 }
971 }
972
973 /* the current input unit starts out as stdin or a script */
974 thee->cinUnit = thee->inUnit;
975
976 /* we first execute the user's configuration file */
977 if ( !stat(Vsh_getenv(thee,"ENV"), &fInfo) ) {
978 if (VS_ISREG(fInfo.st_mode)) {
979 thee->scUnit = fopen(Vsh_getenv(thee,"ENV"), "r");
980 if (thee->scUnit != VNULL) {
981 thee->cinUnit = thee->scUnit;
982 strncpy(thee->cinName,Vsh_getenv(thee,"ENV"),VMAX_ARGLEN);
983 Vnm_print(0,"Starting <%s> script named <%s>\n",
984 thee->PR,thee->cinName);
985 }
986 }
987 }
988
989 /* start the command shell parsing loop */
990 cmdKey = 0;
991 while (cmdKey != 2) {
992
993 /*
994 * Parse a single input unit.
995 * An input unit is a complete shell statement
996 * (e.g. one-line command, if-then-else, while, case, etc)
997 * which may span multiple lines of input.
998 */
999 #if defined(VSH_LEX_YACC)
1000 yyparse(); /* for complex Bourne-shell compatible input units */
1001 Vsh_yyexecute(global_command);
1002 #else
1003 Vsh_parse(); /* for simple one-line commands only */
1004 Vsh_execute();
1005 #endif
1006
1007 }
1008
1009 /* close the input unit for a command-line file if we had one */
1010 if (thee->clUnit != VNULL) VASSERT( !fclose(thee->clUnit) );
1011
1012 /* free the argv storage */
1013 Vmem_free( thee->vmem, VMAX_ARGLEN, sizeof(char*), (void**)&argvPtr );
1014
1015 /* no error */
1016 return 1;
1017
1018 VERROR1:
1019 /* close the input unit for a command-line file if we had one */
1020 if (thee->clUnit != VNULL) VASSERT( !fclose(thee->clUnit) );
1021
1022 /* free the argv storage */
1023 Vmem_free( thee->vmem, VMAX_ARGLEN, sizeof(char*), (void**)argvPtr );
1024
1025 /* print a usage menu */
1026 Vnm_print(2,"usage: ./%s [ -h | -io | -noio ]"
1027 " [ shellScriptFile ]\n",thee->PR);
1028
1029 /* error, but not fatal */
1030 return 1;
1031 }
1032
1033 /*
1034 * ***************************************************************************
1035 * Routine: Vsh_input
1036 *
1037 * Purpose: Read a single newline-terminated line of input.
1038 *
1039 * Notes: We output a prompt if appropriate to do so.
1040 * We catch any SIGINTs generated during input just like
1041 * any normal command shell. If one is caught, we jump
1042 * back to the input prompt via setjmp/longjmp.
1043 * We also handle killing of scripts via SIGINT, and
1044 * correctly handle prompt output on redirection.
1045 *
1046 * This routine is used with the following macro:
1047 *
1048 * define VSH_INPUT(buf,result,max_size) { \
1049 * result = Vsh_input(buf,max_size); \
1050 * }
1051 *
1052 * which has exactly the same functionality as the YY_INPUT
1053 * macro used by LEX. Forcing LEX to use VSH_INPUT in place
1054 * of YY_INPUT allows all of the above to work for a
1055 * LEX/YACC-generated command shell parser.
1056 *
1057 * Input: buf[0..buflen-1] = character buffer to read in to
1058 * buflen = length of buf
1059 *
1060 * Output: returned = number of characters actually read in.
1061 *
1062 * Author: Michael Holst
1063 * ***************************************************************************
1064 */
Vsh_input(char * buf,int buflen)1065 VPUBLIC int Vsh_input(char *buf, int buflen)
1066 {
1067 int numRead;
1068 char *key, currDirectory[VMAX_ARGLEN];
1069 jmp_buf *jbuf;
1070
1071 /* setup for the jump */
1072 jbuf = Vnm_signalInit();
1073 if (setjmp(*jbuf)) {
1074
1075 /* FIRST: kill any script that may have been executing */
1076 Vsh_thee->cinUnit = Vsh_thee->inUnit;
1077
1078 /* SECOND: reset the readline input buffer */
1079 Vsh_readlineReset();
1080
1081 /* THIRD: restart lex on the (possibly) new input unit */
1082 #if defined(VSH_LEX_YACC)
1083 yyrestart(Vsh_thee->cinUnit);
1084 #endif
1085
1086 /* FOURTH: print a newline if we are in interactive mode */
1087 if (Vsh_isInteractive(Vsh_thee)) {
1088 Vnm_print(1,"%s",VNEWLINE_STRING);
1089 }
1090 }
1091
1092 /* close script unit if open -- must have killed it */
1093 if ( ((Vsh_thee->cinUnit != Vsh_thee->scUnit)
1094 || feof(Vsh_thee->scUnit)) && (Vsh_thee->scUnit != VNULL) ) {
1095 VASSERT( !fclose(Vsh_thee->scUnit) );
1096 Vsh_thee->scUnit = VNULL;
1097 Vnm_print(0,"Stopping <%s> script named <%s>\n",
1098 Vsh_thee->PR,Vsh_thee->cinName);
1099 strncpy(Vsh_thee->cinName," ",VMAX_ARGLEN);
1100 }
1101
1102 /* OKAY-TO-JUMP back to the input prompt now */
1103 Vnm_jmpOkSet();
1104
1105 /* deal with different I/O units */
1106 if (Vsh_isInteractive(Vsh_thee)) {
1107 VASSERT( Vnm_getcwd(currDirectory,sizeof(currDirectory)) );
1108 sprintf(Vsh_thee->PR_PATH,"%s@%s<%s+%s>%% ",
1109 Vsh_getenv(Vsh_thee,"USER"),
1110 Vsh_getenv(Vsh_thee,"HOSTNAME"),
1111 Vsh_getenv(Vsh_thee,"OSTYPE"),
1112 Vsh_thee->PR);
1113 Vsh_putenv(Vsh_thee,"PROMPT",Vsh_thee->PR_PATH);
1114 }
1115
1116 /* get the input line */
1117 memset(buf, VNULL_SYMBOL, buflen);
1118 key = Vsh_readline(Vsh_thee->PR_PATH, buf, buflen, Vsh_thee->cinUnit);
1119 if ((key == VNULL) && (Vsh_thee->cinUnit==Vsh_thee->scUnit)) {
1120
1121 /* shut down the script handling */
1122 VASSERT( Vsh_thee->scUnit != VNULL );
1123 VASSERT( feof(Vsh_thee->scUnit) );
1124 VASSERT( !fclose(Vsh_thee->scUnit) );
1125 Vsh_thee->scUnit = VNULL;
1126 Vnm_print(0,"Stopping <%s> script named <%s>\n",
1127 Vsh_thee->PR,Vsh_thee->cinName);
1128 strncpy(Vsh_thee->cinName," ",VMAX_ARGLEN);
1129
1130 /* deal with different I/O units */
1131 Vsh_thee->cinUnit = Vsh_thee->inUnit;
1132 if (Vsh_isInteractive(Vsh_thee)) {
1133 VASSERT( Vnm_getcwd(currDirectory,sizeof(currDirectory)) );
1134 sprintf(Vsh_thee->PR_PATH,"%s@%s<%s+%s>%% ",
1135 Vsh_getenv(Vsh_thee,"USER"),
1136 Vsh_getenv(Vsh_thee,"HOSTNAME"),
1137 Vsh_getenv(Vsh_thee,"OSTYPE"),
1138 Vsh_thee->PR);
1139 Vsh_putenv(Vsh_thee,"PROMPT",Vsh_thee->PR_PATH);
1140 }
1141
1142 /* get the input line */
1143 memset(buf, VNULL_SYMBOL, buflen);
1144 key = Vsh_readline(Vsh_thee->PR_PATH,
1145 buf, buflen, Vsh_thee->cinUnit);
1146 }
1147
1148 /* calculate the number of characters actually read */
1149 if (key == VNULL) {
1150 numRead = 0;
1151 } else {
1152 numRead = strlen(buf);
1153 }
1154 VASSERT( numRead <= buflen );
1155
1156 /* NOT-OKAY-TO-JUMP back to the input prompt now */
1157 Vnm_jmpOkClear();
1158
1159 /* clear the numerical loop signal before executing the command */
1160 Vnm_sigIntClear();
1161
1162 /* return num chars read */
1163 return numRead;
1164 }
1165
1166 /*
1167 * ***************************************************************************
1168 * Routine: Vsh_getCmd
1169 *
1170 * Purpose: Decode the input string into a legal command.
1171 *
1172 * Author: Michael Holst
1173 * ***************************************************************************
1174 */
Vsh_getCmd(int argc,char ** argv)1175 VPRIVATE VSH_command Vsh_getCmd(int argc, char **argv)
1176 {
1177 VSH_command theCmd = vshcom_none;
1178 if (!strcmp(argv[0],"")) {
1179 theCmd = vshcom_none;
1180 } else if ( (!strcmp(argv[0],"c")) || (!strcmp(argv[0],"clear")) ) {
1181 theCmd = vshcom_clear;
1182 } else if (!strcmp(argv[0],"help")) {
1183 theCmd = vshcom_help;
1184 } else if (!strcmp(argv[0],"pause")) {
1185 theCmd = vshcom_pause;
1186 } else if (!strcmp(argv[0],"delay")) {
1187 theCmd = vshcom_delay;
1188 } else if (!strcmp(argv[0],"set")) {
1189 theCmd = vshcom_set;
1190 } else if (!strcmp(argv[0],"penv")) {
1191 theCmd = vshcom_penv;
1192 } else if (!strcmp(argv[0],"pinfo")) {
1193 theCmd = vshcom_pinfo;
1194 } else if (!strcmp(argv[0],"cd")) {
1195 theCmd = vshcom_cd;
1196 } else if (!strcmp(argv[0],"cdw")) {
1197 theCmd = vshcom_cdw;
1198 } else if (!strcmp(argv[0],"io")) {
1199 theCmd = vshcom_io;
1200 } else if (!strcmp(argv[0],"noio")) {
1201 theCmd = vshcom_noio;
1202 } else if (!strcmp(argv[0],"exit")) {
1203 theCmd = vshcom_exit;
1204 } else if (!strcmp(argv[0],".")) {
1205 theCmd = vshcom_dot;
1206 } else if (!strcmp(argv[0],"sockg")) {
1207 theCmd = vshcom_sockg;
1208 } else if (!strcmp(argv[0],"sockm")) {
1209 theCmd = vshcom_sockm;
1210 } else if (!strcmp(argv[0],"sockk")) {
1211 theCmd = vshcom_sockk;
1212 } else {
1213 theCmd = vshcom_none;
1214 }
1215 return theCmd;
1216 }
1217
1218 /*
1219 * ***************************************************************************
1220 * Routine: Vsh_execCmd
1221 *
1222 * Purpose: Fork a child to exec a command, wait for child to finish.
1223 *
1224 * Author: Michael Holst
1225 * ***************************************************************************
1226 */
Vsh_execCmd(const char * PR,int argc,char ** argv,char * inbuf)1227 VPUBLIC void Vsh_execCmd(const char *PR, int argc, char **argv, char *inbuf)
1228 {
1229 /* fork a child to do the work (real shell behavior) */
1230 #if !defined(HAVE_WINSOCK_H)
1231
1232 static pid_t child_pid;
1233 char PR_TMP[VMAX_ARGLEN];
1234
1235 VASSERT( argc > 0 );
1236 sprintf(PR_TMP,"%s: %s",PR,argv[0]);
1237
1238 if ((child_pid=fork()) == 0) {
1239 /* NOTE: child should NOT return except on error */
1240 Vpup_execCmd(PR_TMP,argc,argv,inbuf);
1241 perror(PR_TMP);
1242 exit(1);
1243 } else if (child_pid > 0) {
1244 wait(VNULL);
1245 } else {
1246 perror(PR_TMP);
1247 }
1248
1249 /* fork() does not exist on Win32 */
1250 /* (also fork() is BROKEN in Linux 2.1.85 believe it or not...) */
1251 /* SO, we fake it by passing command to underlying shell -- bummer! */
1252 #else
1253
1254 Vnm_system(inbuf);
1255
1256 #endif
1257 }
1258
1259 /*
1260 * ***************************************************************************
1261 * Routine: Vsh_memChk
1262 *
1263 * Purpose: Print the exact current malloc usage.
1264 *
1265 * Author: Michael Holst
1266 * ***************************************************************************
1267 */
Vsh_memChk(Vsh * thee)1268 VPUBLIC void Vsh_memChk(Vsh *thee)
1269 {
1270 if (thee->iMadeVmem) Vmem_print(thee->vmem);
1271 }
1272
1273 /*
1274 * ***************************************************************************
1275 * Routine: Vsh_killSockets
1276 *
1277 * Purpose: Kill any socket graphics.
1278 *
1279 * Author: Michael Holst
1280 * ***************************************************************************
1281 */
Vsh_killSockets(Vsh * thee)1282 VPRIVATE void Vsh_killSockets(Vsh *thee)
1283 {
1284 Vnm_systemKill("gvx");
1285 Vnm_systemKill("mcsg");
1286 Vnm_systemKill("mcbridge");
1287 Vnm_system("sleep 1");
1288 }
1289
1290 /*
1291 * ***************************************************************************
1292 * Routine: Vsh_builtIn
1293 *
1294 * Purpose: Vsh_shell built-in commands.
1295 *
1296 * Author: Michael Holst
1297 * ***************************************************************************
1298 */
Vsh_builtIn(Vsh * thee,int argc,char ** argv)1299 VPUBLIC int Vsh_builtIn(Vsh *thee, int argc, char **argv)
1300 {
1301 int i, rc;
1302 VSH_command theCmd;
1303 struct stat fInfo;
1304 jmp_buf *jbuf;
1305
1306 char sysc[VMAX_BUFSIZE];
1307 char sofmt[VMAX_ARGLEN], sokey[VMAX_ARGLEN];
1308
1309 static int init=0;
1310 static char buf[VMAX_BUFSIZE], workDirectory[VMAX_ARGLEN];
1311 static char PR_TMP[VMAX_ARGLEN];
1312 static char env[VMAX_BUFSIZE], com[VMAX_BUFSIZE];
1313 static char sock[VMAX_BUFSIZE];
1314 const char *stmp;
1315
1316 /* one-time intialization */
1317 if (!init) {
1318 init=1;
1319
1320 /* make the env message (%s slots = 12) */
1321 stmp =
1322 "%s: Execution environment, directories, and files:\n"
1323 " Shell --> <%s>\n"
1324 " User name --> <%s>\n"
1325 " Host name --> <%s>\n"
1326 " Operating system --> <%s>\n"
1327 " Home directory --> <%s>\n"
1328 " Work directory --> <%s>\n"
1329 " Startup script --> <%s/%s>\n"
1330 " Command history file --> <%s/%s>\n"
1331 " I/O capture file --> <%s/%s>\n";
1332 sprintf(env,stmp,thee->PR,
1333 thee->PR,
1334 Vsh_getenv(thee,"USER"),
1335 Vsh_getenv(thee,"HOSTNAME"),
1336 Vsh_getenv(thee,"OSTYPE"),
1337 Vsh_getenv(thee,"HOME"),
1338 Vsh_getenv(thee,"CWD"),
1339 Vsh_getenv(thee,"HOME"),"rc.mcsh",
1340 Vsh_getenv(thee,"HOME"),"hist.mcsh",
1341 Vsh_getenv(thee,"HOME"),"io.mc");
1342
1343 /* make the com message (%s slots = 2) */
1344 stmp =
1345 "%s: Shell interaction commands: \n"
1346 " help [ env|com|sock ] --> print help messages\n"
1347 " c | clear --> clear the screen\n"
1348 " pause --> pause until carriage return\n"
1349 " delay --> delay for three seconds\n"
1350 " cd | cdw --> cd to home or work directory\n";
1351 sprintf(com,stmp,thee->PR);
1352 stmp =
1353 " io | noio --> display extra io or not\n"
1354 " set [var [val]] --> set or print variables\n"
1355 " penv [var] --> print variable\n"
1356 " pinfo [var] --> print variable information\n"
1357 " . scriptfile --> execute an vsh scriptfile\n"
1358 " exit | CTRL-D --> exit the <%s> shell\n";
1359 sprintf(buf,stmp,thee->PR);
1360 strcat(com,buf);
1361
1362 /* make the socket message (%s slots = 1) */
1363 stmp = "%s: Socket Graphics manipulation commands: \n"
1364 " sockk --> kill all socket graphics processes\n"
1365 " sockg --> start geomview socket displays\n"
1366 " sockm --> start mcsg socket displays\n";
1367 sprintf(sock,stmp,thee->PR);
1368 }
1369
1370 /* the user-defined shell gets first shot at the command */
1371 if (thee->Ext_builtin != VNULL) {
1372 rc = (*(thee->Ext_builtin))(thee->Ext_thee,argc,argv);
1373 if (rc != 0) return rc;
1374 }
1375
1376 /* now it is our turn; set default return code (success) */
1377 rc = 1;
1378
1379 /* get the command */
1380 theCmd = Vsh_getCmd(argc, argv);
1381
1382 /* decode and execute the command */
1383 switch (theCmd) {
1384
1385 case vshcom_pause:
1386 sprintf(PR_TMP,"%s: Press <return> to continue..", thee->PR);
1387 memset(buf, VNULL_SYMBOL, sizeof(buf));
1388
1389 /* setup for the jump */
1390 jbuf = Vnm_signalInit();
1391 if (setjmp(*jbuf)) {
1392
1393 /* FIRST: kill any script that may have been executing */
1394 thee->cinUnit = thee->inUnit;
1395
1396 /* SECOND: reset the readline input buffer */
1397 Vsh_readlineReset();
1398
1399 /* THIRD: restart lex on the (possibly) new input unit */
1400 #if defined(VSH_LEX_YACC)
1401 yyrestart(thee->cinUnit);
1402 #endif
1403
1404 /* FOURTH: print a newline if we are in interactive mode */
1405 if (Vsh_isInteractive(thee)) {
1406 Vnm_print(1,"%s",VNEWLINE_STRING);
1407 }
1408
1409 Vnm_jmpOkClear();
1410 Vnm_sigIntClear();
1411 } else {
1412 Vnm_jmpOkSet();
1413 Vsh_readline(PR_TMP, buf, sizeof(buf), stdin);
1414 Vnm_jmpOkClear();
1415 Vnm_sigIntClear();
1416 }
1417 rc = 1;
1418 break;
1419
1420 case vshcom_delay:
1421 Vnm_sleep(3000000);
1422 break;
1423
1424 case vshcom_clear:
1425 memset(buf, VNULL_SYMBOL, sizeof(buf));
1426 #if !defined(HAVE_WINSOCK_H)
1427 strcpy(buf,"clear");
1428 #else
1429 strcpy(buf,"cls");
1430 #endif
1431 Vnm_system(buf);
1432 break;
1433
1434 case vshcom_help:
1435 if (argc==1) {
1436 Vnm_print(1,"%s: Vsh-layer Help Menu:\n",thee->PR);
1437 Vnm_print(1," help env --> Help on %s environment\n",
1438 thee->PR);
1439 Vnm_print(1," help com --> Help on %s shell commands\n",
1440 thee->PR);
1441 Vnm_print(1," help sock --> Help on %s socket graphics\n",
1442 thee->PR);
1443 } else {
1444 if (!strcmp(argv[1],"env")) {
1445 Vnm_print(1, "%s", env);
1446 } else if (!strcmp(argv[1],"com")) {
1447 Vnm_print(1, "%s", com);
1448 } else if (!strcmp(argv[1],"sock")) {
1449 Vnm_print(1, "%s", sock);
1450 } else {
1451 /* we are the last shell layer; nothing to defer to */
1452 }
1453 }
1454 break;
1455
1456 case vshcom_set:
1457 if (argc <= 1) {
1458 Vsh_printenv(thee);
1459 } else if (argc == 2) {
1460 Vnm_print(2,"%s: %s=%s\n",
1461 thee->PR,argv[1],Vsh_getenv(thee,argv[1]));
1462 } else if (argc == 3) {
1463 Vsh_putenv(thee,argv[1],argv[2]);
1464 } else if (argc > 3) {
1465 Vsh_putenv(thee,argv[1],argv[2]);
1466 buf[0] = '\0';
1467 for (i=3; i<argc; i++) {
1468 if (i>3) strcat(buf," ");
1469 strcat(buf,argv[i]);
1470 }
1471 Vsh_putenvInfo(thee,argv[1],buf);
1472 } else VASSERT(0);
1473 break;
1474
1475 case vshcom_penv:
1476 if (argc <= 1) {
1477 Vsh_printenv(thee);
1478 } else if (argc == 2) {
1479 Vnm_print(2,"%s: %s=%s\n",
1480 thee->PR,argv[1],Vsh_getenv(thee,argv[1]));
1481 } else Vnm_print(2,"%s: %s: Too many arguments\n",thee->PR,argv[0]);
1482 break;
1483
1484 case vshcom_pinfo:
1485 if (argc <= 1) {
1486 Vsh_printenvInfo(thee);
1487 } else if (argc == 2) {
1488 Vnm_print(2,"%s: %s: %s\n",
1489 thee->PR,argv[1],Vsh_getenvInfo(thee,argv[1]));
1490 } else Vnm_print(2,"%s: %s: Too many arguments\n",thee->PR,argv[0]);
1491 break;
1492
1493 case vshcom_cd:
1494 if (argc==1) {
1495 if (Vnm_chdir(Vsh_getenv(thee,"HOME")) == -1) {
1496 Vnm_print(2,"%s: %s: %s: No such directory\n",
1497 thee->PR, argv[0], Vsh_getenv(thee,"HOME"));
1498 }
1499 VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
1500 Vsh_putenv(thee,"CWD", workDirectory);
1501 } else {
1502 if (Vnm_chdir(argv[1]) == -1) {
1503 Vnm_print(2,"%s: %s: %s: No such directory\n",
1504 thee->PR, argv[0], argv[1]);
1505 }
1506 VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
1507 Vsh_putenv(thee,"CWD", workDirectory);
1508 }
1509 break;
1510
1511 case vshcom_cdw:
1512 if (argc==1) {
1513 if (Vnm_chdir(Vsh_getenv(thee,"MCSH_HOME")) == -1) {
1514 Vnm_print(2,"%s: %s: %s: No such directory\n",
1515 thee->PR, argv[0], Vsh_getenv(thee,"MCSH_HOME"));
1516 }
1517 VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
1518 Vsh_putenv(thee,"CWD", workDirectory);
1519 } else {
1520 if (Vnm_chdir(argv[1]) == -1) {
1521 Vnm_print(2,"%s: %s: %s: No such directory\n",
1522 thee->PR, argv[0], argv[1]);
1523 }
1524 VASSERT( Vnm_getcwd(workDirectory,sizeof(workDirectory)) );
1525 Vsh_putenv(thee,"CWD", workDirectory);
1526 }
1527 break;
1528
1529 case vshcom_io:
1530 Vnm_redirect(0);
1531 break;
1532
1533 case vshcom_noio:
1534 Vnm_redirect(1);
1535 break;
1536
1537 case vshcom_exit:
1538 if (Vnm_chdir(Vsh_getenv(thee,"HOME")) == -1)
1539 Vnm_print(2,"%s: %s: %s: No such directory\n",
1540 thee->PR, "cd", Vsh_getenv(thee,"HOME"));
1541 rc = 2;
1542 break;
1543
1544 case vshcom_dot:
1545 if (argc <= 1) {
1546 Vnm_print(2,"%s: Filename argument required\n", thee->PR);
1547 } else if ( !stat(argv[1], &fInfo) ) {
1548 if (VS_ISREG(fInfo.st_mode)) {
1549 thee->scUnit = fopen(argv[1], "r");
1550 if (thee->scUnit != VNULL) {
1551 thee->cinUnit = thee->scUnit;
1552 strncpy(thee->cinName,argv[1],VMAX_ARGLEN);
1553 Vnm_print(0,"Starting <%s> script named <%s>\n",
1554 thee->PR,thee->cinName);
1555 } else {
1556 Vnm_print(2,"%s: Problem opening <%s>\n",
1557 thee->PR,argv[1]);
1558 }
1559 } else {
1560 Vnm_print(2,"%s: File <%s> not normal\n",
1561 thee->PR,argv[1]);
1562 }
1563 } else {
1564 Vnm_print(2,"%s: File <%s> not found\n",thee->PR,argv[1]);
1565 }
1566 break;
1567
1568 case vshcom_sockg:
1569 Vsh_killSockets(thee);
1570 strncpy(sofmt,Vsh_getenv(thee,"OSFMT"),VMAX_ARGLEN);
1571 if (!strcmp("unix",Vsh_getenv(thee,"OSKEY"))) {
1572 strncpy(sokey,"Mcs",VMAX_ARGLEN);
1573 } else if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1574 strncpy(sokey,"Mcs",VMAX_ARGLEN);
1575 } else {
1576 strncpy(sokey,"Mcs",VMAX_ARGLEN);
1577 }
1578 if (!strcmp("1x1",Vsh_getenv(thee,"GVLO"))) {
1579 sprintf(sysc,"geomview -nopanels -wpos 436,445@55,520 -%s 0",sokey);
1580 Vnm_systemBack(sysc);
1581 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1582 Vnm_systemBack("mcbridge -i2u 0 0");
1583 }
1584 } else if (!strcmp("2x1",Vsh_getenv(thee,"GVLO"))) {
1585 sprintf(sysc,"geomview -nopanels -wpos 436,445@55,520 -%s 0",sokey);
1586 Vnm_systemBack(sysc);
1587 sprintf(sysc,"geomview -nopanels -wpos 436,445@55,50 -%s 1",sokey);
1588 Vnm_systemBack(sysc);
1589 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1590 Vnm_systemBack("mcbridge -i2u 0 0");
1591 Vnm_systemBack("mcbridge -i2u 1 1");
1592 }
1593 } else if (!strcmp("3x1",Vsh_getenv(thee,"GVLO"))) {
1594 sprintf(sysc,"geomview -nopanels -wpos 436,287@55,684 -%s 0",sokey);
1595 Vnm_systemBack(sysc);
1596 sprintf(sysc,"geomview -nopanels -wpos 436,287@55,367 -%s 1",sokey);
1597 Vnm_systemBack(sysc);
1598 sprintf(sysc,"geomview -nopanels -wpos 436,287@55,50 -%s 2",sokey);
1599 Vnm_systemBack(sysc);
1600 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1601 Vnm_systemBack("mcbridge -i2u 0 0");
1602 Vnm_systemBack("mcbridge -i2u 1 1");
1603 Vnm_systemBack("mcbridge -i2u 2 2");
1604 }
1605 } else if (!strcmp("4x1",Vsh_getenv(thee,"GVLO"))) {
1606 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 0",sokey);
1607 Vnm_systemBack(sysc);
1608 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 1",sokey);
1609 Vnm_systemBack(sysc);
1610 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 2",sokey);
1611 Vnm_systemBack(sysc);
1612 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 3",sokey);
1613 Vnm_systemBack(sysc);
1614 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1615 Vnm_systemBack("mcbridge -i2u 0 0");
1616 Vnm_systemBack("mcbridge -i2u 1 1");
1617 Vnm_systemBack("mcbridge -i2u 2 2");
1618 Vnm_systemBack("mcbridge -i2u 3 3");
1619 }
1620 } else if (!strcmp("1x1s",Vsh_getenv(thee,"GVLO"))) {
1621 sprintf(sysc,"geomview -nopanels -wpos 282,245 -%s 0",sokey);
1622 Vnm_systemBack(sysc);
1623 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1624 Vnm_systemBack("mcbridge -i2u 0 0");
1625 }
1626 } else if (!strcmp("2x1s",Vsh_getenv(thee,"GVLO"))) {
1627 sprintf(sysc,"geomview -nopanels -wpos 282,245 -%s 0",sokey);
1628 Vnm_systemBack(sysc);
1629 sprintf(sysc,"geomview -nopanels -wpos 282,245 -%s 1",sokey);
1630 Vnm_systemBack(sysc);
1631 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1632 Vnm_systemBack("mcbridge -i2u 0 0");
1633 Vnm_systemBack("mcbridge -i2u 1 1");
1634 }
1635 } else if (!strcmp("3x1s",Vsh_getenv(thee,"GVLO"))) {
1636 sprintf(sysc,"geomview -nopanels -wpos 282,152 -%s 0",sokey);
1637 Vnm_systemBack(sysc);
1638 sprintf(sysc,"geomview -nopanels -wpos 282,152 -%s 1",sokey);
1639 Vnm_systemBack(sysc);
1640 sprintf(sysc,"geomview -nopanels -wpos 282,152 -%s 2",sokey);
1641 Vnm_systemBack(sysc);
1642 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1643 Vnm_systemBack("mcbridge -i2u 0 0");
1644 Vnm_systemBack("mcbridge -i2u 1 1");
1645 Vnm_systemBack("mcbridge -i2u 2 2");
1646 }
1647 } else if (!strcmp("4x1s",Vsh_getenv(thee,"GVLO"))) {
1648 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 0",sokey);
1649 Vnm_systemBack(sysc);
1650 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 1",sokey);
1651 Vnm_systemBack(sysc);
1652 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 2",sokey);
1653 Vnm_systemBack(sysc);
1654 sprintf(sysc,"geomview -nopanels -wpos 255,255 -%s 3",sokey);
1655 Vnm_systemBack(sysc);
1656 if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1657 Vnm_systemBack("mcbridge -i2u 0 0");
1658 Vnm_systemBack("mcbridge -i2u 1 1");
1659 Vnm_systemBack("mcbridge -i2u 2 2");
1660 Vnm_systemBack("mcbridge -i2u 3 3");
1661 }
1662 } else {
1663 Vnm_print(2,"%s: %s: Incorrect argument <%s>\n",
1664 thee->PR,"GVLO",Vsh_getenv(thee,"GVLO"));
1665 }
1666 Vnm_system("sleep 3");
1667 break;
1668
1669 case vshcom_sockm:
1670 Vsh_killSockets(thee);
1671 strncpy(sofmt,Vsh_getenv(thee,"OSFMT"),VMAX_ARGLEN);
1672 if (!strcmp("unix",Vsh_getenv(thee,"OSKEY"))) {
1673 strncpy(sokey,"Mcs",VMAX_ARGLEN);
1674 } else if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1675 strncpy(sokey,"Mci",VMAX_ARGLEN);
1676 } else {
1677 strncpy(sokey,"Mci",VMAX_ARGLEN);
1678 }
1679 if (!strcmp("1x1",Vsh_getenv(thee,"GVLO"))) {
1680 sprintf(sysc,"mcsg -%s -wpos 436,445@55,520 -%s 0",sofmt,sokey);
1681 Vnm_systemBack(sysc);
1682 } else if (!strcmp("2x1",Vsh_getenv(thee,"GVLO"))) {
1683 sprintf(sysc,"mcsg -%s -wpos 436,445@55,520 -%s 0",sofmt,sokey);
1684 Vnm_systemBack(sysc);
1685 sprintf(sysc,"mcsg -%s -wpos 436,445@55,50 -%s 1",sofmt,sokey);
1686 Vnm_systemBack(sysc);
1687 } else if (!strcmp("3x1",Vsh_getenv(thee,"GVLO"))) {
1688 sprintf(sysc,"mcsg -%s -wpos 436,287@55,684 -%s 0",sofmt,sokey);
1689 Vnm_systemBack(sysc);
1690 sprintf(sysc,"mcsg -%s -wpos 436,287@55,367 -%s 1",sofmt,sokey);
1691 Vnm_systemBack(sysc);
1692 sprintf(sysc,"mcsg -%s -wpos 436,287@55,50 -%s 2",sofmt,sokey);
1693 Vnm_systemBack(sysc);
1694 } else if (!strcmp("4x1",Vsh_getenv(thee,"GVLO"))) {
1695 sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 0",sofmt,sokey);
1696 Vnm_systemBack(sysc);
1697 sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 1",sofmt,sokey);
1698 Vnm_systemBack(sysc);
1699 sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 2",sofmt,sokey);
1700 Vnm_systemBack(sysc);
1701 sprintf(sysc,"mcsg -%s -wpos 255,255 -%s 3",sofmt,sokey);
1702 Vnm_systemBack(sysc);
1703 } else if (!strcmp("1x1s",Vsh_getenv(thee,"GVLO"))) {
1704 sprintf(sysc,"mcsg -%s -wpos 282,245 -%s 0",sofmt,sokey);
1705 Vnm_systemBack(sysc);
1706 } else if (!strcmp("2x1s",Vsh_getenv(thee,"GVLO"))) {
1707 sprintf(sysc,"mcsg -%s -wpos 282,245 -%s 0",sofmt,sokey);
1708 Vnm_systemBack(sysc);
1709 sprintf(sysc,"mcsg -%s -wpos 282,245 -%s 1",sofmt,sokey);
1710 Vnm_systemBack(sysc);
1711 } else if (!strcmp("3x1s",Vsh_getenv(thee,"GVLO"))) {
1712 sprintf(sysc,"mcsg -%s -wpos 282,152 -%s 0",sofmt,sokey);
1713 Vnm_systemBack(sysc);
1714 sprintf(sysc,"mcsg -%s -wpos 282,152 -%s 1",sofmt,sokey);
1715 Vnm_systemBack(sysc);
1716 sprintf(sysc,"mcsg -%s -wpos 282,152 -%s 2",sofmt,sokey);
1717 Vnm_systemBack(sysc);
1718 } else if (!strcmp("4x1s",Vsh_getenv(thee,"GVLO"))) {
1719 sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 0",sofmt,sokey);
1720 Vnm_systemBack(sysc);
1721 sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 1",sofmt,sokey);
1722 Vnm_systemBack(sysc);
1723 sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 2",sofmt,sokey);
1724 Vnm_systemBack(sysc);
1725 sprintf(sysc,"mcsg -%s -wpos 500,300 -%s 3",sofmt,sokey);
1726 Vnm_systemBack(sysc);
1727 } else if (!strcmp("2x1r",Vsh_getenv(thee,"GVLO"))) {
1728 sprintf(sysc,"mcsg -%s -wpos 425,345@55,0 -%s 0",sofmt,sokey);
1729 Vnm_systemBack(sysc);
1730 sprintf(sysc,"mcsg -%s -wpos 425,345@55,369 -%s 1",sofmt,sokey);
1731 Vnm_systemBack(sysc);
1732 } else {
1733 Vnm_print(2,"%s: %s: Incorrect argument <%s>\n",
1734 thee->PR,"GVLO",Vsh_getenv(thee,"GVLO"));
1735 }
1736 Vnm_system("sleep 3");
1737 break;
1738
1739 case vshcom_sockk:
1740 Vsh_killSockets(thee);
1741 break;
1742
1743 case vshcom_sorry:
1744 Vnm_system("play sorry.au");
1745 break;
1746
1747 default:
1748 rc = 0;
1749 break;
1750 }
1751 return rc;
1752 }
1753
1754 /*
1755 * ***************************************************************************
1756 * Routine: Vsh_ioSetup
1757 *
1758 * Purpose: Setup for an I/O command.
1759 *
1760 * Author: Michael Holst
1761 * ***************************************************************************
1762 */
Vsh_ioSetup(Vsh * thee,char * key)1763 VPUBLIC Vio *Vsh_ioSetup(Vsh *thee, char *key)
1764 {
1765 char iodev[VMAX_BUFSIZE], iofmt[VMAX_BUFSIZE];
1766 char iohost[VMAX_BUFSIZE], iofile[VMAX_BUFSIZE];
1767 Vio *sock;
1768
1769 /* setup for a read */
1770 if (!strcmp("r",key)) {
1771
1772 strncpy(iohost,Vsh_getenv(thee,"IHVAL"),VMAX_BUFSIZE);
1773
1774 if (!strcmp("sdio",Vsh_getenv(thee,"ISKEY"))) {
1775 strncpy(iodev,"SDIO",VMAX_BUFSIZE);
1776 strncpy(iofile,"console",VMAX_BUFSIZE);
1777 } else if (!strcmp("file",Vsh_getenv(thee,"ISKEY"))) {
1778 strncpy(iodev,"FILE",VMAX_BUFSIZE);
1779 strncpy(iofile,Vsh_getenv(thee,"IFNAM"),VMAX_BUFSIZE);
1780 } else if (!strcmp("buff",Vsh_getenv(thee,"ISKEY"))) {
1781 strncpy(iodev,"BUFF",VMAX_BUFSIZE);
1782 strncpy(iofile,Vsh_getenv(thee,"ISNAM"),VMAX_BUFSIZE);
1783 } else if (!strcmp("unix",Vsh_getenv(thee,"ISKEY"))) {
1784 strncpy(iodev,"UNIX",VMAX_BUFSIZE);
1785 strncpy(iofile,Vsh_getenv(thee,"ISNAM"),VMAX_BUFSIZE);
1786 } else if (!strcmp("inet",Vsh_getenv(thee,"ISKEY"))) {
1787 strncpy(iodev,"INET",VMAX_BUFSIZE);
1788 strncpy(iofile,Vsh_getenv(thee,"ISNAM"),VMAX_BUFSIZE);
1789 } else {
1790 Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
1791 VJMPERR1( 0 );
1792 }
1793
1794 if (!strcmp("asc",Vsh_getenv(thee,"ISFMT"))) {
1795 strncpy(iofmt,"ASC", VMAX_BUFSIZE);
1796 } else if (!strcmp("xdr",Vsh_getenv(thee,"ISFMT"))) {
1797 strncpy(iofmt,"XDR", VMAX_BUFSIZE);
1798 } else {
1799 Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
1800 VJMPERR1( 0 );
1801 }
1802
1803 /* setup for a write */
1804 } else if (!strcmp("w",key)) {
1805
1806 strncpy(iohost,Vsh_getenv(thee,"OHVAL"),VMAX_BUFSIZE);
1807
1808 if (!strcmp("sdio",Vsh_getenv(thee,"OSKEY"))) {
1809 strncpy(iodev,"SDIO",VMAX_BUFSIZE);
1810 strncpy(iofile,"console",VMAX_BUFSIZE);
1811 } else if (!strcmp("file",Vsh_getenv(thee,"OSKEY"))) {
1812 strncpy(iodev,"FILE",VMAX_BUFSIZE);
1813 strncpy(iofile,Vsh_getenv(thee,"OFNAM"),VMAX_BUFSIZE);
1814 } else if (!strcmp("buff",Vsh_getenv(thee,"OSKEY"))) {
1815 strncpy(iodev,"BUFF",VMAX_BUFSIZE);
1816 strncpy(iofile,Vsh_getenv(thee,"OSNAM"),VMAX_BUFSIZE);
1817 } else if (!strcmp("unix",Vsh_getenv(thee,"OSKEY"))) {
1818 strncpy(iodev,"UNIX",VMAX_BUFSIZE);
1819 strncpy(iofile,Vsh_getenv(thee,"OSNAM"),VMAX_BUFSIZE);
1820 } else if (!strcmp("inet",Vsh_getenv(thee,"OSKEY"))) {
1821 strncpy(iodev,"INET",VMAX_BUFSIZE);
1822 strncpy(iofile,Vsh_getenv(thee,"OSNAM"),VMAX_BUFSIZE);
1823 } else {
1824 Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
1825 VJMPERR1( 0 );
1826 }
1827
1828 if (!strcmp("asc",Vsh_getenv(thee,"OSFMT"))) {
1829 strncpy(iofmt,"ASC", VMAX_BUFSIZE);
1830 } else if (!strcmp("xdr",Vsh_getenv(thee,"OSFMT"))) {
1831 strncpy(iofmt,"XDR", VMAX_BUFSIZE);
1832 } else {
1833 Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
1834 VJMPERR1( 0 );
1835 }
1836
1837 } else {
1838 Vnm_print(2,"Vsh_ioSetup: Internal logic error.\n");
1839 VJMPERR1( 0 );
1840 }
1841
1842 /* create socket and associate the buffer */
1843 VJMPERR1( VNULL != (sock=Vio_socketOpen(key,iodev,iofmt,iohost,iofile)) );
1844 Vio_bufTake(sock, thee->buf, thee->bufsize);
1845 thee->bufsize = 0;
1846 thee->buf = VNULL;
1847
1848 /* return without error */
1849 return sock;
1850
1851 VERROR1:
1852 Vnm_print(2,"Vsh_ioSetup: bailing out.\n");
1853 return VNULL;
1854 }
1855
1856 /*
1857 * ***************************************************************************
1858 * Routine: Vsh_ioCleanup
1859 *
1860 * Purpose: Cleanup an I/O command.
1861 *
1862 * Author: Michael Holst
1863 * ***************************************************************************
1864 */
Vsh_ioCleanup(Vsh * thee,Vio ** sock)1865 VPUBLIC void Vsh_ioCleanup(Vsh *thee, Vio **sock)
1866 {
1867 VJMPERR1( VNULL != thee );
1868 VJMPERR1( VNULL != *sock );
1869
1870 /* snag the buffer before destroying the socket */
1871 thee->bufsize = Vio_bufSize(*sock);
1872 thee->buf = Vio_bufGive(*sock);
1873
1874 /* return without error */
1875 Vio_socketClose( sock );
1876 return;
1877
1878 VERROR1:
1879 Vnm_print(2,"Vsh_ioCleanup: bailing out.\n");
1880 return;
1881 }
1882
1883