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

1.1       snw         1: /*
                      2:  *                            *
                      3:  *                           * *
                      4:  *                          *   *
                      5:  *                     ***************
                      6:  *                      * *       * *
                      7:  *                       *  MUMPS  *
                      8:  *                      * *       * *
                      9:  *                     ***************
                     10:  *                          *   *
                     11:  *                           * *
                     12:  *                            *
                     13:  *
                     14:  *   ssvn_global.c
                     15:  *    ^$GLOBAL ssv
                     16:  *
                     17:  *  
                     18:  *   Author: Serena Willis <jpw@coherent-logic.com>
                     19:  *    Copyright (C) 1998 MUG Deutschland
                     20:  *    Copyright (C) 2020 Coherent Logic Development LLC
                     21:  *
                     22:  *
                     23:  *   This file is part of FreeM.
                     24:  *
                     25:  *   FreeM is free software: you can redistribute it and/or modify
                     26:  *   it under the terms of the GNU Affero Public License as published by
                     27:  *   the Free Software Foundation, either version 3 of the License, or
                     28:  *   (at your option) any later version.
                     29:  *
                     30:  *   FreeM is distributed in the hope that it will be useful,
                     31:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     32:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     33:  *   GNU Affero Public License for more details.
                     34:  *
                     35:  *   You should have received a copy of the GNU Affero Public License
                     36:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
                     37:  *
                     38:  **/
                     39: 
                     40: #include <stdio.h>
                     41: #include <unistd.h>
                     42: #include <fcntl.h>
                     43: #include <string.h>
                     44: #include <stdlib.h>
                     45: 
                     46: #include "mpsdef.h"
                     47: #include "mref.h"
                     48: #include "iniconf.h"
                     49: #include "namespace.h"
                     50: 
                     51: #define DATALIM (BLOCKLEN-11)
                     52: #define LLPTR   (BLOCKLEN-10)
                     53: #define NRBLK    LLPTR
                     54: #define COLLA   (BLOCKLEN- 7)
                     55: #define RLPTR   (BLOCKLEN- 6)
                     56: #define FREE     RLPTR
                     57: #define BTYP    (BLOCKLEN- 3)
                     58: #define OFFS    (BLOCKLEN- 2)
                     59: 
                     60: /* length of blockpointers in bytes */
                     61: #define PLEN     3
                     62: 
                     63: #define EMPTY    0
                     64: #define FBLK     1
                     65: #define POINTER  2
                     66: #define BOTTOM   6
                     67: #define DATA     8
                     68: 
                     69: typedef struct db_blockinfo {
                     70: 
                     71:     int keylen;
                     72:     int keyoffs;
                     73:     char key[STRLEN];
                     74:     int datalen;
                     75:     char data[STRLEN];
                     76: 
                     77:     long llptr;
                     78:     long rlptr;
                     79:     
                     80:     long blockcount;
                     81:     int collation;
                     82:     
                     83:     int btype;
                     84:     long free_offset;
                     85: 
                     86: } db_blockinfo;
                     87: 
                     88: short frm_global_exists(char *, char *, char *);
                     89: void frm_decode_block(db_blockinfo *, char *, long);
                     90: long frm_blockcount(char *);
                     91: long frm_bytecount(char *);
                     92: 
                     93: void frm_decode_block(db_blockinfo *b, char *gbpth, long blocknum)
                     94: {
                     95: 
                     96:     int fd;
                     97:     char blk[BLOCKLEN];
                     98: 
                     99: 
                    100:     fd = open (gbpth, O_RDONLY);
                    101:     lseek (fd, blocknum * BLOCKLEN, SEEK_SET);
                    102:     read (fd, blk, BLOCKLEN);
                    103: 
                    104:     close (fd);
                    105:     
                    106:     b->btype = blk[BTYP];
                    107: 
                    108:     if (blocknum == 0) {
                    109:         b->collation = blk[COLLA];
                    110:         b->blockcount = ((int) blk[NRBLK]) << 4;
                    111:     }
                    112:     else {        
                    113:         b->llptr = UNSIGN (blk[LLPTR]) * 65536 + UNSIGN (blk[LLPTR + 1]) * 256 + UNSIGN (blk[LLPTR + 2]);
                    114:         b->rlptr = UNSIGN (blk[RLPTR]) * 65536 + UNSIGN (blk[RLPTR + 1]) * 256 + UNSIGN (blk[RLPTR + 2]);
                    115:     }
                    116: 
                    117:     if (b->btype == DATA) {
                    118:         b->free_offset = UNSIGN (blk[OFFS]) * 256 + UNSIGN (blk[OFFS + 1]);
                    119:         b->keylen = blk[0];
                    120:     }
                    121: 
                    122:     return;
                    123:     
                    124: }
                    125: 
                    126: void ssvn_global(short action, char *key, char *data)
                    127: {
                    128:     char gb_ns[STRLEN];
                    129:     char gb_path[STRLEN];
                    130:     char gb_cpath[STRLEN];
                    131: 
                    132:     char ns_key[256];
                    133:     char ns_data[256];
                    134:     
                    135:     long blkcount;
                    136: 
                    137:     freem_ref_t *r;
                    138:     db_blockinfo *bi;
                    139:     
                    140:     r = (freem_ref_t *) malloc (sizeof (freem_ref_t));
                    141:     NULLPTRCHK(r,"ssvn_global");
                    142: 
                    143:     bi = (db_blockinfo *) malloc (sizeof (db_blockinfo));
                    144:     NULLPTRCHK(bi,"ssvn_global");
                    145:     
                    146:     mref_init (r, MREF_RT_SSV, "^$GLOBAL");
                    147:     internal_to_mref (r, key);
                    148: 
                    149:     switch (action) {
                    150: 
                    151:         case set_sym:
                    152: 
                    153:             if (strcmp (mref_get_subscript (r, 1), "NAMESPACE") != 0) {
                    154:                 merr_raise (M29);
                    155:                 goto done;
                    156:             }
                    157: 
                    158:             snprintf (ns_key, 255, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", mref_get_subscript (r, 0));
                    159:             global (set_sym, ns_key, data);
                    160: 
                    161:             goto done;
                    162: 
                    163:         case kill_sym:
                    164: 
                    165:             if (strcmp (mref_get_subscript (r, 1), "NAMESPACE") != 0) {
                    166:                 merr_raise (M29);
                    167:                 goto done;
                    168:             }
                    169: 
                    170:             snprintf (ns_key, 255, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", mref_get_subscript (r, 0));
                    171:             global (kill_sym, ns_key, data);
                    172: 
                    173:             goto done;
                    174: 
                    175:             
                    176:         
                    177:         case get_sym:
                    178: 
                    179:             if (frm_global_exists (gb_ns, gb_path, r->subscripts[0]) != TRUE) {
                    180:                 merr_raise (M7);
                    181:                 goto done;
                    182:             }
                    183: 
                    184:             if (strcmp (mref_get_subscript (r, 1), "BLOCK") == 0) {
                    185: 
                    186:                 long bn = atol (mref_get_subscript (r, 2));
                    187: 
                    188:                 stcpy (gb_cpath, gb_path);
                    189:                 stcnv_m2c (gb_cpath);
                    190: 
                    191:                 blkcount = frm_blockcount (gb_cpath);
                    192: 
                    193:                 if (bn > (blkcount - 1)) {
                    194:                     merr_raise (M38);
                    195:                     goto done;
                    196:                 }
                    197:                 
                    198:                 frm_decode_block (bi, gb_cpath, bn);
                    199:                 
                    200:                 if (strcmp (mref_get_subscript (r, 3), "TYPE") == 0) {
                    201: 
                    202:                     switch (bi->btype) {
                    203: 
                    204:                         case 2:
                    205:                             sprintf (data, "%s\201", "POINTER");
                    206:                             merr_raise (OK);
                    207:                             goto done;
                    208: 
                    209:                         case 6:
                    210:                             sprintf (data, "%s\201", "ROOT");
                    211:                             merr_raise (OK);
                    212:                             goto done;
                    213: 
                    214:                         case 8:
                    215:                             sprintf (data, "%s\201", "DATA");
                    216:                             merr_raise (OK);
                    217:                             goto done;
                    218:                     }
                    219:                             
                    220:                             
                    221:                     sprintf (data, "%d\201", bi->btype);
                    222:                     merr_raise (OK);
                    223:                     goto done;
                    224:                     
                    225:                 }
                    226:                 else if (strcmp (mref_get_subscript (r, 3), "BLOCKCOUNT") == 0) {
                    227: 
                    228:                     if (bn != 0) {
                    229:                         merr_raise (M38);
                    230:                         goto done;
                    231:                     }
                    232:                     
1.2     ! snw       233:                     sprintf (data, "%ld\201", bi->blockcount);
1.1       snw       234:                     merr_raise (OK);
                    235:                     goto done;                    
                    236:                 }
                    237:                 else if (strcmp (mref_get_subscript (r, 3), "KEYLEN") == 0) {
                    238: 
                    239:                     if (bn == 0) {
                    240:                         merr_raise (M38);
                    241:                         goto done;
                    242:                     }
                    243: 
                    244:                     sprintf (data, "%d\201", bi->keylen);
                    245:                     merr_raise (OK);
                    246:                     goto done;
                    247:                 }
                    248:                 else if (strcmp (mref_get_subscript (r, 3), "RLPTR") == 0) {
                    249: 
                    250:                     if (bn == 0) {
                    251:                         merr_raise (M38);
                    252:                         goto done;
                    253:                     }
                    254: 
                    255:                     
1.2     ! snw       256:                     sprintf (data, "%ld\201", bi->rlptr);
1.1       snw       257:                     merr_raise (OK);
                    258:                     goto done;
                    259:                 }
                    260:                 else if (strcmp (mref_get_subscript (r, 3), "OFFS") == 0) {
                    261: 
                    262:                     if (bi->btype != DATA) {
                    263:                         merr_raise (M38);
                    264:                         goto done;
                    265:                     }
                    266: 
1.2     ! snw       267:                     sprintf (data, "%ld\201", bi->free_offset);
1.1       snw       268:                     merr_raise (OK);
                    269:                     goto done;
                    270:                 }                
                    271:                 else if (strcmp (mref_get_subscript (r, 3), "LLPTR") == 0) {
                    272: 
                    273:                     if (bn == 0) {
                    274:                         merr_raise (M38);
                    275:                         goto done;                        
                    276:                     }
                    277: 
1.2     ! snw       278:                     sprintf (data, "%ld\201", bi->llptr);
1.1       snw       279:                     merr_raise (OK);
                    280:                     goto done;
                    281:                 }
                    282:                 
                    283:             }
                    284:             else if (strcmp (mref_get_subscript (r, 1), "CHARACTER") == 0) {
                    285:                 stcpy (gb_cpath, gb_path);
                    286:                 stcnv_m2c (gb_cpath);
                    287: 
                    288:                 frm_decode_block (bi, gb_cpath, 0L);
                    289: 
                    290:                 if (bi->collation == 0) {
                    291:                     sprintf (data, "M\201");
                    292:                     merr_raise (OK);
                    293:                     goto done;
                    294:                 }
                    295:                 else {
                    296:                     sprintf (data, "ASCII\201");
                    297:                     merr_raise (OK);
                    298:                     goto done;
                    299:                 }
                    300:             }
                    301:             else if (strcmp (mref_get_subscript (r, 1), "COLLATE") == 0) {
                    302:                 stcpy (gb_cpath, gb_path);
                    303:                 stcnv_m2c (gb_cpath);
                    304: 
                    305:                 frm_decode_block (bi, gb_cpath, 0L);
                    306: 
                    307:                 if (bi->collation == 0) {
                    308:                     sprintf (data, "M\201");
                    309:                     merr_raise (OK);
                    310:                     goto done;
                    311:                 }
                    312:                 else {
                    313:                     sprintf (data, "ASCII\201");
                    314:                     merr_raise (OK);
                    315:                     goto done;
                    316:                 }
                    317:             }
                    318:             else if (strcmp (mref_get_subscript (r, 1), "NAMESPACE") == 0) {
                    319:                 sprintf (data, "%s\201", gb_ns);
                    320:                 merr_raise (OK);
                    321:                 goto done;
                    322:             }
                    323:             else if (strcmp (mref_get_subscript (r, 1), "FILE") == 0) {
                    324:                 sprintf (data, "%s\201", gb_path);
                    325:                 merr_raise (OK);
                    326:                 goto done;
                    327:             }
                    328:             else if (strcmp (mref_get_subscript (r, 1), "BLOCKSIZE") == 0) {
                    329:                 sprintf (data, "%d\201", BLOCKLEN);
                    330:                 merr_raise (OK);
                    331:                 goto done;
                    332:             }
                    333:             else if (strcmp (mref_get_subscript (r, 1), "BLOCKS") == 0) {
                    334: 
                    335:                 long blockcount;
                    336:                 
                    337:                 stcpy (gb_cpath, gb_path);
                    338:                 stcnv_m2c (gb_cpath);
                    339: 
                    340:                 blockcount = frm_blockcount (gb_cpath);
                    341:                 
                    342:                 sprintf (data, "%ld\201", blockcount);
                    343: 
                    344:                 merr_raise (OK);
                    345:                 goto done;
                    346:                 
                    347:             }
                    348:             else if (strcmp (mref_get_subscript (r, 1), "BYTES") == 0) {
                    349: 
                    350:                 FILE *fp;
                    351:                 long bytecount;
                    352:                 
                    353:                 stcpy (gb_cpath, gb_path);
                    354:                 stcnv_m2c (gb_cpath);
                    355: 
                    356:                 bytecount = frm_bytecount (gb_cpath);
                    357:                 
                    358:                 sprintf (data, "%ld\201", bytecount);
                    359: 
                    360:                 merr_raise (OK);
                    361:                 goto done;
                    362:                 
                    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;
                    385:     char glofile[STRLEN];
                    386:     char goobuf[STRLEN];
                    387: 
                    388:     char mapk_buf[255];
                    389:     char mapd_buf[255];
                    390:     char old_ns[255];
                    391:     
                    392:     int ierr_sav = OK;
                    393: 
                    394:     if (global_name[0] != '^') {
                    395:         snprintf (mapk_buf, 254, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", global_name);
                    396:     }
                    397:     else {
                    398:         snprintf (mapk_buf, 254, "^$SYSTEM\202MAPPINGS\202GLOBAL\202%s\201", global_name);
                    399:     }
                    400:     
                    401:     global (get_sym, mapk_buf, mapd_buf);
                    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] != '^') {
                    438:         snprintf (glofile, STRLEN - 1, "%s/^%s", goobuf, global_name);
                    439:     }
                    440:     else {
                    441:         snprintf (glofile, STRLEN - 1, "%s/%s", goobuf, global_name);
                    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>