xref: /freebsd/contrib/file/src/memtest.c (revision a2dfb7224ec9933ee804cae54d51848dce938b6b)
143a5ec4eSXin LI /*
243a5ec4eSXin LI  * Copyright (c) Christos Zoulas 2021.
343a5ec4eSXin LI  * All Rights Reserved.
443a5ec4eSXin LI  *
543a5ec4eSXin LI  * Redistribution and use in source and binary forms, with or without
643a5ec4eSXin LI  * modification, are permitted provided that the following conditions
743a5ec4eSXin LI  * are met:
843a5ec4eSXin LI  * 1. Redistributions of source code must retain the above copyright
943a5ec4eSXin LI  *    notice immediately at the beginning of the file, without modification,
1043a5ec4eSXin LI  *    this list of conditions, and the following disclaimer.
1143a5ec4eSXin LI  * 2. Redistributions in binary form must reproduce the above copyright
1243a5ec4eSXin LI  *    notice, this list of conditions and the following disclaimer in the
1343a5ec4eSXin LI  *    documentation and/or other materials provided with the distribution.
1443a5ec4eSXin LI  *
1543a5ec4eSXin LI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1643a5ec4eSXin LI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1743a5ec4eSXin LI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1843a5ec4eSXin LI  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
1943a5ec4eSXin LI  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2043a5ec4eSXin LI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2143a5ec4eSXin LI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2243a5ec4eSXin LI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2343a5ec4eSXin LI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2443a5ec4eSXin LI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2543a5ec4eSXin LI  * SUCH DAMAGE.
2643a5ec4eSXin LI  */
2743a5ec4eSXin LI 
28*a2dfb722SXin LI #ifndef lint
29*a2dfb722SXin LI FILE_RCSID("@(#)$File: memtest.c,v 1.3 2022/09/13 18:46:07 christos Exp $")
30*a2dfb722SXin LI #endif
31*a2dfb722SXin LI 
3243a5ec4eSXin LI #include <sys/types.h>
3343a5ec4eSXin LI #include <sys/stat.h>
3443a5ec4eSXin LI #include <sys/mman.h>
3543a5ec4eSXin LI #include <stdio.h>
3643a5ec4eSXin LI #include <stdbool.h>
3743a5ec4eSXin LI #include <string.h>
3843a5ec4eSXin LI #include <stdlib.h>
3943a5ec4eSXin LI #include <err.h>
4043a5ec4eSXin LI #include <fcntl.h>
4143a5ec4eSXin LI #include <unistd.h>
4243a5ec4eSXin LI #include <dlfcn.h>
4343a5ec4eSXin LI #include <magic.h>
4443a5ec4eSXin LI 
4543a5ec4eSXin LI void *
4643a5ec4eSXin LI malloc(size_t len)
4743a5ec4eSXin LI {
4843a5ec4eSXin LI 	char buf[512];
4943a5ec4eSXin LI 	void *(*orig)(size_t) = dlsym(RTLD_NEXT, "malloc");
5043a5ec4eSXin LI 	void *p = (*orig)(len);
5143a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "malloc %zu %p\n", len, p);
5243a5ec4eSXin LI 	write(2, buf, l);
5343a5ec4eSXin LI 	return p;
5443a5ec4eSXin LI }
5543a5ec4eSXin LI 
5643a5ec4eSXin LI void
5743a5ec4eSXin LI free(void *p)
5843a5ec4eSXin LI {
5943a5ec4eSXin LI 	char buf[512];
6043a5ec4eSXin LI 	void (*orig)(void *) = dlsym(RTLD_NEXT, "free");
6143a5ec4eSXin LI 	(*orig)(p);
6243a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "free %p\n", p);
6343a5ec4eSXin LI 	write(2, buf, l);
6443a5ec4eSXin LI }
6543a5ec4eSXin LI 
6643a5ec4eSXin LI void *
6743a5ec4eSXin LI calloc(size_t len, size_t nitems)
6843a5ec4eSXin LI {
6943a5ec4eSXin LI 	char buf[512];
7043a5ec4eSXin LI 	void *(*orig)(size_t, size_t) = dlsym(RTLD_NEXT, "calloc");
7143a5ec4eSXin LI 	void *p = (*orig)(len, nitems);
7243a5ec4eSXin LI 	size_t tot = len * nitems;
7343a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "calloc %zu %p\n", tot, p);
7443a5ec4eSXin LI 	write(2, buf, l);
7543a5ec4eSXin LI 	return p;
7643a5ec4eSXin LI }
7743a5ec4eSXin LI void *
7843a5ec4eSXin LI realloc(void *q, size_t len)
7943a5ec4eSXin LI {
8043a5ec4eSXin LI 	char buf[512];
8143a5ec4eSXin LI 	void *(*orig)(void *, size_t) = dlsym(RTLD_NEXT, "realloc");
8243a5ec4eSXin LI 	void *p = (*orig)(q, len);
8343a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "realloc %zu %p\n", len, p);
8443a5ec4eSXin LI 	write(2, buf, l);
8543a5ec4eSXin LI 	return p;
8643a5ec4eSXin LI }
8743a5ec4eSXin LI 
8843a5ec4eSXin LI static void
8943a5ec4eSXin LI usage(void)
9043a5ec4eSXin LI {
9143a5ec4eSXin LI 	fprintf(stderr, "Usage: test [-b] <filename>\n");
9243a5ec4eSXin LI 	exit(EXIT_FAILURE);
9343a5ec4eSXin LI }
9443a5ec4eSXin LI 
9543a5ec4eSXin LI int
9643a5ec4eSXin LI main(int argc, char *argv[])
9743a5ec4eSXin LI {
9843a5ec4eSXin LI 	bool buf = false;
9943a5ec4eSXin LI 	int c;
10043a5ec4eSXin LI 
10143a5ec4eSXin LI 	while ((c = getopt(argc, argv, "b")) != -1)
10243a5ec4eSXin LI 		switch (c) {
10343a5ec4eSXin LI 		case 'b':
10443a5ec4eSXin LI 			buf = true;
10543a5ec4eSXin LI 			break;
10643a5ec4eSXin LI 		default:
10743a5ec4eSXin LI 			usage();
10843a5ec4eSXin LI 		}
10943a5ec4eSXin LI 
11043a5ec4eSXin LI 	argc -= optind;
11143a5ec4eSXin LI 	argv += optind;
11243a5ec4eSXin LI 
11343a5ec4eSXin LI 	if (argc == 0)
11443a5ec4eSXin LI 		usage();
11543a5ec4eSXin LI 
11643a5ec4eSXin LI 	magic_t m = magic_open(0);
11743a5ec4eSXin LI 	if (m == NULL)
11843a5ec4eSXin LI 		err(EXIT_FAILURE, "magic_open");
11943a5ec4eSXin LI 
12043a5ec4eSXin LI 	magic_load(m, NULL);
12143a5ec4eSXin LI 
12243a5ec4eSXin LI 	const char *r;
12343a5ec4eSXin LI 	if (buf) {
12443a5ec4eSXin LI 		int fd = open(argv[0], O_RDONLY);
12543a5ec4eSXin LI 		if (fd == -1)
12643a5ec4eSXin LI 			err(EXIT_FAILURE, "Cannot open `%s'", argv[0]);
12743a5ec4eSXin LI 
12843a5ec4eSXin LI 		struct stat st;
12943a5ec4eSXin LI 		if (fstat(fd, &st) == -1)
13043a5ec4eSXin LI 			err(EXIT_FAILURE, "Cannot stat `%s'", argv[0]);
13143a5ec4eSXin LI 		size_t l = (size_t)st.st_size;
13243a5ec4eSXin LI 		void *p = mmap(NULL, l, PROT_READ, MAP_FILE | MAP_PRIVATE, fd,
13343a5ec4eSXin LI 		    (off_t)0);
13443a5ec4eSXin LI 		if (p == MAP_FAILED)
13543a5ec4eSXin LI 			err(EXIT_FAILURE, "Cannot map `%s'", argv[0]);
13643a5ec4eSXin LI 		close(fd);
13743a5ec4eSXin LI 		r = magic_buffer(m, p, l);
13843a5ec4eSXin LI 		munmap(p, l);
13943a5ec4eSXin LI 	} else {
14043a5ec4eSXin LI 		r = magic_file(m, argv[0]);
14143a5ec4eSXin LI 	}
14243a5ec4eSXin LI 	magic_close(m);
14343a5ec4eSXin LI 
14443a5ec4eSXin LI 	printf("%s\n", r ? r : "(null)");
14543a5ec4eSXin LI 
14643a5ec4eSXin LI 	return 0;
14743a5ec4eSXin LI }
148