Annotation of freem/src/ssvn.c, revision 1.5
1.1 snw 1: /*
1.5 ! snw 2: * $Id: ssvn.c,v 1.4 2025/04/09 15:16:50 snw Exp $
1.1 snw 3: * structured system variable support
4: *
5: *
1.2 snw 6: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 7: * Copyright (C) 1998 MUG Deutschland
1.3 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: ssvn.c,v $
1.5 ! snw 27: * Revision 1.4 2025/04/09 15:16:50 snw
! 28: * Fix buffer overruns in mref_to_external and ssvn.c
! 29: *
1.4 snw 30: * Revision 1.3 2025/03/09 19:50:47 snw
31: * Second phase of REUSE compliance and header reformat
32: *
1.3 snw 33: *
34: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
35: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 36: **/
37:
38: #include <stdio.h>
39: #include <stdlib.h>
40: #include <string.h>
41: #include <sys/types.h>
42: #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
43: # include <sys/timeb.h>
44: #endif
45: #include "mpsdef.h"
46: #include "freem.h"
47: #include "mref.h"
48: #include "mdebug.h"
49:
50: #ifdef USE_SYS_TIME_H
51: # include <sys/time.h>
52: #endif
53:
54: typedef struct ssvn_lut {
55: const char *input_name;
56: const char *canonical_name;
57: } ssvn_lut;
58:
59: ssvn_lut ssv_tab[] = {
60: {"^$C", "^$CHARACTER"},
61: {"^$CHARACTER", "^$CHARACTER"},
62: {"^$D", "^$DEVICE"},
63: {"^$DEVICE", "^$DEVICE"},
64: {"^$DI", "^$DISPLAY"},
65: {"^$DISPLAY", "^$DISPLAY"},
66: {"^$E", "^$EVENT"},
67: {"^$EVENT", "^$EVENT"},
68: {"^$G", "^$GLOBAL"},
69: {"^$GLOBAL", "^$GLOBAL"},
70: {"^$J", "^$JOB"},
71: {"^$JOB", "^$JOB"},
72: {"^$LI","^$LIBRARY"},
73: {"^$LIBRARY","^$LIBRARY"},
74: {"^$L", "^$LOCK"},
75: {"^$LOCK", "^$LOCK"},
76: {"^$O", "^$OBJECT"},
77: {"^$OBJECT", "^$OBJECT"},
78: {"^$R", "^$ROUTINE"},
79: {"^$ROUTINE", "^$ROUTINE"},
80: {"^$S", "^$SYSTEM"},
81: {"^$SYSTEM", "^$SYSTEM"},
82: {"^$W", "^$WINDOW"},
83: {"^$WINDOW", "^$WINDOW"},
84: {"^$ZF", "^$ZFILE"},
85: {"^$ZFILE", "^$ZFILE"},
86: {"^$ZFR", "^$ZFREEM"},
87: {"^$ZFREEM", "^$ZFREEM"},
88: {"^$ZD", "^$ZDIRECTORY"},
89: {"^$ZDIRECTORY", "^$ZDIRECTORY"},
90: {"^$ZO", "^$ZOS"},
91: {"^$ZOS", "^$ZOS"},
92: {"^$ZP", "^$ZPROCESS"},
93: {"^$ZPROCESS", "^$ZPROCESS"},
94: {"^$ZR", "^$ZRPI"},
95: {"^$ZRPI", "^$ZRPI"},
96: {NULL, NULL}
97: };
98:
99:
100: void ssvn (short action, char *key, char *data);
101: void ssvn_normalize_key (char *key);
102:
103: /* structured system variable management */
104: /* set_sym get_sym */
105: /* kill_sym $data */
106: /* kill_all $fra_order */
107: /* killexcl $fra_query */
108: /* new_sym */
109: /* new_all getinc */
110: /* newexcl */
111: /* killone m_alias */
112: /* merge_sym zdata */
113: void ssvn (short action, char *key, char *data)
114: {
115: int i, j;
116: char ch;
117: char ptmp[256];
1.4 snw 118: char sbuf[256];
1.1 snw 119:
1.5 ! snw 120: snprintf (sbuf, sizeof (sbuf) - 1, " C CHARACTER D DEVICE DI DISPLAY E EVENT G GLOBAL J JOB LI LIBRARY L LOCK O OBJECT P R ROUTINE S SYSTEM W WINDOW \201");
1.4 snw 121:
122:
1.1 snw 123: if ((rtn_dialect () == D_M77) ||
124: (rtn_dialect () == D_M84) ||
125: (rtn_dialect () == D_M90)) {
126: merr_raise (NOSTAND);
127: return;
128: }
129:
130: i = 1;
131: j = 2;
132:
133: while ((ch = key[j]) != EOL) {
134:
135: if (ch >= 'a' && ch <= 'z') ch -= 32;
136: if (ch == DELIM) break;
137:
138: ptmp[i++] = ch;
139: j++;
140:
141: }
142:
143: ptmp[0] = SP;
144: ptmp[i++] = SP;
145: ptmp[i] = EOL;
146:
147: ssvn_normalize_key (key);
148:
149: if (dbg_enable_watch && (action == set_sym)) dbg_fire_watch (key);
150:
151: if (merr () > OK) return;
152:
153:
154: if ((ptmp[1] != 'Z') && (ptmp[1] != 'Y')) {
155:
1.4 snw 156: if (find (sbuf, ptmp) == FALSE) {
1.1 snw 157: merr_raise (M60);
158: return;
159: }
160:
161: switch (ptmp[1]) {
162:
163: case 'C': /* ^$CHARACTER ssvn */
164: ssvn_character (action, key, data);
165: break;
166:
167: case 'D': /* ^$DEVICE and ^$DISPLAY ssvns */
168: switch(ptmp[2]) {
169:
170: case 'E': /* ^$DEVICE */
171: ssvn_device (action, key, data);
172: break;
173:
174: case 'I': /* ^$DISPLAY */
175: ssvn_display (action, key, data);
176: break;
177:
178: default:
179: merr_raise (INVREF);
180: break;
181: }
182:
183: break;
184:
185: case 'E': /* ^$EVENT ssvn */
186: ssvn_event (action, key, data);
187: break;
188:
189: case 'G': /* ^$GLOBAL ssvn */
190: ssvn_global (action, key, data);
191: break;
192:
193: case 'J': /* ^$JOB ssvn */
194: ssvn_job (action, key, data);
195: break;
196:
197: case 'L': /* ^$LIBRARY/^$LOCK ssvns */
198: if (ptmp[2] == 'I') {
199: ssvn_library (action, key, data);
200: }
201: else {
202: ssvn_lock (action, key, data);
203: }
204: break;
205:
206: case 'O':
207: ssvn_object (action, key, data);
208: break;
209:
210: case 'R': /* ^$ROUTINE ssvn */
211: ssvn_routine (action, key, data);
212: break;
213:
214: case 'S': /* ^$SYSTEM ssvn */
215: ssvn_system (action, key, data);
216: break;
217:
218: case 'W': /* ^$WINDOW ssvn */
219: ssvn_window (action, key, data);
220: break;
221:
222: default:
223: merr_raise (INVREF);
224: break;
225: }
226: }
227: else { /* implementation-specific ssvns */
228: ssvn_z (action, key, data);
229: return;
230: }
231:
232: return;
233: }
234:
235: /* convert SSVN names to canonical form (all caps, full-length name) */
236: void ssvn_normalize_key (char *key)
237: {
238: freem_ref_t *ref;
239: char *new_key;
240: ssvn_lut *p;
241: register int i;
242:
243:
244: ref = malloc (sizeof (freem_ref_t));
245: NULLPTRCHK(ref,"ssvn_normalize_key");
246:
247: mref_init (ref, MREF_RT_SSVN, "");
248: internal_to_mref (ref, key);
249:
250: for (i = 0; i < strlen (ref->name); i++) {
251: if (ref->name[i] >= 'a' && ref->name[i] <= 'z') ref->name[i] -= 32;
252: }
253:
254:
255: for (p = ssv_tab; p->input_name != NULL; ++p) {
256:
257: if (strcmp (ref->name, p->input_name) == 0) {
258:
259: strcpy (ref->name, p->canonical_name);
260:
261: new_key = mref_to_internal (ref);
262: stcpy (key, new_key);
263:
264: free (ref);
265: free (new_key);
266:
267: merr_clear ();
268: return;
269:
270: }
271:
272: }
273:
274: merr_raise (M60);
275:
276: free (ref);
277:
278: return;
279:
280: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>