Annotation of freem/src/frmgbl.c, revision 1.17

1.1       snw         1: /*
1.17    ! snw         2:  *   $Id: frmgbl.c,v 1.16 2025/04/30 17:19:16 snw Exp $
1.1       snw         3:  *    freem global C variables
                      4:  *
                      5:  *  
1.4       snw         6:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw         7:  *    Copyright (C) 1998 MUG Deutschland
1.5       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.6       snw        26:  *   $Log: frmgbl.c,v $
1.17    ! snw        27:  *   Revision 1.16  2025/04/30 17:19:16  snw
        !            28:  *   Improve backtraces in debugger
        !            29:  *
1.16      snw        30:  *   Revision 1.15  2025/04/30 14:41:03  snw
                     31:  *   Further debugger work
                     32:  *
1.15      snw        33:  *   Revision 1.14  2025/04/28 19:38:55  snw
                     34:  *   Add trace mode
                     35:  *
1.14      snw        36:  *   Revision 1.13  2025/04/17 14:34:27  snw
                     37:  *   Further logging improvements
                     38:  *
1.13      snw        39:  *   Revision 1.12  2025/04/16 17:36:12  snw
                     40:  *   Add FreeBSD shm cleanup script
                     41:  *
1.12      snw        42:  *   Revision 1.11  2025/04/13 04:22:43  snw
                     43:  *   Fix snprintf calls
                     44:  *
1.11      snw        45:  *   Revision 1.10  2025/04/10 01:24:38  snw
                     46:  *   Remove C++ style comments
                     47:  *
1.10      snw        48:  *   Revision 1.9  2025/04/03 01:41:02  snw
                     49:  *   New features frozen; prepare 0.63.0-rc1
                     50:  *
1.9       snw        51:  *   Revision 1.8  2025/04/02 03:02:42  snw
                     52:  *   Stop requiring users to pass -e to fmadm when -u or -g are passed
                     53:  *
1.8       snw        54:  *   Revision 1.7  2025/04/01 16:37:12  snw
                     55:  *   Configure DEFAULT environment the same as others, and set permissions/ownership directly in fmadm configure. Add env.conf file as a centralized configuration listing all environments.
                     56:  *
1.7       snw        57:  *   Revision 1.6  2025/03/24 04:05:36  snw
                     58:  *   Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2
                     59:  *
1.6       snw        60:  *   Revision 1.5  2025/03/09 19:14:25  snw
                     61:  *   First phase of REUSE compliance and header reformat
                     62:  *
1.5       snw        63:  *
                     64:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
                     65:  * SPDX-License-Identifier: AGPL-3.0-or-later
1.1       snw        66:  **/
                     67: 
                     68: /* needed if byte data are to be interpreted as unsigned integer */
                     69: #include <stdlib.h>
                     70: #include <setjmp.h>
                     71: #include <signal.h>
                     72: #include <stdio.h>
                     73: #include "mpsdef0.h"
                     74: #include <fcntl.h>
                     75: #include <unistd.h>
                     76: #include <string.h>
                     77: #include <sys/types.h>
                     78: #include <sys/wait.h>
1.13      snw        79: #include <errno.h>
1.1       snw        80: #include "transact.h"
                     81: #include "locktab.h"
1.13      snw        82: #include "log.h"
1.1       snw        83: 
                     84: #ifdef LIBFREEM
                     85: # include "errmsg.h"
                     86: #endif
                     87: 
                     88: #define UNSIGN(A) ((A)&0377)
                     89: 
                     90: #define g_EOL 30
                     91: #define POINT 28
                     92: #define MINUS 26
                     93: 
                     94: #define ROOT 0L
                     95:     /* length of blocks. status bytes defined as offset to blocklength */
                     96: #define DATALIM (BLOCKLEN-11)
                     97: #define LLPTR   (BLOCKLEN-10)
                     98: #define NRBLK    LLPTR
                     99: #define RLPTR   (BLOCKLEN- 6)
                    100: #define FREE     RLPTR
                    101: #define BTYP    (BLOCKLEN- 3)
                    102: #define OFFS    (BLOCKLEN- 2)
                    103: 
                    104: #define EMPTY    0
                    105: #define FBLK     1
                    106: #define POINTER  2
                    107: #define BOTTOM   6
                    108: #define DATA     8
                    109: 
                    110: #define PROTECT 30
                    111: 
                    112: 
                    113: #ifndef SYSFIVE
                    114:     #define FreeM_timezone -3600
                    115: #else
                    116: 
                    117:     #ifdef __CYGWIN__
                    118:         #define FreeM_timezone _timezone
                    119:     #else
                    120:         long FreeM_timezone;
                    121:     #endif /* __CYGWIN__ */
                    122: 
                    123: #endif /* SYSFIVE */
                    124: 
                    125: #if defined(__CYGWIN__)
                    126: # define FreeM_timezone _timezone
                    127: #endif
                    128: 
                    129: /* mumps commands */
                    130: #define BREAK       'b'
                    131: #define CLOSE       'c'
                    132: #define DO          'd'
                    133: #define DO_BLOCK     2
                    134: #define ELSE        'e'
                    135: #define FOR         'f'
                    136: #define GOTO        'g'
                    137: #define HA          'h'
                    138: #define HALT        '0'
                    139: #define HANG        '1'
                    140: #define IF          'i'
                    141: #define JOB         'j'
                    142: #define KILL        'k'
                    143: #define LOCK        'l'
                    144: #define NEW         'n'
                    145: #define OPEN        'o'
                    146: #define QUIT        'q'
                    147: #define READ        'r'
                    148: #define SET         's'
                    149: #define USE         'u'
                    150: #define VIEW        'v'
                    151: #define WRITE       'w'
                    152: #define XECUTE      'x'
                    153: #define ZBREAK      'B'
                    154: #define ZGO         'G'
                    155: #define ZHALT       'H'
                    156: #define ZINSERT     'I'
                    157: #define ZJOB        'J'
                    158: #define ZLOAD       'L'
                    159: #define ZNEW        'N'
                    160: #define ZPRINT      'P'
                    161: #define ZQUIT       'Q'
                    162: #define ZREMOVE     'R'
                    163: #define ZSAVE       'S'
                    164: #define ZTRAP       'T'
                    165: #define ZWRITE      'W'
                    166: #define PRIVATE     SP
                    167: 
                    168: #if defined(HAVE_MWAPI_MOTIF)
                    169: # include <Xm/Xm.h>
                    170: XtAppContext mwapi_context;
                    171: #endif
                    172: 
                    173: short run_daemon = FALSE;
                    174: short nofork = FALSE;
                    175: char *pid_file_path;
                    176: int pid_fd;
                    177: 
                    178: /* USING and WITH */
                    179: char i_using[STRLEN] = {'\201'};
                    180: char i_with[STRLEN] = {'\201'};
                    181: 
                    182: /* common definitions for all mumps modules           */
                    183: /* same as external definition in include_file mpsdef */
                    184: 
                    185: extern int errno;           /* external error code for systemcalls */
                    186: 
                    187: int     m_argc;             /* arguments count     */
                    188: char  **m_argv;             /* arguments string    */
                    189: char  **m_envp;             /* environment pointer */
                    190: 
                    191: short frm_throw_all_errors = 1;
                    192: 
                    193: /* glvn size parameters       */
                    194: union four_fl {
                    195: long unsigned all;
                    196: char    one[4];
                    197: } glvnflag;             /* [0] unique name chars          0=no limit */
                    198: 
                    199: /* [1] case sensitivity flag      0=sensitive */
                    200: /* [2] max. name+subscripts       0=no limit */
                    201: /* [3] max. length of a subscript 0=no limit */
                    202: int     libflag = FALSE;        /* running as library? */
                    203: int     lonelyflag = FALSE;     /* single user flag */
                    204: int     lowerflag = TRUE;       /* lowercase everywhere flag */
                    205: int     killerflag = TRUE;      /* SIGTERM handling flag */
                    206: int     huperflag = TRUE;       /* SIGHUP handling flag */
                    207: int     s_fun_flag = TRUE;      /* VIEW 70: ZSORT/ZSYNTAX flag */
                    208: int     n_fun_flag = TRUE;      /* VIEW 71: ZNEXT/ZNAME flag */
                    209: int     p_fun_flag = TRUE;      /* VIEW 72: ZPREVIOUS/ZPIECE flag */
                    210: int     d_fun_flag = TRUE;      /* VIEW 73: ZDATA/ZDATE flag */
                    211: int     zjobflag = TRUE;        /* VIEW 79: old ZJOB vs. new ZJOB flag */
                    212: int     eightbit = TRUE;        /* VIEW 80: 7 vs. 8 bit flag */
                    213: int     PF1flag = FALSE;        /* VIEW 81: PF1 flag */
                    214: int     ordercounter = 0;       /* VIEW 82: order counter */
                    215: int     etxtflag = FALSE;       /* VIEW 83: text in $ZE flag */
                    216: char    lvndefault[256] = "\201";   /* VIEW 89: UNDEF lvn default */
                    217: char    gvndefault[256] = "\201";   /* VIEW 90: UNDEF gvn default */
                    218: char    exfdefault[256] = "\201";   /* VIEW 91: missing QUIT expr default */
                    219: int     typemmflag = FALSE;     /* VIEW 92: EUR2DEM: type mismatch error */
                    220: int     namespace = 0;          /* VIEW 200: namespace index */
                    221: int     config = 0;         /* VIEW 201: configuration index */
                    222: char    WHR[12][4] = {                  /* names of currencies */
                    223:     "\201",
                    224:     "EUR\201",
                    225:     "ATS\201",
                    226:     "BFR\201",
                    227:     "DEM\201",
                    228:     "ESP\201",
                    229:     "FMK\201",
                    230:     "FRF\201",
                    231:     "IEP\201",
                    232:     "ITL\201",
                    233:     "NLG\201",
                    234:     "PTE\201"
                    235: };
                    236: 
                    237: char    EUR2WHR[12][9] = {                  /* conversion factors EUR to ... */
                    238:     "\201",             /* dont care */
                    239:     "1\201",                /* to EUR */
                    240:     "13.7603\201",          /* to ATS */
                    241:     "40.3399\201",          /* to BFR */
                    242:     "1.95583\201",          /* to DEM (DM) */
                    243:     "166.386\201",          /* to ESP */
                    244:     "5.94573\201",          /* to FMK */
                    245:     "6.55957\201",          /* to FRF (FF) */
                    246:     ".787564\201",          /* to IEP */
                    247:     "1936.27\201",          /* to ITL */
                    248:     "2.20371\201",          /* to NLG */
                    249:     "200.482\201"           /* to PTE */
                    250: };
                    251: 
                    252: long    v93 = 1;            /* VIEW 93: ASCII rule default */
                    253: char    v93a[NO_V93][2560] = {
                    254:     /*     ASCII    */
                    255:     " :, :!,A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z\201",
                    256:     /* B  - BELGIAN */
                    257:     " :, :!,@:a,\\:c,{:e,}:e,\
                    258:     A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z\201,\200:e",
                    259:     /* D  - GERMAN  */
                    260:     " \001\002 \001\002!\001\002\042\001\002#\001\002$\001\002%\001\002&\001\002\
                    261:     '\001\002(\001\002)\001\002*\001\002+\001\002,\001\002-\001\002.\001\002\
                    262:     /\001\002:\001\002;\001\002<\001\002=\001\002>\001\002?\001\002@\001\002\
                    263:     ^\001\002_\001\002`\001\002A\001a\002B\001b\002C\001c\002D\001d\002E\001e\002\
                    264:     F\001f\002G\001g\002H\001h\002I\001i\002J\001j\002K\001k\002L\001l\002\
                    265:     M\001m\002N\001n\002O\001o\002P\001p\002Q\001q\002R\001r\002S\001s\002\
                    266:     T\001t\002U\001u\002V\001v\002W\001w\002X\001x\002Y\001y\002Z\001z\002\
                    267:     {\001ae\002[\001ae\002|\001oe\002\134\001oe\002}\001ue\002]\001ue\002\
                    268:     ~\001ss\002\200\001e\002\201",
                    269:     /* DK - DANISH  */
                    270:     " :, :!,{:ae,|:oe,}:au,~:ue,\
                    271:     A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z,\
                    272:     [:ae,\\:oe,]:ao,^:ue,\200:e\201",
                    273:     /* E  - SPANISH */
                    274:     " :, :!,|:n,}:c,ll:l,\
                    275:     A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z,\200:e,\
                    276:     \\:n,LL:l\201",
                    277:     /* F  - FRENCH  */
                    278:     " :, :!,\\:c,{:e,|:u,}:e,\
                    279:     A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z,\200:e,\201",
                    280:     /* I  - ITALIAN */
                    281:     " :, :!,\\:c,]:e,`:u,{:a,|:o,}:e,~:i,\
                    282:     A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z,\200:e,\201",
                    283:     /* S  - SWEDISH */
                    284:     " :, :!,`:e,{:ae,|:oe,}:ao,~:ue,\
                    285:     A:a,B:b,C:c,D:d,E:e,F:f,G:g,H:h,I:i,J:j,K:k,L:l,M:m,N:n,O:o,P:p,Q:q,R:r,S:s,T:t,U:u,V:v,W:w,X:x,Y:y,Z:z,\
                    286:     @:e,[:ae,\\:oe,]:ao,~:ue,\200:e,\201"
                    287: };
                    288: 
                    289: 
                    290: char    glo_prefix[MONTH_LEN] = "^\201";    /* VIEW 96: global prefix */
                    291: char    glo_ext[MONTH_LEN] = "\201";    /* VIEW 97: global postfix */
                    292: char    rou_ext[MONTH_LEN] = ".m\201";  /* VIEW 98: routine extention */
                    293: long    tzoffset = 0L;          /* VIEW 99:  timer offset     */
                    294: int     v100 = 0;           /* VIEW 100: return value of kill */
                    295: char    l_o_val[256] = "\201";      /* VIEW 110: local $o/$q data value */
                    296: char    g_o_val[256] = "\201";      /* VIEW 111: global $o/$q data value */
                    297: int     zsavestrategy = TRUE;       /* VIEW 133: remember ZLOAD directory on ZSAVE */
                    298: 
                    299: /* vars for screen save/restore     */
                    300: struct vtstyp *screen = NULL;       /* active screen */
                    301: short   jour_flag = 0;          /* journal flag 0/1/-1              */
                    302: 
                    303: /* trace vars for global module     */
                    304: unsigned long traceblk[TRLIM];      /* trace stack - block numbers      */
                    305: short   traceadr[TRLIM];        /*             - status             */
                    306: short   trx;                /*             - stack pointer      */
                    307: char    compactkey[256];        /* internal form of key in global.c */
                    308: 
                    309: short   mcmnd;              /* mumps command letter */
                    310: short   arg;                /* stack pointer for expr.c         */
                    311: char   *argstck[PARDEPTH + 1];      /* stack of pointers to             */
                    312: 
                    313: /*       intermediate results       */
                    314: 
                    315: long    ordercnt = 0L;          /* repeater for $order/$query       */
                    316: short   setpiece = FALSE;       /* TRUE: set$piece executing        */
                    317: short   setop = 0;          /* SET op flag                      */
                    318: char    rou_name[256] =
                    319: {EOL};                  /* $T(+0)/$ZN routine name          */
                    320: char   *namstck;            /* routine name stack               */
                    321: char   *namptr;             /* routine name stack pointer       */
                    322: char   *framstck;           /* DO_frame stack                   */
                    323: char   *dofrmptr;           /* DO_frame stack pointer           */
                    324: char    zb[40] = "\201";        /* $ZB last ESC_sequence            */
                    325: char    zerror[300] = "\201";       /* $ZE last error                   */
                    326: short   DSM2err = FALSE;        /* enable normal error processing   */
                    327: short   nesterr = 0;            /* nesterr and callerr contain info */
                    328: char    callerr[NESTLEVLS + 1][40]; /* about call situation at error    */
                    329: 
                    330: char    stack0[256] = "\201";
                    331: 
                    332: char    zmc[128] = "\
                    333: \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\
                    334: \020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177\201";
                    335: 
                    336: /* $ZMC loadable match 'controls'  */
                    337: char    zmn[128] = "0123456789\201";    /* $ZMN loadable match 'numerics'  */
                    338: 
                    339: /* $ZMP loadable match 'punctuation' */
                    340: char    zmp[128] = " !\042#$%&'()*+,-./:;<=>?@^_`\201";
                    341: 
                    342: /* $ZML loadable match 'lowercase' */
                    343: char    zml[128] = "abcdefghijklmnopqrstuvwxyz{|}~\201";
                    344: 
                    345: /* $ZMU loadable match 'uppercase' */
                    346: char    zmu[128] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\201";
                    347: 
                    348: short   zerr = OK;          /* $ZE numeric error code          */
                    349: char    zloc[256] = "\201";     /* $ZL last local reference        */
                    350: char    zref[256] = "\201";     /* $ZR last global reference       */
                    351: short   nakoffs = 0;            /* offset to naked reference       */
                    352: char    zfunkey[44][FUNLEN];        /* $ZF function key */
                    353: 
                    354: typedef struct frm_devstat {
                    355:     short mdc_err;
                    356:     short frm_err;
                    357:     char err_txt[80];
                    358: } frm_devstat;
                    359: 
                    360: frm_devstat devstat[MAXDEV + 1]; /* channel statuses for $DEVICE */
                    361: 
                    362: short   xpos[MAXDEV + 1];       /* $X-vector                       */
                    363: short   ypos[MAXDEV + 1];       /* $Y-vector                       */
1.6       snw       364: short   frm_crlf[MAXDEV + 1];       /* CR/LF flag vector               */
1.1       snw       365: short   fm_nodelay[MAXDEV + 1];     /* nodelay flag vector             */
                    366: 
                    367: int     ESCflag[MAXDEV + 1] =
                    368: {0, 0, 0, 0, 0};            /* ESC flag                     */
                    369: 
                    370: short   RightMargin = 0;        /* Output Margin. Default no       */
                    371: 
                    372: /* automatic CR/LF                 */
                    373: short   InFieldLen = 255;       /* Input Field length Def: 255 char */
                    374: long    DSW = BIT2 + BIT21;     /* Device Status word (Terminal)   */
                    375: char    LineTerm[32] = "\012\015\201";  /* Input Line Terminator chars     */
                    376: char    BrkKey = 3;         /* <INTERRUPT> key Def: CTRL/C     */
                    377: char    ug_buf[MAXDEV + 1][256];    /* ungetc-buffers                  */
                    378: char    devopen[MAXDEV + 1] =
                    379: {0, 0, 0, 0, 0};            /*  0         not open             */
                    380: 
                    381: /* 'r'        input                */
                    382: /* 'w' or 'a' output               */
                    383: 
                    384: /* names of IO devices */
                    385: char    dev[MAXDEV + 1][40] = {
                    386:     " ",                    /* HOME  */
                    387:     "/usr/tmp/mout.1/a\201",        /* dev 1 */
                    388:     "/usr/tmp/mout.2/a\201",        /* dev 2 */
                    389:     "/usr/tmp/mout.3/a\201",        /* dev 3 */
                    390:     "/usr/tmp/mout.4/a\201"     /* dev 4 */
                    391: };
                    392: 
                    393: char    G0I[MAXDEV + 1][257];       /* G0 input translation table */
                    394: char    G0O[MAXDEV + 1][257];       /* G0 output translation table */
                    395: char    G1I[MAXDEV + 1][257];       /* G1 input translation table */
                    396: char    G1O[MAXDEV + 1][257];       /* G1 output translation table */
                    397: 
                    398: FILE   *opnfile[MAXDEV + 1];
                    399: char    act_oucpath[MAXDEV + 1][40] = {"\201", "\201", "\201", "\201", "\201"};
                    400: char    sq_modes[MAXDEV + 1];
                    401: 
                    402: short   olddes[NO_GLOBLS];      /* filedescr of open global files */
                    403: char    oldfil[NO_GLOBLS][1024];      /* names of open global files */
                    404: long    g_ages[NO_GLOBLS];      /* last access of global files */
                    405: short   usage[NO_GLOBLS];       /* usage count of global files */
                    406: short   inuse = 0;          /* file in use */
                    407: 
                    408: int     lio_mode = -1;
                    409: short   io = HOME;          /* $IO */
                    410: short   test = FALSE;           /* $TEST */
                    411: short   pattrnflag = FALSE;     /* incomplete match flag */
                    412: char    pattrnchar = EOL;       /* incomplete match flag supplement */
                    413: int     zsystem = 0;            /* $ZSYSTEM return status of UNIX call */
                    414: short   zcc = FALSE;            /* $ZC (ControlC-Flag)            */
                    415: 
                    416: char   *rouptr;             /* pointer to begin of routine    */
                    417: char   *roucur;             /* cursor into routine            */
                    418: char   *rouend;             /* pointer to end of pgm          */
                    419: char   *rouins;             /* pointer for direct mode insert */
                    420: short   breakon = ENABLE;       /* BREAK enable/disable-flag      */
                    421: short   zbreakon = DISABLE;     /* ZBREAK enable/disable-flag     */
                    422: short   zbflag = FALSE;         /* 'ZBREAK from terminal'-flag    */
                    423: short   zprecise = 100;          /* $ZPRECISION of arithmetic      */
                    424: char    fp_conversion[10];      /* sprintf conversion constant for ieee754 support */
                    425: long    nrandom;                /* random number seed             */
                    426: long    ran_a = 24298L;         /* random number parameter a      */
                    427: long    ran_b = 99991L;         /* random number parameter b      */
                    428: long    ran_c = 199017L;        /* random number parameter c      */
                    429: 
                    430: short   usermode = 1;           /* 0=user mode 1=programmer mode  */
                    431: int     restricted_mode = FALSE; /* TRUE=restricted FALSE=unrestricted */
                    432: short   demomode = FALSE;       /* 0=no demo   1=demo mode        */
                    433: int     d0char = DEL;           /* demomode ouput character       */
                    434: int     d1char = CAN;           /* demomode '!'   character       */
                    435: short   cset = FALSE;           /* 0=mumps set 1='C' set flag     */
                    436: 
                    437: /* startup flags */
                    438: int     hardcopy = DISABLE;     /* hardcopy flag                   */
                    439: int     frm_filter = FALSE;         /* filter flag                     */
                    440: int     noclear = FALSE;        /* noclear flag                    */
                    441: int     standard = D_FREEM;     /* default dialect */
                    442: int     quiet_mode = FALSE;      /* quiet mode */
                    443: char    config_file[4096];      /* path to configuration file      */
1.7       snw       444: char    env_config_file[4096];  /* path to environment config file */
                    445: char    env_user[255];
                    446: char    env_group[255];
1.9       snw       447: char    env_enabled[10];
1.1       snw       448: char    shm_env[255];           /* shared memory environment       */
                    449: 
                    450: short fp_mode = 0;             /* set to 0 for fixed-point math, 1 for IEEE754 floating point */
                    451: short en_revstrf = 1;          /* enable reverse forms of string intrinsics */
                    452: 
                    453: short   ierr;               /* immediate error status          */
                    454: short   deferred_ierr;      /* deferred error status (after returning from a private routine) */
                    455: char    err_suppl[255];     /* supplemental information about an error */
                    456: 
                    457: long    PSIZE = DEFPSIZE;       /* size of 'partition'             */
                    458: char   *mbpartition;        /* memory-backed globals partition */
                    459: short   writing_mb = FALSE;
                    460: char   *partition;          /* partition (symbol table)                      */
                    461: long    symlen = DEFPSIZE;      /* 'lower' bound of symbol table   */
                    462: unsigned long alphptr[128] =        /* pointers into symbol table      */
                    463: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    464: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    465: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    466: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
                    467: char   *apartition;         /* alternate partition             */
                    468: long    asymlen = DEFPSIZE;     /* 'lower' bound of symbol table   */
                    469: unsigned long aalphptr[128] =       /* pointers into symbol table      */
                    470: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    471: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    472: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    473: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
                    474: 
                    475: short   autopsize = TRUE;       /* automatic increase of PSIZE     */
                    476: long    svnlen = DEFUDFSVSIZ;       /* 'lower' bound of udf_svn_tab    */
                    477: long    UDFSVSIZ = DEFUDFSVSIZ;     /* size of userdef special var tab. */
                    478: char   *svntable;           /* udf special variable table      */
                    479: unsigned long svnaptr[128] =        /* pointers into udf_svn_tab       */
                    480: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    481: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    482: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    483: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
                    484: 
                    485: short   autousize = TRUE;       /* automatic increase of UDFSVSIZ  */
                    486: long    NO_OF_RBUF = DEFNO_OF_RBUF; /* number of routine buffers       */
                    487: long    PSIZE0 = DEFPSIZE0;     /* size of routine buffers         */
                    488: short   autorsize = TRUE;       /* automatic increase of PSIZE0    */
                    489: short   aliases = 0;            /* aliases pointer                 */
                    490: char    ali[2000];          /* aliases table                   */
                    491: long    v22ptr = 0L;            /* view 22 aliases pointer         */
                    492: char   *v22ali;             /* view 22 aliases field           */
                    493: long    v22size = 0L;           /* current size of aliases field   */
                    494: 
                    495: 
                    496: long    NSIZE = DEFNSIZE;       /* size of newstack                */
                    497: char   *newstack;           /* stack for NEWed variables       */
                    498: char   *newptr;             /* pointer to NEW stack            */
                    499: char   *newlimit;           /* pointer to NEW stack end        */
                    500: 
                    501: short   nstx = 0;           /* nest stack:       */
                    502: short   nestc[NESTLEVLS + 1];       /* - command (DO...) */
                    503: char   *nestp[NESTLEVLS + 1];       /* - cmdptr          */
                    504: char   *nestn[NESTLEVLS + 1];       /* - namptr          */
                    505: long    nestr[NESTLEVLS + 1];       /* - roucur          */
                    506: char   *nestnew[NESTLEVLS + 1];     /* - newptr          */
                    507: short   neste[NESTLEVLS + 1];       /* - was this frame entered as the result of an error? */
                    508: short   nestlt[NESTLEVLS + 1];      /* stack $T / stack levelcount */
                    509: short   brkstk[NESTLEVLS + 1];      /* stack for BREAK information */
                    510: 
                    511: char    ztrap[NESTLEVLS + 2][ZTLEN];    /* $ZTRAP to be xecuted on error    */
                    512: 
                    513: 
                    514: char   *s;              /* pointer to symlen_offset        */
                    515: char   *argptr;             /* pointer to beg of tmp-storage   */
                    516: 
                    517: char    code[512] =
                    518: {EOL, EOL};             /* currently interpreted code      */
                    519: char   *codptr = code;          /* pointer within code[]           */
                    520: 
                    521: char    dosave[20];         /* in a FOR range save DO label    */
                    522: char   *xdosave;
                    523: 
                    524: int     errfunlvl = 0;          /* avoid wrong error message in $$FUN */
                    525: short   repQUIT = 0;            /* QUIT repeater     */
                    526: 
                    527: char    varnam[256];            /* variable/array/function name  */
                    528: char    varerr[256] =
                    529: {EOL};                  /* reference in error message    */
                    530: char   *buff;               /* routine buffer pool           */
                    531: char    pgms[MAXNO_OF_RBUF][40];    /* names of alt.pgms             */
                    532: long    ages[MAXNO_OF_RBUF];        /* last call to this pgm         */
                    533: char   *ends[MAXNO_OF_RBUF];        /* saved rouend-pointer          */
                    534: char    path[MAXNO_OF_RBUF][256];   /* directory where routine was loaded */
                    535: rtn_flags rbuf_flags[MAXNO_OF_RBUF]; /* per-routine flags */
                    536: 
                    537: char    glopath[PATHLEN];           /* path to access globals        */
                    538: char    rou0path[PATHLEN];          /* routine access with DO,GOTO,JOB */
                    539: char    rou1path[PATHLEN];          /* routine access with ZL,ZS     */
                    540: char    gloplib[PATHLEN];           /* path to access %globals   */
                    541: 
                    542: char    gbl_u_engine[255];          /* user global engine */
                    543: char    gbl_s_engine[255];          /* system global engine */
                    544: char    loc_engine[255];            /* local engine */
                    545: 
                    546: unsigned long int bdb_flush_threshold;
                    547: 
                    548: char    rou0plib[PATHLEN];          /* %routine path (DO..)     */
                    549: char    rou1plib[PATHLEN];          /* %routine path (ZL..)     */
                    550: char    oucpath[PATHLEN] = "\201";  /* OPEN/USE/CLOSE path */
                    551: char    zargdefname[PATHLEN]= "%\201";  /* default varname for Z-commands */
                    552: FILE   *jouraccess;         /* dto. filedes */
                    553: char    curdir[256] = ".";      /* current directory */
                    554: 
                    555: char    startuprou[PATHLEN] = "\201";   /* start up routine from cmdline*/
                    556: 
                    557: char    zcommds[256] =
1.17    ! snw       558: " za zb zc zd zg zh zi zj zl zm zn zp zq zr zs zth ztr zwa zwi zwr zassert zbreak \
        !           559: zconst zgo zhalt zinsert zjob zload zmap znamespace zprint zquit zremove zsave zthrow ztrap zunmap zwatch zwith zwrite \201";  /* intrinsic z-commands */
1.1       snw       560: char    zfunctions[256] =       /* intrinsic z-functions */
                    561: " zb zc zd ze zh zht zk zl zm zn zo zp zr zs zt zboolean zcall zcr zcrc zdata zdate zedit zhorolog \
                    562: zkey zlength zlsd zname znext zorder zpiece zprevious zreplace zsyntax zsort ztime \201";
                    563: char    zsvn[256] =         /* intrinsic z-special variables */
                    564: " za zb zc zd ze zf zh zi zj zl zmc zmn zmp zma zml zmu zme zn zo zp zs zt zu zv \
                    565: zcontrolc zdate zerror zname zhorolog zinrpt zjob zlocal zorder zprecision zsystem ztime ztr ztrap zuuid zut zversion \201";
                    566: char    brkaction[256] = "\201";    /* action in case of BREAK     */
                    567: pid_t   father = 0;         /* JOB-ID of father process         */
                    568: char jour_hostid[256];
                    569: /* date types parameters */
                    570: char    month[NO_DATETYPE][12][MONTH_LEN] = {
                    571:     {"01\201", "02\201", "03\201", "04\201", "05\201", "06\201", "07\201", "08\201", "09\201", "10\201", "11\201", "12\201"},
                    572:     {"01\201", "02\201", "03\201", "04\201", "05\201", "06\201", "07\201", "08\201", "09\201", "10\201", "11\201", "12\201"},
                    573:     {"JAN\201", "FEB\201", "MAR\201", "APR\201", "MAY\201", "JUN\201", "JUL\201", "AUG\201", "SEP\201", "OCT\201", "NOV\201", "DEC\201"},
                    574:     {"01\201", "02\201", "03\201", "04\201", "05\201", "06\201", "07\201", "08\201", "09\201", "10\201", "11\201", "12\201"},
                    575:     {"1\201", "2\201", "3\201", "4\201", "5\201", "6\201", "7\201", "8\201", "9\201", "10\201", "11\201", "12\201"},
                    576:     {"1\201", "2\201", "3\201", "4\201", "5\201", "6\201", "7\201", "8\201", "9\201", "10\201", "11\201", "12\201"},
                    577:     {"1\201", "2\201", "3\201", "4\201", "5\201", "6\201", "7\201", "8\201", "9\201", "10\201", "11\201", "12\201"},
                    578:     {"01\201", "02\201", "03\201", "04\201", "05\201", "06\201", "07\201", "08\201", "09\201", "10\201", "11\201", "12\201"}
                    579: };
                    580: char    dat1char[NO_DATETYPE][MONTH_LEN] =  /* date 1st delimiter */
                    581: {"/\201", "/\201", " \201", "/\201", ".\201", ".\201", ".\201", ".\201"};
                    582: char    dat2char[NO_DATETYPE][MONTH_LEN] =  /* date 2nd delimmiter */
                    583: {"/\201", "/\201", " \201", "/\201", ".\201", ".\201", ".\201", ".\201"};
                    584: char    dat3char[NO_DATETYPE] =
                    585: {'0', '0', '0', '0', '\201', '\201', '\201', '0'};  /* date day justify char */
                    586: char    dat4flag[NO_DATETYPE] =
                    587: {2, 1, 0, 0, 0, 0, 0, 0};       /* 0=DMY, 1=MDY, 2=YMD */
                    588: char    dat5flag[NO_DATETYPE] =
                    589: {0, 1, 1, 1, 1, 1, 0, 1};       /* suppress century digits */
                    590: long int datGRbeg[NO_DATETYPE] =
                    591: {578101L, 578101L, 578101L, 578101L, 578101L, 578101L, 578101L, 578101L};
                    592: 
                    593: /* first day of gregorian calendar 15-OCT-1582 ($H+672411) */
                    594: int     datetype = 0;           /* type for $zd special variable */
                    595: 
                    596: char    tim1char[NO_TIMETYPE] =
                    597: {':', ':'};             /* time 1st delimiter */
                    598: char    tim2char[NO_TIMETYPE] =
                    599: {':', ':'};             /* time 2nd delimiter */
                    600: char    tim3char[NO_TIMETYPE] =
                    601: {SP, SP};               /* time hour justify char */
                    602: char    tim4flag[NO_TIMETYPE] =
                    603: {0, 1};                 /* 0=24 Hrs 1=12 Hrs */
                    604: char    tim5flag[NO_TIMETYPE] =
                    605: {0, 0};                 /* suppress seconds */
                    606: int     timetype = 0;           /* type for $zt special variable */
                    607: 
                    608: jmp_buf sjbuf;
                    609: char   *roucu0;
                    610: char   *dofram0;
                    611: 
                    612: short   forx = 0;           /* FOR stack pointer */
                    613: char    forvar[NESTLEVLS + 1][40],  /* FOR variable */
                    614:     forinc[NESTLEVLS + 1][40],  /* FOR increment */
                    615:     forpost[NESTLEVLS + 1][128], /* FOR postconditional */
                    616:     forlim[NESTLEVLS + 1][40];  /* FOR limit value */
                    617: short   fortyp[NESTLEVLS + 1];      /* 0 = forever    1 = single,     */
                    618: 
                    619: /* 2 = unlim.iter,3 = limit iter. */
                    620: /* 4 =  "" +inc=1 5 =  "" + inc=1 */
                    621: short   fori[NESTLEVLS + 1];        /* if fortyp=5 length of forlimit */
                    622: 
                    623: char   *fvar;               /* current forvar */
                    624: char   *finc;               /* current forinc */
                    625: char   *fpost;              /* current forpost */
                    626: char   *flim;               /* current forlim */
                    627: short   ftyp;               /* current fortyp */
                    628: short   fi;             /* current fori   */
                    629: short   forsw = FALSE;          /* FOR switch */
                    630: short   loadsw = TRUE;          /* flag to avoid redundant loads */
                    631: short   argless_forsw_quit = FALSE; /* QUIT from argumentless FOR */
                    632: short   sigint_in_for = FALSE;
                    633: short   direct_mode = TRUE;     /* are we in direct mode? */
                    634: 
                    635: short   extr_types[NESTLEVLS + 1]; /* return types of extrinsic functions */
1.11      snw       636: char destructors[MAX_DESTRUCTORS][OBJ_DSTRSIZE];
1.1       snw       637: int destructor_ct;
                    638: char private_keys[MAX_PRIVATE_KEYS][255];
                    639: 
                    640: /* after XECUTEs */
                    641: short   promflag = TRUE;        /* prompt execute flag */
                    642: short   privflag = FALSE;       /* extrinsic z-command flag */
                    643: 
                    644: 
                    645: char   *cmdstack;
                    646: char   *cmdptr;
                    647: 
                    648: short   offset;
                    649: long    frm_timeout;
                    650: short   timeoutms;
                    651: char    tmp4[80] = "\201";
                    652: short   param = 0;          /* parameter count */
                    653: short   paramx = 0;         /* current parameter */
                    654: short   level = 0;          /* level count */
                    655: pid_t    pid;                /* $J = process ID */
                    656: 
                    657: char    nsname[256] = "USER\0"; /* namespace name */
                    658: char    nsroot[4096];        /* root path of namespace */
                    659: char    *freem_path;    /* path to the running instance of FreeM */
                    660: char    history_file[256];  /* path to the history file */
                    661: int n_lines;
                    662: int n_columns;
                    663: 
                    664: short ipc_pending = 0;   /* 1 if an incoming IPC is pending, 0 otherwise */
                    665: 
                    666: int strict_mode = 0;
                    667: 
1.14      snw       668: int trace_mode = 0;
1.16      snw       669: short debug_mode = FALSE;
                    670: int lasterr[NESTLEVLS + 1];
1.14      snw       671: 
1.1       snw       672: short first_process = FALSE;
1.12      snw       673: #if defined(__FreeBSD__)
                    674:  size_t shm_init_size = 4194304;
                    675: #else
                    676:  size_t shm_init_size = 16777216;
                    677: #endif
1.1       snw       678: short inrpt_after_async = FALSE;
                    679: 
                    680: void unnew (void)
                    681: {
                    682:     char   *xptr;
                    683:     int     i;
                    684:     long    j;
                    685:     char    tmp[256];
                    686:     
                    687:     #ifdef DEBUG_NEWPTR
                    688:         int loop;
                    689:         printf("Un-Newing: ");
                    690:         printf("[nstx] nstx is %d\r\n",nstx);
                    691:         printf("[nestnew] nestnew[nstx] is %d\r\n",nestnew[nstx]);
                    692:     #endif
                    693:     
                    694: 
                    695:     xptr = nestnew[nstx];       /* get position of newpointer */
                    696:     
                    697:     while (xptr < newptr) {
                    698:         i = *--newptr;
                    699: 
                    700:         if (i != kill_all) {
                    701:             j = UNSIGN (*--newptr);
                    702:             newptr -= (j + 1);
                    703:             stcpy0 (varnam, newptr, j + 1);
                    704: 
                    705:             if (i == set_sym) {
                    706:                 j = UNSIGN (*--newptr);
                    707:                 newptr -= (j + 1);
                    708:                 stcpy (tmp, newptr);
                    709:             } 
                    710:             else {
                    711:                 tmp[0] = EOL;
                    712:             }
                    713:         } 
                    714:         else {
                    715:             varnam[0] = EOL;
                    716:             tmp[0] = EOL;
                    717:         }
                    718: 
                    719:         if (varnam[0] == '$') {
                    720:             if (varnam[1] == 't') test = tmp[0]; /* pop $TEST */
                    721:             else if (varnam[1] == 'j') pid = UNSIGN (tmp[0]) * 256 + UNSIGN (tmp[1]); /* pop $job */
                    722:             else if (varnam[1] == 'z' && varnam[2] == 'i') breakon = tmp[0]; /* pop $zinrpt */
                    723:             else if (varnam[1] == 'e' && varnam[2] == 't') { /* pop $etrap */
                    724:                 stcpy (etrap, tmp);
                    725:             }
                    726:             else if (varnam[1] == 'e' && varnam[2] == 's') { /* pop $estack */
                    727:                 char esbuf[256];
                    728: 
                    729:                 stcpy (esbuf, tmp);
                    730:                 stcnv_m2c (esbuf);
                    731: 
                    732:                 estack = atoi (esbuf);
                    733:             }
                    734:             else { /* pop $reference/$zreference */
                    735:                 stcpy (zref, tmp); 
                    736:                 nakoffs = UNSIGN (varnam[4]);
                    737:             }
                    738:             
                    739:             continue;
                    740:         }
                    741:         symtab (i, varnam, tmp);
                    742:     }
                    743: 
                    744:     newptr = nestnew[nstx];
                    745:     nestnew[nstx] = 0;          /* reset pointers */
                    746: 
                    747:     return;
                    748: 
                    749: }                   /* end unnew() */
                    750: 
                    751: void m_fatal(char *s)
                    752: {
                    753:     int errno_sav;
                    754:     errno_sav = errno;
                    755:     
                    756:     set_io (UNIX);
                    757: 
                    758: 
                    759:     if (tp_level) {
1.13      snw       760:         /* TODO: make this FM_LOG_FATAL (logger will need to do a tp_trollback) */
                    761:        logprintf (FM_LOG_ERROR, "freem:  memory allocation failure in %s; rolling back %d transactions (error code %d [%s])", s, tp_level, errno_sav, strerror (errno_sav));
1.1       snw       762:        tp_trollback (tp_level);
                    763:     }
                    764:     else {
1.13      snw       765:        logprintf (FM_LOG_FATAL, "freem:  memory allocation failure in %s (error code %d [%s])", s, errno_sav, strerror (errno_sav));
1.1       snw       766:     }
                    767:     
                    768:     exit (3);
                    769: }

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