xref: /freebsd/contrib/file/tests/test.c (revision 898496ee09ed2b7d25f6807edc4515628196ec0a)
128a8b562SDavid E. O'Brien /*
228a8b562SDavid E. O'Brien  * Copyright (c) Christos Zoulas 2003.
328a8b562SDavid E. O'Brien  * All Rights Reserved.
428a8b562SDavid E. O'Brien  *
528a8b562SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
628a8b562SDavid E. O'Brien  * modification, are permitted provided that the following conditions
728a8b562SDavid E. O'Brien  * are met:
828a8b562SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
928a8b562SDavid E. O'Brien  *    notice immediately at the beginning of the file, without modification,
1028a8b562SDavid E. O'Brien  *    this list of conditions, and the following disclaimer.
1128a8b562SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
1228a8b562SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
1328a8b562SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1428a8b562SDavid E. O'Brien  *
1528a8b562SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1628a8b562SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1728a8b562SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1828a8b562SDavid E. O'Brien  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
1928a8b562SDavid E. O'Brien  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2028a8b562SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2128a8b562SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2228a8b562SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2328a8b562SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2428a8b562SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2528a8b562SDavid E. O'Brien  * SUCH DAMAGE.
2628a8b562SDavid E. O'Brien  */
2728a8b562SDavid E. O'Brien 
2828a8b562SDavid E. O'Brien #include <stdio.h>
2928a8b562SDavid E. O'Brien #include <stdlib.h>
30*898496eeSXin LI #include <unistd.h>
3128a8b562SDavid E. O'Brien #include <string.h>
3243a5ec4eSXin LI #include <errno.h>
33*898496eeSXin LI #include <time.h>
3443a5ec4eSXin LI 
3528a8b562SDavid E. O'Brien #include "magic.h"
3628a8b562SDavid E. O'Brien 
3743a5ec4eSXin LI static const char *prog;
3843a5ec4eSXin LI 
3928a8b562SDavid E. O'Brien static void *
xrealloc(void * p,size_t n)4028a8b562SDavid E. O'Brien xrealloc(void *p, size_t n)
4128a8b562SDavid E. O'Brien {
4228a8b562SDavid E. O'Brien 	p = realloc(p, n);
4328a8b562SDavid E. O'Brien 	if (p == NULL) {
4443a5ec4eSXin LI 		(void)fprintf(stderr, "%s ERROR slurping file: %s\n",
4543a5ec4eSXin LI 			prog, strerror(errno));
4628a8b562SDavid E. O'Brien 		exit(10);
4728a8b562SDavid E. O'Brien 	}
4828a8b562SDavid E. O'Brien 	return p;
4928a8b562SDavid E. O'Brien }
5028a8b562SDavid E. O'Brien 
5128a8b562SDavid E. O'Brien static char *
slurp(FILE * fp,size_t * final_len)5228a8b562SDavid E. O'Brien slurp(FILE *fp, size_t *final_len)
5328a8b562SDavid E. O'Brien {
5428a8b562SDavid E. O'Brien 	size_t len = 256;
5528a8b562SDavid E. O'Brien 	int c;
56*898496eeSXin LI 	char *l = xrealloc(NULL, len), *s = l;
5728a8b562SDavid E. O'Brien 
5828a8b562SDavid E. O'Brien 	for (c = getc(fp); c != EOF; c = getc(fp)) {
5928a8b562SDavid E. O'Brien 		if (s == l + len) {
60*898496eeSXin LI 			s = l + len;
6128a8b562SDavid E. O'Brien 			len *= 2;
62*898496eeSXin LI 			l = xrealloc(l, len);
6328a8b562SDavid E. O'Brien 		}
6428a8b562SDavid E. O'Brien 		*s++ = c;
6528a8b562SDavid E. O'Brien 	}
66a2dfb722SXin LI 	if (s != l && s[-1] == '\n')
67a2dfb722SXin LI 		s--;
68*898496eeSXin LI 	if (s == l + len) {
69*898496eeSXin LI 		l = xrealloc(l, len + 1);
70*898496eeSXin LI 		s = l + len;
71*898496eeSXin LI 	}
7228a8b562SDavid E. O'Brien 	*s++ = '\0';
7328a8b562SDavid E. O'Brien 
7428a8b562SDavid E. O'Brien 	*final_len = s - l;
75*898496eeSXin LI 	return xrealloc(l, s - l);
7628a8b562SDavid E. O'Brien }
7728a8b562SDavid E. O'Brien 
7828a8b562SDavid E. O'Brien int
main(int argc,char ** argv)7928a8b562SDavid E. O'Brien main(int argc, char **argv)
8028a8b562SDavid E. O'Brien {
81*898496eeSXin LI 	struct magic_set *ms = NULL;
8228a8b562SDavid E. O'Brien 	const char *result;
8343a5ec4eSXin LI 	size_t result_len, desired_len;
8443a5ec4eSXin LI 	char *desired = NULL;
85*898496eeSXin LI 	int e = EXIT_FAILURE, flags, c;
8628a8b562SDavid E. O'Brien 	FILE *fp;
8728a8b562SDavid E. O'Brien 
88*898496eeSXin LI 	setenv("TZ", "UTC", 1);
89*898496eeSXin LI 	tzset();
90*898496eeSXin LI 
9143a5ec4eSXin LI 
9243a5ec4eSXin LI 	prog = strrchr(argv[0], '/');
9343a5ec4eSXin LI 	if (prog)
9443a5ec4eSXin LI 		prog++;
9543a5ec4eSXin LI 	else
9643a5ec4eSXin LI 		prog = argv[0];
9743a5ec4eSXin LI 
98*898496eeSXin LI 	if (argc == 1)
99*898496eeSXin LI 		return 0;
100*898496eeSXin LI 
101*898496eeSXin LI 	flags = 0;
102*898496eeSXin LI 	while ((c = getopt(argc, argv, "ek")) != -1)
103*898496eeSXin LI 		switch (c) {
104*898496eeSXin LI 		case 'e':
105*898496eeSXin LI 			flags |= MAGIC_ERROR;
106*898496eeSXin LI 			break;
107*898496eeSXin LI 		case 'k':
108*898496eeSXin LI 			flags |= MAGIC_CONTINUE;
109*898496eeSXin LI 			break;
110*898496eeSXin LI 		default:
111*898496eeSXin LI 			goto usage;
112*898496eeSXin LI 		}
113*898496eeSXin LI 
114*898496eeSXin LI 	argc -= optind;
115*898496eeSXin LI 	argv += optind;
116*898496eeSXin LI 	if (argc != 2) {
117*898496eeSXin LI usage:
118*898496eeSXin LI 		(void)fprintf(stderr,
119*898496eeSXin LI 		    "Usage: %s [-ek] TEST-FILE RESULT\n", prog);
120*898496eeSXin LI 		goto bad;
121*898496eeSXin LI 	}
122*898496eeSXin LI 
123*898496eeSXin LI 	ms = magic_open(flags);
12428a8b562SDavid E. O'Brien 	if (ms == NULL) {
12543a5ec4eSXin LI 		(void)fprintf(stderr, "%s: ERROR opening MAGIC_NONE: %s\n",
12643a5ec4eSXin LI 		    prog, strerror(errno));
12743a5ec4eSXin LI 		return e;
12828a8b562SDavid E. O'Brien 	}
12928a8b562SDavid E. O'Brien 	if (magic_load(ms, NULL) == -1) {
13043a5ec4eSXin LI 		(void)fprintf(stderr, "%s: ERROR loading with NULL file: %s\n",
13143a5ec4eSXin LI 		    prog, magic_error(ms));
13243a5ec4eSXin LI 		goto bad;
13328a8b562SDavid E. O'Brien 	}
13428a8b562SDavid E. O'Brien 
135*898496eeSXin LI 	if ((result = magic_file(ms, argv[0])) == NULL) {
13643a5ec4eSXin LI 		(void)fprintf(stderr, "%s: ERROR loading file %s: %s\n",
13743a5ec4eSXin LI 		    prog, argv[1], magic_error(ms));
13843a5ec4eSXin LI 		goto bad;
13943a5ec4eSXin LI 	}
140*898496eeSXin LI 	fp = fopen(argv[1], "r");
14128a8b562SDavid E. O'Brien 	if (fp == NULL) {
14243a5ec4eSXin LI 		(void)fprintf(stderr, "%s: ERROR opening `%s': %s",
143*898496eeSXin LI 		    prog, argv[1], strerror(errno));
14443a5ec4eSXin LI 		goto bad;
14528a8b562SDavid E. O'Brien 	}
14628a8b562SDavid E. O'Brien 	desired = slurp(fp, &desired_len);
14728a8b562SDavid E. O'Brien 	fclose(fp);
148*898496eeSXin LI 	(void)printf("%s: %s\n", argv[0], result);
14928a8b562SDavid E. O'Brien 	if (strcmp(result, desired) != 0) {
15043a5ec4eSXin LI 	    result_len = strlen(result);
15143a5ec4eSXin LI 	    (void)fprintf(stderr, "%s: ERROR: result was (len %zu)\n%s\n"
15243a5ec4eSXin LI 		"expected (len %zu)\n%s\n", prog, result_len, result,
15343a5ec4eSXin LI 		desired_len, desired);
15443a5ec4eSXin LI 	    goto bad;
15528a8b562SDavid E. O'Brien 	}
15643a5ec4eSXin LI 	e = 0;
15743a5ec4eSXin LI bad:
15843a5ec4eSXin LI 	free(desired);
159*898496eeSXin LI 	if (ms)
16028a8b562SDavid E. O'Brien 		magic_close(ms);
16143a5ec4eSXin LI 	return e;
16228a8b562SDavid E. O'Brien }
163