File:  [Coherent Logic Development] / freem / src / grestore.c
Revision 1.4: download - view: text, annotated - select for diffs
Wed Apr 2 03:02:42 2025 UTC (4 months ago) by snw
Branches: MAIN
CVS tags: v0-63-1-rc1, v0-63-0-rc1, v0-63-0, HEAD
Stop requiring users to pass -e to fmadm when -u or -g are passed

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

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