File:  [Coherent Logic Development] / freem / src / merr.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (3 weeks, 2 days ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

/*
 *   $Id: merr.c,v 1.3 2025/03/09 19:50:47 snw Exp $
 *    stuff for handling program bogosity
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 *   $Log: merr.c,v $
 *   Revision 1.3  2025/03/09 19:50:47  snw
 *   Second phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

#include <string.h>
#include <stdlib.h>

#include "mpsdef.h"
#include "merr.h"
#include "jobtab.h"

merr_stackent merr_stack[NESTLEVLS + 1];
char etrap[256];
char ecode[256];
char user_ecode[256];
int estack;
int etrap_lvl = 0;
int merr_topstk = 0;

typedef struct err_lut {
    int ecode;
    const char *canonical_name;
} err_lut;

err_lut errtab[] = {
    {0, "ZOK"},
    {1, "ZINRPT"},
    {2, "ZBKERR"},
    {3, "ZNOSTAND"},
    {4, "ZUNDEF"},
    {5, "ZLBLUNDEF"},
    {6, "ZMISSOPD"},
    {7, "ZMISSOP"},
    {8, "ZILLOP"},
    {9, "ZQUOTER"},
    {10, "ZCOMMAER"},
    {11, "ZASSIGNER"},
    {12, "ZARGER"},
    {13, "ZSPACER"},
    {14, "ZBRAER"},
    {15, "ZLVLERR"},
    {16, "ZDIVER"},
    {17, "ZILLFUN"},
    {18, "ZFUNARG"},
    {19, "ZZTERR"},
    {20, "ZNEXTER"},
    {21, "ZSELER"},
    {22, "ZCMMND"},
    {23, "ZARGLIST"},
    {24, "ZINVEXPR"},
    {25, "ZINVREF"},
    {26, "ZMXSTR"},
    {27, "ZTOOPARA"},
    {28, "ZNOPEN"},
    {29, "ZNODEVICE"},
    {30, "ZPROTECT"},
    {31, "ZGLOBER"},
    {32, "ZFILERR"},
    {33, "ZPGMOV"},
    {34, "ZSTKOV"},
    {35, "ZSTORE"},
    {36, "ZNOREAD"},
    {37, "ZNOWRITE"},
    {38, "ZNOPGM"},
    {39, "ZNAKED"},
    {40, "ZSBSCR"},
    {41, "ZISYNTX"},
    {42, "ZDBDGD"},
    {43, "ZKILLER"},
    {44, "ZHUPER"},
    {45, "ZMXNUM"},
    {46, "ZNOVAL"},
    {47, "ZTYPEMISMATCH"},
    {48, "ZMEMOV"},
    {49, "ZNAMERES"},
    {50, "ZSCKCREAT"},
    {51, "ZSCKIFAM"},
    {52, "ZSCKITYP"},
    {53, "ZSCKIPRT"},
    {54, "ZSCKCERR"},
    {55, "ZSCKAERR"},
    {56, "ZSCKACON"},
    {57, "ZSCKNCON"},
    {58, "ZSCKEOPT"},
    {59, "ZSCKERCV"},
    {60, "ZSCKESND"},
    {61, "ZNORPI"},
    {62, "ZCREDEF"},
    {63, "ZCMODIFY"},
    {64, "ZFILEXWR"},
    {65, "ZINEWMUL"},
    {66, "ZINVHORO"},
    {67, "ZTYPMISMATCH"},
    {68, "ZINVTYPE"},
    {69, "ZINVLIBOPT"},
    {80, "ZECODEINV"},
    {81, "ZASSERT"},
    {82, "ZUSERERR"},
    {83, "ZOBJFLDACCV"},
    {84, "ZOBJCONFLICT"},
    {85, "ZOBJPRIVOVFL"},
    {86, "ZOBJACINVALID"},
    {128, "ZSYNTERR"},
    {140, "M1"},
    {141, "M2"},
    {142, "M3"},
    {143, "M4"},
    {144, "M5"},
    {145, "M6"},
    {146, "M7"},
    {147, "M8"},
    {148, "M9"},
    {149, "M10"},
    {150, "M11"},
    {151, "M12"},
    {152, "M13"},
    {153, "M14"},
    {154, "M15"},
    {155, "M16"},
    {156, "M17"},
    {157, "M18"},
    {158, "M19"},
    {159, "M20"},
    {160, "M21"},
    {161, "M22"},
    {162, "M23"},
    {163, "M24"},
    {164, "M25"},
    {165, "M26"},
    {166, "M27"},
    {167, "M28"},
    {168, "M29"},
    {169, "M30"},
    {170, "M31"},
    {171, "M32"},
    {172, "M33"},
    {173, "M34"},
    {174, "M35"},
    {175, "M36"},
    {176, "M37"},
    {177, "M38"},
    {178, "M39"},
    {179, "M40"},
    {180, "M41"},
    {181, "M42"},
    {182, "M43"},
    {183, "M44"},
    {184, "M45"},
    {185, "M46"},
    {186, "M47"},
    {187, "M48"},
    {188, "M49"},
    {189, "M50"},
    {190, "M51"},
    {191, "M52"},
    {192, "M53"},
    {193, "M54"},
    {194, "M55"},
    {195, "M56"},
    {196, "M57"},
    {197, "M58"},
    {198, "M59"},
    {199, "M60"},
    {214, "M75"},
    {240, "M101"},
    {241, "M102"},
    {242, "M103"},
    {243, "M104"},
    {254, "ZASYNC"},
    {255, "ZCTRLB"},
    {-1, NULL}
};

inline int merr_raise(int num)
{
    char place[256];
    char cod[256];
    
    if (merr_in_break ()) {
        ierr = num - CTRLB;
    }
    else {
        ierr = num;
    }

    if (num != OK) {
        merr_set_ecode_ierr ();
        
        stcpy (merr_stack[nstx].MCODE, code);
        stcpy (merr_stack[nstx].ECODE, ecode);
        
        if (direct_mode == 1 && nstx == 0) {
            stcpy (merr_stack[nstx].PLACE, "@\201\0");
        }
        else {
            if (!rtn_get_offset (merr_stack[nstx].PLACE)) {
                stcpy (merr_stack[nstx].PLACE, "???\201");
            }
        }
       
        if (nstx > merr_topstk) merr_topstk = nstx;
    }
    
    return ierr;    
}

inline int merr(void)
{
    return ierr < OK ? ierr + CTRLB : ierr;
}

short merr_in_break(void)
{
    if (ierr < OK) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}

void merr_set_break(void)
{
    if (!merr_in_break ()) {
        ierr = ierr - CTRLB;
    }
}

void merr_clear_break(void)
{
    if (merr_in_break ()) {
        ierr = ierr + CTRLB;
    }
}

int merr_num_to_code (int num, char *code)
{

    err_lut *p;

    for (p = errtab; p->canonical_name != NULL; ++p) {

        if (p->ecode == num) {
            strcpy (code, p->canonical_name);            
            return 1;
        }

    }

    return -1;

}

int merr_code_to_num (char *code)
{

    err_lut *p;

    for (p = errtab; p->canonical_name != NULL; ++p) {

        if (strcmp (p->canonical_name, code) == 0) {            
            return p->ecode;
        }

    }
    
    return -1;

}

void merr_set_ecode_ierr (void)
{
    char *cod;
    char *t;
    
    cod = (char *) malloc (256 * sizeof (char));
    NULLPTRCHK(cod,"merr_set_ecode_ierr");
    
    t = (char *) malloc (256 * sizeof (char));
    NULLPTRCHK(t,"merr_set_ecode_ierr");
    
    if ((merr_num_to_code (merr (), cod)) == -1) goto done;

    snprintf (t, 255, ",%s,\201", cod);
    merr_set_ecode (t);
    
    job_set_ecode (pid, cod);
    
done:

    free (cod);
    free (t);
    return;

}

int merr_set_ecode (char *t_code)
{
    int ec;
    char *tmp;
    
    if (t_code[0] == '\201') {
        stcpy (ecode, "\201");
        return 0;
    }

    if (t_code[1] != 'M' && t_code[1] != 'Z' && t_code[1] != 'U') { 
        return M101;
    }

    stcpy (ecode, t_code);

    if (stcmp (t_code, "") == 0) {
        merr_clear ();
        stcpy (t_code, ",ZOK,");  
        stcpy (user_ecode, t_code);      
    }

    tmp = strtok (t_code, ",");    

    /* caller may set ierr with return value */
    if (ecode[1] == 'U') {
        stcpy (user_ecode, ecode);
        return USERERR;
    }
    else {        
        ec = merr_code_to_num (tmp);
        return (ec);
    }
}

void merr_dump (int num, char *rtn, char *nsn, char *tcod, int tpos)
{
    char *tbuf;
    char *dbuf;
    char *nem;
    char *nrt;
    char *real_ecode;
    err_lut *p;
    
    tbuf = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(tbuf,"merr_dump");

    dbuf = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(dbuf,"merr_dump");
    
    nem = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(nem,"merr_dump");
    
    nrt = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(nrt,"merr_dump");
    
    real_ecode = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(real_ecode,"merr_dump");

    stcpy (nrt, rtn);
    stcnv_m2c (nrt);

    stcpy (nem, errmes[num]);
    stcnv_m2c (nem);

    for (p = errtab; p->canonical_name != NULL; ++p) {

        if (p->ecode == num) {

            if (strcmp (p->canonical_name, "ZUSERERR") == 0) {
                stcpy (real_ecode, &user_ecode[1]);
                stcnv_m2c (real_ecode);
                real_ecode [strlen (real_ecode) - 1] = NUL;

                snprintf (tbuf, STRLEN - 1, "^$JOB\202%d\202USER_ERRORS\202%s\201", pid, &user_ecode[1]);
                tbuf [stlen (tbuf) - 1] = '\201';

                global (get_sym, tbuf, dbuf);
                
                if (merr () == OK) {
                    stcpy (nem, dbuf);
                    stcnv_m2c (nem);
                }
                else {
                    merr_clear ();
                }
                
            }
            else {
                strcpy (real_ecode, p->canonical_name);
            }

            if (!stlen (err_suppl)) {
                sprintf (tbuf, "\r\n>> Error %s:  %s in %s.%s::%s  [$STACK = %d]\r\n\201", real_ecode, nem, shm_env, nsn, nrt, nstx);
            }
            else {
                stcnv_m2c (err_suppl);
                sprintf (tbuf, "\r\n>> Error %s:  %s (%s) in %s::%s  [$STACK = %d]\r\n\201", real_ecode, nem, err_suppl, nsn, nrt, nstx);
                err_suppl[0] = EOL;
            }
            write_m (tbuf);
            write_m (">> \201");
            write_m (tcod);
            write_m ("\r\n\201");
            write_t (tpos);
            write_m ("^\201");            

            goto done;
        }

    }


done:

    free (tbuf);
    free (dbuf);
    free (nem);
    free (nrt);
    free (real_ecode);

    return;
}


void merr_set_iochan_err(int channel, short frm_err, char *err_text)
{
    if (channel > MAXDEV || channel < 0) {
        merr_raise (ARGLIST);
        return;
    }

    devstat[channel].mdc_err = 1;
    devstat[channel].frm_err = frm_err;

    strncpy (devstat[channel].err_txt, err_text, 79);

    return;
}

void merr_clear_iochan_err(int channel)
{
    if (channel > MAXDEV || channel < 0) {
        merr_raise (ARGLIST);
        return;
    }

    devstat[channel].mdc_err = 1;
    devstat[channel].frm_err = OK;
    devstat[channel].err_txt[0] = '\0';

    return;

}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>