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