Annotation of freem/src/merr.c, revision 1.5
1.1 snw 1: /*
1.5 ! snw 2: * $Id: merr.c,v 1.4 2025/04/09 19:52:02 snw Exp $
1.1 snw 3: * stuff for handling program bogosity
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: merr.c,v $
1.5 ! snw 27: * Revision 1.4 2025/04/09 19:52:02 snw
! 28: * Eliminate as many warnings as possible while building with -Wall
! 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 <string.h>
39: #include <stdlib.h>
40:
41: #include "mpsdef.h"
42: #include "merr.h"
43: #include "jobtab.h"
44:
45: merr_stackent merr_stack[NESTLEVLS + 1];
46: char etrap[256];
47: char ecode[256];
48: char user_ecode[256];
49: int estack;
50: int etrap_lvl = 0;
51: int merr_topstk = 0;
52:
53: typedef struct err_lut {
54: int ecode;
55: const char *canonical_name;
56: } err_lut;
57:
58: err_lut errtab[] = {
59: {0, "ZOK"},
60: {1, "ZINRPT"},
61: {2, "ZBKERR"},
62: {3, "ZNOSTAND"},
63: {4, "ZUNDEF"},
64: {5, "ZLBLUNDEF"},
65: {6, "ZMISSOPD"},
66: {7, "ZMISSOP"},
67: {8, "ZILLOP"},
68: {9, "ZQUOTER"},
69: {10, "ZCOMMAER"},
70: {11, "ZASSIGNER"},
71: {12, "ZARGER"},
72: {13, "ZSPACER"},
73: {14, "ZBRAER"},
74: {15, "ZLVLERR"},
75: {16, "ZDIVER"},
76: {17, "ZILLFUN"},
77: {18, "ZFUNARG"},
78: {19, "ZZTERR"},
79: {20, "ZNEXTER"},
80: {21, "ZSELER"},
81: {22, "ZCMMND"},
82: {23, "ZARGLIST"},
83: {24, "ZINVEXPR"},
84: {25, "ZINVREF"},
85: {26, "ZMXSTR"},
86: {27, "ZTOOPARA"},
87: {28, "ZNOPEN"},
88: {29, "ZNODEVICE"},
89: {30, "ZPROTECT"},
90: {31, "ZGLOBER"},
91: {32, "ZFILERR"},
92: {33, "ZPGMOV"},
93: {34, "ZSTKOV"},
94: {35, "ZSTORE"},
95: {36, "ZNOREAD"},
96: {37, "ZNOWRITE"},
97: {38, "ZNOPGM"},
98: {39, "ZNAKED"},
99: {40, "ZSBSCR"},
100: {41, "ZISYNTX"},
101: {42, "ZDBDGD"},
102: {43, "ZKILLER"},
103: {44, "ZHUPER"},
104: {45, "ZMXNUM"},
105: {46, "ZNOVAL"},
106: {47, "ZTYPEMISMATCH"},
107: {48, "ZMEMOV"},
108: {49, "ZNAMERES"},
109: {50, "ZSCKCREAT"},
110: {51, "ZSCKIFAM"},
111: {52, "ZSCKITYP"},
112: {53, "ZSCKIPRT"},
113: {54, "ZSCKCERR"},
114: {55, "ZSCKAERR"},
115: {56, "ZSCKACON"},
116: {57, "ZSCKNCON"},
117: {58, "ZSCKEOPT"},
118: {59, "ZSCKERCV"},
119: {60, "ZSCKESND"},
120: {61, "ZNORPI"},
121: {62, "ZCREDEF"},
122: {63, "ZCMODIFY"},
123: {64, "ZFILEXWR"},
124: {65, "ZINEWMUL"},
125: {66, "ZINVHORO"},
126: {67, "ZTYPMISMATCH"},
127: {68, "ZINVTYPE"},
128: {69, "ZINVLIBOPT"},
129: {80, "ZECODEINV"},
130: {81, "ZASSERT"},
131: {82, "ZUSERERR"},
132: {83, "ZOBJFLDACCV"},
133: {84, "ZOBJCONFLICT"},
134: {85, "ZOBJPRIVOVFL"},
135: {86, "ZOBJACINVALID"},
136: {128, "ZSYNTERR"},
137: {140, "M1"},
138: {141, "M2"},
139: {142, "M3"},
140: {143, "M4"},
141: {144, "M5"},
142: {145, "M6"},
143: {146, "M7"},
144: {147, "M8"},
145: {148, "M9"},
146: {149, "M10"},
147: {150, "M11"},
148: {151, "M12"},
149: {152, "M13"},
150: {153, "M14"},
151: {154, "M15"},
152: {155, "M16"},
153: {156, "M17"},
154: {157, "M18"},
155: {158, "M19"},
156: {159, "M20"},
157: {160, "M21"},
158: {161, "M22"},
159: {162, "M23"},
160: {163, "M24"},
161: {164, "M25"},
162: {165, "M26"},
163: {166, "M27"},
164: {167, "M28"},
165: {168, "M29"},
166: {169, "M30"},
167: {170, "M31"},
168: {171, "M32"},
169: {172, "M33"},
170: {173, "M34"},
171: {174, "M35"},
172: {175, "M36"},
173: {176, "M37"},
174: {177, "M38"},
175: {178, "M39"},
176: {179, "M40"},
177: {180, "M41"},
178: {181, "M42"},
179: {182, "M43"},
180: {183, "M44"},
181: {184, "M45"},
182: {185, "M46"},
183: {186, "M47"},
184: {187, "M48"},
185: {188, "M49"},
186: {189, "M50"},
187: {190, "M51"},
188: {191, "M52"},
189: {192, "M53"},
190: {193, "M54"},
191: {194, "M55"},
192: {195, "M56"},
193: {196, "M57"},
194: {197, "M58"},
195: {198, "M59"},
196: {199, "M60"},
197: {214, "M75"},
198: {240, "M101"},
199: {241, "M102"},
200: {242, "M103"},
201: {243, "M104"},
202: {254, "ZASYNC"},
203: {255, "ZCTRLB"},
204: {-1, NULL}
205: };
206:
207: inline int merr_raise(int num)
208: {
209:
210: if (merr_in_break ()) {
211: ierr = num - CTRLB;
212: }
213: else {
214: ierr = num;
215: }
216:
217: if (num != OK) {
218: merr_set_ecode_ierr ();
219:
220: stcpy (merr_stack[nstx].MCODE, code);
221: stcpy (merr_stack[nstx].ECODE, ecode);
222:
223: if (direct_mode == 1 && nstx == 0) {
224: stcpy (merr_stack[nstx].PLACE, "@\201\0");
225: }
226: else {
227: if (!rtn_get_offset (merr_stack[nstx].PLACE)) {
228: stcpy (merr_stack[nstx].PLACE, "???\201");
229: }
230: }
231:
232: if (nstx > merr_topstk) merr_topstk = nstx;
233: }
234:
235: return ierr;
236: }
237:
238: inline int merr(void)
239: {
240: return ierr < OK ? ierr + CTRLB : ierr;
241: }
242:
243: short merr_in_break(void)
244: {
245: if (ierr < OK) {
246: return TRUE;
247: }
248: else {
249: return FALSE;
250: }
251: }
252:
253: void merr_set_break(void)
254: {
255: if (!merr_in_break ()) {
256: ierr = ierr - CTRLB;
257: }
258: }
259:
260: void merr_clear_break(void)
261: {
262: if (merr_in_break ()) {
263: ierr = ierr + CTRLB;
264: }
265: }
266:
267: int merr_num_to_code (int num, char *code)
268: {
269:
270: err_lut *p;
271:
272: for (p = errtab; p->canonical_name != NULL; ++p) {
273:
274: if (p->ecode == num) {
275: strcpy (code, p->canonical_name);
276: return 1;
277: }
278:
279: }
280:
281: return -1;
282:
283: }
284:
285: int merr_code_to_num (char *code)
286: {
287:
288: err_lut *p;
289:
290: for (p = errtab; p->canonical_name != NULL; ++p) {
291:
292: if (strcmp (p->canonical_name, code) == 0) {
293: return p->ecode;
294: }
295:
296: }
297:
298: return -1;
299:
300: }
301:
302: void merr_set_ecode_ierr (void)
303: {
304: char *cod;
305: char *t;
306:
1.5 ! snw 307: cod = (char *) malloc (MERR_COD_LENGTH * sizeof (char));
1.1 snw 308: NULLPTRCHK(cod,"merr_set_ecode_ierr");
309:
1.5 ! snw 310: t = (char *) malloc (MERR_COD_LENGTH * sizeof (char));
1.1 snw 311: NULLPTRCHK(t,"merr_set_ecode_ierr");
312:
313: if ((merr_num_to_code (merr (), cod)) == -1) goto done;
314:
1.5 ! snw 315: snprintf (t, MERR_COD_LENGTH - 1, ",%s,\201", cod);
1.1 snw 316: merr_set_ecode (t);
317:
318: job_set_ecode (pid, cod);
319:
320: done:
321:
322: free (cod);
323: free (t);
324: return;
325:
326: }
327:
328: int merr_set_ecode (char *t_code)
329: {
330: int ec;
331: char *tmp;
332:
333: if (t_code[0] == '\201') {
334: stcpy (ecode, "\201");
335: return 0;
336: }
337:
338: if (t_code[1] != 'M' && t_code[1] != 'Z' && t_code[1] != 'U') {
339: return M101;
340: }
341:
342: stcpy (ecode, t_code);
343:
344: if (stcmp (t_code, "") == 0) {
345: merr_clear ();
346: stcpy (t_code, ",ZOK,");
347: stcpy (user_ecode, t_code);
348: }
349:
350: tmp = strtok (t_code, ",");
351:
352: /* caller may set ierr with return value */
353: if (ecode[1] == 'U') {
354: stcpy (user_ecode, ecode);
355: return USERERR;
356: }
357: else {
358: ec = merr_code_to_num (tmp);
359: return (ec);
360: }
361: }
362:
363: void merr_dump (int num, char *rtn, char *nsn, char *tcod, int tpos)
364: {
365: char *tbuf;
366: char *dbuf;
367: char *nem;
368: char *nrt;
369: char *real_ecode;
370: err_lut *p;
371:
372: tbuf = (char *) malloc (STRLEN * sizeof (char));
373: NULLPTRCHK(tbuf,"merr_dump");
374:
375: dbuf = (char *) malloc (STRLEN * sizeof (char));
376: NULLPTRCHK(dbuf,"merr_dump");
377:
378: nem = (char *) malloc (STRLEN * sizeof (char));
379: NULLPTRCHK(nem,"merr_dump");
380:
381: nrt = (char *) malloc (STRLEN * sizeof (char));
382: NULLPTRCHK(nrt,"merr_dump");
383:
384: real_ecode = (char *) malloc (STRLEN * sizeof (char));
385: NULLPTRCHK(real_ecode,"merr_dump");
386:
387: stcpy (nrt, rtn);
388: stcnv_m2c (nrt);
389:
390: stcpy (nem, errmes[num]);
391: stcnv_m2c (nem);
392:
393: for (p = errtab; p->canonical_name != NULL; ++p) {
394:
395: if (p->ecode == num) {
396:
397: if (strcmp (p->canonical_name, "ZUSERERR") == 0) {
398: stcpy (real_ecode, &user_ecode[1]);
399: stcnv_m2c (real_ecode);
400: real_ecode [strlen (real_ecode) - 1] = NUL;
401:
1.5 ! snw 402: snprintf (tbuf, STRLEN - 1, "^$JOB\202%d\202USER_ERRORS\202%s\201", pid, &user_ecode[1]);
1.1 snw 403: tbuf [stlen (tbuf) - 1] = '\201';
404:
405: global (get_sym, tbuf, dbuf);
406:
407: if (merr () == OK) {
408: stcpy (nem, dbuf);
409: stcnv_m2c (nem);
410: }
411: else {
412: merr_clear ();
413: }
414:
415: }
416: else {
417: strcpy (real_ecode, p->canonical_name);
418: }
419:
1.4 snw 420:
421:
1.1 snw 422: if (!stlen (err_suppl)) {
1.5 ! snw 423: snprintf (tbuf, STRLEN - 1, "\r\n>> Error %s: %s in %s.%s::%s [$STACK = %d]\r\n\201", real_ecode, nem, shm_env, nsn, nrt, nstx);
1.1 snw 424: }
425: else {
426: stcnv_m2c (err_suppl);
1.5 ! snw 427: snprintf (tbuf, STRLEN - 1, "\r\n>> Error %s: %s (%s) in %s::%s [$STACK = %d]\r\n\201", real_ecode, nem, err_suppl, nsn, nrt, nstx);
1.1 snw 428: err_suppl[0] = EOL;
429: }
430: write_m (tbuf);
431: write_m (">> \201");
432: write_m (tcod);
433: write_m ("\r\n\201");
434: write_t (tpos);
435: write_m ("^\201");
436:
437: goto done;
438: }
439:
440: }
441:
442:
443: done:
444:
445: free (tbuf);
446: free (dbuf);
447: free (nem);
448: free (nrt);
449: free (real_ecode);
450:
451: return;
452: }
453:
454:
455: void merr_set_iochan_err(int channel, short frm_err, char *err_text)
456: {
457: if (channel > MAXDEV || channel < 0) {
458: merr_raise (ARGLIST);
459: return;
460: }
461:
462: devstat[channel].mdc_err = 1;
463: devstat[channel].frm_err = frm_err;
464:
465: strncpy (devstat[channel].err_txt, err_text, 79);
466:
467: return;
468: }
469:
470: void merr_clear_iochan_err(int channel)
471: {
472: if (channel > MAXDEV || channel < 0) {
473: merr_raise (ARGLIST);
474: return;
475: }
476:
477: devstat[channel].mdc_err = 1;
478: devstat[channel].frm_err = OK;
479: devstat[channel].err_txt[0] = '\0';
480:
481: return;
482:
483: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>