File:  [Coherent Logic Development] / freem / src / ssvn_global.c
Revision 1.8: 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_global.c,v 1.8 2025/04/13 04:22:43 snw Exp $
    3:  *    ^$GLOBAL 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:  *   $Log: ssvn_global.c,v $
   27:  *   Revision 1.8  2025/04/13 04:22:43  snw
   28:  *   Fix snprintf calls
   29:  *
   30:  *   Revision 1.7  2025/04/10 17:21:54  snw
   31:  *   Remove traces of BDB global handler
   32:  *
   33:  *   Revision 1.6  2025/04/09 19:52:02  snw
   34:  *   Eliminate as many warnings as possible while building with -Wall
   35:  *
   36:  *   Revision 1.5  2025/03/22 18:43:54  snw
   37:  *   Make STRLEN 255 chars and add BIGSTR macro for larger buffers
   38:  *
   39:  *   Revision 1.4  2025/03/09 19:50:47  snw
   40:  *   Second phase of REUSE compliance and header reformat
   41:  *
   42:  *
   43:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   44:  * SPDX-License-Identifier: AGPL-3.0-or-later
   45:  **/
   46: 
   47: #include <stdio.h>
   48: #include <unistd.h>
   49: #include <fcntl.h>
   50: #include <string.h>
   51: #include <stdlib.h>
   52: 
   53: #include "mpsdef.h"
   54: #include "mref.h"
   55: #include "iniconf.h"
   56: #include "namespace.h"
   57: 
   58: #define DATALIM (BLOCKLEN-11)
   59: #define LLPTR   (BLOCKLEN-10)
   60: #define NRBLK    LLPTR
   61: #define COLLA   (BLOCKLEN- 7)
   62: #define RLPTR   (BLOCKLEN- 6)
   63: #define FREE     RLPTR
   64: #define BTYP    (BLOCKLEN- 3)
   65: #define OFFS    (BLOCKLEN- 2)
   66: 
   67: /* length of blockpointers in bytes */
   68: #define PLEN     3
   69: 
   70: #define EMPTY    0
   71: #define FBLK     1
   72: #define POINTER  2
   73: #define BOTTOM   6
   74: #define DATA     8
   75: 
   76: typedef struct db_blockinfo {
   77: 
   78:     int keylen;
   79:     int keyoffs;
   80:     char key[STRLEN];
   81:     int datalen;
   82:     char data[STRLEN];
   83: 
   84:     long llptr;
   85:     long rlptr;
   86:     
   87:     long blockcount;
   88:     int collation;
   89:     
   90:     int btype;
   91:     long free_offset;
   92: 
   93: } db_blockinfo;
   94: 
   95: short frm_global_exists(char *, char *, char *);
   96: void frm_decode_block(db_blockinfo *, char *, long);
   97: long frm_blockcount(char *);
   98: long frm_bytecount(char *);
   99: 
  100: void frm_decode_block(db_blockinfo *b, char *gbpth, long blocknum)
  101: {
  102: 
  103:     int fd;
  104:     char blk[BLOCKLEN];
  105: 
  106: 
  107:     fd = open (gbpth, O_RDONLY);
  108:     lseek (fd, blocknum * BLOCKLEN, SEEK_SET);
  109:     read (fd, blk, BLOCKLEN);
  110: 
  111:     close (fd);
  112:     
  113:     b->btype = blk[BTYP];
  114: 
  115:     if (blocknum == 0) {
  116:         b->collation = blk[COLLA];
  117:         b->blockcount = ((int) blk[NRBLK]) << 4;
  118:     }
  119:     else {        
  120:         b->llptr = UNSIGN (blk[LLPTR]) * 65536 + UNSIGN (blk[LLPTR + 1]) * 256 + UNSIGN (blk[LLPTR + 2]);
  121:         b->rlptr = UNSIGN (blk[RLPTR]) * 65536 + UNSIGN (blk[RLPTR + 1]) * 256 + UNSIGN (blk[RLPTR + 2]);
  122:     }
  123: 
  124:     if (b->btype == DATA) {
  125:         b->free_offset = UNSIGN (blk[OFFS]) * 256 + UNSIGN (blk[OFFS + 1]);
  126:         b->keylen = blk[0];
  127:     }
  128: 
  129:     return;
  130:     
  131: }
  132: 
  133: void ssvn_global(short action, char *key, char *data)
  134: {
  135:     char gb_ns[STRLEN];
  136:     char gb_path[PATHLEN];
  137:     char gb_cpath[PATHLEN];
  138: 
  139:     char ns_key[STRLEN];
  140:     
  141:     long blkcount;
  142: 
  143:     freem_ref_t *r;
  144:     db_blockinfo *bi;
  145:     
  146:     r = (freem_ref_t *) malloc (sizeof (freem_ref_t));
  147:     NULLPTRCHK(r,"ssvn_global");
  148: 
  149:     bi = (db_blockinfo *) malloc (sizeof (db_blockinfo));
  150:     NULLPTRCHK(bi,"ssvn_global");
  151:     
  152:     mref_init (r, MREF_RT_SSV, "^$GLOBAL");
  153:     internal_to_mref (r, key);
  154: 
  155:     switch (action) {
  156: 
  157:         case set_sym:
  158: 
  159:             if (strcmp (mref_get_subscript (r, 1), "NAMESPACE") != 0) {
  160:                 merr_raise (M29);
  161:                 goto done;
  162:             }
  163: 
  164:             snprintf (ns_key, STRLEN - 1, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", mref_get_subscript (r, 0));
  165:             symtab_shm (set_sym, ns_key, data);
  166: 
  167:             goto done;
  168: 
  169:         case kill_sym:
  170: 
  171:             if (strcmp (mref_get_subscript (r, 1), "NAMESPACE") != 0) {
  172:                 merr_raise (M29);
  173:                 goto done;
  174:             }
  175: 
  176:             snprintf (ns_key, STRLEN - 1, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", mref_get_subscript (r, 0));
  177:             symtab_shm (kill_sym, ns_key, data);
  178: 
  179:             goto done;
  180: 
  181:             
  182:         
  183:         case get_sym:
  184: 
  185:             if (frm_global_exists (gb_ns, gb_path, r->subscripts[0]) != TRUE) {
  186:                 merr_raise (M7);
  187:                 goto done;
  188:             }
  189: 
  190:             if (strcmp (mref_get_subscript (r, 1), "BLOCK") == 0) {
  191: 
  192:                 long bn = atol (mref_get_subscript (r, 2));
  193: 
  194:                 stcpy (gb_cpath, gb_path);
  195:                 stcnv_m2c (gb_cpath);
  196: 
  197:                 blkcount = frm_blockcount (gb_cpath);
  198: 
  199:                 if (bn > (blkcount - 1)) {
  200:                     merr_raise (M38);
  201:                     goto done;
  202:                 }
  203:                 
  204:                 frm_decode_block (bi, gb_cpath, bn);
  205:                 
  206:                 if (strcmp (mref_get_subscript (r, 3), "TYPE") == 0) {
  207: 
  208:                     switch (bi->btype) {
  209: 
  210:                         case 2:
  211:                             sprintf (data, "%s\201", "POINTER");
  212:                             merr_raise (OK);
  213:                             goto done;
  214: 
  215:                         case 6:
  216:                             sprintf (data, "%s\201", "ROOT");
  217:                             merr_raise (OK);
  218:                             goto done;
  219: 
  220:                         case 8:
  221:                             sprintf (data, "%s\201", "DATA");
  222:                             merr_raise (OK);
  223:                             goto done;
  224:                     }
  225:                             
  226:                             
  227:                     sprintf (data, "%d\201", bi->btype);
  228:                     merr_raise (OK);
  229:                     goto done;
  230:                     
  231:                 }
  232:                 else if (strcmp (mref_get_subscript (r, 3), "BLOCKCOUNT") == 0) {
  233: 
  234:                     if (bn != 0) {
  235:                         merr_raise (M38);
  236:                         goto done;
  237:                     }
  238:                     
  239:                     sprintf (data, "%ld\201", bi->blockcount);
  240:                     merr_raise (OK);
  241:                     goto done;                    
  242:                 }
  243:                 else if (strcmp (mref_get_subscript (r, 3), "KEYLEN") == 0) {
  244: 
  245:                     if (bn == 0) {
  246:                         merr_raise (M38);
  247:                         goto done;
  248:                     }
  249: 
  250:                     sprintf (data, "%d\201", bi->keylen);
  251:                     merr_raise (OK);
  252:                     goto done;
  253:                 }
  254:                 else if (strcmp (mref_get_subscript (r, 3), "RLPTR") == 0) {
  255: 
  256:                     if (bn == 0) {
  257:                         merr_raise (M38);
  258:                         goto done;
  259:                     }
  260: 
  261:                     
  262:                     sprintf (data, "%ld\201", bi->rlptr);
  263:                     merr_raise (OK);
  264:                     goto done;
  265:                 }
  266:                 else if (strcmp (mref_get_subscript (r, 3), "OFFS") == 0) {
  267: 
  268:                     if (bi->btype != DATA) {
  269:                         merr_raise (M38);
  270:                         goto done;
  271:                     }
  272: 
  273:                     sprintf (data, "%ld\201", bi->free_offset);
  274:                     merr_raise (OK);
  275:                     goto done;
  276:                 }                
  277:                 else if (strcmp (mref_get_subscript (r, 3), "LLPTR") == 0) {
  278: 
  279:                     if (bn == 0) {
  280:                         merr_raise (M38);
  281:                         goto done;                        
  282:                     }
  283: 
  284:                     sprintf (data, "%ld\201", bi->llptr);
  285:                     merr_raise (OK);
  286:                     goto done;
  287:                 }
  288:                 
  289:             }
  290:             else if (strcmp (mref_get_subscript (r, 1), "CHARACTER") == 0) {
  291:                 stcpy (gb_cpath, gb_path);
  292:                 stcnv_m2c (gb_cpath);
  293: 
  294:                 frm_decode_block (bi, gb_cpath, 0L);
  295: 
  296:                 if (bi->collation == 0) {
  297:                     sprintf (data, "M\201");
  298:                     merr_raise (OK);
  299:                     goto done;
  300:                 }
  301:                 else {
  302:                     sprintf (data, "ASCII\201");
  303:                     merr_raise (OK);
  304:                     goto done;
  305:                 }
  306:             }
  307:             else if (strcmp (mref_get_subscript (r, 1), "COLLATE") == 0) {
  308:                 stcpy (gb_cpath, gb_path);
  309:                 stcnv_m2c (gb_cpath);
  310: 
  311:                 frm_decode_block (bi, gb_cpath, 0L);
  312: 
  313:                 if (bi->collation == 0) {
  314:                     sprintf (data, "M\201");
  315:                     merr_raise (OK);
  316:                     goto done;
  317:                 }
  318:                 else {
  319:                     sprintf (data, "ASCII\201");
  320:                     merr_raise (OK);
  321:                     goto done;
  322:                 }
  323:             }
  324:             else if (strcmp (mref_get_subscript (r, 1), "NAMESPACE") == 0) {
  325:                 sprintf (data, "%s\201", gb_ns);
  326:                 merr_raise (OK);
  327:                 goto done;
  328:             }
  329:             else if (strcmp (mref_get_subscript (r, 1), "FILE") == 0) {
  330:                 sprintf (data, "%s\201", gb_path);
  331:                 merr_raise (OK);
  332:                 goto done;
  333:             }
  334:             else if (strcmp (mref_get_subscript (r, 1), "BLOCKSIZE") == 0) {
  335:                 sprintf (data, "%d\201", BLOCKLEN);
  336:                 merr_raise (OK);
  337:                 goto done;
  338:             }
  339:             else if (strcmp (mref_get_subscript (r, 1), "BLOCKS") == 0) {
  340: 
  341:                 long blockcount;
  342:                 
  343:                 stcpy (gb_cpath, gb_path);
  344:                 stcnv_m2c (gb_cpath);
  345: 
  346:                 blockcount = frm_blockcount (gb_cpath);
  347:                 
  348:                 sprintf (data, "%ld\201", blockcount);
  349: 
  350:                 merr_raise (OK);
  351:                 goto done;
  352:                 
  353:             }
  354:             else if (strcmp (mref_get_subscript (r, 1), "BYTES") == 0) {
  355:                 long bytecount;
  356:                 
  357:                 stcpy (gb_cpath, gb_path);
  358:                 stcnv_m2c (gb_cpath);
  359: 
  360:                 bytecount = frm_bytecount (gb_cpath);
  361:                 
  362:                 sprintf (data, "%ld\201", bytecount);
  363: 
  364:                 merr_raise (OK);
  365:                 goto done;                
  366:             }
  367: 
  368:             merr_raise (M38);
  369:             goto done;
  370: 
  371:             
  372:         default:
  373:             merr_raise (INVREF);
  374:             goto done;
  375:             
  376:     }
  377:     
  378: done:
  379: 
  380:     free (r);
  381:     
  382:     return;
  383: }
  384: 
  385: short frm_global_exists(char *gbl_namespace, char *gbl_path, char *global_name)
  386: {
  387:     char *gpth;
  388:     char glofile[PATHLEN];
  389:     char goobuf[STRLEN];
  390: 
  391:     char mapk_buf[STRLEN];
  392:     char mapd_buf[STRLEN];
  393:     char old_ns[STRLEN];
  394:     
  395:     int ierr_sav = OK;
  396: 
  397:     if (global_name[0] != '^') {
  398:         snprintf (mapk_buf, STRLEN - 1, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", global_name);
  399:     }
  400:     else {
  401:         snprintf (mapk_buf, STRLEN - 1, "^$SYSTEM\202MAPPINGS\202GLOBAL\202%s\201", global_name);
  402:     }
  403:     
  404:     symtab_shm (get_sym, mapk_buf, mapd_buf);
  405: 
  406:     stcnv_m2c (mapd_buf);
  407: 
  408:     if (merr () == OK) {
  409: 
  410:         strncpy (old_ns, nsname, 255);
  411:         set_namespace (mapd_buf, 0);
  412: 
  413:         gpth = (char *) malloc (PATHLEN * sizeof (char));
  414:         NULLPTRCHK(gpth,"frm_global_exists");
  415: 
  416:         strncpy (gpth, glopath, PATHLEN - 1);
  417:         strncpy (gbl_namespace, mapd_buf, 254);
  418:         
  419:         set_namespace (old_ns, 0);
  420:         
  421:     }
  422:     else {
  423: 
  424:         merr_raise (ierr_sav);
  425:         
  426:         if (global_name[0] == '%') {
  427:             gpth = gloplib;
  428:             sprintf (gbl_namespace, "SYSTEM"); 
  429:         }
  430:         else {
  431:             gpth = glopath;
  432:             sprintf (gbl_namespace, "%s\201", nsname);
  433:         }
  434: 
  435:     }
  436: 
  437:     stcpy (goobuf, gpth);
  438:     stcnv_m2c (goobuf);
  439: 
  440:     if (global_name[0] != '^') {
  441:         snprintf (glofile, PATHLEN - 1, "%s/^%s", goobuf, global_name);
  442:     }
  443:     else {
  444:         snprintf (glofile, PATHLEN - 1, "%s/%s", goobuf, global_name);
  445:     }
  446:     
  447:     strcpy (gbl_path, glofile);
  448:     stcnv_c2m (gbl_path);
  449:     
  450:     if (file_exists (glofile)) {
  451:         return TRUE;
  452:     }
  453:     else {
  454:         return FALSE;
  455:     }
  456:     
  457:     
  458: }
  459: 
  460: long frm_blockcount(char *gbl_path)
  461: {
  462:     FILE *fp;
  463:     long blockcount;
  464:     
  465:         
  466:     fp = fopen (gbl_path, "r");
  467:     fseek (fp, 0L, SEEK_END);
  468:     blockcount = ftell (fp) / BLOCKLEN;
  469:     fclose (fp);
  470:     
  471: 
  472:     return blockcount;
  473: }
  474: 
  475: long frm_bytecount(char *gbl_path)
  476: {
  477:     FILE *fp;
  478:     long bytecount;
  479:     
  480:         
  481:     fp = fopen (gbl_path, "r");
  482:     fseek (fp, 0L, SEEK_END);
  483:     bytecount = ftell (fp);
  484:     fclose (fp);
  485:     
  486:     return bytecount;
  487: }

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