[comp.unix.xenix] undump for Tex

debra@alice.UUCP (Paul De Bra) (12/10/88)

This is undump for SCO Xenix 286, release 2.2.1 or newer. It assumes that
no memory has been allocated (with malloc or sbrk) before dumping.
Tex is hacked so it reads fmt files with unbuffered I/O, to comply with
this requirement. This implies that one should not use virtex without
a preloaded fmt file all the time because that would be slow.

Put undump in a separate directory, in order not to clobber the makefile
for tex or the drivers.

================================ cut here ===============================
# To unbundle, sh this file
echo Makefile 1>&2
sed 's/.//' >Makefile <<'//GO.SYSIN DD Makefile'
-BINDIR=/usr/local
-
-undump: undump.o scanargs.o
-	cc -O -M2e -o undump undump.o scanargs.o
-
-undump.o: undump.c
-	cc -O -M2e -c undump.c
-
-clean:
-	rm -f *.o
-
-install: undump
-	cp undump $(BINDIR)
//GO.SYSIN DD Makefile
echo scanargs.c 1>&2
sed 's/.//' >scanargs.c <<'//GO.SYSIN DD scanargs.c'
-/*
-		Version 7 compatible
-	Argument scanner, scans argv style argument list.
-
-	Some stuff is a kludge because sscanf screws up
-
-	Gary Newman - 10/4/1979 - Ampex Corp.
-
-	Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to
-	add args introduced by 	a flag, add qscanargs call,
-	allow empty flags.
-
-	Compiling with QUICK defined generates 'qscanargs' ==
-	scanargs w/o floating point support; avoids huge size
-	of scanf.
-
-	If you make improvements we'd like to get them too.
-	Jay Lepreau	lepreau@utah-20, decvax!{harpo,randvax}!utah-cs!lepreau
-	Spencer Thomas	thomas@utah-20, decvax!{harpo,randvax}!utah-cs!thomas
-
-	(There seems to be a bug here in that if the last option you have
-	is a flag, and the user enters args incorrectly, sometimes the usage
-	message printed will miss the null and go flying off thru core...)
-							--jay for spencer
-*/
-#include <stdio.h>
-#include <ctype.h>
-
-#define YES 1
-#define NO 0
-#define ERROR(msg)  {fprintf(stderr, "msg\n"); goto error; }
-
-char	*prformat();
-
-#ifndef	QUICK
-scanargs (argc, argv, format, arglist)
-#else
-qscanargs (argc, argv, format, arglist)
-#endif
-int     argc;
-char  **argv;
-char   *format;
-int     arglist[];
-{
-#ifndef	QUICK
-    _scanargs (argc, argv, format, &arglist);
-#else
-    _qscanargs (argc, argv, format, &arglist);
-#endif
-}
-
-#ifndef	QUICK
-_scanargs (argc, argv, format, arglist)
-#else
-_qscanargs (argc, argv, format, arglist)
-#endif
-int     argc;
-char  **argv;
-char   *format;
-int    *arglist[];
-{
-    register    check;			/* check counter to be sure all argvs
-					   are processed */
-    register char  *cp;
-    register    cnt;
-    char    tmpflg;			/* temp flag */
-    char    c;
-    char    numnum;			/* number of numbers already processed
-					   */
-    char    numstr;			/* count # of strings already
-					   processed */
-    char    tmpcnt;			/* temp count of # things already
-					   processed */
-    char    required;
-    char    exflag;			/* when set, one of a set of exclusive
-					   flags is set */
-    char    excnt;			/* count of which exclusive flag is
-					   being processed */
-    char   *ncp;			/* remember cp during flag scanning */
-#ifndef	QUICK
-    char   *cntrl;			/* control string for scanf's */
-    char    junk[2];			/* junk buffer for scanf's */
-
-    cntrl = "% %1s";			/* control string initialization for
-					   scanf's */
-#endif
-    check = numnum = numstr = 0;
-    cp = format;
-    while (*cp)
-    {
-	required = NO;
-	switch (*(cp++))
-	{
-	    default: 			/* all other chars */
-		break;
-	    case '!': 			/* required argument */
-		required = YES;
-	    case '%': 			/* not required argument */
-		switch (tmpflg = *(cp++))
-		{
-		    case '-': 		/* argument is flag */
-		    /* go back to label */
-			ncp = cp-1;	/* remember */
-			cp -= 3;
-			for (excnt = exflag = 0
-				; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%'));
-				(--cp, excnt++))
-			{
-			    for (cnt = 1; cnt < argc; cnt++)
-			    {
-			    /* flags all start with - */
-				if (*argv[cnt] == '-' && !isdigit(argv[cnt][1]))
-				    if (*(argv[cnt] + 1) == *cp)
-				    {
-					if (*(argv[cnt] + 2) != 0)
-					    ERROR (extra flags ignored);
-					if (exflag)
-					    ERROR (more than one exclusive flag chosen);
-					exflag++;
-					required = NO;
-					check += cnt;
-					**arglist |=
-					    (1 << excnt);
-					break;
-				    }
-			    }
-			}
-			if (required)
-			    ERROR (flag argument missing);
-			cp = ncp;
-			if (!exflag)	/* if no flags scanned, skip */
-			{
-			    while (*++cp != ' ' && *cp)
-				if (*cp == '!' || *cp == '%')
-				    arglist++;
-			}
-			else
-			    cp++;	/* skip over - */
-			while (*cp == ' ')
-			    cp++;
-			arglist++;
-			break;
-		    case 's': 		/* char string */
-		    case 'd': 		/* decimal # */
-		    case 'o': 		/* octal # */
-		    case 'x': 		/* hexadecimal # */
-#ifndef	QUICK
-		    case 'f': 		/* floating # */
-#endif
-		    case 'D': 		/* long decimal # */
-		    case 'O': 		/* long octal # */
-		    case 'X': 		/* long hexadecimal # */
-#ifndef	QUICK
-		    case 'F': 		/* double precision floating # */
-#endif
-			tmpcnt = tmpflg == 's' ? numstr : numnum;
-			for (cnt = 1; cnt < argc; cnt++)
-			{
-			    if (tmpflg == 's')/* string */
-			    {
-				if ((c = *argv[cnt]) == '-')
-				    continue;
-				if (c >= '0' && c <= '9')
-				    continue;
-				if (tmpcnt-- != 0)
-				    continue;
-				**arglist = (int) argv[cnt];
-				check += cnt;
-				numstr++;
-				required = NO;
-				break;
-			    }
-			    if (*argv[cnt] == '-')
-			    {
-				if(!isdigit (*(argv[cnt] + 1)))
-				    continue;
-			    }
-			    else if (!isdigit(*argv[cnt]))
-				continue;
-			    if (tmpcnt-- != 0)/* skip to new one */
-				continue;
-#ifndef	QUICK
-			/* kludge for sscanf */
-			    if ((tmpflg == 'o' || tmpflg == 'O')
-				    && *argv[cnt] > '7')
-				ERROR (Bad numeric argument);
-			    cntrl[1] = tmpflg;/* put in conversion */
-			    if (sscanf (argv[cnt], cntrl, *arglist
-					,junk) != 1)
-#else
-			    if (numcvt(argv[cnt], tmpflg, *arglist) != 1)
-#endif
-				ERROR (Bad numeric argument);
-			    check += cnt;
-			    numnum++;
-			    required = NO;
-			    break;
-			}
-			if (required)
-			    switch (tmpflg)
-			    {
-				case 'x':
-				case 'X':
-				    ERROR (missing hexadecimal argument);
-				case 's':
-				    ERROR (missing string argument);
-				case 'o':
-				case 'O':
-				    ERROR (missing octal argument);
-				case 'd':
-				case 'D':
-				    ERROR (missing decimal argument);
-				case 'f':
-				case 'F':
-				    ERROR (missing floating argument);
-			    }
-			arglist++;
-			while (*cp == ' ')
-			    cp++;
-			break;
-		    default: 		/* error */
-			fprintf (stderr, "error in call to scanargs\n");
-			return (0);
-		}
-	}
-    }
-/*  Count up empty flags */
-    for (cnt=1; cnt<argc; cnt++)
-	if (argv[cnt][0] == '-' && argv[cnt][1] == 0)
-	    check += cnt;
- /* sum from 1 to N = n*(n+1)/2 used to count up checks */
-    if (check != (((argc - 1) * argc) / 2))
-	ERROR (extra arguments not processed);
-	    return (1);
-
-error:
-    fprintf (stderr, "usage : ");
-    if (*(cp = format) != ' ')
-	while (putc (*cp++, stderr) != ' ');
-    else
-	fprintf (stderr, "?? ");
-    while (*cp == ' ')
-	cp++;
-    prformat (cp, NO);
-    return 0;
-}
-
-char *
-prformat (format, recurse)
-char   *format;
-{
-    register char  *cp;
-    char    required;
-
-    cp = format;
-    if (recurse)
-	putc (' ', stderr);
-    required = NO;
-    while (*cp)
-    {
-	if (recurse && *cp == ' ')
-	    break;
-	switch (*cp)
-	{
-	    default:
-		cp++;
-		break;
-	    case '!':
-		required = YES;
-	    case '%':
-		switch (*++cp)
-		{
-		    case '-': 		/* flags */
-			if (!required)
-			{
-			    putc ('[', stderr);
-			    putc ('-', stderr);
-			}
-			else
-			{
-			    putc ('-', stderr);
-			    putc ('{', stderr);
-			}
-			cp = format;
-			while (*cp != '%' && *cp != '!')
-			    putc (*cp++, stderr);
-			if (required)
-			    putc ('}', stderr);
-			cp += 2;	/* skip !- or %- */
-			if (*cp != ' ')
-			    cp = prformat (cp, YES);
-					/* this is a recursive call */
-			if (!required)
-			    putc (']', stderr);
-			break;
-		    case 's': 		/* char string */
-		    case 'd': 		/* decimal # */
-		    case 'o': 		/* octal # */
-		    case 'x': 		/* hexadecimal # */
-		    case 'f': 		/* floating # */
-		    case 'D': 		/* long decimal # */
-		    case 'O': 		/* long octal # */
-		    case 'X': 		/* long hexadecimal # */
-		    case 'F': 		/* double precision floating # */
-			if (!required)
-			    putc ('[', stderr);
-			for (; format < cp - 1; format++)
-			    putc (*format, stderr);
-			if (!required)
-			    putc (']', stderr);
-			break;
-		    default:
-			break;
-		}
-		required = NO;
-		format = ++cp;
-		putc (' ', stderr);
-	}
-    }
-    if (!recurse)
-	putc ('\n', stderr);
-    return (cp);
-}
-
-#ifdef	QUICK
-numcvt(str, conv, val)
-register char *str;
-char conv;
-int *val;
-{
-    int base, neg = 0;
-    register unsigned int d;
-    long retval = 0;
-    register char *digits;
-    extern char *index();
-    if (conv == 'o' || conv == 'O')
-	base = 8;
-    else if (conv == 'd' || conv == 'D')
-	base = 10;
-    else if (conv == 'x' || conv == 'X')
-	base = 16;
-    else
-	return 0;
-
-    if (*str == '-')
-    {
-	neg = 1;
-	str++;
-    }
-    while (*str)
-    {
-	if (*str >= '0' && *str < '0'+base)
-	    d = *str - '0';
-	else if (base == 16 && *str >= 'a' && *str <= 'f')
-	    d = 10 + *str - 'a';
-	else if (base == 16 && *str >= 'A' && *str <= 'F')
-	    d = 10 + *str - 'A';
-	else
-	    return 0;
-	retval = retval*base + d;
-	str++;
-    }
-    if (neg)
-	retval = -retval;
-    if (conv == 'D' || conv == 'O' || conv == 'X')
-	*(long *) val = retval;
-    else
-	*val = (int) retval;
-    return 1;
-}
-#endif	QUICK
-
//GO.SYSIN DD scanargs.c
echo undump.c 1>&2
sed 's/.//' >undump.c <<'//GO.SYSIN DD undump.c'
-/*
- * undump.c - Convert a core file to an a.out.
- *
- * Author:	Spencer W. Thomas
- * 		Computer Science Dept.
- * 		University of Utah
- * Date:	Wed Feb 17 1982
- * Copyright (c) 1982 Spencer W. Thomas
- * Copyright Xenix version (c) 1987 Paul De Bra
- *
- * Usage:
- * undump new-a.out [a.out] [core]
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <sys/signal.h>
-#include <sys/user.h>
-#include <sys/proc.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/ulimit.h>
-#include <core.h>
-
-#define PSIZE	    10240
-char page[PSIZE];
-
-struct user u;
-struct xexec hdr, ohdr;
-struct xext exthdr;
-struct xseg seghdr[100];
-char mdttab[5000];
-long datacnt=0;
-long firstcnt=0;
-
-main(argc, argv)
-char **argv;
-{
-    char *new_name, *a_out_name = "a.out", *core_name = "core";
-    FILE *new, *a_out, *core;
-
-    if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
-	    &new_name, &a_out_name, &core_name)
-		    != 1)
-	exit(1);
-
-    if ((a_out = fopen(a_out_name, "r")) == NULL)
-    {
-	perror(a_out_name);
-	exit(1);
-    }
-    if ((core = fopen(core_name, "r")) == NULL)
-    {
-	perror(core_name);
-	exit(1);
-    }
-    if ((new = fopen(new_name, "w")) == NULL)
-    {
-	perror(new_name);
-	exit(1);
-    }
-
-    read_u(core);
-    make_hdr(new, a_out);
-    copy_segtable(new,a_out);
-    copy_text(new, a_out);
-    copy_data(new, core);
-    copy_sym(new, a_out);
-    fclose(new);
-    fclose(core);
-    fclose(a_out);
-    mark_x(new_name);
-}
-
-/*
- * read the u structure from the core file.
- */
-read_u(core)
-FILE *core;
-{
-    if ( fread(&u, sizeof u, 1, core) != 1 )
-    {
-	perror("Couldn't read user structure from core file");
-	exit(1);
-    }
-}
-
-/*
- * Make the header in the new a.out from the header in the old one
- * modified by the new data size.
- */
-make_hdr(new, a_out)
-FILE *new, *a_out;
-{
-    if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
-    {
-	perror("Couldn't read header from a.out file");
-	exit(1);
-    }
-    ohdr = hdr;
-    if (hdr.x_text != u.u_exdata.x_text ||
-	hdr.x_data + hdr.x_bss != u.u_exdata.x_data + u.u_exdata.x_bss)
-    {
-	fprintf(stderr, "Core file didn't come from this a.out\n");
-	exit(1);
-    }
-
-    hdr.x_bss = 0;			/* all data is inited now! */
-
-    if (fread(&exthdr, sizeof exthdr, 1, a_out) != 1)
-    {
-	perror("Couldn't read header extension from a.out file");
-	exit(1);
-    }
-}
-/* Copy the segment table from the a.out to the new a.out */
-copy_segtable(new,a_out)
-FILE *new, *a_out;
-{
-    int i;
-    long ofset=exthdr.xe_segsize+exthdr.xe_segpos;
-    fread(page,(int)exthdr.xe_segpos-sizeof(hdr)-sizeof(exthdr),1,a_out);
-    if (fread(seghdr, (int)exthdr.xe_segsize,1,a_out) != 1)
-    {
-	perror("Couldn't read segment table from a.out");
-	exit(1);
-    }
-    for (i=0;i<exthdr.xe_segsize/sizeof(struct xseg);i++)
-    {
-      if (seghdr[i].xs_type <3)
-	seghdr[i].xs_psize=seghdr[i].xs_vsize;
-      if (seghdr[i].xs_type == 2)
-	if (firstcnt==0)
-	  firstcnt = seghdr[i].xs_vsize;
-	else
-	  datacnt += seghdr[i].xs_vsize;
-      if (seghdr[i].xs_type == 4)
-        ofset+=4;
-      seghdr[i].xs_filpos=ofset;
-      ofset+=seghdr[i].xs_vsize;
-    }
-    hdr.x_data=firstcnt+datacnt;
-    if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
-    {
-	perror("Couldn't write header to new a.out file");
-	exit(1);
-    }
-    if (fwrite(&exthdr, sizeof exthdr,1,new) != 1)
-    {
-	perror("Couldn't write header extension to new a.out file");
-	exit(1);
-    }
-    fwrite(page,(int)exthdr.xe_segpos-sizeof(hdr)-sizeof(exthdr),1,new);
-    if (fwrite(seghdr, (int)exthdr.xe_segsize,1,new)!=1)
-    {
-	perror("Couldn't write segment table to new a.out");
-	exit(1);
-    }
-}
-
-/*
- * Copy the text from the a.out to the new a.out
- */
-copy_text(new, a_out)
-FILE *new, *a_out;
-{
-    long txtcnt = hdr.x_text;
-
-    if (hdr.x_magic == OMAGIC)
-    {
-	printf("a.out file is not shared text, getting text from core file\n");
-	fseek(a_out, hdr.x_text, 1);	/* skip over text */
-	return;
-    }
-    while (txtcnt >= PSIZE)
-    {
-	if (fread(page, PSIZE, 1, a_out) != 1)
-	{
-	    perror("Read failure on a.out text");
-	    exit(1);
-	}
-	if (fwrite(page, PSIZE, 1, new) != 1)
-	{
-	    perror("Write failure in text segment");
-	    exit(1);
-	}
-	txtcnt -= PSIZE;
-    }
-    if (txtcnt)
-    {
-	if (fread(page,(int)txtcnt, 1, a_out) != 1)
-	{
-	    perror("Read failure on a.out text");
-	    exit(1);
-	}
-	if (fwrite(page, (int)txtcnt, 1, new) != 1)
-	{
-	    perror("Write failure in text segment");
-	    exit(1);
-	}
-    }
-}
-
-/*
- * copy the data from the core file to the new a.out
- */
-copy_data(new, core)
-FILE *new, *core;
-{
-    struct stat corestat;
-    fstat(fileno(core),&corestat);
-    if (hdr.x_magic == OMAGIC)
-	datacnt += u.u_tsize;
-    fseek(core, corestat.st_size - hdr.x_data - u.u_ssize*512L, 0);
-    while (firstcnt >= PSIZE)
-    {
-	if (fread(page, PSIZE, 1, core) != 1)
-	{
-	    perror("Read failure on core data");
-	    exit(1);
-	}
-	if (fwrite(page, PSIZE, 1, new) != 1)
-	{
-	    perror("Write failure in data segment");
-	    exit(1);
-	}
-	firstcnt -= PSIZE;
-    }
-    if (firstcnt)
-    {
-	if (fread(page, (int)firstcnt, 1, core) != 1)
-	{
-	    perror("Read failure on core data");
-	    exit(1);
-	}
-	if (fwrite(page, (int)firstcnt, 1, new) != 1)
-	{
-	    perror("Write failure in data segment");
-	    exit(1);
-	}
-    }
-    fseek(core,(long)u.u_ssize*512L,1);
-    while (datacnt >= PSIZE)
-    {
-	if (fread(page, PSIZE, 1, core) != 1)
-	{
-	    perror("Read failure on core data");
-	    exit(1);
-	}
-	if (fwrite(page, PSIZE, 1, new) != 1)
-	{
-	    perror("Write failure in data segment");
-	    exit(1);
-	}
-	datacnt -= PSIZE;
-    }
-    if (datacnt)
-    {
-	if (fread(page, (int)datacnt, 1, core) != 1)
-	{
-	    perror("Read failure on core data");
-	    exit(1);
-	}
-	if (fwrite(page, (int)datacnt, 1, new) != 1)
-	{
-	    perror("Write failure in data segment");
-	    exit(1);
-	}
-    }
-}
-
-/*
- * Copy the relocation information and symbol table from the a.out to the new
- */
-copy_sym(new, a_out)
-FILE *new, *a_out;
-{
-    int n;
-    long total=0;
-
-    fseek(a_out, ohdr.x_data, 1);	/* skip over data segment */
-    while ((n = fread(page, 1, PSIZE, a_out)) > 0)
-    {
-	if (fwrite(page, 1, n, new) != n)
-	{
-	    perror("Error writing symbol table to new a.out");
-	    fprintf(stderr, "new a.out should be ok otherwise\n");
-	    return;
-	}
-	total+=n;
-    }
-    if (n < 0)
-    {
-	perror("Error reading symbol table from a.out");
-	fprintf(stderr, "new a.out should be ok otherwise\n");
-    }
-}
-
-/*
- * After succesfully building the new a.out, mark it executable
- */
-mark_x(name)
-char *name;
-{
-    struct stat sbuf;
-    int um;
-
-    um = umask(777);
-    umask(um);
-    if (stat(name, &sbuf) == -1)
-    {
-	perror ("Can't stat new a.out");
-	fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
-	sbuf.st_mode = 0777;
-    }
-    sbuf.st_mode |= 0111 & ~um;
-    if (chmod(name, sbuf.st_mode) == -1)
-	perror("Couldn't change mode of new a.out to executable");
-
-}
-
//GO.SYSIN DD undump.c
-- 
------------------------------------------------------
|debra@research.att.com   | uunet!research!debra     |
------------------------------------------------------