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

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

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