Annotation of freem/src/init.c, revision 1.18

1.1       snw         1: /*
1.18    ! snw         2:  *   $Id: init.c,v 1.17 2026/03/14 21:04:51 snw Exp $
1.1       snw         3:  *    FreeM initialization 
                      4:  *
                      5:  *  
1.5       snw         6:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw         7:  *    Copyright (C) 1998 MUG Deutschland
1.6       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.7       snw        26:  *   $Log: init.c,v $
1.18    ! snw        27:  *   Revision 1.17  2026/03/14 21:04:51  snw
        !            28:  *   Fix segfault in OPEN command with I/O channel specified but no file
        !            29:  *
1.17      snw        30:  *   Revision 1.16  2026/01/07 19:51:33  snw
                     31:  *   Fix segfault in reverse $QUERY
                     32:  *
1.16      snw        33:  *   Revision 1.15  2025/05/16 04:02:14  snw
                     34:  *   Make FreeM build on macOS on Apple Silicon
                     35:  *
1.15      snw        36:  *   Revision 1.14  2025/04/20 03:13:17  snw
                     37:  *   Updates to init_execution_context
                     38:  *
1.14      snw        39:  *   Revision 1.13  2025/04/17 14:34:27  snw
                     40:  *   Further logging improvements
                     41:  *
1.13      snw        42:  *   Revision 1.12  2025/04/15 14:39:06  snw
                     43:  *   Further improvements to logging
                     44:  *
1.12      snw        45:  *   Revision 1.11  2025/04/13 04:22:43  snw
                     46:  *   Fix snprintf calls
                     47:  *
1.11      snw        48:  *   Revision 1.10  2025/04/10 01:24:38  snw
                     49:  *   Remove C++ style comments
                     50:  *
1.10      snw        51:  *   Revision 1.9  2025/04/03 16:58:34  snw
                     52:  *   Make error message for shm_init error during initialization more friendly
                     53:  *
1.9       snw        54:  *   Revision 1.8  2025/03/24 04:44:55  snw
                     55:  *   Don't call ttyname on OS/2
                     56:  *
1.8       snw        57:  *   Revision 1.7  2025/03/24 04:05:36  snw
                     58:  *   Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2
                     59:  *
1.7       snw        60:  *   Revision 1.6  2025/03/09 19:14:25  snw
                     61:  *   First phase of REUSE compliance and header reformat
                     62:  *
1.6       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: #include <stdio.h>
                     69: #include <stdlib.h>
                     70: #include <string.h>
                     71: #include <unistd.h>
                     72: #include <limits.h>
                     73: #include <sys/types.h>
                     74: #include <sys/stat.h>
                     75: #include <pwd.h>
                     76: #include <time.h>
                     77: #include <errno.h>
                     78: #include <sys/ioctl.h>
1.2       snw        79: 
1.4       snw        80: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(EMSCRIPTEN)
                     81: # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__AMIGA)
                     82: #  include <termios.h>
                     83: #  if !defined(__AMIGA)
                     84: #   define TCGETA TIOCGETA
                     85: #   define TCSETA TIOCSETA
                     86: #  endif
                     87: #  define termio termios
                     88: # else
1.16      snw        89: #  if !defined(MSDOS) && !defined(__linux__)
1.4       snw        90: #    include <termio.h>
1.16      snw        91: #  else
                     92: #    include <termios.h>
                     93: #    define termio termios
1.4       snw        94: #  endif
                     95: # endif
1.2       snw        96: #else
                     97: # include <termios.h>
                     98: #endif
1.1       snw        99: 
1.16      snw       100: 
1.15      snw       101: #if defined(__APPLE__)
                    102: # define termio termios
                    103: # define TCGETA TIOCGETA
                    104: # define TCSETA TIOCSETA
                    105: #endif
                    106: 
1.1       snw       107: #include "config.h"
                    108: 
                    109: #if defined(HAVE_MWAPI_MOTIF)
                    110: # include <Xm/Xm.h>
                    111: #endif
                    112: 
                    113: #include "mpsdef.h"
                    114: #include "transact.h"
                    115: #include "namespace.h"
                    116: #include "events.h"
                    117: #include "mdebug.h"
                    118: #include "shmmgr.h"
                    119: #include "locktab.h"
                    120: #include "jobtab.h"
                    121: #include "datatypes.h"
                    122: #include "objects.h"
1.12      snw       123: #include "log.h"
1.1       snw       124: 
                    125: #ifdef HAVE_LIBREADLINE
                    126: #  if defined(HAVE_READLINE_READLINE_H)
                    127: #    include <readline/readline.h>
                    128: #  elif defined(HAVE_READLINE_H)
                    129: #    include <readline.h>
                    130: #  else /* !defined(HAVE_READLINE_H) */
                    131: extern char *readline ();
                    132: #  endif /* !defined(HAVE_READLINE_H) */
                    133: char *cmdline = NULL;
                    134: #else /* !defined(HAVE_READLINE_READLINE_H) */
                    135:   /* no readline */
                    136: #endif /* HAVE_LIBREADLINE */
                    137: 
                    138: #ifdef HAVE_READLINE_HISTORY
                    139: #  if defined(HAVE_READLINE_HISTORY_H)
                    140: #    include <readline/history.h>
                    141: #  elif defined(HAVE_HISTORY_H)
                    142: #    include <history.h>
                    143: #  else /* !defined(HAVE_HISTORY_H) */
                    144: extern void add_history ();
                    145: extern int write_history ();
                    146: extern int read_history ();
                    147: #  endif /* defined(HAVE_READLINE_HISTORY_H) */
                    148:   /* no history */
                    149: #endif /* HAVE_READLINE_HISTORY */
                    150: 
                    151: #if defined(HAVE_WIRINGPI_H)
                    152: # include <wiringPi.h>
                    153: #endif
                    154: 
                    155: #if !defined(PATH_MAX) && defined(_SCO_DS)
                    156: # define PATH_MAX 4096
                    157: #endif
                    158: 
                    159: #if !defined(PATH_MAX) && defined(__gnu_hurd__)
                    160: # define PATH_MAX 1024
                    161: #endif
                    162: 
                    163: #if !defined(PATH_MAX) && defined(__sun__)
                    164: # include <limits.h>
                    165: #endif
                    166: 
                    167: #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
                    168: # include <sys/syslimits.h>
                    169: #endif
                    170: 
                    171: #define SHMKEY 0x990120
                    172: #define SHMSIZ 1048576
                    173: 
                    174: void init_process(void);
                    175: void init_devtable(void);
                    176: void init_signals(void);
                    177: void init_timezone(void);
                    178: void init_freem_path(void);
                    179: 
                    180: #if defined(HAVE_LIBREADLINE)
                    181: void init_readline(void);
                    182: #endif
                    183: 
                    184: void init_execution_context(void);
                    185: void init_io(void);
                    186: void init_random_number(void);
                    187: void init_ztrap(void);
                    188: void init_ssvn(void);
                    189: void init_terminal(void);
                    190: void init_estack(void);
                    191: 
                    192: void init_mwapi(void);
                    193: 
                    194: short init (char *namespace_name) 
                    195: {
                    196:     short retval;
1.13      snw       197:     int log_level;
                    198:     
1.12      snw       199:     init_log ();
1.1       snw       200:     init_process ();
                    201:     init_devtable ();
                    202:     init_signals ();
                    203:     init_freem_path ();
                    204:     init_timezone ();
                    205: 
                    206: #if defined(HAVE_LIBREADLINE)
                    207:     init_readline ();
                    208: #endif    
                    209: 
                    210:     init_execution_context ();
                    211: 
                    212:     if (run_daemon == FALSE) {
                    213:         init_io ();
                    214:     }
                    215:     
                    216:     init_random_number ();
                    217:     init_ztrap ();
                    218: 
                    219:     retval = shm_init (shm_init_size);
                    220: 
                    221:     if (retval == SHMS_GET_ERR) {
1.9       snw       222:         if (errno != 13) {
1.13      snw       223:             logprintf (FM_LOG_FATAL, "init:  error initializing shared memory (error code %d [%s])", errno, strerror (errno));
1.9       snw       224:         }
                    225:         else {
1.13      snw       226:             logprintf (FM_LOG_FATAL, "init:  error attaching to environment -- does your user belong to the group that owns environment '%s'?", shm_env);
1.9       snw       227:         }
1.1       snw       228:     }
                    229: 
                    230:     symtab_init ();
                    231:     tp_init ();
                    232:     
                    233:     set_namespace (namespace_name, FALSE);
                    234: 
                    235:     if (first_process) {
1.13      snw       236:         log_level = FM_LOG_INFO;
                    237:     }
                    238:     else {
                    239:         log_level = FM_LOG_DEBUG;
                    240:     }
                    241:     
                    242:     if (first_process) {
                    243:         logprintf (log_level, "init:  we are the first process in the environment (pid %d)", pid);
1.1       snw       244:     }
                    245: 
1.13      snw       246:     logprintf (log_level, "init:  initializing job table");
1.1       snw       247:     jobtab_init ();
                    248: 
1.13      snw       249:     logprintf (log_level, "init:  adding job to job table");
1.1       snw       250:     job_init (FALSE);
                    251: 
1.13      snw       252:     logprintf (log_level, "init:  initializing structured system variables");
1.1       snw       253:     init_ssvn ();
                    254: 
1.13      snw       255:     logprintf (log_level, "init:  initializing terminal");
1.1       snw       256:     init_terminal ();
                    257: 
1.13      snw       258:     logprintf (log_level, "init:  initializing asynchronous events");
1.1       snw       259:     evt_init ();
                    260: 
1.13      snw       261:     logprintf (log_level, "init:  initializing debugger");
1.1       snw       262:     dbg_init ();    
                    263: 
1.13      snw       264:     logprintf (log_level, "init:  initializing error stack");
1.1       snw       265:     init_estack();
                    266:     
                    267:     etrap[0] = EOL;
                    268:     ecode[0] = EOL;
                    269:     estack = 0;
                    270: 
                    271:     init_mwapi();
                    272:     
                    273:     if (merr () == OK) {
                    274:         return TRUE;
                    275:     }
                    276: 
                    277:     return FALSE;
                    278: }
                    279: 
                    280: void init_process (void)
                    281: {
                    282:     pid = getpid ();            /* get $J = process ID */
                    283:     umask (0);              /* protection bits mask to full rights */
1.11      snw       284:     snprintf (fp_conversion, sizeof (fp_conversion) - 1, "%%.%df\201", DBL_DIG);
1.1       snw       285: 
                    286:     if (fp_mode) {
                    287:         zprecise = DBL_DIG;
                    288:     }
                    289:     else {
                    290:         zprecise = 100;
                    291:     }
                    292: }
                    293: 
                    294: void init_devtable (void)
                    295: {
                    296:     register int i;
                    297:     register int j;
                    298: 
                    299:     for (j = 0; j <= MAXDEV; j++) { /* init. translation tables */
                    300:         
                    301:         for (i = 0; i < 256; i++) {
                    302:             G0I[j][i] = (char) i;
                    303:             G0O[j][i] = (char) i;
                    304:             G1I[j][i] = (char) i;
                    305:             G1O[j][i] = (char) i;
                    306:         }
                    307:         
                    308:         G0I[j][UNSIGN (EOL)] = NUL;
                    309:         G0O[j][UNSIGN (EOL)] = NUL;
                    310:         G1I[j][UNSIGN (EOL)] = NUL;
                    311:         G1O[j][UNSIGN (EOL)] = NUL;
                    312:         G0I[j][UNSIGN (DELIM)] = NUL;
                    313:         G0O[j][UNSIGN (DELIM)] = NUL;
                    314:         G1I[j][UNSIGN (DELIM)] = NUL;
                    315:         G1O[j][UNSIGN (DELIM)] = NUL;
                    316:         G0I[j][256] = EOL;
                    317:         G0O[j][256] = EOL;
                    318:         G1I[j][256] = EOL;
                    319:         G1O[j][256] = EOL;
                    320:     
                    321:     }
                    322: 
                    323:     #ifdef SCO
                    324:         #ifndef HACK_NOXLATE
                    325:             G0I[HOME][245] = 64;
                    326:             G0O[HOME][64] = 245;        /* Paragraph */
                    327:             G0I[HOME][142] = 91;
                    328:             G0O[HOME][91] = 142;        /* A umlaut */
                    329:             G0I[HOME][153] = 92;
                    330:             G0O[HOME][92] = 153;        /* O umlaut */
                    331:             G0I[HOME][154] = 93;
                    332:             G0O[HOME][93] = 154;        /* U umlaut */
                    333:             G0I[HOME][132] = 123;
                    334:             G0O[HOME][123] = 132;       /* a umlaut */
                    335:             G0I[HOME][148] = 124;
                    336:             G0O[HOME][124] = 148;       /* o umlaut */
                    337:             G0I[HOME][129] = 125;
                    338:             G0O[HOME][125] = 129;       /* u umlaut */
                    339:             G0I[HOME][225] = 126;
                    340:             G0O[HOME][126] = 225;       /* sharp s  */
                    341:         #endif/*HACK_NOXLATE*/
                    342: 
                    343:         /* DEC Special graphics                             */
                    344:         G1I[HOME][254] = 96;
                    345:         G1O[HOME][96] = 254;        /* diamond  */
                    346:         G1I[HOME][176] = 97;
                    347:         G1O[HOME][97] = 176;        /* checker board */
                    348:         G1I[HOME][241] = 99;
                    349:         G1O[HOME][99] = 241;        /* FF */
                    350:         G1I[HOME][242] = 100;
                    351:         G1O[HOME][100] = 242;       /* CR */
                    352:         G1I[HOME][243] = 101;
                    353:         G1O[HOME][101] = 243;       /* LF */
                    354:         G1I[HOME][248] = 102;
                    355:         G1O[HOME][102] = 248;       /* degree sign */
                    356:         G1I[HOME][241] = 103;
                    357:         G1O[HOME][103] = 241;       /* plus minus */
                    358:         G1I[HOME][244] = 104;
                    359:         G1O[HOME][104] = 244;       /* NL */
                    360:         G1I[HOME][251] = 105;
                    361:         G1O[HOME][105] = 251;       /* VT */
                    362:         G1I[HOME][217] = 106;
                    363:         G1O[HOME][106] = 217;       /* lower right corner */
                    364:         G1I[HOME][191] = 107;
                    365:         G1O[HOME][107] = 191;       /* upper right corner */
                    366:         G1I[HOME][218] = 108;
                    367:         G1O[HOME][108] = 218;       /* upper left corner */
                    368:         G1I[HOME][192] = 109;
                    369:         G1O[HOME][109] = 192;       /* lower left corner */
                    370:         G1I[HOME][197] = 110;
                    371:         G1O[HOME][110] = 197;       /* cross */
                    372:         G1I[HOME][200] = 111;
                    373:         G1O[HOME][111] = 200;       /* linescan 5 */
                    374:         G1I[HOME][201] = 112;
                    375:         G1O[HOME][112] = 201;       /* linescan 4 */
                    376:         G1I[HOME][196] = 113;
                    377:         G1O[HOME][113] = 196;       /* linescan 3 */
                    378:         G1I[HOME][202] = 114;
                    379:         G1O[HOME][114] = 202;       /* linescan 2 */
                    380:         G1I[HOME][203] = 115;
                    381:         G1O[HOME][115] = 203;       /* linescan 1 */
                    382:         G1I[HOME][195] = 116;
                    383:         G1O[HOME][116] = 195;       /* left  junction */
                    384:         G1I[HOME][180] = 117;
                    385:         G1O[HOME][117] = 180;       /* right junction */
                    386:         G1I[HOME][193] = 118;
                    387:         G1O[HOME][118] = 193;       /* lower junction */
                    388:         G1I[HOME][194] = 119;
                    389:         G1O[HOME][119] = 194;       /* upper junction */
                    390:         G1I[HOME][179] = 120;
                    391:         G1O[HOME][120] = 179;       /* vertival bar */
                    392:         G1I[HOME][243] = 121;
                    393:         G1O[HOME][121] = 243;       /* lower equals */
                    394:         G1I[HOME][242] = 122;
                    395:         G1O[HOME][122] = 242;       /* greater equals */
                    396:         G1I[HOME][227] = 123;
                    397:         G1O[HOME][123] = 227;       /* pi */
                    398:         G1I[HOME][246] = 124;
                    399:         G1O[HOME][124] = 246;       /* not equals */
                    400:         G1I[HOME][128] = 125;
                    401:         G1O[HOME][125] = 128;       /* euro sign */
                    402:         G1I[HOME][250] = 126;
                    403:         G1O[HOME][126] = 250;       /* centered dot */
                    404:     #endif /* SCO */
                    405: }
                    406: 
                    407: void init_signals (void)
                    408: {
                    409:     sig_init ();
                    410: }
                    411: 
                    412: void init_timezone (void)
                    413: {
                    414:    
                    415:     struct tm lt;
                    416:     struct tm gt;
                    417: 
                    418:     unsigned long gmt;
                    419:     unsigned long lmt;
                    420: 
                    421:     long clock;
                    422: 
1.14      snw       423: #if defined(__CYGWIN__)
1.1       snw       424:     tzset ();                        /* may be required in order   */
                    425:                                      /* to guarantee _timezone set */
                    426: #else
                    427: 
                    428:     clock = time (0L);
                    429:     lt = *localtime (&clock);
                    430:     gt = *gmtime (&clock);
                    431: 
                    432:     /* This is awkward but I think it is portable: steve_morris */
                    433:     gmt = gt.tm_year * 365;
                    434:     gmt = (gmt + gt.tm_yday) * 24;
                    435:     gmt = (gmt + gt.tm_hour) * 60;
                    436:     gmt = (gmt + gt.tm_min);
                    437: 
                    438:     lmt = lt.tm_year * 365;
                    439:     lmt = (lmt + lt.tm_yday) * 24;
                    440:     lmt = (lmt + lt.tm_hour) * 60;
                    441:     lmt = (lmt + lt.tm_min);
                    442: 
                    443:     FreeM_timezone = (gmt - lmt) * 60;
                    444:     tzoffset = -FreeM_timezone;
                    445:     
                    446: #endif /* __CYGWIN__ */
                    447:     
                    448: 
                    449: }
                    450: 
                    451: void init_freem_path (void)
                    452: {
                    453: 
                    454:     if((freem_path = malloc(PATH_MAX + 1)) == NULL) {
                    455:         fprintf(stderr, "Can't allocate freem_path. Exiting.");
                    456: 
                    457:         exit(1);
                    458:     }
                    459: 
                    460:     freem_path[0] = NUL;
                    461: 
                    462:     /* check where I'm being executed from */
                    463: #ifdef __linux__
                    464:     readlink ("/proc/self/exe", freem_path, PATH_MAX);
                    465: #endif
                    466: #ifdef __FreeBSD__
                    467:     readlink ("/proc/curproc/file", freem_path, PATH_MAX);
                    468: #endif
                    469: #ifdef __sun
                    470:     readlink ("/proc/self/path/a.out", freem_path, PATH_MAX);
                    471: #endif
                    472: 
                    473:     if(freem_path[0] == NUL) {
                    474:         /* we don't know where we came from */
                    475:     }
                    476: 
                    477:     getcwd (curdir, PATHLEN);
                    478:     stcnv_c2m (curdir);
                    479:     
                    480: }
                    481: 
                    482: #if defined(HAVE_LIBREADLINE)
                    483: void init_readline (void)
                    484: {
                    485:     uid_t uid = geteuid ();
                    486:     struct passwd *pw = getpwuid (uid);
                    487:     char *pw_buf;
                    488: 
                    489:     pw_buf = (char *) calloc (strlen(pw->pw_dir) + 1, sizeof(char));
                    490:     strcpy (pw_buf, pw->pw_dir);
                    491: 
1.11      snw       492:     snprintf (history_file, sizeof (history_file) - 1, "%s/.freem_history", pw_buf);
1.1       snw       493: 
                    494:     free (pw_buf);
                    495: 
                    496:     using_history ();
                    497:     read_history (history_file);
                    498: }
                    499: #endif    
                    500: 
                    501: void init_execution_context (void)
                    502: {
                    503:     register int i;
                    504: 
                    505:     obj_init ();
                    506:     
                    507:     merr_clear ();
                    508:     
                    509:     codptr = code;
                    510:     code[0] = EOL;          /* init code_pointer */
                    511: 
1.14      snw       512:     if ((partition = calloc ((unsigned) (PSIZE + 2), 1)) == NULL) {
                    513:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate symbol table (error code %d [%s])", errno, strerror (errno));
                    514:     }
1.1       snw       515: 
                    516:     for (i = 0; i < MAXNO_OF_RBUF; i++) {
                    517:         rbuf_flags[i].standard = standard;
                    518:     }
                    519: 
                    520:     for (i = 0; i < NESTLEVLS; i++) {
                    521:         extr_types[i] = DT_STRING;
                    522:     }
                    523:     
                    524:     symlen = PSIZE;
                    525:     s = &partition[PSIZE] - 256;    /* pointer to symlen_offset        */
                    526:     argptr = partition;         /* pointer to beg of tmp-storage   */
                    527: 
1.14      snw       528:     if ((svntable = calloc ((unsigned) (UDFSVSIZ + 1), 1)) == NULL) {
                    529:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate user-defined ISV table (error code %d [%s])", errno, strerror (errno));
                    530:     }    
1.1       snw       531:     svnlen = UDFSVSIZ;          /* begin of udf_svn_table         */
                    532: 
1.14      snw       533:     if ((buff = calloc ((unsigned) NO_OF_RBUF * (unsigned) PSIZE0, 1)) == NULL) {
                    534:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate routine buffers (error code %d [%s])", errno, strerror (errno));
                    535:     }
1.1       snw       536:     
1.14      snw       537:     if ((newstack = calloc ((unsigned) NSIZE, 1)) == NULL) {
                    538:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate NEW stack (error code %d [%s])", errno, strerror (errno));
                    539:     }
1.1       snw       540: 
1.14      snw       541:     logprintf (FM_LOG_DEBUG, "allocating newptr stack...");
1.1       snw       542: 
                    543:     newptr = newstack;
                    544:     newlimit = newstack + NSIZE - 1024;
                    545:     
                    546: 
1.14      snw       547:     if ((namstck = calloc ((unsigned) NESTLEVLS * 13, 1)) == NULL) {
                    548:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate newptr stack (error code %d [%s])", errno, strerror (errno));
                    549:     }
                    550:     
1.1       snw       551:     *namstck = EOL;
                    552:     *(namstck + 1) = EOL;
                    553:     namptr = namstck;           /* routine name stack pointer       */
1.14      snw       554:     
                    555:     if ((framstck = calloc ((unsigned) NESTLEVLS * 256, 1)) == NULL) {
                    556:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate DO frame stack stack (error code %d [%s])", errno, strerror (errno));
                    557:     }
1.1       snw       558: 
                    559:     *framstck = EOL;
                    560:     *(framstck + 1) = EOL;
                    561:     dofrmptr = framstck;        /* DO_frame stack pointer           */
1.14      snw       562: 
                    563:     if ((cmdstack = calloc ((unsigned) NESTLEVLS * 256, 1)) == NULL) {
                    564:         logprintf (FM_LOG_FATAL, "init_execution_context:  could not allocate command stack (error code %d [%s])", errno, strerror (errno));
                    565:     }
1.1       snw       566: 
                    567:     cmdptr = cmdstack;          /* command stack */
                    568: 
                    569:     rouend = rouins = rouptr = buff;
                    570:     roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
                    571:     *rouptr = EOL;
                    572:     *(rouptr + 1) = EOL;
                    573:     *(rouptr + 2) = EOL;
                    574: 
                    575:     err_suppl[0] = EOL; /* empty out supplemental error info */
                    576: }
                    577: 
                    578: void init_estack (void)
                    579: {
                    580:     stcpy (merr_stack[0].PLACE, "xecline()\201");
                    581: }
                    582: 
                    583: #if defined(HAVE_MWAPI_MOTIF)
                    584: void init_mwapi (void)
                    585: {
                    586:     /*
                    587:     if (getenv("DISPLAY") != NULL) {
                    588:         gtk_init (0, NULL);
                    589:     }
                    590:     */
1.10      snw       591:     /* TODO: init Motif/libXt */
1.1       snw       592: }
                    593: #else
                    594: void init_mwapi (void)
                    595: {
                    596:     return;
                    597: }
                    598: #endif
                    599: 
                    600: void init_io (void)
                    601: {
                    602:     register int i;
                    603: 
                    604:     /* initialize screen */
                    605:     setbuf (stdin, NULL);      /* no input buffering */
                    606:     glvnflag.all = 0L;
                    607:     stcpy (buff, "\201");
                    608:     writeHOME (buff);
                    609:     sq_modes[0] = '+';
                    610:     for (i = 0; i <= MAXDEV; ug_buf[i++][0] = EOL); /* init read-buffers */
                    611: 
1.7       snw       612:     frm_crlf[HOME] = frm_filter;
1.1       snw       613: 
                    614:     if (hardcopy) zbreakon = ENABLE;        /* enable CTRL/B */
                    615: 
                    616:     set_io (MUMPS);         /* set i/o parameters */
                    617: 
1.8       snw       618: #if !defined(__AMIGA) && !defined(__OS2__)
1.1       snw       619:     if (ttyname (HOME)) {       /* for $IO of HOME */
                    620:         strcpy (dev[HOME], ttyname (HOME));
                    621:         dev[HOME][strlen (dev[HOME])] = EOL;
                    622:     } 
                    623:     else {
                    624:         dev[HOME][0] = EOL;     /* ...we are in a pipe */
                    625:     }
1.17      snw       626:     for (i = 5; i <= MAXDEV; i++) dev[i][0] = EOL;
1.1       snw       627: #else
1.8       snw       628: #if defined(__AMIGA)
1.1       snw       629:     strcpy (dev[HOME], "CONSOLE:");
1.8       snw       630: #else
                    631: #if defined(__OS2__)
                    632:     strcpy (dev[HOME], "CON:");
                    633: #endif
                    634: #endif
1.1       snw       635: #endif    
                    636: 
                    637:     /* init function keys */
                    638:     for (i = 0; i < 44; zfunkey[i++][0] = EOL);
                    639: }
                    640: 
                    641: void init_random_number (void)
                    642: {
                    643: 
                    644:     srand (time (NULL));
                    645: 
                    646:     if ((nrandom = time (0L) * getpid ()) < 0) {
                    647:         nrandom = (-nrandom);
                    648:     }
                    649: 
                    650: }
                    651: 
                    652: void init_ztrap (void)
                    653: {
                    654: 
                    655:     if (frm_filter) { 
                    656:         ztrap[0][0] = EOL;      /* no default ztrap for filters */
                    657:     }
                    658:     else if (startuprou[0] == '^') {
                    659:         stcpy (ztrap[0], startuprou);
                    660:     }
                    661:     else {
                    662:         stcpy (ztrap[0], "^%SYSINIT\201");
                    663:     }
                    664: 
                    665:     /* $ZT to be xecuted on startup */
                    666:     
                    667:     stcpy (ztrap[NESTLEVLS + 1], ztrap[0]); /* DSM V.2 error trapping */
                    668: 
                    669: }
                    670: 
                    671: void init_ssvn(void)
                    672: {
                    673:     ssvn_job_update ();
                    674:     ssvn_display_update ();
                    675:     ssvn_routine_update ();
                    676:     ssvn_library_update ();
                    677:     if (first_process) ssvn_system_update ();
                    678: }
                    679: 
                    680: void init_terminal(void)
                    681: {
                    682:     xpos[HOME] = 80;
                    683:     ypos[HOME] = 24;
                    684: }
                    685: 
                    686: void reset_terminal(void)
                    687: {
                    688:     struct termio tpara;
                    689: 
                    690:     ioctl (0, TCGETA, &tpara);
                    691: 
                    692:     tpara.c_lflag |= (ECHO | ICANON);  /* enable echo/no cbreak mode */
                    693:     tpara.c_iflag |= ICRNL;            /* cr-lf mapping */
                    694:     tpara.c_oflag |= ONLCR;            /* cr-lf mapping */
                    695:     tpara.c_cc[VMIN] = EOT;
                    696:     tpara.c_cc[VTIME] = -1;
                    697: 
                    698:     ioctl (0, TCSETA, &tpara);
                    699: }
                    700: 
                    701: void cleanup (void)
                    702: {
                    703:     char k_buf[256];
                    704:     int ch;
                    705: 
                    706:     /* remove this job's entry from ^$JOB SSVN */
1.11      snw       707:     snprintf (k_buf, sizeof (k_buf) - 1, "^$JOB\202%d\201", pid);
1.1       snw       708:     symtab_shm (kill_sym, k_buf, " \201");
                    709:     
                    710:     reset_terminal ();
                    711: 
                    712:     if (tp_level > 0) {
                    713: 
                    714:         if (direct_mode == TRUE) {
                    715:             fprintf (stderr, "UNCOMMITTED TRANSACTIONS EXIST:\n\n");
                    716:             tp_tdump ();
                    717:             set_io (UNIX);
                    718:             fprintf (stderr, "\nWould you like to c)ommit or r)ollback the above transactions and their operations? ($TLEVEL = %d) ", tp_level);
                    719: 
                    720:             for (;;) {
                    721:                 ch = fgetc (stdin);
                    722: 
                    723:                 if (ch == 'c' || ch == 'C') {
                    724:                     while (tp_level > 0) tp_tcommit ();
                    725: 
                    726:                     fprintf (stderr, "\n\nTransactions have been committed.\n");
                    727: 
                    728:                     break;
                    729:                 }
                    730:                 else if (ch == 'r' || ch == 'R') {
                    731:                     tp_trollback (tp_level);
                    732: 
                    733:                     fprintf (stderr, "\n\nTransactions have been rolled back.\n");
                    734: 
                    735:                     break;
                    736:                 }
                    737:                 else {
                    738:                     fprintf (stderr, "\n\nInvalid input '%c'. Must choose c)ommit or r)ollback.\n", ch);
                    739:                 }
                    740:             }
                    741:         }
                    742:         else {
                    743:             fprintf (stderr, "Uncommitted transactions exist. Rolling back.\n");
                    744:             tp_trollback (tp_level);
                    745:         }
                    746:     }
                    747: 
                    748: #if defined(HAVE_LIBREADLINE)
                    749:     write_history (history_file);
                    750: #endif
                    751: 
                    752:     locktab_unlock_all ();    
                    753:     job_remove (pid);
                    754: 
                    755:     shm_exit ();
                    756: 
                    757:     if (run_daemon == TRUE) {
                    758: 
                    759:         if (pid_fd != -1) {
                    760:             lockf (pid_fd, F_ULOCK, 0);
                    761:             close (pid_fd);
                    762:         }
                    763: 
                    764:         if (pid_file_path != NULL) {
                    765:             unlink (pid_file_path);
                    766:         }
                    767: 
1.18    ! snw       768:     }  
1.1       snw       769:     
                    770:     free (buff);            /* free previously allocated space */
                    771:     free (svntable);
                    772:     if (partition) free (partition);
                    773:     if (apartition) free (apartition);
                    774: 
                    775:    
                    776:     free (newstack);
                    777:     
                    778:     
                    779:     if (v22size) free (v22ali);    
                    780:     
                    781:     return;
                    782: }                   /* end of cleanup */

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