Annotation of freem/src/ssvn_global.c, revision 1.1.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>