xref: /netbsd-src/external/bsd/file/dist/tests/test.c (revision e15daa8be9575f7ad2ca804c7c7c2d7f8e182d98)
1*e15daa8bSchristos /*	$NetBSD: test.c,v 1.1.1.8 2023/08/18 18:36:51 christos Exp $	*/
23c9d2f35Schristos 
31b108b8bSchristos /*
41b108b8bSchristos  * Copyright (c) Christos Zoulas 2003.
51b108b8bSchristos  * All Rights Reserved.
61b108b8bSchristos  *
71b108b8bSchristos  * Redistribution and use in source and binary forms, with or without
81b108b8bSchristos  * modification, are permitted provided that the following conditions
91b108b8bSchristos  * are met:
101b108b8bSchristos  * 1. Redistributions of source code must retain the above copyright
111b108b8bSchristos  *    notice immediately at the beginning of the file, without modification,
121b108b8bSchristos  *    this list of conditions, and the following disclaimer.
131b108b8bSchristos  * 2. Redistributions in binary form must reproduce the above copyright
141b108b8bSchristos  *    notice, this list of conditions and the following disclaimer in the
151b108b8bSchristos  *    documentation and/or other materials provided with the distribution.
161b108b8bSchristos  *
171b108b8bSchristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
181b108b8bSchristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191b108b8bSchristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201b108b8bSchristos  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
211b108b8bSchristos  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221b108b8bSchristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231b108b8bSchristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241b108b8bSchristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251b108b8bSchristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261b108b8bSchristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271b108b8bSchristos  * SUCH DAMAGE.
281b108b8bSchristos  */
291b108b8bSchristos 
301b108b8bSchristos #include <stdio.h>
311b108b8bSchristos #include <stdlib.h>
32*e15daa8bSchristos #include <unistd.h>
331b108b8bSchristos #include <string.h>
3425f16eeaSchristos #include <errno.h>
35*e15daa8bSchristos #include <time.h>
3625f16eeaSchristos 
371b108b8bSchristos #include "magic.h"
381b108b8bSchristos 
3925f16eeaSchristos static const char *prog;
4025f16eeaSchristos 
411b108b8bSchristos static void *
xrealloc(void * p,size_t n)421b108b8bSchristos xrealloc(void *p, size_t n)
431b108b8bSchristos {
441b108b8bSchristos 	p = realloc(p, n);
451b108b8bSchristos 	if (p == NULL) {
4625f16eeaSchristos 		(void)fprintf(stderr, "%s ERROR slurping file: %s\n",
4725f16eeaSchristos 			prog, strerror(errno));
481b108b8bSchristos 		exit(10);
491b108b8bSchristos 	}
501b108b8bSchristos 	return p;
511b108b8bSchristos }
521b108b8bSchristos 
531b108b8bSchristos static char *
slurp(FILE * fp,size_t * final_len)541b108b8bSchristos slurp(FILE *fp, size_t *final_len)
551b108b8bSchristos {
561b108b8bSchristos 	size_t len = 256;
571b108b8bSchristos 	int c;
58*e15daa8bSchristos 	char *l = xrealloc(NULL, len), *s = l;
591b108b8bSchristos 
601b108b8bSchristos 	for (c = getc(fp); c != EOF; c = getc(fp)) {
611b108b8bSchristos 		if (s == l + len) {
62*e15daa8bSchristos 			s = l + len;
631b108b8bSchristos 			len *= 2;
64*e15daa8bSchristos 			l = xrealloc(l, len);
651b108b8bSchristos 		}
661b108b8bSchristos 		*s++ = c;
671b108b8bSchristos 	}
68a77ebd86Schristos 	if (s != l && s[-1] == '\n')
69a77ebd86Schristos 		s--;
70*e15daa8bSchristos 	if (s == l + len) {
71*e15daa8bSchristos 		l = xrealloc(l, len + 1);
72*e15daa8bSchristos 		s = l + len;
73*e15daa8bSchristos 	}
741b108b8bSchristos 	*s++ = '\0';
751b108b8bSchristos 
761b108b8bSchristos 	*final_len = s - l;
77*e15daa8bSchristos 	return xrealloc(l, s - l);
781b108b8bSchristos }
791b108b8bSchristos 
801b108b8bSchristos int
main(int argc,char ** argv)811b108b8bSchristos main(int argc, char **argv)
821b108b8bSchristos {
83*e15daa8bSchristos 	struct magic_set *ms = NULL;
841b108b8bSchristos 	const char *result;
8525f16eeaSchristos 	size_t result_len, desired_len;
86a77ebd86Schristos 	char *desired = NULL;
87*e15daa8bSchristos 	int e = EXIT_FAILURE, flags, c;
881b108b8bSchristos 	FILE *fp;
891b108b8bSchristos 
90*e15daa8bSchristos 	setenv("TZ", "UTC", 1);
91*e15daa8bSchristos 	tzset();
92*e15daa8bSchristos 
9325f16eeaSchristos 
9425f16eeaSchristos 	prog = strrchr(argv[0], '/');
9525f16eeaSchristos 	if (prog)
9625f16eeaSchristos 		prog++;
9725f16eeaSchristos 	else
9825f16eeaSchristos 		prog = argv[0];
9925f16eeaSchristos 
100*e15daa8bSchristos 	if (argc == 1)
101*e15daa8bSchristos 		return 0;
102*e15daa8bSchristos 
103*e15daa8bSchristos 	flags = 0;
104*e15daa8bSchristos 	while ((c = getopt(argc, argv, "ek")) != -1)
105*e15daa8bSchristos 		switch (c) {
106*e15daa8bSchristos 		case 'e':
107*e15daa8bSchristos 			flags |= MAGIC_ERROR;
108*e15daa8bSchristos 			break;
109*e15daa8bSchristos 		case 'k':
110*e15daa8bSchristos 			flags |= MAGIC_CONTINUE;
111*e15daa8bSchristos 			break;
112*e15daa8bSchristos 		default:
113*e15daa8bSchristos 			goto usage;
114*e15daa8bSchristos 		}
115*e15daa8bSchristos 
116*e15daa8bSchristos 	argc -= optind;
117*e15daa8bSchristos 	argv += optind;
118*e15daa8bSchristos 	if (argc != 2) {
119*e15daa8bSchristos usage:
120*e15daa8bSchristos 		(void)fprintf(stderr,
121*e15daa8bSchristos 		    "Usage: %s [-ek] TEST-FILE RESULT\n", prog);
122*e15daa8bSchristos 		goto bad;
123*e15daa8bSchristos 	}
124*e15daa8bSchristos 
125*e15daa8bSchristos 	ms = magic_open(flags);
1261b108b8bSchristos 	if (ms == NULL) {
12725f16eeaSchristos 		(void)fprintf(stderr, "%s: ERROR opening MAGIC_NONE: %s\n",
12825f16eeaSchristos 		    prog, strerror(errno));
12925f16eeaSchristos 		return e;
1301b108b8bSchristos 	}
1311b108b8bSchristos 	if (magic_load(ms, NULL) == -1) {
13225f16eeaSchristos 		(void)fprintf(stderr, "%s: ERROR loading with NULL file: %s\n",
13325f16eeaSchristos 		    prog, magic_error(ms));
13425f16eeaSchristos 		goto bad;
1351b108b8bSchristos 	}
1361b108b8bSchristos 
137*e15daa8bSchristos 	if ((result = magic_file(ms, argv[0])) == NULL) {
13825f16eeaSchristos 		(void)fprintf(stderr, "%s: ERROR loading file %s: %s\n",
13925f16eeaSchristos 		    prog, argv[1], magic_error(ms));
14025f16eeaSchristos 		goto bad;
14125f16eeaSchristos 	}
142*e15daa8bSchristos 	fp = fopen(argv[1], "r");
1431b108b8bSchristos 	if (fp == NULL) {
14425f16eeaSchristos 		(void)fprintf(stderr, "%s: ERROR opening `%s': %s",
145*e15daa8bSchristos 		    prog, argv[1], strerror(errno));
14625f16eeaSchristos 		goto bad;
1471b108b8bSchristos 	}
1481b108b8bSchristos 	desired = slurp(fp, &desired_len);
1491b108b8bSchristos 	fclose(fp);
150*e15daa8bSchristos 	(void)printf("%s: %s\n", argv[0], result);
1511b108b8bSchristos 	if (strcmp(result, desired) != 0) {
15225f16eeaSchristos 	    result_len = strlen(result);
15325f16eeaSchristos 	    (void)fprintf(stderr, "%s: ERROR: result was (len %zu)\n%s\n"
15425f16eeaSchristos 		"expected (len %zu)\n%s\n", prog, result_len, result,
15525f16eeaSchristos 		desired_len, desired);
15625f16eeaSchristos 	    goto bad;
1571b108b8bSchristos 	}
15825f16eeaSchristos 	e = 0;
15925f16eeaSchristos bad:
160a77ebd86Schristos 	free(desired);
161*e15daa8bSchristos 	if (ms)
1621b108b8bSchristos 		magic_close(ms);
16325f16eeaSchristos 	return e;
1641b108b8bSchristos }
165