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