File:  [Coherent Logic Development] / freem / src / ssvn_device.c
Revision 1.6: download - view: text, annotated - select for diffs
Sun Apr 13 04:22:43 2025 UTC (3 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Fix snprintf calls

    1: /*
    2:  *   $Id: ssvn_device.c,v 1.6 2025/04/13 04:22:43 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:     fd = -1;
   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:                         sprintf (data, "0\201\0");
  108:                     }
  109:                     else {
  110:                         sprintf (data, "%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) {
  190:                     sprintf (data, "%s", dev[channel]);
  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:                     
  216:                     sprintf (data, "%ld\201", (long) siz);  
  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>