Annotation of freem/src/ssvn_global.c, revision 1.8

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

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