1 /*	WMCS.C:	Operating specific I/O and Spawning functions
2 		for the WICAT computer/operating system
3 		for MicroEMACS 4.00
4 		(C)Copyright 1995 by Daniel M. Lawrence
5 */
6 
7 #include        <stdio.h>
8 #include	"estruct.h"
9 #include	"eproto.h"
10 #if	WMCS
11 #include        "edef.h"
12 #include	"elang.h"
13 
14 #include	"/sysincl.sys/devtdisp.h"
15 #include	"/sysincl.sys/dstatdisp.h"
16 
17 devicetable	dtable;
18 devicestatus	dstat;
19 ushort	xmdstat = 0x019d;
20 ushort	xmdsave;
21 ushort	xmdmask = 0xfe62;
22 
23 /*
24  * This function is called once to set up the terminal device streams.
25  * On VMS, it translates TT until it finds the terminal, then assigns
26  * a channel to it and sets it raw. On CPM it is a no-op.
27  */
ttopen()28 ttopen()
29 {
30 	strcpy(os, "WMCS");
31 
32 	/* set device status */
33 	_giodst(1,&dtable,sizeof(dtable),&dstat);
34 	xmdsave = dstat.class.tty.dstyflags1;
35 	dstat.class.tty.dstyflags1 &= xmdmask;	/* clear the bits we need to use */
36 	dstat.class.tty.dstyflags1 |= xmdstat;	/* set our status bits */
37 	_siodst(1,&dstat);	/* set device status */
38 
39 	/* on all screens we are not sure of the initial position
40 	   of the cursor					*/
41 	ttrow = 999;
42 	ttcol = 999;
43 }
44 
45 /*
46  * This function gets called just before we go back home to the command
47  * interpreter. On VMS it puts the terminal back in a reasonable state.
48  * Another no-operation on CPM.
49  */
ttclose()50 ttclose()
51 {
52 	/* reset device status back to saved values */
53 	dstat.class.tty.dstyflags1 = xmdsave;
54 	_siodst(1,&dstat);
55 }
56 
57 /*
58  * Write a character to the display. On VMS, terminal output is buffered, and
59  * we just put the characters in the big array, after checking for overflow.
60  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
61  * MS-DOS (use the very very raw console output routine).
62  */
ttputc(c)63 ttputc(c)
64 {
65         fputc(c, stdout);
66 }
67 
68 /*
69  * Flush terminal buffer. Does real work where the terminal output is buffered
70  * up. A no-operation on systems where byte at a time terminal I/O is done.
71  */
ttflush()72 ttflush()
73 {
74         fflush(stdout);
75 }
76 
77 /*
78  * Read a character from the terminal, performing no editing and doing no echo
79  * at all. More complex in VMS that almost anyplace else, which figures. Very
80  * simple on CPM, because the system can do exactly what you want.
81  */
ttgetc()82 ttgetc()
83 {
84 	char c;
85 	long trns;
86 	_read(1,-1,0,-1,&c,1,&trns);
87 	return((int)(c & 0x7f));
88 }
89 
90 #if	TERMCAP
91 /* get a character with timeout */
mttgetc()92 mttgetc()
93 {
94 	char c;
95 	long trns,status;
96 
97 	status = _read(1,-1,0,4,&c,1,&trns);
98 	if(status) return(-1);
99 	return((int)(c & 0x7f));
100 }
101 #endif
102 
103 #if	TYPEAH
104 /* typahead:	Check to see if any characters are already in the
105 		keyboard buffer
106 */
107 
typahead()108 typahead()
109 
110 {
111 /*  This doesnt seem to work even though it should
112     So I leave it commented out...
113 
114 	devicetable	xdtable;
115 	devicestatus	xdstat;
116 
117 	_giodst(1,&xdtable,sizeof(xdtable),&xdstat);
118 	return(dstat.class.tty.dstyinputcnt);
119 */
120 	return(FALSE);
121 }
122 #endif
123 
124 /*
125  * Create a subjob with a copy of the command intrepreter in it. When the
126  * command interpreter exits, mark the screen as garbage so that you do a full
127  * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
128  * Under some (unknown) condition, you don't get one free when DCL starts up.
129  */
spawncli(f,n)130 spawncli(f, n)
131 {
132         register char *cp;
133 
134 	/* don't allow this command if restricted */
135 	if (restflag)
136 		return(resterr());
137 
138         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
139         TTflush();
140         TTclose();                              /* stty to old settings */
141 	if ((cp = getenv("SYS$CIP")) != NULL && *cp != '\0')
142                 system(cp);
143         else
144 		system("CIP");
145 
146         sgarbf = TRUE;
147 	sleep(2);
148         TTopen();
149         return(TRUE);
150 }
151 
152 /*
153  * Run a one-liner in a subjob. When the command returns, wait for a single
154  * character to be typed, then mark the screen as garbage so a full repaint is
155  * done. Bound to "C-X !".
156  */
spawn(f,n)157 spawn(f, n)
158 {
159         register int    s;
160         char            line[NLINE];
161 
162 	/* don't allow this command if restricted */
163 	if (restflag)
164 		return(resterr());
165         if ((s=mlreply("!", line, NLINE)) != TRUE)
166                 return (s);
167         TTputc('\n');                /* Already have '\r'    */
168         TTflush();
169         TTclose();                              /* stty to old modes    */
170         system(line);
171         TTopen();
172         mlputs(TEXT188);                        /* Pause.               */
173 /*             "[End]" */
174         TTflush();
175         while ((s = tgetc()) != '\r' && s != ' ')
176                 ;
177         sgarbf = TRUE;
178         return (TRUE);
179 }
180 
181 /*
182  * Run an external program with arguments. When it returns, wait for a single
183  * character to be typed, then mark the screen as garbage so a full repaint is
184  * done. Bound to "C-X $".
185  */
186 
execprg(f,n)187 execprg(f, n)
188 
189 {
190         register int    s;
191         char            line[NLINE];
192 
193 	/* don't allow this command if restricted */
194 	if (restflag)
195 		return(resterr());
196 
197         if ((s=mlreply("!", line, NLINE)) != TRUE)
198                 return (s);
199         TTputc('\n');                /* Already have '\r'    */
200         TTflush();
201         TTclose();                              /* stty to old modes    */
202         system(line);
203         TTopen();
204         mlputs(TEXT188);                        /* Pause.               */
205 /*             "[End]" */
206         TTflush();
207         while ((s = tgetc()) != '\r' && s != ' ')
208                 ;
209         sgarbf = TRUE;
210         return (TRUE);
211 }
212 
213 /*
214  * Pipe a one line command into a window
215  * Bound to ^X @
216  */
pipecmd(f,n)217 pipecmd(f, n)
218 {
219         register int    s;	/* return status from CLI */
220 	register EWINDOW *wp;	/* pointer to new window */
221 	register BUFFER *bp;	/* pointer to buffer to zot */
222         char	line[NLINE];	/* command line send to shell */
223 	static char bname[] = "command";
224 
225 	static char filnam[NSTRING] = "command";
226 
227 	/* don't allow this command if restricted */
228 	if (restflag)
229 		return(resterr());
230 
231 	/* get the command to pipe in */
232         if ((s=mlreply("@", line, NLINE)) != TRUE)
233                 return(s);
234 
235 	/* get rid of the command output buffer if it exists */
236         if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
237 		/* try to make sure we are off screen */
238 		wp = wheadp;
239 		while (wp != NULL) {
240 			if (wp->w_bufp == bp) {
241 				onlywind(FALSE, 1);
242 				break;
243 			}
244 			wp = wp->w_wndp;
245 		}
246 		if (zotbuf(bp) != TRUE)
247 
248 			return(FALSE);
249 	}
250 
251         TTputc('\n');                /* Already have '\r'    */
252         TTflush();
253         TTclose();                              /* stty to old modes    */
254 	strcat(line,">");
255 	strcat(line,filnam);
256         system(line);
257         TTopen();
258         TTflush();
259         sgarbf = TRUE;
260         s = TRUE;
261 
262 	if (s != TRUE)
263 		return(s);
264 
265 	/* split the current window to make room for the command output */
266 	if (splitwind(FALSE, 1) == FALSE)
267 			return(FALSE);
268 
269 	/* and read the stuff in */
270 	if (getfile(filnam, FALSE) == FALSE)
271 		return(FALSE);
272 
273 	/* make this window in VIEW mode, update all mode lines */
274 	curwp->w_bufp->b_mode |= MDVIEW;
275 	wp = wheadp;
276 	while (wp != NULL) {
277 		wp->w_flag |= WFMODE;
278 		wp = wp->w_wndp;
279 	}
280 
281 	/* and get rid of the temporary file */
282 	unlink(filnam);
283 	return(TRUE);
284 }
285 
286 /*
287  * filter a buffer through an external DOS program
288  * Bound to ^X #
289  */
filter(f,n)290 filter(f, n)
291 
292 {
293         register int    s;	/* return status from CLI */
294 	register BUFFER *bp;	/* pointer to buffer to zot */
295         char line[NLINE];	/* command line send to shell */
296 	char tmpnam[NFILEN];	/* place to store real file name */
297 	static char bname1[] = "fltinp";
298 
299 	static char filnam1[] = "fltinp";
300 	static char filnam2[] = "fltout";
301 
302 	/* don't allow this command if restricted */
303 	if (restflag)
304 		return(resterr());
305 
306 	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
307 		return(rdonly());	/* we are in read only mode	*/
308 
309 	/* get the filter name and its args */
310         if ((s=mlreply("#", line, NLINE)) != TRUE)
311                 return(s);
312 
313 	/* setup the proper file names */
314 	bp = curbp;
315 	strcpy(tmpnam, bp->b_fname);	/* save the original name */
316 	strcpy(bp->b_fname, bname1);	/* set it to our new one */
317 
318 	/* write it out, checking for errors */
319 	if (writeout(filnam1, "w") != TRUE) {
320 		mlwrite(TEXT2);
321 /*                      "[Cannot write filter file]" */
322 		strcpy(bp->b_fname, tmpnam);
323 		return(FALSE);
324 	}
325 
326         TTputc('\n');                /* Already have '\r'    */
327         TTflush();
328         TTclose();                              /* stty to old modes    */
329 	strcat(line," <fltinp >fltout");
330         system(line);
331         TTopen();
332         TTflush();
333         sgarbf = TRUE;
334         s = TRUE;
335 
336 	/* on failure, escape gracefully */
337 	if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
338 		mlwrite(TEXT3);
339 /*                      "[Execution failed]" */
340 		strcpy(bp->b_fname, tmpnam);
341 		unlink(filnam1);
342 		unlink(filnam2);
343 		return(s);
344 	}
345 
346 	/* reset file name */
347 	strcpy(bp->b_fname, tmpnam);	/* restore name */
348 	bp->b_flag |= BFCHG;		/* flag it as changed */
349 
350 	/* and get rid of the temporary file */
351 	unlink(filnam1);
352 	unlink(filnam2);
353 	return(TRUE);
354 }
355 
356 /* return a system dependant string with the current time */
357 
timeset()358 char *PASCAL NEAR timeset()
359 
360 {
361 	register char *sp;	/* temp string pointer */
362 	char buf[16];		/* time data buffer */
363 	extern char *ctime();
364 
365 	time(buf);
366 	sp = ctime(buf);
367 	sp[strlen(sp)-1] = 0;
368 	return(sp);
369 }
370 #else
wmcshello()371 wmcshello()
372 {
373 }
374 #endif
375