--- src/Makefile.in.orig 2005-09-01 12:11:25.000000000 -0700 +++ src/Makefile.in 2005-09-01 12:11:59.000000000 -0700 @@ -58,7 +58,7 @@ LTLIBRARIES = $(lib_LTLIBRARIES) libmagic_la_DEPENDENCIES = $(LTLIBOBJS) am_libmagic_la_OBJECTS = magic.lo apprentice.lo softmagic.lo \ - ascmagic.lo encoding.lo compress.lo is_tar.lo readelf.lo \ + ascmagic.lo encoding.lo compress.lo is_tar.lo readelf.lo readmacho.lo \ print.lo fsmagic.lo funcs.lo apptype.lo cdf.lo cdf_time.lo \ readcdf.lo libmagic_la_OBJECTS = $(am_libmagic_la_OBJECTS) @@ -206,7 +206,7 @@ AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"' AM_CFLAGS = @WARNINGS@ libmagic_la_SOURCES = magic.c apprentice.c softmagic.c ascmagic.c \ - encoding.c compress.c is_tar.c readelf.c print.c fsmagic.c \ + encoding.c compress.c is_tar.c readelf.c readmacho.c print.c fsmagic.c \ funcs.c file.h names.h patchlevel.h readelf.h tar.h apptype.c \ file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h @@ -334,6 +334,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readcdf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readelf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readmacho.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/softmagic.Plo@am__quote@ .c.o: --- src/file.h.orig 2005-09-01 12:12:38.000000000 -0700 +++ src/file.h 2005-09-01 12:13:06.000000000 -0700 @@ -355,6 +355,7 @@ protected int file_reset(struct magic_set *); protected int file_tryelf(struct magic_set *, int, const unsigned char *, size_t); +protected int file_trymacho(struct magic_set *, int, const unsigned char *, size_t, const char *); protected int file_trycdf(struct magic_set *, int, const unsigned char *, size_t); protected int file_zmagic(struct magic_set *, int, const char *, --- src/funcs.c.orig 2007-12-27 08:35:59.000000000 -0800 +++ src/funcs.c 2008-01-11 17:53:30.000000000 -0800 @@ -248,6 +248,9 @@ "elf %d\n", m); } #endif +#ifdef BUILTIN_MACHO + file_trymacho(ms, fd, ubuf, nb, inname); +#endif goto done; } @@ -374,7 +377,7 @@ break; } - if (iswprint(nextchar)) { + if (iswprint(nextchar) || nextchar == L'\t' || nextchar == L'\n') { (void)memcpy(np, op, bytesconsumed); op += bytesconsumed; np += bytesconsumed; @@ -392,7 +395,7 @@ #endif for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) { - if (isprint((unsigned char)*op)) { + if (isprint((unsigned char)*op) || ((unsigned char)*op) == '\t' || ((unsigned char)*op) == '\n') { *np++ = *op; } else { OCTALIFY(np, op); --- /dev/null 2008-12-15 16:50:25.000000000 -0800 +++ src/readmacho.c 2008-12-15 16:57:13.000000000 -0800 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1999-2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifdef BUILTIN_MACHO +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/file.h> +#include <unistd.h> + +#include <mach-o/fat.h> +#include <mach-o/arch.h> +#include <mach-o/swap.h> + +#include "file.h" + +/* Silence a compiler warning. */ +FILE_RCSID("") + +static void +print_arch_name_for_file(struct magic_set *ms, cpu_type_t cputype, + cpu_subtype_t cpusubtype) +{ + const NXArchInfo *ArchInfoTable, *ai; + + ArchInfoTable = NXGetAllArchInfos(); + + for (ai = ArchInfoTable; ai->name != NULL; ai++) { + if(ai->cputype == cputype && ai->cpusubtype == (cpu_subtype_t)(cpusubtype & ~CPU_SUBTYPE_MASK)) { + file_printf(ms, " (for architecture %s)", ai->name); + return; + } + } + + file_printf(ms, " (for architecture cputype (%d) cpusubtype (%d))", + cputype, cpusubtype); +} + +protected int +file_trymacho(struct magic_set *ms, int fd, const unsigned char *buf, + size_t nbytes, const char *inname) +{ + struct stat stat_buf; + unsigned long size; + struct fat_header fat_header; + struct fat_arch *fat_archs; + uint32_t arch_size, i; + ssize_t tbytes; + unsigned char *tmpbuf; + + if (fstat(fd, &stat_buf) == -1) { + return -1; + } + + size = stat_buf.st_size; + + if (nbytes < sizeof(struct fat_header)) { + return -1; + } + + memcpy(&fat_header, buf, sizeof(struct fat_header)); +#ifdef __LITTLE_ENDIAN__ + swap_fat_header(&fat_header, NX_LittleEndian); +#endif /* __LITTLE_ENDIAN__ */ + + /* Check magic number, plus little hack for Mach-O vs. Java. */ + if(!(fat_header.magic == FAT_MAGIC && fat_header.nfat_arch < 20)) { + return -1; + } + + arch_size = fat_header.nfat_arch * sizeof(struct fat_arch); + + if (nbytes < sizeof(struct fat_header) + arch_size) { + return -1; + } + + if ((fat_archs = (struct fat_arch *)malloc(arch_size)) == NULL) { + return -1; + } + + memcpy((void *)fat_archs, buf + sizeof(struct fat_header), arch_size); +#ifdef __LITTLE_ENDIAN__ + swap_fat_arch(fat_archs, fat_header.nfat_arch, NX_LittleEndian); +#endif /* __LITTLE_ENDIAN__ */ + + for(i = 0; i < fat_header.nfat_arch; i++) { + file_printf(ms, "\n%s", inname); + print_arch_name_for_file(ms, + fat_archs[i].cputype, fat_archs[i].cpusubtype); + file_printf(ms, ":\t"); + + if (fat_archs[i].offset + fat_archs[i].size > size) { + free(fat_archs); + return -1; + } + + if (lseek(fd, fat_archs[i].offset, SEEK_SET) == -1) { + free(fat_archs); + return -1; + } + + tmpbuf = malloc(HOWMANY + 1); + memset(tmpbuf, 0, sizeof(tmpbuf)); + if ((tbytes = read(fd, tmpbuf, HOWMANY)) == -1) { + free(fat_archs); + free(tmpbuf); + return -1; + } + + file_buffer(ms, -1, inname, tmpbuf, (size_t)tbytes); + free(tmpbuf); + } + + free(fat_archs); + return 0; +} +#endif /* BUILTIN_MACHO */