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