Annotation of freem/src/ssvn_device.c, revision 1.1.1.1
1.1 snw 1: /*
2: * *
3: * * *
4: * * *
5: * ***************
6: * * * * *
7: * * MUMPS *
8: * * * * *
9: * ***************
10: * * *
11: * * *
12: * *
13: *
14: * ssvn_device.c
15: * ^$DEVICE ssv
16: *
17: *
18: * Author: Serena Willis <jpw@coherent-logic.com>
19: * Copyright (C) 1998 MUG Deutschland
20: * Copyright (C) 2020 Coherent Logic Development LLC
21: *
22: *
23: * This file is part of FreeM.
24: *
25: * FreeM is free software: you can redistribute it and/or modify
26: * it under the terms of the GNU Affero Public License as published by
27: * the Free Software Foundation, either version 3 of the License, or
28: * (at your option) any later version.
29: *
30: * FreeM is distributed in the hope that it will be useful,
31: * but WITHOUT ANY WARRANTY; without even the implied warranty of
32: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33: * GNU Affero Public License for more details.
34: *
35: * You should have received a copy of the GNU Affero Public License
36: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
37: *
38: **/
39:
40: #include <stdio.h>
41: #include <stdlib.h>
42: #include <string.h>
43: #include <errno.h>
44: #include <ctype.h>
45: #include <sys/types.h>
46: #include <sys/stat.h>
47: #include <unistd.h>
48: #include "mref.h"
49: #include "mpsdef.h"
50:
51: void set_dsw_bit(int bit);
52: void clear_dsw_bit(int bit);
53:
54: void ssvn_device(short action, char *key, char *data)
55: {
56: int channel;
57: int fd;
58: int i;
59: FILE *fp;
60: freem_ref_t *r;
61: char *dbuf;
62: char *envbuf;
63:
64: r = (freem_ref_t *) malloc (sizeof (freem_ref_t));
65: NULLPTRCHK(r,"ssvn_device");
66:
67: dbuf = (char *) malloc (100 * sizeof (char));
68: NULLPTRCHK(dbuf,"ssvn_device");
69:
70: mref_init (r, MREF_RT_SSV, "^$DEVICE");
71: internal_to_mref (r, key);
72:
73: if (!isdigit (r->subscripts[0][0])) {
74: merr_raise (NODEVICE);
75: goto done;
76: }
77:
78: strcpy (dbuf, r->subscripts[0]);
79: stcnv_c2m (dbuf);
80:
81: channel = intexpr (dbuf);
82:
83: if (channel < 0 || channel >= MAXDEV) {
84: merr_raise (NODEVICE);
85: goto done;
86: }
87:
88:
89: for (i = 0; i < strlen (r->subscripts[1]); i++) r->subscripts[1][i] = toupper (r->subscripts[1][i]);
90:
91:
92: fp = opnfile[channel];
93:
94: if (channel != 0 && (fp == NULL || (fd = fileno (fp)) == -1) && channel < FIRSTSCK && strcmp (r->subscripts[1], "$DEVICE") != 0) {
95: merr_raise (NOPEN);
96: goto done;
97: }
98:
99:
100: key = mref_to_internal (r);
101:
102: switch (action) {
103:
104: case get_sym:
105:
106: if (r->subscript_count == 1) {
107: stcpy (data, dev[channel]);
108: break;
109: }
110:
111:
112:
113: if (r->subscript_count == 2) {
114: if (strcmp (r->subscripts[1], "$DEVICE") == 0) {
115:
116: if (devstat[channel].mdc_err == 0) {
117: snprintf (data, 3, "0\201\0");
118: }
119: else {
120: snprintf (data, 120, "%d,%d,%s\201\0", devstat[channel].mdc_err, devstat[channel].frm_err, devstat[channel].err_txt);
121: }
122:
123: break;
124:
125: }
126: if (strcmp (r->subscripts[1], "EOF") == 0 && channel != 0) {
127:
128: if (feof (fp)) {
129: sprintf (data, "1\201");
130: }
131: else {
132: sprintf (data, "0\201");
133: }
134:
135: break;
136:
137: }
138: else if (strcmp (r->subscripts[1], "INPUT_BUFFER") == 0) {
139: stcpy (data, ug_buf[channel]);
140: break;
141: }
142: else if ((strcmp (r->subscripts[1], "$X") == 0)) {
143: sprintf (data, "%d\201", xpos[channel]);
144: break;
145: }
146: else if ((strcmp (r->subscripts[1], "$Y") == 0)) {
147: sprintf (data, "%d\201", ypos[channel]);
148: break;
149: }
150: else if ((strcmp (r->subscripts[1], "ROWS") == 0) && (channel == 0)) {
151: sprintf (data, "%d\201", n_lines);
152: break;
153: }
154: else if ((strcmp (r->subscripts[1], "COLUMNS") == 0) && (channel == 0)) {
155: sprintf (data, "%d\201", n_columns);
156: break;
157: }
158: else if (strcmp (r->subscripts[1], "FD") == 0) {
159: sprintf (data, "%d\201", fileno (fp));
160: break;
161: }
162: else if (strcmp (r->subscripts[1], "MODE") == 0) {
163:
164: switch (sq_modes[channel]) {
165:
166: case 'r':
167:
168: sprintf (data, "READ\201");
169: break;
170:
171: case 'w':
172:
173: sprintf (data, "WRITE\201");
174: break;
175:
176: case 'a':
177:
178: sprintf (data, "APPEND\201");
179: break;
180:
181: case '+':
182:
183: sprintf (data, "READWRITE\201");
184: break;
185:
186:
187: default:
188:
189: sprintf (data, "\201");
190: break;
191:
192: }
193:
194: }
195: else if (strcmp (r->subscripts[1], "CHARACTER") == 0) {
196: sprintf (data, "M\201");
197: break;
198: }
199: else if (strcmp (r->subscripts[1], "NAME") == 0) {
200: sprintf (data, dev[channel]);
201: break;
202: }
203: else if (strcmp (r->subscripts[1], "TYPE") == 0) {
204:
205: if (channel == 0) {
206: sprintf (data, "4,TERMINAL\201");
207: }
208: else if (channel > 0 && channel < FIRSTSCK) {
209: sprintf (data, "1,FILE\201");
210: }
211: else {
212: sprintf (data, "2,SOCKET\201");
213: }
214:
215: break;
216:
217: }
218: else if (strcmp (r->subscripts[1], "LENGTH") == 0 && channel != 0) {
219:
220: struct stat s;
221: off_t siz;
222:
223: fstat (fd, &s);
224: siz = s.st_size;
225:
226: sprintf (data, "%ld\201", siz);
227:
228: break;
229:
230: }
231: else if (strcmp (r->subscripts[1], "NAMESPACE") == 0) {
232:
233: switch (channel) {
234:
235: case 0:
236: sprintf (data, "X364\201");
237: break;
238:
239: default:
240: sprintf (data, "\201");
241: break;
242: }
243:
244: break;
245: }
246: else {
247: merr_raise (M38);
248: goto done;
249: }
250:
251: goto done;
252: }
253:
254:
255:
256: if ((r->subscript_count == 3) && (strcmp (r->subscripts[1], "OPTIONS") == 0)) {
257:
258: if (strcmp (r->subscripts[2], "DSW") == 0 && channel == 0) {
259:
260: sprintf (data, "%ld\201", DSW);
261:
262: merr_raise (OK);
263: goto done;
264:
265: }
266: else if (strcmp (r->subscripts[2], "TERMINATOR") == 0) {
267: symtab (get_sym, key, data);
268: goto done;
269: }
270: else if (strcmp (r->subscripts[2], "TERMID") == 0 && channel == 0) {
271: envbuf = getenv ("TERM");
272: strcpy (data, envbuf);
273: stcnv_c2m (data);
274: goto done;
275: }
276: else if (strcmp (r->subscripts[2], "ECHO") == 0 && channel == 0) {
277:
278: if (ECHOON) {
279: sprintf (data, "1\201");
280: }
281: else {
282: sprintf (data, "0\201");
283: }
284:
285: }
286: else if (strcmp (r->subscripts[2], "DELMODE") == 0 && channel == 0) {
287:
288: if (DELMODE) {
289: sprintf (data, "1\201");
290: }
291: else {
292: sprintf (data, "0\201");
293: }
294:
295: }
296: else if (strcmp (r->subscripts[2], "ESCAPE") == 0 && channel == 0) {
297:
298: if (ESCSEQPROC) {
299: sprintf (data, "1\201");
300: }
301: else {
302: sprintf (data, "0\201");
303: }
304:
305: }
306: else if (strcmp (r->subscripts[2], "CONVUPPER") == 0 && channel == 0) {
307:
308: if (CONVUPPER) {
309: sprintf (data, "1\201");
310: }
311: else {
312: sprintf (data, "0\201");
313: }
314:
315: }
316: else if (strcmp (r->subscripts[2], "DELEMPTY") == 0 && channel == 0) {
317:
318: if (DELEMPTY) {
319: sprintf (data, "1\201");
320: }
321: else {
322: sprintf (data, "0\201");
323: }
324:
325: }
326: else if (strcmp (r->subscripts[2], "NOCTRLS") == 0 && channel == 0) {
327:
328: if (NOCTRLS) {
329: sprintf (data, "1\201");
330: }
331: else {
332: sprintf (data, "0\201");
333: }
334:
335: }
336: else if (strcmp (r->subscripts[2], "CTRLOPROC") == 0 && channel == 0) {
337:
338: if (CTRLOPROC) {
339: sprintf (data, "1\201");
340: }
341: else {
342: sprintf (data, "0\201");
343: }
344:
345: }
346: else if (strcmp (r->subscripts[2], "NOTYPEAHEAD") == 0 && channel == 0) {
347:
348: if (NOTYPEAHEAD) {
349: sprintf (data, "1\201");
350: }
351: else {
352: sprintf (data, "0\201");
353: }
354:
355: }
356: else {
357: merr_raise (M38);
358: goto done;
359: }
360:
361: break;
362: }
363: else {
364: merr_raise (M38);
365: goto done;
366: }
367:
368: case set_sym:
369:
370:
371: if (r->subscript_count == 2) {
372:
373: if (strcmp (r->subscripts[1], "DSW") == 0 && channel == 0) {
374:
375: stcpy (dbuf, data);
376: stcnv_m2c (dbuf);
377:
378: DSW = atol (dbuf);
379:
380: merr_raise (OK);
381: goto done;
382:
383: }
384: else if (strcmp (r->subscripts[1], "INPUT_BUFFER") == 0) {
385: stcpy (ug_buf[channel], data);
386:
387: merr_raise (OK);
388: goto done;
389: }
390: else {
391:
392: merr_raise (M29);
393: goto done;
394:
395: }
396:
397: }
398:
399: if ((r->subscript_count == 3) && (strcmp (r->subscripts[1], "OPTIONS") == 0)) {
400:
401: if (strcmp (r->subscripts[2], "ECHO") == 0 && channel == 0) {
402:
403: if (tvexpr (data)) {
404: clear_dsw_bit (0);
405: }
406: else {
407: set_dsw_bit (0);
408: }
409:
410: }
411: else if (strcmp (r->subscripts[2], "TERMINATOR") == 0) {
412: symtab (set_sym, key, data);
413:
414: merr_raise (OK);
415: goto done;
416: }
417: else if (strcmp (r->subscripts[2], "DELMODE") == 0 && channel == 0) {
418:
419: if (tvexpr (data)) {
420: set_dsw_bit (2);
421: }
422: else {
423: clear_dsw_bit (2);
424: }
425:
426: }
427: else if (strcmp (r->subscripts[2], "ESCAPE") == 0 && channel == 0) {
428:
429: if (tvexpr (data)) {
430: set_dsw_bit (6);
431: }
432: else {
433: clear_dsw_bit (6);
434: }
435:
436: }
437: else if (strcmp (r->subscripts[2], "CONVUPPER") == 0 && channel == 0) {
438:
439: if (tvexpr (data)) {
440: set_dsw_bit (14);
441: }
442: else {
443: clear_dsw_bit (14);
444: }
445:
446: }
447: else if (strcmp (r->subscripts[2], "DELEMPTY") == 0 && channel == 0) {
448:
449: if (tvexpr (data)) {
450: set_dsw_bit (19);
451: }
452: else {
453: clear_dsw_bit (19);
454: }
455:
456: }
457: else if (strcmp (r->subscripts[2], "NOCTRLS") == 0 && channel == 0) {
458:
459: if (tvexpr (data)) {
460: set_dsw_bit (20);
461: }
462: else {
463: clear_dsw_bit (20);
464: }
465:
466: }
467: else if (strcmp (r->subscripts[2], "CTRLOPROC") == 0 && channel == 0) {
468:
469: if (tvexpr (data)) {
470: set_dsw_bit (21);
471: }
472: else {
473: clear_dsw_bit (21);
474: }
475:
476: }
477: else if (strcmp (r->subscripts[2], "NOTYPEAHEAD") == 0 && channel == 0) {
478:
479: if (tvexpr (data)) {
480: set_dsw_bit (25);
481: }
482: else {
483: clear_dsw_bit (25);
484: }
485:
486: }
487: else {
488: merr_raise (M29);
489: goto done;
490: }
491:
492: break;
493:
494: }
495:
496:
497: default:
498: merr_raise (INVREF);
499: break;
500: }
501:
502: done:
503:
504: free (key);
505: free (r);
506: free (dbuf);
507:
508: return;
509: }
510:
511: void set_dsw_bit(int bit)
512: {
513: DSW = ((1 << bit) | DSW);
514: }
515:
516: void clear_dsw_bit(int bit)
517: {
518: DSW &= ~(1 << bit);
519: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>