File:  [Coherent Logic Development] / freem / src / ssvn_device.c
Revision 1.4: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (12 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: v0-63-1-rc1, v0-63-0-rc1, v0-63-0, v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

    1: /*
    2:  *   $Id: ssvn_device.c,v 1.4 2025/03/09 19:50:47 snw Exp $
    3:  *    ^$DEVICE ssvn
    4:  *
    5:  *  
    6:  *   Author: Serena Willis <snw@coherent-logic.com>
    7:  *    Copyright (C) 1998 MUG Deutschland
    8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
    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) {
  188:                     sprintf (data, "%s", dev[channel]);
  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:                     
  214:                     sprintf (data, "%ld\201", (long) siz);  
  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>