#include #include #include #include #include #include #include #include /* Maximum bytes to check for low bytes. */ #define MAX 0x1000 /* Return 1 if binary, 0 if probably not binary. */ int test_binary (const unsigned char * c, size_t len) { int i; size_t max = MAX; /* Make sure not to overshoot the end of the file while looking for bad bytes. */ if (len < max) { max = len; } /* Look for the ELF magic number. */ if (len > 4 && c[1] == 'E' && c[2] == 'L' && c[3] == 'F') { return 1; } /* Look for bytes which don't normally occur in ASCII or UTF-8 text. */ for (i = 0; i < max; i++) { if (c[i] < 0x20 && c[i] != '\n' && c[i] != '\t' && c[i] != '\r' && c[i] != '\f') { #if 0 /* Uncomment this to get a printout of the bad byte. */ printf ("%d at byte %d\n", c[i], i); #endif /* 0 */ return 1; } } return 0; } static void check (int test, const char * message, ...) { if (test) { va_list args; va_start (args, message); vfprintf (stderr, message, args); va_end (args); fprintf (stderr, "\n"); exit (EXIT_FAILURE); } } /* See https://www.lemoda.net/c/mmap-example/index.html for a commented version of this code. */ void mmap_file (const char * file_name, unsigned char ** contents_ptr, size_t * size_ptr) { int fd; struct stat s; int status; fd = open (file_name, O_RDONLY); check (fd < 0, "open %s failed: %s", file_name, strerror (errno)); status = fstat (fd, & s); check (status < 0, "stat %s failed: %s", file_name, strerror (errno)); * size_ptr = s.st_size; * contents_ptr = mmap (0, * size_ptr, PROT_READ, 0, fd, 0); check (* contents_ptr == MAP_FAILED, "mmap %s failed: %s", file_name, strerror (errno)); } void test_file (const char * file_name) { unsigned char * contents; size_t size; int status; mmap_file (file_name, & contents, & size); if (test_binary (contents, size)) { printf ("%s is binary.\n", file_name); } else { printf ("%s is not binary.\n", file_name); } status = munmap (contents, size); check (status != 0, "munmap %s failed", file_name); } int main (int argc, char ** argv) { test_file (argv[0]); test_file ("dbf.c"); return 0; }