Annotation of freem/src/ssvn_global.c, revision 1.7
1.1 snw 1: /*
1.7 ! snw 2: * $Id: ssvn_global.c,v 1.6 2025/04/09 19:52:02 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.7 ! snw 27: * Revision 1.6 2025/04/09 19:52:02 snw
! 28: * Eliminate as many warnings as possible while building with -Wall
! 29: *
1.6 snw 30: * Revision 1.5 2025/03/22 18:43:54 snw
31: * Make STRLEN 255 chars and add BIGSTR macro for larger buffers
32: *
1.5 snw 33: * Revision 1.4 2025/03/09 19:50:47 snw
34: * Second phase of REUSE compliance and header reformat
35: *
1.4 snw 36: *
37: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
38: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 39: **/
40:
41: #include <stdio.h>
42: #include <unistd.h>
43: #include <fcntl.h>
44: #include <string.h>
45: #include <stdlib.h>
46:
47: #include "mpsdef.h"
48: #include "mref.h"
49: #include "iniconf.h"
50: #include "namespace.h"
51:
52: #define DATALIM (BLOCKLEN-11)
53: #define LLPTR (BLOCKLEN-10)
54: #define NRBLK LLPTR
55: #define COLLA (BLOCKLEN- 7)
56: #define RLPTR (BLOCKLEN- 6)
57: #define FREE RLPTR
58: #define BTYP (BLOCKLEN- 3)
59: #define OFFS (BLOCKLEN- 2)
60:
61: /* length of blockpointers in bytes */
62: #define PLEN 3
63:
64: #define EMPTY 0
65: #define FBLK 1
66: #define POINTER 2
67: #define BOTTOM 6
68: #define DATA 8
69:
70: typedef struct db_blockinfo {
71:
72: int keylen;
73: int keyoffs;
74: char key[STRLEN];
75: int datalen;
76: char data[STRLEN];
77:
78: long llptr;
79: long rlptr;
80:
81: long blockcount;
82: int collation;
83:
84: int btype;
85: long free_offset;
86:
87: } db_blockinfo;
88:
89: short frm_global_exists(char *, char *, char *);
90: void frm_decode_block(db_blockinfo *, char *, long);
91: long frm_blockcount(char *);
92: long frm_bytecount(char *);
93:
94: void frm_decode_block(db_blockinfo *b, char *gbpth, long blocknum)
95: {
96:
97: int fd;
98: char blk[BLOCKLEN];
99:
100:
101: fd = open (gbpth, O_RDONLY);
102: lseek (fd, blocknum * BLOCKLEN, SEEK_SET);
103: read (fd, blk, BLOCKLEN);
104:
105: close (fd);
106:
107: b->btype = blk[BTYP];
108:
109: if (blocknum == 0) {
110: b->collation = blk[COLLA];
111: b->blockcount = ((int) blk[NRBLK]) << 4;
112: }
113: else {
114: b->llptr = UNSIGN (blk[LLPTR]) * 65536 + UNSIGN (blk[LLPTR + 1]) * 256 + UNSIGN (blk[LLPTR + 2]);
115: b->rlptr = UNSIGN (blk[RLPTR]) * 65536 + UNSIGN (blk[RLPTR + 1]) * 256 + UNSIGN (blk[RLPTR + 2]);
116: }
117:
118: if (b->btype == DATA) {
119: b->free_offset = UNSIGN (blk[OFFS]) * 256 + UNSIGN (blk[OFFS + 1]);
120: b->keylen = blk[0];
121: }
122:
123: return;
124:
125: }
126:
127: void ssvn_global(short action, char *key, char *data)
128: {
129: char gb_ns[STRLEN];
1.5 snw 130: char gb_path[PATHLEN];
131: char gb_cpath[PATHLEN];
1.1 snw 132:
1.5 snw 133: char ns_key[STRLEN];
1.1 snw 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));
1.7 ! snw 159: symtab_shm (set_sym, ns_key, data);
1.1 snw 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:
1.5 snw 170: snprintf (ns_key, STRLEN, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", mref_get_subscript (r, 0));
1.7 ! snw 171: symtab_shm (kill_sym, ns_key, data);
1.1 snw 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: long bytecount;
350:
351: stcpy (gb_cpath, gb_path);
352: stcnv_m2c (gb_cpath);
353:
354: bytecount = frm_bytecount (gb_cpath);
355:
356: sprintf (data, "%ld\201", bytecount);
357:
358: merr_raise (OK);
1.6 snw 359: goto done;
1.1 snw 360: }
361:
362: merr_raise (M38);
363: goto done;
364:
365:
366: default:
367: merr_raise (INVREF);
368: goto done;
369:
370: }
371:
372: done:
373:
374: free (r);
375:
376: return;
377: }
378:
379: short frm_global_exists(char *gbl_namespace, char *gbl_path, char *global_name)
380: {
381: char *gpth;
1.5 snw 382: char glofile[PATHLEN];
1.1 snw 383: char goobuf[STRLEN];
384:
1.5 snw 385: char mapk_buf[STRLEN];
386: char mapd_buf[STRLEN];
387: char old_ns[STRLEN];
1.1 snw 388:
389: int ierr_sav = OK;
390:
391: if (global_name[0] != '^') {
1.5 snw 392: snprintf (mapk_buf, STRLEN, "^$SYSTEM\202MAPPINGS\202GLOBAL\202^%s\201", global_name);
1.1 snw 393: }
394: else {
1.5 snw 395: snprintf (mapk_buf, STRLEN, "^$SYSTEM\202MAPPINGS\202GLOBAL\202%s\201", global_name);
1.1 snw 396: }
397:
1.7 ! snw 398: symtab_shm (get_sym, mapk_buf, mapd_buf);
1.1 snw 399:
400: stcnv_m2c (mapd_buf);
401:
402: if (merr () == OK) {
403:
404: strncpy (old_ns, nsname, 255);
405: set_namespace (mapd_buf, 0);
406:
407: gpth = (char *) malloc (PATHLEN * sizeof (char));
408: NULLPTRCHK(gpth,"frm_global_exists");
409:
410: strncpy (gpth, glopath, PATHLEN - 1);
411: strncpy (gbl_namespace, mapd_buf, 254);
412:
413: set_namespace (old_ns, 0);
414:
415: }
416: else {
417:
418: merr_raise (ierr_sav);
419:
420: if (global_name[0] == '%') {
421: gpth = gloplib;
422: sprintf (gbl_namespace, "SYSTEM");
423: }
424: else {
425: gpth = glopath;
426: sprintf (gbl_namespace, "%s\201", nsname);
427: }
428:
429: }
430:
431: stcpy (goobuf, gpth);
432: stcnv_m2c (goobuf);
433:
434: if (global_name[0] != '^') {
1.5 snw 435: snprintf (glofile, PATHLEN, "%s/^%s", goobuf, global_name);
1.1 snw 436: }
437: else {
1.5 snw 438: snprintf (glofile, PATHLEN, "%s/%s", goobuf, global_name);
1.1 snw 439: }
440:
441: strcpy (gbl_path, glofile);
442: stcnv_c2m (gbl_path);
443:
444: if (file_exists (glofile)) {
445: return TRUE;
446: }
447: else {
448: return FALSE;
449: }
450:
451:
452: }
453:
454: long frm_blockcount(char *gbl_path)
455: {
456: FILE *fp;
457: long blockcount;
458:
459:
460: fp = fopen (gbl_path, "r");
461: fseek (fp, 0L, SEEK_END);
462: blockcount = ftell (fp) / BLOCKLEN;
463: fclose (fp);
464:
465:
466: return blockcount;
467: }
468:
469: long frm_bytecount(char *gbl_path)
470: {
471: FILE *fp;
472: long bytecount;
473:
474:
475: fp = fopen (gbl_path, "r");
476: fseek (fp, 0L, SEEK_END);
477: bytecount = ftell (fp);
478: fclose (fp);
479:
480: return bytecount;
481: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>