1/*	$NetBSD: test.c,v 1.1.1.8 2023/08/18 18:36:51 christos Exp $	*/
2
3/*
4 * Copyright (c) Christos Zoulas 2003.
5 * All Rights Reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice immediately at the beginning of the file, without modification,
12 *    this list of conditions, and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <unistd.h>
33#include <string.h>
34#include <errno.h>
35#include <time.h>
36
37#include "magic.h"
38
39static const char *prog;
40
41static void *
42xrealloc(void *p, size_t n)
43{
44	p = realloc(p, n);
45	if (p == NULL) {
46		(void)fprintf(stderr, "%s ERROR slurping file: %s\n",
47			prog, strerror(errno));
48		exit(10);
49	}
50	return p;
51}
52
53static char *
54slurp(FILE *fp, size_t *final_len)
55{
56	size_t len = 256;
57	int c;
58	char *l = xrealloc(NULL, len), *s = l;
59
60	for (c = getc(fp); c != EOF; c = getc(fp)) {
61		if (s == l + len) {
62			s = l + len;
63			len *= 2;
64			l = xrealloc(l, len);
65		}
66		*s++ = c;
67	}
68	if (s != l && s[-1] == '\n')
69		s--;
70	if (s == l + len) {
71		l = xrealloc(l, len + 1);
72		s = l + len;
73	}
74	*s++ = '\0';
75
76	*final_len = s - l;
77	return xrealloc(l, s - l);
78}
79
80int
81main(int argc, char **argv)
82{
83	struct magic_set *ms = NULL;
84	const char *result;
85	size_t result_len, desired_len;
86	char *desired = NULL;
87	int e = EXIT_FAILURE, flags, c;
88	FILE *fp;
89
90	setenv("TZ", "UTC", 1);
91	tzset();
92
93
94	prog = strrchr(argv[0], '/');
95	if (prog)
96		prog++;
97	else
98		prog = argv[0];
99
100	if (argc == 1)
101		return 0;
102
103	flags = 0;
104	while ((c = getopt(argc, argv, "ek")) != -1)
105		switch (c) {
106		case 'e':
107			flags |= MAGIC_ERROR;
108			break;
109		case 'k':
110			flags |= MAGIC_CONTINUE;
111			break;
112		default:
113			goto usage;
114		}
115
116	argc -= optind;
117	argv += optind;
118	if (argc != 2) {
119usage:
120		(void)fprintf(stderr,
121		    "Usage: %s [-ek] TEST-FILE RESULT\n", prog);
122		goto bad;
123	}
124
125	ms = magic_open(flags);
126	if (ms == NULL) {
127		(void)fprintf(stderr, "%s: ERROR opening MAGIC_NONE: %s\n",
128		    prog, strerror(errno));
129		return e;
130	}
131	if (magic_load(ms, NULL) == -1) {
132		(void)fprintf(stderr, "%s: ERROR loading with NULL file: %s\n",
133		    prog, magic_error(ms));
134		goto bad;
135	}
136
137	if ((result = magic_file(ms, argv[0])) == NULL) {
138		(void)fprintf(stderr, "%s: ERROR loading file %s: %s\n",
139		    prog, argv[1], magic_error(ms));
140		goto bad;
141	}
142	fp = fopen(argv[1], "r");
143	if (fp == NULL) {
144		(void)fprintf(stderr, "%s: ERROR opening `%s': %s",
145		    prog, argv[1], strerror(errno));
146		goto bad;
147	}
148	desired = slurp(fp, &desired_len);
149	fclose(fp);
150	(void)printf("%s: %s\n", argv[0], result);
151	if (strcmp(result, desired) != 0) {
152	    result_len = strlen(result);
153	    (void)fprintf(stderr, "%s: ERROR: result was (len %zu)\n%s\n"
154		"expected (len %zu)\n%s\n", prog, result_len, result,
155		desired_len, desired);
156	    goto bad;
157	}
158	e = 0;
159bad:
160	free(desired);
161	if (ms)
162		magic_close(ms);
163	return e;
164}
165