Annotation of freem/src/ssvn_global.c, revision 1.1
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:
! 233: sprintf (data, "%d\201", bi->blockcount);
! 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:
! 256: sprintf (data, "%d\201", bi->rlptr);
! 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:
! 267: sprintf (data, "%d\201", bi->free_offset);
! 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:
! 278: sprintf (data, "%d\201", bi->llptr);
! 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>