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