1*43a5ec4eSXin LI /* 2*43a5ec4eSXin LI * Copyright (c) Christos Zoulas 2021. 3*43a5ec4eSXin LI * All Rights Reserved. 4*43a5ec4eSXin LI * 5*43a5ec4eSXin LI * Redistribution and use in source and binary forms, with or without 6*43a5ec4eSXin LI * modification, are permitted provided that the following conditions 7*43a5ec4eSXin LI * are met: 8*43a5ec4eSXin LI * 1. Redistributions of source code must retain the above copyright 9*43a5ec4eSXin LI * notice immediately at the beginning of the file, without modification, 10*43a5ec4eSXin LI * this list of conditions, and the following disclaimer. 11*43a5ec4eSXin LI * 2. Redistributions in binary form must reproduce the above copyright 12*43a5ec4eSXin LI * notice, this list of conditions and the following disclaimer in the 13*43a5ec4eSXin LI * documentation and/or other materials provided with the distribution. 14*43a5ec4eSXin LI * 15*43a5ec4eSXin LI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*43a5ec4eSXin LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*43a5ec4eSXin LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*43a5ec4eSXin LI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19*43a5ec4eSXin LI * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*43a5ec4eSXin LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*43a5ec4eSXin LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*43a5ec4eSXin LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*43a5ec4eSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*43a5ec4eSXin LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*43a5ec4eSXin LI * SUCH DAMAGE. 26*43a5ec4eSXin LI */ 27*43a5ec4eSXin LI 28*43a5ec4eSXin LI #include <sys/types.h> 29*43a5ec4eSXin LI #include <sys/stat.h> 30*43a5ec4eSXin LI #include <sys/mman.h> 31*43a5ec4eSXin LI #include <stdio.h> 32*43a5ec4eSXin LI #include <stdbool.h> 33*43a5ec4eSXin LI #include <string.h> 34*43a5ec4eSXin LI #include <stdlib.h> 35*43a5ec4eSXin LI #include <err.h> 36*43a5ec4eSXin LI #include <fcntl.h> 37*43a5ec4eSXin LI #include <unistd.h> 38*43a5ec4eSXin LI #include <dlfcn.h> 39*43a5ec4eSXin LI #include <magic.h> 40*43a5ec4eSXin LI 41*43a5ec4eSXin LI void * 42*43a5ec4eSXin LI malloc(size_t len) 43*43a5ec4eSXin LI { 44*43a5ec4eSXin LI char buf[512]; 45*43a5ec4eSXin LI void *(*orig)(size_t) = dlsym(RTLD_NEXT, "malloc"); 46*43a5ec4eSXin LI void *p = (*orig)(len); 47*43a5ec4eSXin LI int l = snprintf(buf, sizeof(buf), "malloc %zu %p\n", len, p); 48*43a5ec4eSXin LI write(2, buf, l); 49*43a5ec4eSXin LI return p; 50*43a5ec4eSXin LI } 51*43a5ec4eSXin LI 52*43a5ec4eSXin LI void 53*43a5ec4eSXin LI free(void *p) 54*43a5ec4eSXin LI { 55*43a5ec4eSXin LI char buf[512]; 56*43a5ec4eSXin LI void (*orig)(void *) = dlsym(RTLD_NEXT, "free"); 57*43a5ec4eSXin LI (*orig)(p); 58*43a5ec4eSXin LI int l = snprintf(buf, sizeof(buf), "free %p\n", p); 59*43a5ec4eSXin LI write(2, buf, l); 60*43a5ec4eSXin LI } 61*43a5ec4eSXin LI 62*43a5ec4eSXin LI void * 63*43a5ec4eSXin LI calloc(size_t len, size_t nitems) 64*43a5ec4eSXin LI { 65*43a5ec4eSXin LI char buf[512]; 66*43a5ec4eSXin LI void *(*orig)(size_t, size_t) = dlsym(RTLD_NEXT, "calloc"); 67*43a5ec4eSXin LI void *p = (*orig)(len, nitems); 68*43a5ec4eSXin LI size_t tot = len * nitems; 69*43a5ec4eSXin LI int l = snprintf(buf, sizeof(buf), "calloc %zu %p\n", tot, p); 70*43a5ec4eSXin LI write(2, buf, l); 71*43a5ec4eSXin LI return p; 72*43a5ec4eSXin LI } 73*43a5ec4eSXin LI void * 74*43a5ec4eSXin LI realloc(void *q, size_t len) 75*43a5ec4eSXin LI { 76*43a5ec4eSXin LI char buf[512]; 77*43a5ec4eSXin LI void *(*orig)(void *, size_t) = dlsym(RTLD_NEXT, "realloc"); 78*43a5ec4eSXin LI void *p = (*orig)(q, len); 79*43a5ec4eSXin LI int l = snprintf(buf, sizeof(buf), "realloc %zu %p\n", len, p); 80*43a5ec4eSXin LI write(2, buf, l); 81*43a5ec4eSXin LI return p; 82*43a5ec4eSXin LI } 83*43a5ec4eSXin LI 84*43a5ec4eSXin LI static void 85*43a5ec4eSXin LI usage(void) 86*43a5ec4eSXin LI { 87*43a5ec4eSXin LI fprintf(stderr, "Usage: test [-b] <filename>\n"); 88*43a5ec4eSXin LI exit(EXIT_FAILURE); 89*43a5ec4eSXin LI } 90*43a5ec4eSXin LI 91*43a5ec4eSXin LI int 92*43a5ec4eSXin LI main(int argc, char *argv[]) 93*43a5ec4eSXin LI { 94*43a5ec4eSXin LI bool buf = false; 95*43a5ec4eSXin LI int c; 96*43a5ec4eSXin LI 97*43a5ec4eSXin LI while ((c = getopt(argc, argv, "b")) != -1) 98*43a5ec4eSXin LI switch (c) { 99*43a5ec4eSXin LI case 'b': 100*43a5ec4eSXin LI buf = true; 101*43a5ec4eSXin LI break; 102*43a5ec4eSXin LI default: 103*43a5ec4eSXin LI usage(); 104*43a5ec4eSXin LI } 105*43a5ec4eSXin LI 106*43a5ec4eSXin LI argc -= optind; 107*43a5ec4eSXin LI argv += optind; 108*43a5ec4eSXin LI 109*43a5ec4eSXin LI if (argc == 0) 110*43a5ec4eSXin LI usage(); 111*43a5ec4eSXin LI 112*43a5ec4eSXin LI magic_t m = magic_open(0); 113*43a5ec4eSXin LI if (m == NULL) 114*43a5ec4eSXin LI err(EXIT_FAILURE, "magic_open"); 115*43a5ec4eSXin LI 116*43a5ec4eSXin LI magic_load(m, NULL); 117*43a5ec4eSXin LI 118*43a5ec4eSXin LI const char *r; 119*43a5ec4eSXin LI if (buf) { 120*43a5ec4eSXin LI int fd = open(argv[0], O_RDONLY); 121*43a5ec4eSXin LI if (fd == -1) 122*43a5ec4eSXin LI err(EXIT_FAILURE, "Cannot open `%s'", argv[0]); 123*43a5ec4eSXin LI 124*43a5ec4eSXin LI struct stat st; 125*43a5ec4eSXin LI if (fstat(fd, &st) == -1) 126*43a5ec4eSXin LI err(EXIT_FAILURE, "Cannot stat `%s'", argv[0]); 127*43a5ec4eSXin LI size_t l = (size_t)st.st_size; 128*43a5ec4eSXin LI void *p = mmap(NULL, l, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 129*43a5ec4eSXin LI (off_t)0); 130*43a5ec4eSXin LI if (p == MAP_FAILED) 131*43a5ec4eSXin LI err(EXIT_FAILURE, "Cannot map `%s'", argv[0]); 132*43a5ec4eSXin LI close(fd); 133*43a5ec4eSXin LI r = magic_buffer(m, p, l); 134*43a5ec4eSXin LI munmap(p, l); 135*43a5ec4eSXin LI } else { 136*43a5ec4eSXin LI r = magic_file(m, argv[0]); 137*43a5ec4eSXin LI } 138*43a5ec4eSXin LI magic_close(m); 139*43a5ec4eSXin LI 140*43a5ec4eSXin LI printf("%s\n", r ? r : "(null)"); 141*43a5ec4eSXin LI 142*43a5ec4eSXin LI return 0; 143*43a5ec4eSXin LI } 144