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>