File:  [Coherent Logic Development] / freem / src / grestore.c
Revision 1.2: download - view: text, annotated - select for diffs
Sun Mar 9 15:20:18 2025 UTC (6 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Begin formatting overhaul and REUSE compliance

    1: /*
    2:  *                            *
    3:  *                           * *
    4:  *                          *   *
    5:  *                     ***************
    6:  *                      * *       * *
    7:  *                       *  MUMPS  *
    8:  *                      * *       * *
    9:  *                     ***************
   10:  *                          *   *
   11:  *                           * *
   12:  *                            *
   13:  *
   14:  *   grestore.c
   15:  *    repairs degraded freem globals
   16:  *
   17:  *  
   18:  *   Author: Serena Willis <snw@coherent-logic.com>
   19:  *    Copyright (C) 1998 MUG Deutschland
   20:  *    Copyright (C) 2020 Coherent Logic Development LLC
   21:  *
   22:  *
   23:  *   This file is part of FreeM.
   24:  *
   25:  *   FreeM is free software: you can redistribute it and/or modify
   26:  *   it under the terms of the GNU Affero Public License as published by
   27:  *   the Free Software Foundation, either version 3 of the License, or
   28:  *   (at your option) any later version.
   29:  *
   30:  *   FreeM is distributed in the hope that it will be useful,
   31:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   32:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33:  *   GNU Affero Public License for more details.
   34:  *
   35:  *   You should have received a copy of the GNU Affero Public License
   36:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   37:  *
   38:  **/
   39: 
   40: /* restores mumps globals.
   41:  * needs free disk storages approx. the size of the
   42:  * global to be restored. only data blocks are interpreted.
   43:  * it cannot recover from some errors in data blocks.
   44:  * anyway the global to be restored should be saved for
   45:  * a detailed analysis of the error.
   46:  */
   47: 
   48: #include <stdlib.h>
   49: #include <stddef.h>
   50: #include "mpsdef0.h"
   51: #include "errmsg.h"
   52: #include <signal.h>
   53: #include <setjmp.h>
   54: #include <stdio.h>
   55: #include <fcntl.h>
   56: #include <unistd.h>
   57: #include <sys/types.h>
   58: #include <sys/stat.h>
   59: #include <sys/wait.h>
   60: #include <string.h>
   61: 
   62: 
   63: /* needed if byte data are to be interpreted as unsigned integer */
   64: #define UNSIGN(A) ((A)&0377)
   65: 
   66: #define g_EOL 30
   67: #define POINT 28
   68: #define MINUS 26
   69: 
   70: #define ROOT 0L
   71: 	/* length of blocks. status bytes defined as offset to blocklength */
   72: #define DATALIM (BLOCKLEN-11)
   73: #define LLPTR   (BLOCKLEN-10)
   74: #define NRBLK    LLPTR
   75: #define RLPTR   (BLOCKLEN- 6)
   76: #define FREE     RLPTR
   77: #define BTYP    (BLOCKLEN- 3)
   78: #define OFFS    (BLOCKLEN- 2)
   79: 
   80: #define EMPTY    0
   81: #define FBLK     1
   82: #define POINTER  2
   83: #define BOTTOM   6
   84: #define DATA     8
   85: 
   86: #define PROTECT 30
   87: 
   88: 
   89: #ifndef SYSFIVE
   90:     #define FreeM_timezone -3600
   91: #else
   92: 
   93:     #ifdef __CYGWIN__
   94:         #define FreeM_timezone _timezone
   95:     #else
   96:         extern long FreeM_timezone;
   97:     #endif /* __CYGWIN__ */
   98: 
   99: #endif /* SYSFIVE */
  100: 
  101: /* mumps commands */
  102: #define BREAK       'b'
  103: #define CLOSE       'c'
  104: #define DO          'd'
  105: #define DO_BLOCK     2
  106: #define ELSE        'e'
  107: #define FOR         'f'
  108: #define GOTO        'g'
  109: #define HA          'h'
  110: #define HALT        '0'
  111: #define HANG        '1'
  112: #define IF          'i'
  113: #define JOB         'j'
  114: #define KILL        'k'
  115: #define LOCK        'l'
  116: #define NEW         'n'
  117: #define OPEN        'o'
  118: #define QUIT        'q'
  119: #define READ        'r'
  120: #define SET         's'
  121: #define USE         'u'
  122: #define VIEW        'v'
  123: #define WRITE       'w'
  124: #define XECUTE      'x'
  125: 
  126: #define ZALLOCATE   'A'
  127: #define ZBREAK      'B'
  128: #define ZDEALLOCATE 'D'
  129: #define ZGO         'G'
  130: #define ZHALT       'H'
  131: #define ZINSERT     'I'
  132: #define ZJOB        'J'
  133: #define ZLOAD       'L'
  134: #define ZNEW        'N'
  135: #define ZPRINT      'P'
  136: #define ZQUIT       'Q'
  137: #define ZREMOVE     'R'
  138: #define ZSAVE       'S'
  139: #define ZTRAP       'T'
  140: #define ZWRITE      'W'
  141: #define PRIVATE     SP
  142: 
  143: extern short ierr;
  144: 
  145: int main (argc, argv)
  146: 	int     argc;			/* arguments count */
  147: 	char   *argv[];			/* arguments string */
  148: 
  149: {
  150:     char    filnam[40];			/* global to be restored     */
  151:     static
  152:     char    savnam[512] = "^/usr/tmp/",	/* intermediate storage      */
  153:             unlnam[40] = "/usr/tmp/^";	/* "unlink" filename         */
  154:     short   fildes;			/* file descriptor to filnam */
  155:     char    block[BLOCKLEN];
  156:     char    key[512];
  157:     char    data[512];
  158:     unsigned long blknbr;
  159:     long    offset;
  160:     short   type;
  161:     long    length;
  162:     long    koffs;
  163: 
  164:     register int i,
  165:             j,
  166:             k,
  167:             ch;
  168: 
  169:     umask (0);				/* protection bits mask to full rights */
  170:     filnam[0] = '^';
  171:     filnam[1] = 0;
  172: 
  173:     if (argc > 1) {
  174: 	j = 0;
  175: 	while (--argc > 0) {
  176: 	    j++;
  177: 	    if (**(argv + j) == '-') {
  178: 		printf ("usage is: %s [^]global\012\015", *argv);
  179: 		exit (0);
  180: 	    }
  181: 	    strcpy (&filnam[1], *(argv + j));
  182: 	}
  183:     } else {
  184: 	printf ("\012\015%s global ^", *argv);
  185: 	scanf ("%s", &filnam[1]);
  186:     }
  187: 
  188:     j = filnam[1];
  189:     if (j == '.' || j == '/' || j == '^') {
  190: 	j = 0;
  191: 	while ((filnam[j] = filnam[j + 1]))
  192: 	    j++;
  193:     }
  194:     if ((fildes = open (filnam, 0)) == -1) {
  195: 	printf ("cannot open file %s\007\012\015", filnam);
  196: 	exit (1);
  197:     }
  198:     strcpy (&savnam[10], &filnam[1]);
  199:     koffs = 10 + strlen (&filnam[1]);
  200:     strcpy (&unlnam[10], &filnam[1]);
  201:     unlink (unlnam);			/* kill previous tmp_file */
  202:     blknbr = ROOT;
  203: 
  204:   again:;
  205: 
  206:     lseek (fildes, blknbr * BLOCKLEN, 0);
  207:     blknbr++;
  208:     if (read (fildes, block, BLOCKLEN) == 0) {
  209: 	strcpy (block, "mv /usr/tmp/\\^");
  210: 	strcat (block, &filnam[1]);
  211: 	strcat (block, " .");
  212: 	system (block);
  213: 	exit (0);
  214:     }
  215:     type = block[BTYP];
  216:     if (type != DATA)
  217: 	goto again;
  218: 
  219:     offset = UNSIGN (block[OFFS]) * 256 +
  220: 	    UNSIGN (block[OFFS + 1]);
  221:     if (offset > DATALIM) {
  222: 	printf ("illegal offset %ld\012", offset);
  223: 	offset = DATALIM;
  224:     }
  225:     i = 0;
  226:     while (i < offset) {
  227: 	length = UNSIGN (block[i++]);
  228: 	k = UNSIGN (block[i++]);
  229: 	if ((i + length) > offset)
  230: 	    break;
  231: 	for (j = 0; j < length; j++)
  232: 	    key[k++] = block[i++];
  233: 	key[k] = g_EOL;
  234: /*----------------------*/
  235: 	{
  236: 	    long    ch0,
  237: 	            i,
  238: 	            j,
  239: 	            k;
  240: 
  241: 	    j = 0;
  242: 	    i = 0;
  243: 	    data[j++] = DELIM;
  244: 	    k = 1;
  245: 	    while ((ch = UNSIGN (key[i++])) != g_EOL) {
  246: 		if (k) {
  247: 		    k = 0;
  248: 		}
  249: 		ch0 = (ch >= SP ? (ch >> 1) :	/* 'string' chars */
  250: 		       (ch < 20 ? (ch >> 1) + '0' :	/* 0...9          */
  251: 			(ch >> 1) + SP));	/* '.' or '-'     */
  252: 		if (ch0 == DEL) {
  253: 		    if (((ch = UNSIGN (key[i++])) >> 1) == DEL) {
  254: 			ch0 += DEL;
  255: 			ch = UNSIGN (key[i++]);
  256: 		    }
  257: 		    ch0 += (ch >> 1);
  258: 		}
  259: 		data[j++] = ch0;
  260: 		if (ch & 01) {
  261: 		    data[j++] = DELIM;
  262: 		    k = 1;
  263: 		}
  264: 	    }
  265: 	    data[j--] = EOL;
  266: 	    if (j == 0)
  267: 		data[0] = EOL;
  268: 	    else if (data[j] == DELIM)
  269: 		data[j] = EOL;
  270: 	    if ((koffs + j) > 255)
  271: 		goto again;		/* oversize subscript */
  272: 	    while (j >= 0) {
  273: 		if ((UNSIGN (ch = data[--j]) < SP) && (ch != DELIM))
  274: 		    break;
  275: 	    }
  276: 
  277: 	    if (j < 0)
  278: 		stcpy (&savnam[koffs], data);
  279: 	    else
  280: 		goto again;		/* illegal subscipt */
  281: /*----------------------*/
  282: 	}
  283: 	length = UNSIGN (block[i++]);
  284: 	k = 0;
  285: 	if ((i + length) > offset)
  286: 	    break;
  287: 	stcpy0 (data, &block[i], length);
  288: 	i += length;
  289: 	data[length] = EOL;
  290: 	global  (0, savnam, data);	/* call original global */
  291: 
  292: 	if (merr () == PROTECT) {
  293: 	    printf ("\012cannot open intermediate file in /usr/tmp\012");
  294: 	    exit (1);
  295: 	}
  296:     }
  297:     if (i != offset)
  298: 	printf ("\012wrong offset %ld vs. %d\012", offset, i);
  299:     goto again;
  300: }

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