🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

3 total messages Started by R.MAUS Mon, 19 Aug 1985 23:18
bugs in file(1) on BTL SYS V (maybe others)
#446
Author: R.MAUS
Date: Mon, 19 Aug 1985 23:18
64 lines
2369 bytes
This line intentionally left non-blank for outdated news facilities.

(Copy of bug report reported to UNIX Support Group via "trouble" system)

BUG #1
    Index:
	.../src/cmd/file/file.c	(BTL SYS V)
    Description:
	"file(1)" fails	to match binary	data when the most significant bit
	is set for "short" types on Vaxen machines.  This is due to sign
	extension when the data	is internally converted	to a "long".
    Repeat-By:
	Create a test data file	that has a "short" value of "0177545" as
	the contents.  Use the following entry in the "/etc/magic" file	(or
	alternate).

		0	short	0177545		I bet you don't	see this!

	Run "file" over	the test data file.
    Fix:
	You can	probably modify	the following code:

		case SHORT:
			val = (long)(*(short *)	p);
			break;

	to read	(something to the effect of):

		case SHORT:
			val = (long)(*(unsigned	short *) p);
			break;

	This is	a quick	hack at	best.

BUG #2
    Index:
	.../src/cmd/file/file.c	(BTL SYS V)
    Description:
	"file(1)" does not check the "type" field of the "magic" file for a
	complete pattern match,	but rather it keys off the first few
	letters.  Therefore, the following "type" patterns are legal:

		PATTERN	TYPE	COMMENT
		sh*	short
		s*	string	After "sh*" pattern has	been eliminated.
		l*	long
    Fix:
	Use full string	comparision on the type	field.

BUG #3
    Index:
	.../src/cmd/file/file.c	(BTL SYS V)
    Description:
	No provision for "byte"	(or "char") specifier type.  It	would also
	be nice	to have	an "unsigned" type.
    Fix:
	Some of	the scaffolding	for the	code exists, but no check is made
	for the	type against the "magic" file.	The rest is left as an
	exercise for the reader.
--

				Richard L. Maus, Jr. (Rick)
				AT&T-ISL HO 1K313 201-834-4532
				...!ho???!ariel!rick
Re: bugs in file(1) on BTL SYS V (maybe others)
#454
Author: Greg Noel
Date: Thu, 22 Aug 1985 23:34
18 lines
1220 bytes
In article <1005@ariel.UUCP> rick@ariel.UUCP (R.MAUS) writes:
>BUG #1
>    Fix:
>		case SHORT:
>			val = (long)(*(short *)	p);
>			break;
>
>	to read	(something to the effect of):
>
>		case SHORT:
>			val = (long)(*(unsigned	short *) p);
>			break;
>
There is a similar cast a few lines below the one quoted that also must be
fixed.  Change the (long)(*(char *) p) into (long)(*(unsigned char *) p).
Then the problem identified in bug #3 has a chance of working.....
-- 
-- Greg Noel, NCR Rancho Bernardo    Greg@ncr-sd.UUCP or Greg@nosc.ARPA
Some improvements to "file"
#460
Author: Guy Harris
Date: Tue, 03 Sep 1985 08:17
971 lines
20605 bytes
1) The SCCS ID contains an extraneous <ESC>, if anybody cares...

2) A new type "byte" has been added to the magic number types in /etc/magic
(the scaffolding was already there), and the numeric types now support an
optional masking operator.  If a mask is specified, the value is ANDed with
the specified mask before it is compared with any test values and before it
is printed.

3) The test values for the "string" type can now contain C string escape
sequences, such as "\n" for newline.

4) The return value of "malloc" is now tested, and the internal table of
/etc/magic file entries is now "realloc"ed if it fills up; printing a
message saying to change some magic number in the source and recompile is
rather dumb, considering most S5 users outside AT&T *don't* have the source
to do that with...

5) The error messages have been cleaned up, and error messages due to
"open"s or "stat"s failing now include the error message corresponding to
the value of "errno".

6) When it tries to reset the time of last access, it now uses "ustat" the
way the manual says you're supposed to.  Thus, it won't fail on systems like
4.2BSD, where "st_atime" and "st_mtime" aren't contiguous.  (Note that the
S3/S5 manual go out of their way *NOT* to tell you that they're contiguous;
somebody made an effort to prevent the very sort of crap that "file",
"cpio", and "pack" do.)

7) Several bits of code, such as the code that parses /etc/magic and the
code that prints the table built from /etc/magic, have been cleaned up.

Note that the bug report (in the referenced articles) about "unsigned short"
vs. "short" may be fixed in the original S5R2 version (they may have seen
the bug in S5R1) - some of the suggested changes seem to have been made).
The version here corrects the other two complaints about no "byte" type and
halfassed checking of the type field in general.

Note that the 4.2BSD version has a number of other useful tests (like tests
against "ditroff" output) which should be tossed into the S5 version.

The original reason I put in the stuff under 2) and 3) was to make it
possible to test for a "compress"ed file (see mod.sources for "compress"
version 4 - it blows "pack" and "compact" away), and to test for block
compression and to dump the number of bits required for decompression,
without having to hack the source.  Here's the entry for "compressed" files:

0	string		\037\235	compressed data
>2	byte&0x80	>0		block compressed
>2	byte&0x1f	x		%d bits

What it means is "test the two bytes starting at location 0 in the file.  If
they are equal to \037 and \235 respectively, print 'compressed data'.  Then
test whether the byte at location 2, when masked with 0x80, is non-zero.  If
so, print 'block compressed'.  Then print that byte, masked with 0x1f, in
the form '<N> bits'."

The gory details of how to construct a "magic" file are given (sketchily,
and *sans* these new features) in "/etc/magic".  This is the wrong place to
give them.  The correct place to give them is MAGIC(4), which I have whipped
up and posted in another article.

Here are the changes, in "diff -c" form:

*** /arch/s5r2/usr/src/cmd/file/file.c	Mon Oct 31 06:46:34 1983
--- ./file.c	Tue Sep  3 00:57:47 1985
***************
*** 2,8
  
  #include	<stdio.h>
  #include	<ctype.h>
- #include	<signal.h>
  #include	<sys/param.h>
  #include	<sys/types.h>
  #include	<sys/sysmacros.h>

--- 2,7 -----
  
  #include	<stdio.h>
  #include	<ctype.h>
  #include	<sys/param.h>
  #include	<sys/types.h>
  #include	<sys/sysmacros.h>
***************
*** 13,21
  */
  
  #define	BYTE	0
! #define	SHORT	2
! #define	LONG	4
! #define	STR	8
  
  /*
  **	Opcodes

--- 12,20 -----
  */
  
  #define	BYTE	0
! #define	SHORT	1
! #define	LONG	2
! #define	STR	3
  
  #define	NTYPES	4
  
***************
*** 17,22
  #define	LONG	4
  #define	STR	8
  
  /*
  **	Opcodes
  */

--- 16,30 -----
  #define	LONG	2
  #define	STR	3
  
+ #define	NTYPES	4
+ 
+ char	*typenames[NTYPES] = {
+ 	"byte",
+ 	"short",
+ 	"long",
+ 	"string"
+ };
+ 
  /*
  **	Opcodes
  */
***************
*** 28,33
  #define	ANY	4
  #define	SUB	64	/* or'ed in */
  
  /*
  **	Misc
  */

--- 36,51 -----
  #define	ANY	4
  #define	SUB	64	/* or'ed in */
  
+ #define	NOPS	5
+ 
+ char	opnames[NOPS] = {
+ 	'=',
+ 	'>',
+ 	'<',
+ 	'=',
+ 	'x'
+ };
+ 
  /*
  **	Misc
  */
***************
*** 51,56
  	char	e_level;	/* 0 or 1 */
  	long	e_off;		/* in bytes */
  	char	e_type;
  	char	e_opcode;
  	union	{
  		long	num;

--- 69,75 -----
  	char	e_level;	/* 0 or 1 */
  	long	e_off;		/* in bytes */
  	char	e_type;
+ 	long	e_mask;		/* if non-zero, mask value with this */
  	char	e_opcode;
  	union	{
  		long	num;
***************
*** 61,67
  
  typedef	struct entry	Entry;
  
! Entry	*mtab;
  char	fbuf[FBSZ];
  char	*mfile = "/etc/magic";
  char	*fort[] = {

--- 80,89 -----
  
  typedef	struct entry	Entry;
  
! Entry	*mtab, *mend;
! int	errno;
! int	sys_nerr;
! char	*sys_errlist[];
  char	fbuf[FBSZ];
  char	*mfile = "/etc/magic";
  char	*fort[] = {
***************
*** 76,81
  char	*strchr();
  char	*malloc();
  long	atolo();
  int	i = 0;
  int	fbsz;
  int	ifd;

--- 98,105 -----
  char	*strchr();
  char	*malloc();
  long	atolo();
+ char	*getstr();
+ void	showstr();
  int	i = 0;
  int	fbsz;
  int	ifd = -1;
***************
*** 78,84
  long	atolo();
  int	i = 0;
  int	fbsz;
! int	ifd;
  
  #define	prf(x)	printf("%s:%s", x, strlen(x)>6 ? "\t" : "\t\t");
  

--- 102,108 -----
  void	showstr();
  int	i = 0;
  int	fbsz;
! int	ifd = -1;
  
  #define	prf(x)	printf("%s:%s", x, strlen(x)>6 ? "\t" : "\t\t");
  
***************
*** 102,108
  	case 'f':
  		fflg++;
  		if ((fl = fopen(optarg, "r")) == NULL) {
! 			fprintf(stderr, "cannot open %s\n", optarg);
  			goto use;
  		}
  		break;

--- 126,133 -----
  	case 'f':
  		fflg++;
  		if ((fl = fopen(optarg, "r")) == NULL) {
! 			fprintf(stderr, "file: %s: %s\n", optarg,
! 			    errno < sys_nerr? sys_errlist[errno]: "Can't open");
  			goto use;
  		}
  		break;
***************
*** 125,134
  		reg	Entry	*ep;
  
  		mkmtab(1);
! 		printf("level	off	type	opcode	value	string\n");
! 		for(ep = mtab; ep->e_off != -1L; ep++) {
! 			printf("%d\t%d\t%d\t%d\t", ep->e_level, ep->e_off,
! 				ep->e_type, ep->e_opcode);
  			if(ep->e_type == STR)
  				printf("%s\t", ep->e_value.str);
  			else

--- 150,162 -----
  		reg	Entry	*ep;
  
  		mkmtab(1);
! 		printf("level\toff\ttype\topcode\tvalue\tstring\n");
! 		for(ep = mtab; ep < mend; ep++) {
! 			printf("%d\t%d\t%s", ep->e_level, ep->e_off,
! 				typenames[ep->e_type]);
! 			if(ep->e_mask != 0L)
! 				printf("&%#lo", ep->e_mask);
! 			printf("\t%c\t", opnames[ep->e_opcode & ~SUB]);
  			if(ep->e_type == STR)
  				showstr(ep->e_value.str);
  			else
***************
*** 130,136
  			printf("%d\t%d\t%d\t%d\t", ep->e_level, ep->e_off,
  				ep->e_type, ep->e_opcode);
  			if(ep->e_type == STR)
! 				printf("%s\t", ep->e_value.str);
  			else
  				printf("%lo\t", ep->e_value.num);
  			printf("%s", ep->e_str);

--- 158,164 -----
  				printf("&%#lo", ep->e_mask);
  			printf("\t%c\t", opnames[ep->e_opcode & ~SUB]);
  			if(ep->e_type == STR)
! 				showstr(ep->e_value.str);
  			else
  				printf("%lo\t", ep->e_value.num);
  			printf("%s", ep->e_str);
***************
*** 156,162
  			p = argv[optind];
  		prf(p);
  		type(p);
! 		if(ifd)
  			close(ifd);
  	}
  	exit(0);

--- 184,190 -----
  			p = argv[optind];
  		prf(p);
  		type(p);
! 		if(ifd >= 0)
  			close(ifd);
  	}
  	exit(0);
***************
*** 168,173
  	int	j,nl;
  	char	ch;
  	struct	stat	mbuf;
  
  	ifd = -1;
  	if(stat(file, &mbuf) < 0) {

--- 196,205 -----
  	int	j,nl;
  	char	ch;
  	struct	stat	mbuf;
+ 	struct	utimbuf {
+ 		time_t	actime;
+ 		time_t	modtime;
+ 	}	utb;
  
  	ifd = -1;
  	if(stat(file, &mbuf) < 0) {
***************
*** 171,177
  
  	ifd = -1;
  	if(stat(file, &mbuf) < 0) {
! 		printf("cannot open\n");
  		return;
  	}
  	switch (mbuf.st_mode & S_IFMT) {

--- 203,210 -----
  
  	ifd = -1;
  	if(stat(file, &mbuf) < 0) {
! 		printf("%s\n",
! 		(unsigned)errno < sys_nerr? sys_errlist[errno]: "Cannot stat");
  		return;
  	}
  	switch (mbuf.st_mode & S_IFMT) {
***************
*** 197,203
  	}
  	ifd = open(file, 0);
  	if(ifd < 0) {
! 		printf("cannot open for reading\n");
  		return;
  	}
  	fbsz = read(ifd, fbuf, FBSZ);

--- 230,237 -----
  	}
  	ifd = open(file, 0);
  	if(ifd < 0) {
! 		printf("%s\n",
! 		(unsigned)errno < sys_nerr? sys_errlist[errno]: "Cannot read");
  		return;
  	}
  	fbsz = read(ifd, fbuf, FBSZ);
***************
*** 206,212
  		goto out;
  	}
  	if(sccs()) {
! 		printf("sccs \n");
  		goto out;
  	}
  	if(ckmtab())

--- 240,246 -----
  		goto out;
  	}
  	if(sccs()) {
! 		printf("sccs\n");
  		goto out;
  	}
  	if(ckmtab())
***************
*** 318,324
  	for(i=0; i < fbsz; i++)
  		if(fbuf[i]&0200) {
  			if (fbuf[0]=='\100' && fbuf[1]=='\357') {
! 				printf("troff output\n");
  				goto out;
  			}
  			printf("data\n"); 

--- 352,358 -----
  	for(i=0; i < fbsz; i++)
  		if(fbuf[i]&0200) {
  			if (fbuf[0]=='\100' && fbuf[1]=='\357') {
! 				printf("otroff output\n");
  				goto out;
  			}
  			printf("data\n"); 
***************
*** 338,344
  		}
  	printf("\n");
  out:
! 	utime(file, &mbuf.st_atime);
  }
  
  mkmtab(cflg)

--- 372,380 -----
  		}
  	printf("\n");
  out:
! 	utb.actime = mbuf.st_atime;
! 	utb.modtime = mbuf.st_mtime;
! 	(void)utime(file, &utb);
  }
  
  mkmtab(cflg)
***************
*** 347,352
  	reg	Entry	*ep;
  	reg	FILE	*fp;
  	reg	int	lcnt = 0;
  	auto	char	buf[BSZ];
  	auto	Entry	*mend;
  

--- 383,389 -----
  	reg	Entry	*ep;
  	reg	FILE	*fp;
  	reg	int	lcnt = 0;
+ 	reg	int	i;
  	auto	char	buf[BSZ];
  	auto	int	curentry;
  	auto	int	nentries;
***************
*** 348,354
  	reg	FILE	*fp;
  	reg	int	lcnt = 0;
  	auto	char	buf[BSZ];
! 	auto	Entry	*mend;
  
  	ep = (Entry *) calloc(sizeof(Entry), NENT);
  	if(ep == NULL) {

--- 385,392 -----
  	reg	int	lcnt = 0;
  	reg	int	i;
  	auto	char	buf[BSZ];
! 	auto	int	curentry;
! 	auto	int	nentries;
  
  	mtab = (Entry *) malloc(sizeof(Entry)*NENT);
  	if(mtab == NULL) {
***************
*** 350,358
  	auto	char	buf[BSZ];
  	auto	Entry	*mend;
  
! 	ep = (Entry *) calloc(sizeof(Entry), NENT);
! 	if(ep == NULL) {
! 		fprintf(stderr, "no memory for magic table\n");
  		exit(2);
  	}
  	mtab = ep;

--- 388,396 -----
  	auto	int	curentry;
  	auto	int	nentries;
  
! 	mtab = (Entry *) malloc(sizeof(Entry)*NENT);
! 	if(mtab == NULL) {
! 		fprintf(stderr, "file: no memory for magic table\n");
  		exit(2);
  	}
  	curentry = 0;
***************
*** 355,362
  		fprintf(stderr, "no memory for magic table\n");
  		exit(2);
  	}
! 	mtab = ep;
! 	mend = &mtab[NENT];
  	fp = fopen(mfile, "r");
  	if(fp == NULL) {
  		fprintf(stderr, "cannot open magic file <%s>.\n", mfile);

--- 393,400 -----
  		fprintf(stderr, "file: no memory for magic table\n");
  		exit(2);
  	}
! 	curentry = 0;
! 	nentries = NENT;
  	fp = fopen(mfile, "r");
  	if(fp == NULL) {
  		fprintf(stderr, "file: cannot open magic file <%s>: %s\n",
***************
*** 359,365
  	mend = &mtab[NENT];
  	fp = fopen(mfile, "r");
  	if(fp == NULL) {
! 		fprintf(stderr, "cannot open magic file <%s>.\n", mfile);
  		exit(2);
  	}
  	while(fgets(buf, BSZ, fp) != NULL) {

--- 397,404 -----
  	nentries = NENT;
  	fp = fopen(mfile, "r");
  	if(fp == NULL) {
! 		fprintf(stderr, "file: cannot open magic file <%s>: %s\n",
! 		    mfile, errno < sys_nerr? sys_errlist[errno]: "Can't open");
  		exit(2);
  	}
  	while(fgets(buf, BSZ, fp) != NULL) {
***************
*** 365,370
  	while(fgets(buf, BSZ, fp) != NULL) {
  		reg	char	*p = buf;
  		reg	char	*p2;
  		reg	char	opc;
  
  		if(*p == '\n' || *p == '#')

--- 404,410 -----
  	while(fgets(buf, BSZ, fp) != NULL) {
  		reg	char	*p = buf;
  		reg	char	*p2;
+ 		reg	char	*p3;
  		reg	char	opc;
  
  		ep = &mtab[curentry];
***************
*** 367,372
  		reg	char	*p2;
  		reg	char	opc;
  
  		if(*p == '\n' || *p == '#')
  			continue;
  		lcnt++;

--- 407,413 -----
  		reg	char	*p3;
  		reg	char	opc;
  
+ 		ep = &mtab[curentry];
  		if(*p == '\n' || *p == '#')
  			continue;
  		lcnt++;
***************
*** 397,409
  			continue;
  		}
  		*p2++ = NULL;
! 		if(*p == 's') {
! 			if(*(p+1) == 'h')
! 				ep->e_type = SHORT;
! 			else
! 				ep->e_type = STR;
! 		} else if (*p == 'l')
! 			ep->e_type = LONG;
  		while(*p2 == '\t')
  			*p2++;
  			/* OP-VALUE */

--- 438,458 -----
  			continue;
  		}
  		*p2++ = NULL;
! 		p3 = strchr(p, '&');
! 		if(p3 != NULL) {
! 			*p3++ = '\0';
! 			ep->e_mask = atolo(p3);
! 		} else
! 			ep->e_mask = 0L;
! 		for (i = 0; i < NTYPES; i++) {
! 			if (strcmp(p, typenames[i]) == 0)
! 				goto foundtype;
! 		}
! 		if(cflg)
! 			fprintf(stderr, "file: illegal type %s\n", p);
! 		continue;
! foundtype:
! 		ep->e_type = i;
  		while(*p2 == '\t')
  			*p2++;
  			/* OP-VALUE */
***************
*** 411,417
  		p2 = strchr(p, '\t');
  		if(p2 == NULL) {
  			if(cflg)
! 				fprintf(stderr, "fmt error, no tab after %son line %d\n", p, lcnt);
  			continue;
  		}
  		*p2++ = NULL;

--- 460,466 -----
  		p2 = strchr(p, '\t');
  		if(p2 == NULL) {
  			if(cflg)
! 				fprintf(stderr, "file: fmt error, no tab after %son line %d\n", p, lcnt);
  			continue;
  		}
  		*p2++ = '\0';
***************
*** 414,420
  				fprintf(stderr, "fmt error, no tab after %son line %d\n", p, lcnt);
  			continue;
  		}
! 		*p2++ = NULL;
  		if(ep->e_type != STR) {
  			opc = *p++;
  			switch(opc) {

--- 463,469 -----
  				fprintf(stderr, "file: fmt error, no tab after %son line %d\n", p, lcnt);
  			continue;
  		}
! 		*p2++ = '\0';
  		if(ep->e_type != STR) {
  			opc = *p++;
  			for (i = 0; i < NOPS; i++) {
***************
*** 417,441
  		*p2++ = NULL;
  		if(ep->e_type != STR) {
  			opc = *p++;
! 			switch(opc) {
! 			case '=':
! 				ep->e_opcode = EQ;
! 				break;
! 
! 			case '>':
! 				ep->e_opcode = GT;
! 				break;
! 
! 			case '<':
! 				ep->e_opcode = LT;
! 				break;
! 
! 			case 'x':
! 				ep->e_opcode = ANY;
! 				break;
! 
! 			default:
! 				p--;
  			}
  		}
  		if(ep->e_opcode != ANY) {

--- 466,474 -----
  		*p2++ = '\0';
  		if(ep->e_type != STR) {
  			opc = *p++;
! 			for (i = 0; i < NOPS; i++) {
! 				if (opc == opnames[i])
! 					goto foundop;
  			}
  			p--;
  			goto notfound;
***************
*** 437,442
  			default:
  				p--;
  			}
  		}
  		if(ep->e_opcode != ANY) {
  			if(ep->e_type != STR)

--- 470,479 -----
  				if (opc == opnames[i])
  					goto foundop;
  			}
+ 			p--;
+ 			goto notfound;
+ 	foundop:
+ 			ep->e_opcode = i;
  		}
  notfound:
  		if(ep->e_opcode != ANY) {
***************
*** 438,443
  				p--;
  			}
  		}
  		if(ep->e_opcode != ANY) {
  			if(ep->e_type != STR)
  				ep->e_value.num = atolo(p);

--- 475,481 -----
  	foundop:
  			ep->e_opcode = i;
  		}
+ notfound:
  		if(ep->e_opcode != ANY) {
  			if(ep->e_type != STR)
  				ep->e_value.num = atolo(p);
***************
*** 441,450
  		if(ep->e_opcode != ANY) {
  			if(ep->e_type != STR)
  				ep->e_value.num = atolo(p);
! 			else {
! 				ep->e_value.str = malloc(strlen(p) + 1);
! 				strcpy(ep->e_value.str, p);
! 			}
  		}
  		while(*p2 == '\t')
  			*p2++;

--- 479,486 -----
  		if(ep->e_opcode != ANY) {
  			if(ep->e_type != STR)
  				ep->e_value.num = atolo(p);
! 			else
! 				ep->e_value.str = getstr(p);
  		}
  		while(*p2 == '\t')
  			*p2++;
***************
*** 450,455
  			*p2++;
  			/* STRING */
  		ep->e_str = malloc(strlen(p2) + 1);
  		p = ep->e_str;
  		while(*p2 != '\n') {
  			if(*p2 == '%')

--- 486,495 -----
  			*p2++;
  			/* STRING */
  		ep->e_str = malloc(strlen(p2) + 1);
+ 		if(ep->e_str == NULL) {
+ 			fprintf(stderr, "file: no memory for magic table\n");
+ 			exit(2);
+ 		}
  		p = ep->e_str;
  		while(*p2 != '\n') {
  			if(*p2 == '%')
***************
*** 457,466
  			*p++ = *p2++;
  		}
  		*p = NULL;
! 		ep++;
! 		if(ep >= mend) {
! 			fprintf(stderr, "file: magic tab overflow - increase NENT in file.c.\n");
! 			exit(2);
  		}
  	}
  	ep->e_off = -1L;

--- 497,510 -----
  			*p++ = *p2++;
  		}
  		*p = NULL;
! 		curentry++;
! 		if(curentry >= nentries) {
! 			mtab = (Entry *) realloc(mtab, sizeof(Entry)*NENT);
! 			if(mtab == NULL) {
! 				fprintf(stderr, "file: no memory for magic table\n");
! 				exit(2);
! 			}
! 			nentries += NENT;
  		}
  	}
  	mend = &mtab[curentry];
***************
*** 463,469
  			exit(2);
  		}
  	}
! 	ep->e_off = -1L;
  }
  
  long

--- 507,513 -----
  			nentries += NENT;
  		}
  	}
! 	mend = &mtab[curentry];
  }
  
  long
***************
*** 486,491
  	return(j);
  }
  
  ckmtab()
  {
  

--- 530,661 -----
  	return(j);
  }
  
+ char *
+ getstr(s)
+ reg	char	*s;
+ {
+ 	auto	char	*store;
+ 	reg	char	*p;
+ 	reg	char	c;
+ 	reg	int	val;
+ 
+ 	if((store = malloc(strlen(s) + 1)) == NULL) {
+ 		fprintf(stderr, "file: no memory for magic table\n");
+ 		exit(2);
+ 	}
+ 	p = store;
+ 	while((c = *s++) != '\0') {
+ 		if(c == '\\') {
+ 			switch(c = *s++) {
+ 
+ 			case '\0':
+ 				goto out;
+ 
+ 			default:
+ 				*p++ = c;
+ 				break;
+ 
+ 			case 'n':
+ 				*p++ = '\n';
+ 				break;
+ 
+ 			case 'r':
+ 				*p++ = '\r';
+ 				break;
+ 
+ 			case 'b':
+ 				*p++ = '\b';
+ 				break;
+ 
+ 			case 't':
+ 				*p++ = '\t';
+ 				break;
+ 
+ 			case 'f':
+ 				*p++ = '\f';
+ 				break;
+ 
+ 			case 'v':
+ 				*p++ = '\v';
+ 				break;
+ 
+ 			case '0':
+ 			case '1':
+ 			case '2':
+ 			case '3':
+ 			case '4':
+ 			case '5':
+ 			case '6':
+ 			case '7':
+ 				val = c - '0';
+ 				c = *s++;  /* try for 2 */
+ 				if(c >= '0' && c <= '7') {
+ 					val = (val<<3) | (c - '0');
+ 					c = *s++;  /* try for 3 */
+ 					if(c >= '0' && c <= '7')
+ 						val = (val<<3) | (c-'0');
+ 					else
+ 						--s;
+ 				}
+ 				else
+ 					--s;
+ 				*p++ = val;
+ 				break;
+ 			}
+ 		} else
+ 			*p++ = c;
+ 	}
+ out:
+ 	*p = '\0';
+ 	return(store);
+ }
+ 
+ void
+ showstr(s)
+ reg	char	*s;
+ {
+ 	reg	char	c;
+ 
+ 	while((c = *s++) != '\0') {
+ 		if(c >= 040 && c <= 0176)
+ 			putchar(c);
+ 		else {
+ 			putchar('\\');
+ 			switch (c) {
+ 			
+ 			case '\n':
+ 				putchar('n');
+ 				break;
+ 
+ 			case '\r':
+ 				putchar('r');
+ 				break;
+ 
+ 			case '\b':
+ 				putchar('b');
+ 				break;
+ 
+ 			case '\t':
+ 				putchar('t');
+ 				break;
+ 
+ 			case '\f':
+ 				putchar('f');
+ 				break;
+ 
+ 			case '\v':
+ 				putchar('v');
+ 				break;
+ 
+ 			default:
+ 				printf("%.3o", c & 0377);
+ 				break;
+ 			}
+ 		}
+ 	}
+ 	putchar('\t');
+ }
+ 
  ckmtab()
  {
  
***************
*** 502,508
  		mkmtab(0);
  		init = 1;
  	}
! 	for(ep = mtab; ep->e_off != -1L; ep++) {
  		if(lev1) {
  			if(ep->e_level != 1)
  				break;

--- 672,678 -----
  		mkmtab(0);
  		init = 1;
  	}
! 	for(ep = mtab; ep < mend; ep++) {
  		if(lev1) {
  			if(ep->e_level != 1)
  				break;
***************
*** 534,539
  			val.l = (*(long *) p);
  			break;
  		}
  		switch(ep->e_opcode & ~SUB) {
  		case EQ:
  #ifdef u3b

--- 704,711 -----
  			val.l = (*(long *) p);
  			break;
  		}
+ 		if(ep->e_mask)
+ 			val.l &= ep->e_mask;
  		switch(ep->e_opcode & ~SUB) {
  		case EQ:
  #ifdef u3b
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads