File:  [Coherent Logic Development] / freem / src / ssvn.c
Revision 1.5: 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.c,v 1.5 2025/04/13 04:22:43 snw Exp $
    3:  *    structured system variable support
    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:  *   $Log: ssvn.c,v $
   27:  *   Revision 1.5  2025/04/13 04:22:43  snw
   28:  *   Fix snprintf calls
   29:  *
   30:  *   Revision 1.4  2025/04/09 15:16:50  snw
   31:  *   Fix buffer overruns in mref_to_external and ssvn.c
   32:  *
   33:  *   Revision 1.3  2025/03/09 19:50:47  snw
   34:  *   Second phase of REUSE compliance and header reformat
   35:  *
   36:  *
   37:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   38:  * SPDX-License-Identifier: AGPL-3.0-or-later
   39:  **/
   40: 
   41: #include <stdio.h>
   42: #include <stdlib.h>
   43: #include <string.h>
   44: #include <sys/types.h>
   45: #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
   46: # include <sys/timeb.h>
   47: #endif
   48: #include "mpsdef.h"
   49: #include "freem.h"
   50: #include "mref.h"
   51: #include "mdebug.h"
   52: 
   53: #ifdef USE_SYS_TIME_H
   54: # include <sys/time.h>
   55: #endif
   56: 
   57: typedef struct ssvn_lut {
   58:     const char *input_name;
   59:     const char *canonical_name;
   60: } ssvn_lut;
   61: 
   62:  ssvn_lut ssv_tab[] = {
   63:     {"^$C", "^$CHARACTER"},
   64:     {"^$CHARACTER", "^$CHARACTER"},
   65:     {"^$D", "^$DEVICE"},
   66:     {"^$DEVICE", "^$DEVICE"},
   67:     {"^$DI", "^$DISPLAY"},
   68:     {"^$DISPLAY", "^$DISPLAY"},
   69:     {"^$E", "^$EVENT"},
   70:     {"^$EVENT", "^$EVENT"},
   71:     {"^$G", "^$GLOBAL"},
   72:     {"^$GLOBAL", "^$GLOBAL"},
   73:     {"^$J", "^$JOB"},
   74:     {"^$JOB", "^$JOB"},
   75:     {"^$LI","^$LIBRARY"},
   76:     {"^$LIBRARY","^$LIBRARY"},
   77:     {"^$L", "^$LOCK"},
   78:     {"^$LOCK", "^$LOCK"},
   79:     {"^$O", "^$OBJECT"},
   80:     {"^$OBJECT", "^$OBJECT"},
   81:     {"^$R", "^$ROUTINE"},
   82:     {"^$ROUTINE", "^$ROUTINE"},
   83:     {"^$S", "^$SYSTEM"},
   84:     {"^$SYSTEM", "^$SYSTEM"},
   85:     {"^$W", "^$WINDOW"},
   86:     {"^$WINDOW", "^$WINDOW"},
   87:     {"^$ZF", "^$ZFILE"},
   88:     {"^$ZFILE", "^$ZFILE"},
   89:     {"^$ZFR", "^$ZFREEM"},
   90:     {"^$ZFREEM", "^$ZFREEM"},
   91:     {"^$ZD", "^$ZDIRECTORY"},
   92:     {"^$ZDIRECTORY", "^$ZDIRECTORY"},
   93:     {"^$ZO", "^$ZOS"},
   94:     {"^$ZOS", "^$ZOS"},
   95:     {"^$ZP", "^$ZPROCESS"},
   96:     {"^$ZPROCESS", "^$ZPROCESS"},
   97:     {"^$ZR", "^$ZRPI"},
   98:     {"^$ZRPI", "^$ZRPI"},
   99:     {NULL, NULL}
  100: };
  101: 
  102: 
  103: void ssvn (short action, char *key, char *data);
  104: void ssvn_normalize_key (char *key);
  105: 
  106: /* structured system variable management */
  107: /* set_sym      get_sym   */
  108: /* kill_sym     $data     */
  109: /* kill_all     $fra_order    */
  110: /* killexcl     $fra_query    */
  111: /* new_sym                */
  112: /* new_all      getinc    */
  113: /* newexcl                */
  114: /* killone      m_alias   */
  115: /* merge_sym    zdata     */
  116: void ssvn (short action, char *key, char *data)
  117: {
  118:     int i, j;
  119:     char ch;
  120:     char ptmp[256];
  121:     char sbuf[256];
  122: 
  123:     snprintf (sbuf, sizeof (sbuf) - 1, " C CHARACTER D DEVICE DI DISPLAY E EVENT G GLOBAL J JOB LI LIBRARY L LOCK O OBJECT P R ROUTINE S SYSTEM W WINDOW \201");
  124:     
  125:     
  126:     if ((rtn_dialect () == D_M77) ||
  127:         (rtn_dialect () == D_M84) ||
  128:         (rtn_dialect () == D_M90)) {
  129:         merr_raise (NOSTAND);
  130:         return;
  131:     }
  132:     
  133:     i = 1;
  134:     j = 2;
  135:     
  136:     while ((ch = key[j]) != EOL) {
  137: 
  138:         if (ch >= 'a' && ch <= 'z') ch -= 32;
  139:         if (ch == DELIM) break;
  140: 	
  141:         ptmp[i++] = ch;
  142:         j++;
  143: 
  144:     }
  145:     
  146:     ptmp[0] = SP;
  147:     ptmp[i++] = SP;
  148:     ptmp[i] = EOL;
  149: 
  150:     ssvn_normalize_key (key);
  151: 
  152:     if (dbg_enable_watch && (action == set_sym)) dbg_fire_watch (key);
  153: 
  154:     if (merr () > OK) return;
  155: 
  156: 
  157:     if ((ptmp[1] != 'Z') && (ptmp[1] != 'Y')) {
  158: 
  159:         if (find (sbuf, ptmp) == FALSE) {
  160:             merr_raise (M60);
  161:             return;
  162:         }
  163: 
  164:         switch (ptmp[1]) {
  165: 
  166:             case 'C':			/* ^$CHARACTER ssvn */
  167:                 ssvn_character (action, key, data);
  168:                 break;
  169: 			
  170:             case 'D':			/* ^$DEVICE and ^$DISPLAY ssvns */
  171:                 switch(ptmp[2]) {
  172:             
  173:                     case 'E':   /* ^$DEVICE */
  174:                         ssvn_device (action, key, data);
  175:                         break;
  176:             
  177:                     case 'I':   /* ^$DISPLAY */
  178:                         ssvn_display (action, key, data);
  179:                         break;
  180:             
  181:                     default:
  182:                         merr_raise (INVREF);
  183:                         break;
  184:                 }  
  185: 
  186:                 break;              			 
  187:             
  188:             case 'E':                   /* ^$EVENT ssvn */
  189:                 ssvn_event (action, key, data);
  190:                 break;
  191: 			
  192:             case 'G':		        /* ^$GLOBAL ssvn */
  193:                 ssvn_global (action, key, data);
  194:                 break;
  195: 			
  196:             case 'J':			/* ^$JOB ssvn */	  
  197:                 ssvn_job (action, key, data);
  198:                 break;
  199: 			
  200:             case 'L':			/* ^$LIBRARY/^$LOCK ssvns */
  201:                 if (ptmp[2] == 'I') {
  202:                     ssvn_library (action, key, data);
  203:                 }
  204:                 else {
  205:                     ssvn_lock (action, key, data);
  206:                 }
  207:                 break;
  208:                 
  209:             case 'O':
  210:                 ssvn_object (action, key, data);
  211:                 break;
  212:                 
  213:             case 'R':			/* ^$ROUTINE ssvn */
  214:                 ssvn_routine (action, key, data);
  215:                 break;
  216: 			
  217:             case 'S':			/* ^$SYSTEM ssvn */
  218:                 ssvn_system (action, key, data);
  219:                 break;
  220: 			
  221:             case 'W':			/* ^$WINDOW ssvn */
  222:                 ssvn_window (action, key, data);
  223:                 break;
  224: 			
  225:             default:
  226:                 merr_raise (INVREF);
  227:                 break;
  228:         }
  229:     } 
  230:     else {				/* implementation-specific ssvns */
  231:         ssvn_z (action, key, data);
  232:         return;
  233:     }
  234: 
  235:     return;
  236: }
  237: 
  238: /* convert SSVN names to canonical form (all caps, full-length name) */
  239: void ssvn_normalize_key (char *key)
  240: {
  241:     freem_ref_t *ref;
  242:     char *new_key;
  243:     ssvn_lut *p;
  244:     register int i;
  245: 
  246:     
  247:     ref = malloc (sizeof (freem_ref_t));
  248:     NULLPTRCHK(ref,"ssvn_normalize_key");
  249:     
  250:     mref_init (ref, MREF_RT_SSVN, "");
  251:     internal_to_mref (ref, key);
  252: 
  253:     for (i = 0; i < strlen (ref->name); i++) {
  254:         if (ref->name[i] >= 'a' && ref->name[i] <= 'z') ref->name[i] -= 32;
  255:     }
  256: 
  257: 
  258:     for (p = ssv_tab; p->input_name != NULL; ++p) {
  259: 
  260:         if (strcmp (ref->name, p->input_name) == 0) {
  261:             
  262:             strcpy (ref->name, p->canonical_name);
  263: 
  264:             new_key = mref_to_internal (ref);
  265:             stcpy (key, new_key);
  266: 
  267:             free (ref);
  268:             free (new_key);
  269: 
  270:             merr_clear ();
  271:             return;
  272: 
  273:         }
  274: 
  275:     }
  276: 
  277:     merr_raise (M60);
  278: 
  279:     free (ref);
  280:     
  281:     return;
  282: 
  283: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>