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