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