[Midnightbsd-cvs] src [6695] trunk/contrib/file: Merge file 5.19
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Mon Jun 30 07:57:28 EDT 2014
Revision: 6695
http://svnweb.midnightbsd.org/src/?rev=6695
Author: laffer1
Date: 2014-06-30 07:57:27 -0400 (Mon, 30 Jun 2014)
Log Message:
-----------
Merge file 5.19
Removed Paths:
-------------
trunk/contrib/file/patchlevel.h
trunk/contrib/file/print.c
trunk/contrib/file/readcdf.c
trunk/contrib/file/readelf.c
trunk/contrib/file/softmagic.c
trunk/contrib/file/strlcat.c
trunk/contrib/file/strlcpy.c
trunk/contrib/file/tar.h
trunk/contrib/file/test.c
trunk/contrib/file/vasprintf.c
Deleted: trunk/contrib/file/patchlevel.h
===================================================================
--- trunk/contrib/file/patchlevel.h 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/patchlevel.h 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,358 +0,0 @@
-#define FILE_VERSION_MAJOR 5
-#define patchlevel 5
-
-/*
- * Patchlevel file for Ian Darwin's MAGIC command.
- * $File: patchlevel.h,v 1.76 2011/01/17 16:40:41 christos Exp $
- *
- * $Log: not supported by cvs2svn $
- * Revision 1.76 2011/01/17 16:40:41 christos
- * welcome to 5_05
- *
- * Revision 1.75 2010/01/22 21:08:13 christos
- * welcome to 5.04
- *
- * Revision 1.74 2009/05/06 20:32:48 christos
- * welcome to 5.03
- *
- * Revision 1.73 2009/05/04 15:15:13 christos
- * 5.02...
- *
- * Revision 1.72 2009/04/30 21:20:15 christos
- * 5.01 we are almost here.
- *
- * Revision 1.71 2009/01/21 19:09:42 christos
- * file 5.0
- *
- * Revision 1.70 2008/08/30 10:01:01 christos
- * file 4.26
- *
- * Revision 1.69 2008/07/02 15:27:05 christos
- * welcome to 4.25
- *
- * Revision 1.68 2008/03/22 21:39:43 christos
- * file 4.24
- *
- * Revision 1.67 2007/12/28 20:08:40 christos
- * welcome to 4.23.
- *
- * Revision 1.66 2007/12/27 16:38:24 christos
- * welcome to 4.22
- *
- * Revision 1.65 2007/05/24 17:22:27 christos
- * Welcome to 4.21
- *
- * Revision 1.64 2007/03/01 22:14:55 christos
- * welcome to 4.20
- *
- * Revision 1.63 2007/01/12 17:38:28 christos
- * Use File id.
- *
- * Revision 1.62 2006/12/11 21:49:58 christos
- * time for 4.19
- *
- * Revision 1.61 2006/10/31 21:18:09 christos
- * bump
- *
- * Revision 1.60 2006/03/02 22:15:12 christos
- * welcome to 4.17
- *
- * Revision 1.59 2005/10/17 17:15:21 christos
- * welcome to 4.16
- *
- * Revision 1.58 2005/08/18 15:52:56 christos
- * welcome to 4.15
- *
- * Revision 1.57 2005/06/25 15:52:14 christos
- * Welcome to 4.14
- *
- * Revision 1.56 2005/02/09 19:25:13 christos
- * Welcome to 4.13
- *
- * Revision 1.55 2004/11/24 18:57:47 christos
- * Re-do the autoconf stuff once more; passes make dist now.
- *
- * Revision 1.54 2004/11/21 05:52:05 christos
- * ready for 4.11
- *
- * Revision 1.53 2004/07/24 20:40:46 christos
- * welcome to 4.10
- *
- * Revision 1.52 2004/04/07 00:32:25 christos
- * welcome to 4.09
- *
- * Revision 1.51 2004/03/22 21:17:11 christos
- * welcome to 4.08.
- *
- * Revision 1.50 2003/12/23 17:34:04 christos
- * 4.07
- *
- * Revision 1.49 2003/10/15 02:08:27 christos
- * welcome to 4.06
- *
- * Revision 1.48 2003/09/12 19:41:14 christos
- * this is 4.04
- *
- * Revision 1.47 2003/05/23 21:38:21 christos
- * welcome to 4.03
- *
- * Revision 1.46 2003/04/02 18:57:43 christos
- * prepare for 4.02
- *
- * Revision 1.45 2003/03/26 15:37:25 christos
- * - Pass lint
- * - make NULL in magic_file mean stdin
- * - Fix "-" argument to file to pass NULL to magic_file
- * - avoid pointer casts by using memcpy
- * - rename magic_buf -> magic_buffer
- * - keep only the first error
- * - manual page: new sentence, new line
- * - fix typo in api function (magic_buf -> magic_buffer)
- *
- * Revision 1.44 2003/03/23 22:23:31 christos
- * finish librarification.
- *
- * Revision 1.43 2003/03/23 21:16:26 christos
- * update copyrights.
- *
- * Revision 1.42 2003/03/23 04:06:05 christos
- * Library re-organization
- *
- * Revision 1.41 2003/02/27 20:53:45 christos
- * - fix memory allocation problem (Jeff Johnson)
- * - fix stack overflow corruption (David Endler)
- * - fixes from NetBSD source (Antti Kantee)
- * - magic fixes
- *
- * Revision 1.40 2003/02/08 18:33:53 christos
- * - detect inttypes.h too (Dave Love <d.love at dl.ac.uk>)
- * - eliminate unsigned char warnings (Petter Reinholdtsen <pere at hungry.com>)
- * - better elf PT_NOTE handling (Nalin Dahyabhai <nalin at redhat.com>)
- * - add options to format the output differently
- * - much more magic.
- *
- * Revision 1.39 2002/07/03 18:57:52 christos
- * - ansify/c99ize
- * - more magic
- * - better COMPILE_ONLY support.
- * - new magic files.
- * - fix solaris compilation problems.
- *
- * Revision 1.38 2002/05/16 18:45:56 christos
- * - pt_note elf additions from NetBSD
- * - EMX os specific changes (Alexander Mai)
- * - stdint.h detection, acconfig.h fixes (Maciej W. Rozycki, Franz Korntner)
- * - regex file additions (Kim Cromie)
- * - getopt_long support and misc cleanups (Michael Piefel)
- * - many magic fixes and additions
- *
- * Revision 1.37 2001/09/03 14:44:22 christos
- * daylight/tm_isdst detection
- * magic fixes
- * don't eat the whole file if it has only nulls
- *
- * Revision 1.36 2001/07/22 21:04:15 christos
- * - magic fixes
- * - add new operators, pascal strings, UTC date printing, $HOME/.magic
- * [from "Tom N Harris" <telliamed at mac.com>]
- *
- * Revision 1.35 2001/04/24 14:40:25 christos
- * - rename magic file sgi to mips and fix it
- * - add support for building magic.mgc
- * - portability fixes for mmap()
- * - try gzip before uncompress, because uncompress sometimes hangs
- * - be more conservative about pipe reads and writes
- * - many magic fixes
- *
- * Revision 1.34 2001/03/12 05:05:57 christos
- * - new compiled magic format
- * - lots of magic additions
- *
- * Revision 1.33 2000/11/13 00:30:50 christos
- * - wordperfect magic fix: freebsd pr 9388
- * - more msdos fixes from freebsd pr's 20131 and 20812
- * - sas and spss magic [Bruce Foster]
- * - mkinstalldirs [John Fremlin]
- * - sgi opengl fixes [Michael Pruett]
- * - netbsd magic fixes [Ignatios Souvatzis]
- * - audio additions [Michael Pruett]
- * - fix problem with non ansi RCSID [Andreas Ley]
- * - oggs magic [Felix von Leitner]
- * - gmon magic [Eugen Dedu]
- * - TNEF magic [Joomy]
- * - netpbm magic and misc other image stuff [Bryan Henderson]
- *
- * Revision 1.32 2000/08/05 18:24:18 christos
- * Correct indianness detection in elf (Charles Hannum)
- * FreeBSD elf core support (Guy Harris)
- * Use gzip in systems that don't have uncompress (Anthon van der Neut)
- * Internationalization/EBCDIC support (Eric Fisher)
- * Many many magic changes
- *
- * Revision 1.31 2000/05/14 17:58:36 christos
- * - new magic for claris files
- * - new magic for mathematica and maple files
- * - new magic for msvc files
- * - new -k flag to keep going matching all possible entries
- * - add the word executable on #! magic files, and fix the usage of
- * the word script
- * - lots of other magic fixes
- * - fix typo test -> text
- *
- * Revision 1.30 2000/04/11 02:41:17 christos
- * - add support for mime output (-i)
- * - make sure we free memory in case realloc fails
- * - magic fixes
- *
- * Revision 1.29 1999/11/28 20:02:29 christos
- * new string/[Bcb] magic from anthon, and adjustments to the magic files to
- * use it.
- *
- * Revision 1.28 1999/10/31 22:11:48 christos
- * - add "char" type for compatibility with HP/UX
- * - recognize HP/UX syntax &=n etc.
- * - include errno.h for CYGWIN
- * - conditionalize the S_IS* macros
- * - revert the SHT_DYNSYM test that broke the linux stripped binaries test
- * - lots of Magdir changes
- *
- * Revision 1.27 1999/02/14 17:21:41 christos
- * Automake support and misc cleanups from Rainer Orth
- * Enable reading character and block special files from Dale R. Worley
- *
- * Revision 1.26 1998/09/12 13:19:39 christos
- * - add support for bi-endian indirect offsets (Richard Verhoeven)
- * - add recognition for bcpl (Joseph Myers)
- * - remove non magic files from Magdir to avoid difficulties building
- * on os2 where files are case independent
- * - magic fixes.
- *
- * Revision 1.25 1998/06/27 14:04:04 christos
- * OLF patch Guy Harris
- * Recognize java/html (debian linux)
- * Const poisoning (debian linux)
- * More magic!
- *
- * Revision 1.24 1998/02/15 23:20:38 christos
- * Autoconf patch: Felix von Leitner <leitner at math.fu-berlin.de>
- * More magic fixes
- * Elf64 fixes
- *
- * Revision 1.23 1997/11/05 16:03:37 christos
- * - correct elf prps offset for SunOS-2.5.1 [guy at netapp.com]
- * - handle 64 bit time_t's correctly [ewt at redhat.com]
- * - new mime style magic [clarosse at netvista.net]
- * - new TI calculator magic [rmcguire at freenet.columbus.oh.us]
- * - new figlet fonts [obrien at freebsd.org]
- * - new cisco magic, and elf fixes [jhawk at bbnplanet.com]
- * - -b flag addition, and x86 filesystem magic [vax at linkhead.paranoia.com]
- * - s/Mpeg/MPEG, header and elf typo fixes [guy at netapp.com]
- * - Windows/NT registry files, audio code [guy at netapp.com]
- * - libGrx graphics lib fonts [guy at netapp.com]
- * - PNG fixes [guy at netapp.com]
- * - more m$ document magic [guy at netapp.com]
- * - PPD files [guy at netapp.com]
- * - archive magic cleanup [guy at netapp.com]
- * - linux kernel magic cleanup [guy at netapp.com]
- * - lecter magic [guy at netapp.com]
- * - vgetty magic [guy at netapp.com]
- * - sniffer additions [guy at netapp.com]
- *
- * Revision 1.22 1997/01/15 17:23:24 christos
- * - add support for elf core files: find the program name under SVR4 [Ken Pizzini]
- * - print strings only up to the first carriage return [various]
- * - freebsd international ascii support [J Wunsch]
- * - magic fixes and additions [Guy Harris]
- * - 64 bit fixes [Larry Schwimmer]
- * - support for both utime and utimes, but don't restore file access times
- * by default [various]
- * - \xXX only takes 2 hex digits, not 3.
- * - re-implement support for core files [Guy Harris]
- *
- * Revision 1.21 1996/10/05 18:15:29 christos
- * Segregate elf stuff and conditionally enable it with -DBUILTIN_ELF
- * More magic fixes
- *
- * Revision 1.20 1996/06/22 22:15:52 christos
- * - support relative offsets of the form >&
- * - fix bug with truncating magic strings that contain \n
- * - file -f - did not read from stdin as documented
- * - support elf file parsing using our own elf support.
- * - as always magdir fixes and additions.
- *
- * Revision 1.19 1995/10/27 23:14:46 christos
- * Ability to parse colon separated list of magic files
- * New LEGAL.NOTICE
- * Various magic file changes
- *
- * Revision 1.18 1995/05/20 22:09:21 christos
- * Passed incorrect argument to eatsize().
- * Use %ld and %lx where appropriate.
- * Remove unused variables
- * ELF support for both big and little endian
- * Fixes for small files again.
- *
- * Revision 1.17 1995/04/28 17:29:13 christos
- * - Incorrect nroff detection fix from der Mouse
- * - Lost and incorrect magic entries.
- * - Added ELF stripped binary detection [in C; ugh]
- * - Look for $MAGIC to find the magic file.
- * - Eat trailing size specifications from numbers i.e. ignore 10L
- * - More fixes for very short files
- *
- * Revision 1.16 1995/03/25 22:06:45 christos
- * - use strtoul() where it exists.
- * - fix sign-extend bug
- * - try to detect tar archives before nroff files, otherwise
- * tar files where the first file starts with a . will not work
- *
- * Revision 1.15 1995/01/21 21:03:35 christos
- * Added CSECTION for the file man page
- * Added version flag -v
- * Fixed bug with -f input flag (from iorio at violet.berkeley.edu)
- * Lots of magic fixes and reorganization...
- *
- * Revision 1.14 1994/05/03 17:58:23 christos
- * changes from mycroft at gnu.ai.mit.edu (Charles Hannum) for unsigned
- *
- * Revision 1.13 1994/01/21 01:27:01 christos
- * Fixed null termination bug from Don Seeley at BSDI in ascmagic.c
- *
- * Revision 1.12 1993/10/27 20:59:05 christos
- * Changed -z flag to understand gzip format too.
- * Moved builtin compression detection to a table, and move
- * the compress magic entry out of the source.
- * Made printing of numbers unsigned, and added the mask to it.
- * Changed the buffer size to 8k, because gzip will refuse to
- * unzip just a few bytes.
- *
- * Revision 1.11 1993/09/24 18:49:06 christos
- * Fixed small bug in softmagic.c introduced by
- * copying the data to be examined out of the input
- * buffer. Changed the Makefile to use sed to create
- * the correct man pages.
- *
- * Revision 1.10 1993/09/23 21:56:23 christos
- * Passed purify. Fixed indirections. Fixed byte order printing.
- * Fixed segmentation faults caused by referencing past the end
- * of the magic buffer. Fixed bus errors caused by referencing
- * unaligned shorts or longs.
- *
- * Revision 1.9 1993/03/24 14:23:40 ian
- * Batch of minor changes from several contributors.
- *
- * Revision 1.8 93/02/19 15:01:26 ian
- * Numerous changes from Guy Harris too numerous to mention but including
- * byte-order independance, fixing "old-style masking", etc. etc. A bugfix
- * for broken symlinks from martin@@d255s004.zfe.siemens.de.
- *
- * Revision 1.7 93/01/05 14:57:27 ian
- * Couple of nits picked by Christos (again, thanks).
- *
- * Revision 1.6 93/01/05 13:51:09 ian
- * Lotsa work on the Magic directory.
- *
- * Revision 1.5 92/09/14 14:54:51 ian
- * Fix a tiny null-pointer bug in previous fix for tar archive + uncompress.
- *
- */
Deleted: trunk/contrib/file/print.c
===================================================================
--- trunk/contrib/file/print.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/print.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * print.c - debugging printout routines
- */
-
-#include "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.69 2010/07/21 16:47:18 christos Exp $")
-#endif /* lint */
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <time.h>
-
-#define SZOF(a) (sizeof(a) / sizeof(a[0]))
-
-#ifndef COMPILE_ONLY
-protected void
-file_mdump(struct magic *m)
-{
- private const char optyp[] = { FILE_OPS };
-
- (void) fprintf(stderr, "[%u", m->lineno);
- (void) fprintf(stderr, ">>>>>>>> %u" + 8 - (m->cont_level & 7),
- m->offset);
-
- if (m->flag & INDIR) {
- (void) fprintf(stderr, "(%s,",
- /* Note: type is unsigned */
- (m->in_type < file_nnames) ?
- file_names[m->in_type] : "*bad*");
- if (m->in_op & FILE_OPINVERSE)
- (void) fputc('~', stderr);
- (void) fprintf(stderr, "%c%u),",
- ((size_t)(m->in_op & FILE_OPS_MASK) <
- SZOF(optyp)) ?
- optyp[m->in_op & FILE_OPS_MASK] : '?',
- m->in_offset);
- }
- (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
- /* Note: type is unsigned */
- (m->type < file_nnames) ? file_names[m->type] : "*bad*");
- if (m->mask_op & FILE_OPINVERSE)
- (void) fputc('~', stderr);
-
- if (IS_STRING(m->type)) {
- if (m->str_flags) {
- (void) fputc('/', stderr);
- if (m->str_flags & STRING_COMPACT_WHITESPACE)
- (void) fputc(CHAR_COMPACT_WHITESPACE, stderr);
- if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE)
- (void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE,
- stderr);
- if (m->str_flags & STRING_IGNORE_LOWERCASE)
- (void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
- if (m->str_flags & STRING_IGNORE_UPPERCASE)
- (void) fputc(CHAR_IGNORE_UPPERCASE, stderr);
- if (m->str_flags & REGEX_OFFSET_START)
- (void) fputc(CHAR_REGEX_OFFSET_START, stderr);
- }
- if (m->str_range)
- (void) fprintf(stderr, "/%u", m->str_range);
- }
- else {
- if ((size_t)(m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
- (void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
- else
- (void) fputc('?', stderr);
-
- if (m->num_mask) {
- (void) fprintf(stderr, "%.8llx",
- (unsigned long long)m->num_mask);
- }
- }
- (void) fprintf(stderr, ",%c", m->reln);
-
- if (m->reln != 'x') {
- switch (m->type) {
- case FILE_BYTE:
- case FILE_SHORT:
- case FILE_LONG:
- case FILE_LESHORT:
- case FILE_LELONG:
- case FILE_MELONG:
- case FILE_BESHORT:
- case FILE_BELONG:
- (void) fprintf(stderr, "%d", m->value.l);
- break;
- case FILE_BEQUAD:
- case FILE_LEQUAD:
- case FILE_QUAD:
- (void) fprintf(stderr, "%" INT64_T_FORMAT "d",
- (unsigned long long)m->value.q);
- break;
- case FILE_PSTRING:
- case FILE_STRING:
- case FILE_REGEX:
- case FILE_BESTRING16:
- case FILE_LESTRING16:
- case FILE_SEARCH:
- file_showstr(stderr, m->value.s, (size_t)m->vallen);
- break;
- case FILE_DATE:
- case FILE_LEDATE:
- case FILE_BEDATE:
- case FILE_MEDATE:
- (void)fprintf(stderr, "%s,",
- file_fmttime(m->value.l, 1));
- break;
- case FILE_LDATE:
- case FILE_LELDATE:
- case FILE_BELDATE:
- case FILE_MELDATE:
- (void)fprintf(stderr, "%s,",
- file_fmttime(m->value.l, 0));
- break;
- case FILE_QDATE:
- case FILE_LEQDATE:
- case FILE_BEQDATE:
- (void)fprintf(stderr, "%s,",
- file_fmttime((uint32_t)m->value.q, 1));
- break;
- case FILE_QLDATE:
- case FILE_LEQLDATE:
- case FILE_BEQLDATE:
- (void)fprintf(stderr, "%s,",
- file_fmttime((uint32_t)m->value.q, 0));
- break;
- case FILE_FLOAT:
- case FILE_BEFLOAT:
- case FILE_LEFLOAT:
- (void) fprintf(stderr, "%G", m->value.f);
- break;
- case FILE_DOUBLE:
- case FILE_BEDOUBLE:
- case FILE_LEDOUBLE:
- (void) fprintf(stderr, "%G", m->value.d);
- break;
- case FILE_DEFAULT:
- /* XXX - do anything here? */
- break;
- default:
- (void) fputs("*bad*", stderr);
- break;
- }
- }
- (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
-}
-#endif
-
-/*VARARGS*/
-protected void
-file_magwarn(struct magic_set *ms, const char *f, ...)
-{
- va_list va;
-
- /* cuz we use stdout for most, stderr here */
- (void) fflush(stdout);
-
- if (ms->file)
- (void) fprintf(stderr, "%s, %lu: ", ms->file,
- (unsigned long)ms->line);
- (void) fprintf(stderr, "Warning: ");
- va_start(va, f);
- (void) vfprintf(stderr, f, va);
- va_end(va);
- (void) fputc('\n', stderr);
-}
-
-protected const char *
-file_fmttime(uint32_t v, int local)
-{
- char *pp;
- time_t t = (time_t)v;
- struct tm *tm;
-
- if (local) {
- pp = ctime(&t);
- } else {
-#ifndef HAVE_DAYLIGHT
- private int daylight = 0;
-#ifdef HAVE_TM_ISDST
- private time_t now = (time_t)0;
-
- if (now == (time_t)0) {
- struct tm *tm1;
- (void)time(&now);
- tm1 = localtime(&now);
- if (tm1 == NULL)
- goto out;
- daylight = tm1->tm_isdst;
- }
-#endif /* HAVE_TM_ISDST */
-#endif /* HAVE_DAYLIGHT */
- if (daylight)
- t += 3600;
- tm = gmtime(&t);
- if (tm == NULL)
- goto out;
- pp = asctime(tm);
- }
-
- if (pp == NULL)
- goto out;
- pp[strcspn(pp, "\n")] = '\0';
- return pp;
-out:
- return "*Invalid time*";
-}
Deleted: trunk/contrib/file/readcdf.c
===================================================================
--- trunk/contrib/file/readcdf.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/readcdf.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,284 +0,0 @@
-/*-
- * Copyright (c) 2008 Christos Zoulas
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#include "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.23 2010/02/20 15:19:53 rrt Exp $")
-#endif
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <ctype.h>
-
-#include "cdf.h"
-#include "magic.h"
-
-#define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0)
-
-private int
-cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
- size_t count)
-{
- size_t i;
- cdf_timestamp_t tp;
- struct timespec ts;
- char buf[64];
- const char *str = "vnd.ms-office";
- const char *s;
- int len;
-
- for (i = 0; i < count; i++) {
- cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
- switch (info[i].pi_type) {
- case CDF_NULL:
- break;
- case CDF_SIGNED16:
- if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
- info[i].pi_s16) == -1)
- return -1;
- break;
- case CDF_SIGNED32:
- if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
- info[i].pi_s32) == -1)
- return -1;
- break;
- case CDF_UNSIGNED32:
- if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
- info[i].pi_u32) == -1)
- return -1;
- break;
- case CDF_LENGTH32_STRING:
- case CDF_LENGTH32_WSTRING:
- len = info[i].pi_str.s_len;
- if (len > 1) {
- char vbuf[1024];
- size_t j, k = 1;
-
- if (info[i].pi_type == CDF_LENGTH32_WSTRING)
- k++;
- s = info[i].pi_str.s_buf;
- for (j = 0; j < sizeof(vbuf) && len--;
- j++, s += k) {
- if (*s == '\0')
- break;
- if (isprint((unsigned char)*s))
- vbuf[j] = *s;
- }
- if (j == sizeof(vbuf))
- --j;
- vbuf[j] = '\0';
- if (NOTMIME(ms)) {
- if (vbuf[0]) {
- if (file_printf(ms, ", %s: %s",
- buf, vbuf) == -1)
- return -1;
- }
- } else if (info[i].pi_id ==
- CDF_PROPERTY_NAME_OF_APPLICATION) {
- if (strstr(vbuf, "Word"))
- str = "msword";
- else if (strstr(vbuf, "Excel"))
- str = "vnd.ms-excel";
- else if (strstr(vbuf, "Powerpoint"))
- str = "vnd.ms-powerpoint";
- else if (strstr(vbuf,
- "Crystal Reports"))
- str = "x-rpt";
- }
- }
- break;
- case CDF_FILETIME:
- tp = info[i].pi_tp;
- if (tp != 0) {
- if (tp < 1000000000000000LL) {
- char tbuf[64];
- cdf_print_elapsed_time(tbuf,
- sizeof(tbuf), tp);
- if (NOTMIME(ms) && file_printf(ms,
- ", %s: %s", buf, tbuf) == -1)
- return -1;
- } else {
- char *c, *ec;
- cdf_timestamp_to_timespec(&ts, tp);
- c = ctime(&ts.tv_sec);
- if ((ec = strchr(c, '\n')) != NULL)
- *ec = '\0';
-
- if (NOTMIME(ms) && file_printf(ms,
- ", %s: %s", buf, c) == -1)
- return -1;
- }
- }
- break;
- case CDF_CLIPBOARD:
- break;
- default:
- return -1;
- }
- }
- if (!NOTMIME(ms)) {
- if (file_printf(ms, "application/%s", str) == -1)
- return -1;
- }
- return 1;
-}
-
-private int
-cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
-{
- cdf_summary_info_header_t si;
- cdf_property_info_t *info;
- size_t count;
- int m;
-
- if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
- return -1;
-
- if (NOTMIME(ms)) {
- if (file_printf(ms, "Composite Document File V2 Document") == -1)
- return -1;
-
- if (file_printf(ms, ", %s Endian",
- si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
- return -1;
- switch (si.si_os) {
- case 2:
- if (file_printf(ms, ", Os: Windows, Version %d.%d",
- si.si_os_version & 0xff,
- (uint32_t)si.si_os_version >> 8) == -1)
- return -1;
- break;
- case 1:
- if (file_printf(ms, ", Os: MacOS, Version %d.%d",
- (uint32_t)si.si_os_version >> 8,
- si.si_os_version & 0xff) == -1)
- return -1;
- break;
- default:
- if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
- si.si_os_version & 0xff,
- (uint32_t)si.si_os_version >> 8) == -1)
- return -1;
- break;
- }
- }
-
- m = cdf_file_property_info(ms, info, count);
- free(info);
-
- return m;
-}
-
-protected int
-file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
- size_t nbytes)
-{
- cdf_info_t info;
- cdf_header_t h;
- cdf_sat_t sat, ssat;
- cdf_stream_t sst, scn;
- cdf_dir_t dir;
- int i;
- const char *expn = "";
- const char *corrupt = "corrupt: ";
-
- info.i_fd = fd;
- info.i_buf = buf;
- info.i_len = nbytes;
- if (ms->flags & MAGIC_APPLE)
- return 0;
- if (cdf_read_header(&info, &h) == -1)
- return 0;
-#ifdef CDF_DEBUG
- cdf_dump_header(&h);
-#endif
-
- if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
- expn = "Can't read SAT";
- goto out0;
- }
-#ifdef CDF_DEBUG
- cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
-#endif
-
- if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
- expn = "Can't read SSAT";
- goto out1;
- }
-#ifdef CDF_DEBUG
- cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
-#endif
-
- if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
- expn = "Can't read directory";
- goto out2;
- }
-
- if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
- expn = "Cannot read short stream";
- goto out3;
- }
-#ifdef CDF_DEBUG
- cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
-#endif
-
- if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
- &scn)) == -1) {
- if (errno == ESRCH) {
- corrupt = expn;
- expn = "No summary info";
- } else {
- expn = "Cannot read summary info";
- }
- goto out4;
- }
-#ifdef CDF_DEBUG
- cdf_dump_summary_info(&h, &scn);
-#endif
- if ((i = cdf_file_summary_info(ms, &scn)) == -1)
- expn = "Can't expand summary_info";
- free(scn.sst_tab);
-out4:
- free(sst.sst_tab);
-out3:
- free(dir.dir_tab);
-out2:
- free(ssat.sat_tab);
-out1:
- free(sat.sat_tab);
-out0:
- if (i != 1) {
- if (file_printf(ms, "Composite Document File V2 Document") == -1)
- return -1;
- if (*expn)
- if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
- return -1;
- i = 1;
- }
- return i;
-}
Deleted: trunk/contrib/file/readelf.c
===================================================================
--- trunk/contrib/file/readelf.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/readelf.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,1215 +0,0 @@
-/*
- * Copyright (c) Christos Zoulas 2003.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.86 2010/07/21 16:47:18 christos Exp $")
-#endif
-
-#ifdef BUILTIN_ELF
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "readelf.h"
-#include "magic.h"
-
-#ifdef ELFCORE
-private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *);
-#endif
-private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *, int);
-private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, int *,
- int);
-private size_t donote(struct magic_set *, void *, size_t, size_t, int,
- int, size_t, int *);
-
-#define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
-
-#define isquote(c) (strchr("'\"`", (c)) != NULL)
-
-private uint16_t getu16(int, uint16_t);
-private uint32_t getu32(int, uint32_t);
-private uint64_t getu64(int, uint64_t);
-
-private uint16_t
-getu16(int swap, uint16_t value)
-{
- union {
- uint16_t ui;
- char c[2];
- } retval, tmpval;
-
- if (swap) {
- tmpval.ui = value;
-
- retval.c[0] = tmpval.c[1];
- retval.c[1] = tmpval.c[0];
-
- return retval.ui;
- } else
- return value;
-}
-
-private uint32_t
-getu32(int swap, uint32_t value)
-{
- union {
- uint32_t ui;
- char c[4];
- } retval, tmpval;
-
- if (swap) {
- tmpval.ui = value;
-
- retval.c[0] = tmpval.c[3];
- retval.c[1] = tmpval.c[2];
- retval.c[2] = tmpval.c[1];
- retval.c[3] = tmpval.c[0];
-
- return retval.ui;
- } else
- return value;
-}
-
-private uint64_t
-getu64(int swap, uint64_t value)
-{
- union {
- uint64_t ui;
- char c[8];
- } retval, tmpval;
-
- if (swap) {
- tmpval.ui = value;
-
- retval.c[0] = tmpval.c[7];
- retval.c[1] = tmpval.c[6];
- retval.c[2] = tmpval.c[5];
- retval.c[3] = tmpval.c[4];
- retval.c[4] = tmpval.c[3];
- retval.c[5] = tmpval.c[2];
- retval.c[6] = tmpval.c[1];
- retval.c[7] = tmpval.c[0];
-
- return retval.ui;
- } else
- return value;
-}
-
-#define elf_getu16(swap, value) getu16(swap, value)
-#define elf_getu32(swap, value) getu32(swap, value)
-#ifdef USE_ARRAY_FOR_64BIT_TYPES
-# define elf_getu64(swap, array) \
- ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
- (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
-#else
-# define elf_getu64(swap, value) getu64(swap, value)
-#endif
-
-#define xsh_addr (clazz == ELFCLASS32 \
- ? (void *) &sh32 \
- : (void *) &sh64)
-#define xsh_sizeof (clazz == ELFCLASS32 \
- ? sizeof sh32 \
- : sizeof sh64)
-#define xsh_size (clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_size) \
- : elf_getu64(swap, sh64.sh_size))
-#define xsh_offset (clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_offset) \
- : elf_getu64(swap, sh64.sh_offset))
-#define xsh_type (clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_type) \
- : elf_getu32(swap, sh64.sh_type))
-#define xph_addr (clazz == ELFCLASS32 \
- ? (void *) &ph32 \
- : (void *) &ph64)
-#define xph_sizeof (clazz == ELFCLASS32 \
- ? sizeof ph32 \
- : sizeof ph64)
-#define xph_type (clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_type) \
- : elf_getu32(swap, ph64.p_type))
-#define xph_offset (off_t)(clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_offset) \
- : elf_getu64(swap, ph64.p_offset))
-#define xph_align (size_t)((clazz == ELFCLASS32 \
- ? (off_t) (ph32.p_align ? \
- elf_getu32(swap, ph32.p_align) : 4) \
- : (off_t) (ph64.p_align ? \
- elf_getu64(swap, ph64.p_align) : 4)))
-#define xph_filesz (size_t)((clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_filesz) \
- : elf_getu64(swap, ph64.p_filesz)))
-#define xnh_addr (clazz == ELFCLASS32 \
- ? (void *) &nh32 \
- : (void *) &nh64)
-#define xph_memsz (size_t)((clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_memsz) \
- : elf_getu64(swap, ph64.p_memsz)))
-#define xnh_sizeof (clazz == ELFCLASS32 \
- ? sizeof nh32 \
- : sizeof nh64)
-#define xnh_type (clazz == ELFCLASS32 \
- ? elf_getu32(swap, nh32.n_type) \
- : elf_getu32(swap, nh64.n_type))
-#define xnh_namesz (clazz == ELFCLASS32 \
- ? elf_getu32(swap, nh32.n_namesz) \
- : elf_getu32(swap, nh64.n_namesz))
-#define xnh_descsz (clazz == ELFCLASS32 \
- ? elf_getu32(swap, nh32.n_descsz) \
- : elf_getu32(swap, nh64.n_descsz))
-#define prpsoffsets(i) (clazz == ELFCLASS32 \
- ? prpsoffsets32[i] \
- : prpsoffsets64[i])
-#define xcap_addr (clazz == ELFCLASS32 \
- ? (void *) &cap32 \
- : (void *) &cap64)
-#define xcap_sizeof (clazz == ELFCLASS32 \
- ? sizeof cap32 \
- : sizeof cap64)
-#define xcap_tag (clazz == ELFCLASS32 \
- ? elf_getu32(swap, cap32.c_tag) \
- : elf_getu64(swap, cap64.c_tag))
-#define xcap_val (clazz == ELFCLASS32 \
- ? elf_getu32(swap, cap32.c_un.c_val) \
- : elf_getu64(swap, cap64.c_un.c_val))
-
-#ifdef ELFCORE
-/*
- * Try larger offsets first to avoid false matches
- * from earlier data that happen to look like strings.
- */
-static const size_t prpsoffsets32[] = {
-#ifdef USE_NT_PSINFO
- 104, /* SunOS 5.x (command line) */
- 88, /* SunOS 5.x (short name) */
-#endif /* USE_NT_PSINFO */
-
- 100, /* SunOS 5.x (command line) */
- 84, /* SunOS 5.x (short name) */
-
- 44, /* Linux (command line) */
- 28, /* Linux 2.0.36 (short name) */
-
- 8, /* FreeBSD */
-};
-
-static const size_t prpsoffsets64[] = {
-#ifdef USE_NT_PSINFO
- 152, /* SunOS 5.x (command line) */
- 136, /* SunOS 5.x (short name) */
-#endif /* USE_NT_PSINFO */
-
- 136, /* SunOS 5.x, 64-bit (command line) */
- 120, /* SunOS 5.x, 64-bit (short name) */
-
- 56, /* Linux (command line) */
- 40, /* Linux (tested on core from 2.4.x, short name) */
-
- 16, /* FreeBSD, 64-bit */
-};
-
-#define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
-#define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
-
-#define NOFFSETS (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
-
-/*
- * Look through the program headers of an executable image, searching
- * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE" or
- * "FreeBSD"; if one is found, try looking in various places in its
- * contents for a 16-character string containing only printable
- * characters - if found, that string should be the name of the program
- * that dropped core. Note: right after that 16-character string is,
- * at least in SunOS 5.x (and possibly other SVR4-flavored systems) and
- * Linux, a longer string (80 characters, in 5.x, probably other
- * SVR4-flavored systems, and Linux) containing the start of the
- * command line for that program.
- *
- * SunOS 5.x core files contain two PT_NOTE sections, with the types
- * NT_PRPSINFO (old) and NT_PSINFO (new). These structs contain the
- * same info about the command name and command line, so it probably
- * isn't worthwhile to look for NT_PSINFO, but the offsets are provided
- * above (see USE_NT_PSINFO), in case we ever decide to do so. The
- * NT_PRPSINFO and NT_PSINFO sections are always in order and adjacent;
- * the SunOS 5.x file command relies on this (and prefers the latter).
- *
- * The signal number probably appears in a section of type NT_PRSTATUS,
- * but that's also rather OS-dependent, in ways that are harder to
- * dissect with heuristics, so I'm not bothering with the signal number.
- * (I suppose the signal number could be of interest in situations where
- * you don't have the binary of the program that dropped core; if you
- * *do* have that binary, the debugger will probably tell you what
- * signal it was.)
- */
-
-#define OS_STYLE_SVR4 0
-#define OS_STYLE_FREEBSD 1
-#define OS_STYLE_NETBSD 2
-
-private const char os_style_names[][8] = {
- "SVR4",
- "FreeBSD",
- "NetBSD",
-};
-
-#define FLAGS_DID_CORE 1
-#define FLAGS_DID_NOTE 2
-#define FLAGS_DID_CORE_STYLE 4
-#define FLAGS_IS_CORE 8
-
-private int
-dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
- int num, size_t size, off_t fsize, int *flags)
-{
- Elf32_Phdr ph32;
- Elf64_Phdr ph64;
- size_t offset;
- unsigned char nbuf[BUFSIZ];
- ssize_t bufsize;
- off_t savedoffset;
- struct stat st;
-
- if (fstat(fd, &st) < 0) {
- file_badread(ms);
- return -1;
- }
-
- if (size != xph_sizeof) {
- if (file_printf(ms, ", corrupted program header size") == -1)
- return -1;
- return 0;
- }
-
- /*
- * Loop through all the program headers.
- */
- for ( ; num; num--) {
- if ((savedoffset = lseek(fd, off, SEEK_SET)) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- if (read(fd, xph_addr, xph_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
- if (xph_offset > fsize) {
- if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- continue;
- }
-
- off += size;
- if (xph_type != PT_NOTE)
- continue;
-
- /*
- * This is a PT_NOTE section; loop through all the notes
- * in the section.
- */
- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- bufsize = read(fd, nbuf,
- ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
- if (bufsize == -1) {
- file_badread(ms);
- return -1;
- }
- offset = 0;
- for (;;) {
- if (offset >= (size_t)bufsize)
- break;
- offset = donote(ms, nbuf, offset, (size_t)bufsize,
- clazz, swap, 4, flags);
- if (offset == 0)
- break;
-
- }
- }
- return 0;
-}
-#endif
-
-private size_t
-donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
- int clazz, int swap, size_t align, int *flags)
-{
- Elf32_Nhdr nh32;
- Elf64_Nhdr nh64;
- size_t noff, doff;
-#ifdef ELFCORE
- int os_style = -1;
-#endif
- uint32_t namesz, descsz;
- unsigned char *nbuf = CAST(unsigned char *, vbuf);
-
- (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
- offset += xnh_sizeof;
-
- namesz = xnh_namesz;
- descsz = xnh_descsz;
- if ((namesz == 0) && (descsz == 0)) {
- /*
- * We're out of note headers.
- */
- return (offset >= size) ? offset : size;
- }
-
- if (namesz & 0x80000000) {
- (void)file_printf(ms, ", bad note name size 0x%lx",
- (unsigned long)namesz);
- return offset;
- }
-
- if (descsz & 0x80000000) {
- (void)file_printf(ms, ", bad note description size 0x%lx",
- (unsigned long)descsz);
- return offset;
- }
-
-
- noff = offset;
- doff = ELF_ALIGN(offset + namesz);
-
- if (offset + namesz > size) {
- /*
- * We're past the end of the buffer.
- */
- return doff;
- }
-
- offset = ELF_ALIGN(doff + descsz);
- if (doff + descsz > size) {
- /*
- * We're past the end of the buffer.
- */
- return (offset >= size) ? offset : size;
- }
-
- if (*flags & FLAGS_DID_NOTE)
- goto core;
-
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
- xnh_type == NT_GNU_VERSION && descsz == 16) {
- uint32_t desc[4];
- (void)memcpy(desc, &nbuf[doff], sizeof(desc));
-
- if (file_printf(ms, ", for GNU/") == -1)
- return size;
- switch (elf_getu32(swap, desc[0])) {
- case GNU_OS_LINUX:
- if (file_printf(ms, "Linux") == -1)
- return size;
- break;
- case GNU_OS_HURD:
- if (file_printf(ms, "Hurd") == -1)
- return size;
- break;
- case GNU_OS_SOLARIS:
- if (file_printf(ms, "Solaris") == -1)
- return size;
- break;
- case GNU_OS_KFREEBSD:
- if (file_printf(ms, "kFreeBSD") == -1)
- return size;
- break;
- case GNU_OS_KNETBSD:
- if (file_printf(ms, "kNetBSD") == -1)
- return size;
- break;
- default:
- if (file_printf(ms, "<unknown>") == -1)
- return size;
- }
- if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
- elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
- return size;
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
- xnh_type == NT_NETBSD_VERSION && descsz == 4) {
- uint32_t desc;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = elf_getu32(swap, desc);
-
- if (file_printf(ms, ", for NetBSD") == -1)
- return size;
- /*
- * The version number used to be stuck as 199905, and was thus
- * basically content-free. Newer versions of NetBSD have fixed
- * this and now use the encoding of __NetBSD_Version__:
- *
- * MMmmrrpp00
- *
- * M = major version
- * m = minor version
- * r = release ["",A-Z,Z[A-Z] but numeric]
- * p = patchlevel
- */
- if (desc > 100000000U) {
- uint32_t ver_patch = (desc / 100) % 100;
- uint32_t ver_rel = (desc / 10000) % 100;
- uint32_t ver_min = (desc / 1000000) % 100;
- uint32_t ver_maj = desc / 100000000;
-
- if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
- return size;
- if (ver_rel == 0 && ver_patch != 0) {
- if (file_printf(ms, ".%u", ver_patch) == -1)
- return size;
- } else if (ver_rel != 0) {
- while (ver_rel > 26) {
- if (file_printf(ms, "Z") == -1)
- return size;
- ver_rel -= 26;
- }
- if (file_printf(ms, "%c", 'A' + ver_rel - 1)
- == -1)
- return size;
- }
- }
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
- xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
- uint32_t desc;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = elf_getu32(swap, desc);
- if (file_printf(ms, ", for FreeBSD") == -1)
- return size;
-
- /*
- * Contents is __FreeBSD_version, whose relation to OS
- * versions is defined by a huge table in the Porter's
- * Handbook. This is the general scheme:
- *
- * Releases:
- * Mmp000 (before 4.10)
- * Mmi0p0 (before 5.0)
- * Mmm0p0
- *
- * Development branches:
- * Mmpxxx (before 4.6)
- * Mmp1xx (before 4.10)
- * Mmi1xx (before 5.0)
- * M000xx (pre-M.0)
- * Mmm1xx
- *
- * M = major version
- * m = minor version
- * i = minor version increment (491000 -> 4.10)
- * p = patchlevel
- * x = revision
- *
- * The first release of FreeBSD to use ELF by default
- * was version 3.0.
- */
- if (desc == 460002) {
- if (file_printf(ms, " 4.6.2") == -1)
- return size;
- } else if (desc < 460100) {
- if (file_printf(ms, " %d.%d", desc / 100000,
- desc / 10000 % 10) == -1)
- return size;
- if (desc / 1000 % 10 > 0)
- if (file_printf(ms, ".%d", desc / 1000 % 10)
- == -1)
- return size;
- if ((desc % 1000 > 0) || (desc % 100000 == 0))
- if (file_printf(ms, " (%d)", desc) == -1)
- return size;
- } else if (desc < 500000) {
- if (file_printf(ms, " %d.%d", desc / 100000,
- desc / 10000 % 10 + desc / 1000 % 10) == -1)
- return size;
- if (desc / 100 % 10 > 0) {
- if (file_printf(ms, " (%d)", desc) == -1)
- return size;
- } else if (desc / 10 % 10 > 0) {
- if (file_printf(ms, ".%d", desc / 10 % 10)
- == -1)
- return size;
- }
- } else {
- if (file_printf(ms, " %d.%d", desc / 100000,
- desc / 1000 % 100) == -1)
- return size;
- if ((desc / 100 % 10 > 0) ||
- (desc % 100000 / 100 == 0)) {
- if (file_printf(ms, " (%d)", desc) == -1)
- return size;
- } else if (desc / 10 % 10 > 0) {
- if (file_printf(ms, ".%d", desc / 10 % 10)
- == -1)
- return size;
- }
- }
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
- xnh_type == NT_OPENBSD_VERSION && descsz == 4) {
- if (file_printf(ms, ", for OpenBSD") == -1)
- return size;
- /* Content of note is always 0 */
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
- xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
- uint32_t desc;
- if (file_printf(ms, ", for DragonFly") == -1)
- return size;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = elf_getu32(swap, desc);
- if (file_printf(ms, " %d.%d.%d", desc / 100000,
- desc / 10000 % 10, desc % 10000) == -1)
- return size;
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
-core:
- /*
- * Sigh. The 2.0.36 kernel in Debian 2.1, at
- * least, doesn't correctly implement name
- * sections, in core dumps, as specified by
- * the "Program Linking" section of "UNIX(R) System
- * V Release 4 Programmer's Guide: ANSI C and
- * Programming Support Tools", because my copy
- * clearly says "The first 'namesz' bytes in 'name'
- * contain a *null-terminated* [emphasis mine]
- * character representation of the entry's owner
- * or originator", but the 2.0.36 kernel code
- * doesn't include the terminating null in the
- * name....
- */
- if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
- (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
- os_style = OS_STYLE_SVR4;
- }
-
- if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
- os_style = OS_STYLE_FREEBSD;
- }
-
- if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
- == 0)) {
- os_style = OS_STYLE_NETBSD;
- }
-
-#ifdef ELFCORE
- if ((*flags & FLAGS_DID_CORE) != 0)
- return size;
-
- if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
- if (file_printf(ms, ", %s-style", os_style_names[os_style])
- == -1)
- return size;
- *flags |= FLAGS_DID_CORE_STYLE;
- }
-
- switch (os_style) {
- case OS_STYLE_NETBSD:
- if (xnh_type == NT_NETBSD_CORE_PROCINFO) {
- uint32_t signo;
- /*
- * Extract the program name. It is at
- * offset 0x7c, and is up to 32-bytes,
- * including the terminating NUL.
- */
- if (file_printf(ms, ", from '%.31s'",
- &nbuf[doff + 0x7c]) == -1)
- return size;
-
- /*
- * Extract the signal number. It is at
- * offset 0x08.
- */
- (void)memcpy(&signo, &nbuf[doff + 0x08],
- sizeof(signo));
- if (file_printf(ms, " (signal %u)",
- elf_getu32(swap, signo)) == -1)
- return size;
- *flags |= FLAGS_DID_CORE;
- return size;
- }
- break;
-
- default:
- if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
- size_t i, j;
- unsigned char c;
- /*
- * Extract the program name. We assume
- * it to be 16 characters (that's what it
- * is in SunOS 5.x and Linux).
- *
- * Unfortunately, it's at a different offset
- * in various OSes, so try multiple offsets.
- * If the characters aren't all printable,
- * reject it.
- */
- for (i = 0; i < NOFFSETS; i++) {
- unsigned char *cname, *cp;
- size_t reloffset = prpsoffsets(i);
- size_t noffset = doff + reloffset;
- for (j = 0; j < 16; j++, noffset++,
- reloffset++) {
- /*
- * Make sure we're not past
- * the end of the buffer; if
- * we are, just give up.
- */
- if (noffset >= size)
- goto tryanother;
-
- /*
- * Make sure we're not past
- * the end of the contents;
- * if we are, this obviously
- * isn't the right offset.
- */
- if (reloffset >= descsz)
- goto tryanother;
-
- c = nbuf[noffset];
- if (c == '\0') {
- /*
- * A '\0' at the
- * beginning is
- * obviously wrong.
- * Any other '\0'
- * means we're done.
- */
- if (j == 0)
- goto tryanother;
- else
- break;
- } else {
- /*
- * A nonprintable
- * character is also
- * wrong.
- */
- if (!isprint(c) || isquote(c))
- goto tryanother;
- }
- }
- /*
- * Well, that worked.
- */
-
- /*
- * Try next offsets, in case this match is
- * in the middle of a string.
- */
- size_t k;
- for (k = i + 1 ; k < NOFFSETS ; k++) {
- if (prpsoffsets(k) >= prpsoffsets(i))
- continue;
- size_t no;
- int adjust = 1;
- for (no = doff + prpsoffsets(k);
- no < doff + prpsoffsets(i); no++)
- adjust = adjust
- && isprint(nbuf[no]);
- if (adjust)
- i = k;
- }
-
- cname = (unsigned char *)
- &nbuf[doff + prpsoffsets(i)];
- for (cp = cname; *cp && isprint(*cp); cp++)
- continue;
- /*
- * Linux apparently appends a space at the end
- * of the command line: remove it.
- */
- while (cp > cname && isspace(cp[-1]))
- cp--;
- if (file_printf(ms, ", from '%.*s'",
- (int)(cp - cname), cname) == -1)
- return size;
- *flags |= FLAGS_DID_CORE;
- return size;
-
- tryanother:
- ;
- }
- }
- break;
- }
-#endif
- return offset;
-}
-
-/* SunOS 5.x hardware capability descriptions */
-typedef struct cap_desc {
- uint64_t cd_mask;
- const char *cd_name;
-} cap_desc_t;
-
-static const cap_desc_t cap_desc_sparc[] = {
- { AV_SPARC_MUL32, "MUL32" },
- { AV_SPARC_DIV32, "DIV32" },
- { AV_SPARC_FSMULD, "FSMULD" },
- { AV_SPARC_V8PLUS, "V8PLUS" },
- { AV_SPARC_POPC, "POPC" },
- { AV_SPARC_VIS, "VIS" },
- { AV_SPARC_VIS2, "VIS2" },
- { AV_SPARC_ASI_BLK_INIT, "ASI_BLK_INIT" },
- { AV_SPARC_FMAF, "FMAF" },
- { AV_SPARC_FJFMAU, "FJFMAU" },
- { AV_SPARC_IMA, "IMA" },
- { 0, NULL }
-};
-
-static const cap_desc_t cap_desc_386[] = {
- { AV_386_FPU, "FPU" },
- { AV_386_TSC, "TSC" },
- { AV_386_CX8, "CX8" },
- { AV_386_SEP, "SEP" },
- { AV_386_AMD_SYSC, "AMD_SYSC" },
- { AV_386_CMOV, "CMOV" },
- { AV_386_MMX, "MMX" },
- { AV_386_AMD_MMX, "AMD_MMX" },
- { AV_386_AMD_3DNow, "AMD_3DNow" },
- { AV_386_AMD_3DNowx, "AMD_3DNowx" },
- { AV_386_FXSR, "FXSR" },
- { AV_386_SSE, "SSE" },
- { AV_386_SSE2, "SSE2" },
- { AV_386_PAUSE, "PAUSE" },
- { AV_386_SSE3, "SSE3" },
- { AV_386_MON, "MON" },
- { AV_386_CX16, "CX16" },
- { AV_386_AHF, "AHF" },
- { AV_386_TSCP, "TSCP" },
- { AV_386_AMD_SSE4A, "AMD_SSE4A" },
- { AV_386_POPCNT, "POPCNT" },
- { AV_386_AMD_LZCNT, "AMD_LZCNT" },
- { AV_386_SSSE3, "SSSE3" },
- { AV_386_SSE4_1, "SSE4.1" },
- { AV_386_SSE4_2, "SSE4.2" },
- { 0, NULL }
-};
-
-private int
-doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
- size_t size, int *flags, int mach)
-{
- Elf32_Shdr sh32;
- Elf64_Shdr sh64;
- int stripped = 1;
- void *nbuf;
- off_t noff;
- uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
- uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
-
- if (size != xsh_sizeof) {
- if (file_printf(ms, ", corrupted section header size") == -1)
- return -1;
- return 0;
- }
-
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
-
- for ( ; num; num--) {
- if (read(fd, xsh_addr, xsh_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
- switch (xsh_type) {
- case SHT_SYMTAB:
-#if 0
- case SHT_DYNSYM:
-#endif
- stripped = 0;
- break;
- case SHT_NOTE:
- if ((off = lseek(fd, (off_t)0, SEEK_CUR)) ==
- (off_t)-1) {
- file_badread(ms);
- return -1;
- }
- if ((nbuf = malloc((size_t)xsh_size)) == NULL) {
- file_error(ms, errno, "Cannot allocate memory"
- " for note");
- return -1;
- }
- if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) ==
- (off_t)-1) {
- file_badread(ms);
- free(nbuf);
- return -1;
- }
- if (read(fd, nbuf, (size_t)xsh_size) !=
- (ssize_t)xsh_size) {
- free(nbuf);
- file_badread(ms);
- return -1;
- }
-
- noff = 0;
- for (;;) {
- if (noff >= (off_t)xsh_size)
- break;
- noff = donote(ms, nbuf, (size_t)noff,
- (size_t)xsh_size, clazz, swap, 4,
- flags);
- if (noff == 0)
- break;
- }
- if ((lseek(fd, off, SEEK_SET)) == (off_t)-1) {
- free(nbuf);
- file_badread(ms);
- return -1;
- }
- free(nbuf);
- break;
- case SHT_SUNW_cap:
- {
- off_t coff;
- if ((off = lseek(fd, (off_t)0, SEEK_CUR)) ==
- (off_t)-1) {
- file_badread(ms);
- return -1;
- }
- if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
- (off_t)-1) {
- file_badread(ms);
- return -1;
- }
- coff = 0;
- for (;;) {
- Elf32_Cap cap32;
- Elf64_Cap cap64;
- char cbuf[/*CONSTCOND*/
- MAX(sizeof cap32, sizeof cap64)];
- if ((coff += xcap_sizeof) > (off_t)xsh_size)
- break;
- if (read(fd, cbuf, (size_t)xcap_sizeof) !=
- (ssize_t)xcap_sizeof) {
- file_badread(ms);
- return -1;
- }
- (void)memcpy(xcap_addr, cbuf, xcap_sizeof);
- switch (xcap_tag) {
- case CA_SUNW_NULL:
- break;
- case CA_SUNW_HW_1:
- cap_hw1 |= xcap_val;
- break;
- case CA_SUNW_SF_1:
- cap_sf1 |= xcap_val;
- break;
- default:
- if (file_printf(ms,
- ", with unknown capability "
- "0x%" INT64_T_FORMAT "x = 0x%"
- INT64_T_FORMAT "x",
- (unsigned long long)xcap_tag,
- (unsigned long long)xcap_val) == -1)
- return -1;
- break;
- }
- }
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
- file_badread(ms);
- return -1;
- }
- break;
- }
- }
- }
- if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
- return -1;
- if (cap_hw1) {
- const cap_desc_t *cdp;
- switch (mach) {
- case EM_SPARC:
- case EM_SPARC32PLUS:
- case EM_SPARCV9:
- cdp = cap_desc_sparc;
- break;
- case EM_386:
- case EM_IA_64:
- case EM_AMD64:
- cdp = cap_desc_386;
- break;
- default:
- cdp = NULL;
- break;
- }
- if (file_printf(ms, ", uses") == -1)
- return -1;
- if (cdp) {
- while (cdp->cd_name) {
- if (cap_hw1 & cdp->cd_mask) {
- if (file_printf(ms,
- " %s", cdp->cd_name) == -1)
- return -1;
- cap_hw1 &= ~cdp->cd_mask;
- }
- ++cdp;
- }
- if (cap_hw1)
- if (file_printf(ms,
- " unknown hardware capability 0x%"
- INT64_T_FORMAT "x",
- (unsigned long long)cap_hw1) == -1)
- return -1;
- } else {
- if (file_printf(ms,
- " hardware capability 0x%" INT64_T_FORMAT "x",
- (unsigned long long)cap_hw1) == -1)
- return -1;
- }
- }
- if (cap_sf1) {
- if (cap_sf1 & SF1_SUNW_FPUSED) {
- if (file_printf(ms,
- (cap_sf1 & SF1_SUNW_FPKNWN)
- ? ", uses frame pointer"
- : ", not known to use frame pointer") == -1)
- return -1;
- }
- cap_sf1 &= ~SF1_SUNW_MASK;
- if (cap_sf1)
- if (file_printf(ms,
- ", with unknown software capability 0x%"
- INT64_T_FORMAT "x",
- (unsigned long long)cap_sf1) == -1)
- return -1;
- }
- return 0;
-}
-
-/*
- * Look through the program headers of an executable image, searching
- * for a PT_INTERP section; if one is found, it's dynamically linked,
- * otherwise it's statically linked.
- */
-private int
-dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
- int num, size_t size, off_t fsize, int *flags, int sh_num)
-{
- Elf32_Phdr ph32;
- Elf64_Phdr ph64;
- const char *linking_style = "statically";
- const char *shared_libraries = "";
- unsigned char nbuf[BUFSIZ];
- ssize_t bufsize;
- size_t offset, align;
- off_t savedoffset = (off_t)-1;
- struct stat st;
-
- if (fstat(fd, &st) < 0) {
- file_badread(ms);
- return -1;
- }
-
- if (size != xph_sizeof) {
- if (file_printf(ms, ", corrupted program header size") == -1)
- return -1;
- return 0;
- }
-
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
-
- for ( ; num; num--) {
- if (read(fd, xph_addr, xph_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
- if (xph_offset > st.st_size && savedoffset != (off_t)-1) {
- if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- continue;
- }
-
- if ((savedoffset = lseek(fd, (off_t)0, SEEK_CUR)) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
-
- if (xph_offset > fsize) {
- if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- continue;
- }
-
- switch (xph_type) {
- case PT_DYNAMIC:
- linking_style = "dynamically";
- break;
- case PT_INTERP:
- shared_libraries = " (uses shared libs)";
- break;
- case PT_NOTE:
- if ((align = xph_align) & 0x80000000UL) {
- if (file_printf(ms,
- ", invalid note alignment 0x%lx",
- (unsigned long)align) == -1)
- return -1;
- align = 4;
- }
- if (sh_num)
- break;
- /*
- * This is a PT_NOTE section; loop through all the notes
- * in the section.
- */
- if (lseek(fd, xph_offset, SEEK_SET)
- == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
- xph_filesz : sizeof(nbuf)));
- if (bufsize == -1) {
- file_badread(ms);
- return -1;
- }
- offset = 0;
- for (;;) {
- if (offset >= (size_t)bufsize)
- break;
- offset = donote(ms, nbuf, offset,
- (size_t)bufsize, clazz, swap, align,
- flags);
- if (offset == 0)
- break;
- }
- if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- break;
- default:
- break;
- }
- }
- if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries)
- == -1)
- return -1;
- return 0;
-}
-
-
-protected int
-file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
- size_t nbytes)
-{
- union {
- int32_t l;
- char c[sizeof (int32_t)];
- } u;
- int clazz;
- int swap;
- struct stat st;
- off_t fsize;
- int flags = 0;
- Elf32_Ehdr elf32hdr;
- Elf64_Ehdr elf64hdr;
- uint16_t type;
-
- if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
- return 0;
- /*
- * ELF executables have multiple section headers in arbitrary
- * file locations and thus file(1) cannot determine it from easily.
- * Instead we traverse thru all section headers until a symbol table
- * one is found or else the binary is stripped.
- * Return immediately if it's not ELF (so we avoid pipe2file unless needed).
- */
- if (buf[EI_MAG0] != ELFMAG0
- || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
- || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
- return 0;
-
- /*
- * If we cannot seek, it must be a pipe, socket or fifo.
- */
- if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
- fd = file_pipe2file(ms, fd, buf, nbytes);
-
- if (fstat(fd, &st) == -1) {
- file_badread(ms);
- return -1;
- }
- fsize = st.st_size;
-
- clazz = buf[EI_CLASS];
-
- switch (clazz) {
- case ELFCLASS32:
-#undef elf_getu
-#define elf_getu(a, b) elf_getu32(a, b)
-#undef elfhdr
-#define elfhdr elf32hdr
-#include "elfclass.h"
- case ELFCLASS64:
-#undef elf_getu
-#define elf_getu(a, b) elf_getu64(a, b)
-#undef elfhdr
-#define elfhdr elf64hdr
-#include "elfclass.h"
- default:
- if (file_printf(ms, ", unknown class %d", clazz) == -1)
- return -1;
- break;
- }
- return 0;
-}
-#endif
Deleted: trunk/contrib/file/softmagic.c
===================================================================
--- trunk/contrib/file/softmagic.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/softmagic.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,2009 +0,0 @@
-/*
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * softmagic - interpret variable magic from MAGIC
- */
-
-#include "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.144 2011/01/07 23:22:28 rrt Exp $")
-#endif /* lint */
-
-#include "magic.h"
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <time.h>
-
-
-private int match(struct magic_set *, struct magic *, uint32_t,
- const unsigned char *, size_t, int);
-private int mget(struct magic_set *, const unsigned char *,
- struct magic *, size_t, unsigned int);
-private int magiccheck(struct magic_set *, struct magic *);
-private int32_t mprint(struct magic_set *, struct magic *);
-private int32_t moffset(struct magic_set *, struct magic *);
-private void mdebug(uint32_t, const char *, size_t);
-private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
- const unsigned char *, uint32_t, size_t, size_t);
-private int mconvert(struct magic_set *, struct magic *);
-private int print_sep(struct magic_set *, int);
-private int handle_annotation(struct magic_set *, struct magic *);
-private void cvt_8(union VALUETYPE *, const struct magic *);
-private void cvt_16(union VALUETYPE *, const struct magic *);
-private void cvt_32(union VALUETYPE *, const struct magic *);
-private void cvt_64(union VALUETYPE *, const struct magic *);
-
-/*
- * softmagic - lookup one file in parsed, in-memory copy of database
- * Passed the name and FILE * of one file to be typed.
- */
-/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
-protected int
-file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, int mode)
-{
- struct mlist *ml;
- int rv;
- for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
- if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode)) != 0)
- return rv;
-
- return 0;
-}
-
-/*
- * Go through the whole list, stopping if you find a match. Process all
- * the continuations of that match before returning.
- *
- * We support multi-level continuations:
- *
- * At any time when processing a successful top-level match, there is a
- * current continuation level; it represents the level of the last
- * successfully matched continuation.
- *
- * Continuations above that level are skipped as, if we see one, it
- * means that the continuation that controls them - i.e, the
- * lower-level continuation preceding them - failed to match.
- *
- * Continuations below that level are processed as, if we see one,
- * it means we've finished processing or skipping higher-level
- * continuations under the control of a successful or unsuccessful
- * lower-level continuation, and are now seeing the next lower-level
- * continuation and should process it. The current continuation
- * level reverts to the level of the one we're seeing.
- *
- * Continuations at the current level are processed as, if we see
- * one, there's no lower-level continuation that may have failed.
- *
- * If a continuation matches, we bump the current continuation level
- * so that higher-level continuations are processed.
- */
-private int
-match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
- const unsigned char *s, size_t nbytes, int mode)
-{
- uint32_t magindex = 0;
- unsigned int cont_level = 0;
- int need_separator = 0;
- int returnval = 0, e; /* if a match is found it is set to 1*/
- int firstline = 1; /* a flag to print X\n X\n- X */
- int printed_something = 0;
- int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
-
- if (file_check_mem(ms, cont_level) == -1)
- return -1;
-
- for (magindex = 0; magindex < nmagic; magindex++) {
- int flush = 0;
- struct magic *m = &magic[magindex];
-
- if ((m->flag & mode) != mode) {
- /* Skip sub-tests */
- while (magic[magindex + 1].cont_level != 0 &&
- ++magindex < nmagic)
- continue;
- continue; /* Skip to next top-level test*/
- }
-
- ms->offset = m->offset;
- ms->line = m->lineno;
-
- /* if main entry matches, print it... */
- switch (mget(ms, s, m, nbytes, cont_level)) {
- case -1:
- return -1;
- case 0:
- flush = m->reln != '!';
- break;
- default:
- if (m->type == FILE_INDIRECT)
- returnval = 1;
-
- switch (magiccheck(ms, m)) {
- case -1:
- return -1;
- case 0:
- flush++;
- break;
- default:
- flush = 0;
- break;
- }
- break;
- }
- if (flush) {
- /*
- * main entry didn't match,
- * flush its continuations
- */
- while (magindex < nmagic - 1 &&
- magic[magindex + 1].cont_level != 0)
- magindex++;
- continue;
- }
-
- if ((e = handle_annotation(ms, m)) != 0)
- return e;
- /*
- * If we are going to print something, we'll need to print
- * a blank before we print something else.
- */
- if (*m->desc) {
- need_separator = 1;
- printed_something = 1;
- if (print_sep(ms, firstline) == -1)
- return -1;
- }
-
-
- if (print && mprint(ms, m) == -1)
- return -1;
-
- ms->c.li[cont_level].off = moffset(ms, m);
-
- /* and any continuations that match */
- if (file_check_mem(ms, ++cont_level) == -1)
- return -1;
-
- while (magic[magindex+1].cont_level != 0 &&
- ++magindex < nmagic) {
- m = &magic[magindex];
- ms->line = m->lineno; /* for messages */
-
- if (cont_level < m->cont_level)
- continue;
- if (cont_level > m->cont_level) {
- /*
- * We're at the end of the level
- * "cont_level" continuations.
- */
- cont_level = m->cont_level;
- }
- ms->offset = m->offset;
- if (m->flag & OFFADD) {
- ms->offset +=
- ms->c.li[cont_level - 1].off;
- }
-
-#ifdef ENABLE_CONDITIONALS
- if (m->cond == COND_ELSE ||
- m->cond == COND_ELIF) {
- if (ms->c.li[cont_level].last_match == 1)
- continue;
- }
-#endif
- switch (mget(ms, s, m, nbytes, cont_level)) {
- case -1:
- return -1;
- case 0:
- if (m->reln != '!')
- continue;
- flush = 1;
- break;
- default:
- if (m->type == FILE_INDIRECT)
- returnval = 1;
- flush = 0;
- break;
- }
-
- switch (flush ? 1 : magiccheck(ms, m)) {
- case -1:
- return -1;
- case 0:
-#ifdef ENABLE_CONDITIONALS
- ms->c.li[cont_level].last_match = 0;
-#endif
- break;
- default:
-#ifdef ENABLE_CONDITIONALS
- ms->c.li[cont_level].last_match = 1;
-#endif
- if (m->type != FILE_DEFAULT)
- ms->c.li[cont_level].got_match = 1;
- else if (ms->c.li[cont_level].got_match) {
- ms->c.li[cont_level].got_match = 0;
- break;
- }
- if ((e = handle_annotation(ms, m)) != 0)
- return e;
- /*
- * If we are going to print something,
- * make sure that we have a separator first.
- */
- if (*m->desc) {
- if (!printed_something) {
- printed_something = 1;
- if (print_sep(ms, firstline)
- == -1)
- return -1;
- }
- }
- /*
- * This continuation matched. Print
- * its message, with a blank before it
- * if the previous item printed and
- * this item isn't empty.
- */
- /* space if previous printed */
- if (need_separator
- && ((m->flag & NOSPACE) == 0)
- && *m->desc) {
- if (print &&
- file_printf(ms, " ") == -1)
- return -1;
- need_separator = 0;
- }
- if (print && mprint(ms, m) == -1)
- return -1;
-
- ms->c.li[cont_level].off = moffset(ms, m);
-
- if (*m->desc)
- need_separator = 1;
-
- /*
- * If we see any continuations
- * at a higher level,
- * process them.
- */
- if (file_check_mem(ms, ++cont_level) == -1)
- return -1;
- break;
- }
- }
- if (printed_something) {
- firstline = 0;
- if (print)
- returnval = 1;
- }
- if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
- return returnval; /* don't keep searching */
- }
- }
- return returnval; /* This is hit if -k is set or there is no match */
-}
-
-private int
-check_fmt(struct magic_set *ms, struct magic *m)
-{
- regex_t rx;
- int rc;
-
- if (strchr(m->desc, '%') == NULL)
- return 0;
-
- rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
- if (rc) {
- char errmsg[512];
- (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
- file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
- return -1;
- } else {
- rc = regexec(&rx, m->desc, 0, 0, 0);
- regfree(&rx);
- return !rc;
- }
-}
-
-#ifndef HAVE_STRNDUP
-char * strndup(const char *, size_t);
-
-char *
-strndup(const char *str, size_t n)
-{
- size_t len;
- char *copy;
-
- for (len = 0; len < n && str[len]; len++)
- continue;
- if ((copy = malloc(len + 1)) == NULL)
- return NULL;
- (void)memcpy(copy, str, len);
- copy[len] = '\0';
- return copy;
-}
-#endif /* HAVE_STRNDUP */
-
-private int32_t
-mprint(struct magic_set *ms, struct magic *m)
-{
- uint64_t v;
- float vf;
- double vd;
- int64_t t = 0;
- char buf[128];
- union VALUETYPE *p = &ms->ms_value;
-
- switch (m->type) {
- case FILE_BYTE:
- v = file_signextend(ms, m, (uint64_t)p->b);
- switch (check_fmt(ms, m)) {
- case -1:
- return -1;
- case 1:
- (void)snprintf(buf, sizeof(buf), "%c",
- (unsigned char)v);
- if (file_printf(ms, m->desc, buf) == -1)
- return -1;
- break;
- default:
- if (file_printf(ms, m->desc, (unsigned char) v) == -1)
- return -1;
- break;
- }
- t = ms->offset + sizeof(char);
- break;
-
- case FILE_SHORT:
- case FILE_BESHORT:
- case FILE_LESHORT:
- v = file_signextend(ms, m, (uint64_t)p->h);
- switch (check_fmt(ms, m)) {
- case -1:
- return -1;
- case 1:
- (void)snprintf(buf, sizeof(buf), "%hu",
- (unsigned short)v);
- if (file_printf(ms, m->desc, buf) == -1)
- return -1;
- break;
- default:
- if (
- file_printf(ms, m->desc, (unsigned short) v) == -1)
- return -1;
- break;
- }
- t = ms->offset + sizeof(short);
- break;
-
- case FILE_LONG:
- case FILE_BELONG:
- case FILE_LELONG:
- case FILE_MELONG:
- v = file_signextend(ms, m, (uint64_t)p->l);
- switch (check_fmt(ms, m)) {
- case -1:
- return -1;
- case 1:
- (void)snprintf(buf, sizeof(buf), "%u", (uint32_t)v);
- if (file_printf(ms, m->desc, buf) == -1)
- return -1;
- break;
- default:
- if (file_printf(ms, m->desc, (uint32_t) v) == -1)
- return -1;
- break;
- }
- t = ms->offset + sizeof(int32_t);
- break;
-
- case FILE_QUAD:
- case FILE_BEQUAD:
- case FILE_LEQUAD:
- v = file_signextend(ms, m, p->q);
- if (file_printf(ms, m->desc, (uint64_t) v) == -1)
- return -1;
- t = ms->offset + sizeof(int64_t);
- break;
-
- case FILE_STRING:
- case FILE_PSTRING:
- case FILE_BESTRING16:
- case FILE_LESTRING16:
- if (m->reln == '=' || m->reln == '!') {
- if (file_printf(ms, m->desc, m->value.s) == -1)
- return -1;
- t = ms->offset + m->vallen;
- }
- else {
- if (*m->value.s == '\0')
- p->s[strcspn(p->s, "\n")] = '\0';
- if (file_printf(ms, m->desc, p->s) == -1)
- return -1;
- t = ms->offset + strlen(p->s);
- if (m->type == FILE_PSTRING)
- t += file_pstring_length_size(m);
- }
- break;
-
- case FILE_DATE:
- case FILE_BEDATE:
- case FILE_LEDATE:
- case FILE_MEDATE:
- if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1)
- return -1;
- t = ms->offset + sizeof(time_t);
- break;
-
- case FILE_LDATE:
- case FILE_BELDATE:
- case FILE_LELDATE:
- case FILE_MELDATE:
- if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1)
- return -1;
- t = ms->offset + sizeof(time_t);
- break;
-
- case FILE_QDATE:
- case FILE_BEQDATE:
- case FILE_LEQDATE:
- if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q,
- 1)) == -1)
- return -1;
- t = ms->offset + sizeof(uint64_t);
- break;
-
- case FILE_QLDATE:
- case FILE_BEQLDATE:
- case FILE_LEQLDATE:
- if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q,
- 0)) == -1)
- return -1;
- t = ms->offset + sizeof(uint64_t);
- break;
-
- case FILE_FLOAT:
- case FILE_BEFLOAT:
- case FILE_LEFLOAT:
- vf = p->f;
- switch (check_fmt(ms, m)) {
- case -1:
- return -1;
- case 1:
- (void)snprintf(buf, sizeof(buf), "%g", vf);
- if (file_printf(ms, m->desc, buf) == -1)
- return -1;
- break;
- default:
- if (file_printf(ms, m->desc, vf) == -1)
- return -1;
- break;
- }
- t = ms->offset + sizeof(float);
- break;
-
- case FILE_DOUBLE:
- case FILE_BEDOUBLE:
- case FILE_LEDOUBLE:
- vd = p->d;
- switch (check_fmt(ms, m)) {
- case -1:
- return -1;
- case 1:
- (void)snprintf(buf, sizeof(buf), "%g", vd);
- if (file_printf(ms, m->desc, buf) == -1)
- return -1;
- break;
- default:
- if (file_printf(ms, m->desc, vd) == -1)
- return -1;
- break;
- }
- t = ms->offset + sizeof(double);
- break;
-
- case FILE_REGEX: {
- char *cp;
- int rval;
-
- cp = strndup((const char *)ms->search.s, ms->search.rm_len);
- if (cp == NULL) {
- file_oomem(ms, ms->search.rm_len);
- return -1;
- }
- rval = file_printf(ms, m->desc, cp);
- free(cp);
-
- if (rval == -1)
- return -1;
-
- if ((m->str_flags & REGEX_OFFSET_START))
- t = ms->search.offset;
- else
- t = ms->search.offset + ms->search.rm_len;
- break;
- }
-
- case FILE_SEARCH:
- if (file_printf(ms, m->desc, m->value.s) == -1)
- return -1;
- if ((m->str_flags & REGEX_OFFSET_START))
- t = ms->search.offset;
- else
- t = ms->search.offset + m->vallen;
- break;
-
- case FILE_DEFAULT:
- if (file_printf(ms, m->desc, m->value.s) == -1)
- return -1;
- t = ms->offset;
- break;
-
- case FILE_INDIRECT:
- t = ms->offset;
- break;
-
- default:
- file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
- return -1;
- }
- return (int32_t)t;
-}
-
-private int32_t
-moffset(struct magic_set *ms, struct magic *m)
-{
- switch (m->type) {
- case FILE_BYTE:
- return CAST(int32_t, (ms->offset + sizeof(char)));
-
- case FILE_SHORT:
- case FILE_BESHORT:
- case FILE_LESHORT:
- return CAST(int32_t, (ms->offset + sizeof(short)));
-
- case FILE_LONG:
- case FILE_BELONG:
- case FILE_LELONG:
- case FILE_MELONG:
- return CAST(int32_t, (ms->offset + sizeof(int32_t)));
-
- case FILE_QUAD:
- case FILE_BEQUAD:
- case FILE_LEQUAD:
- return CAST(int32_t, (ms->offset + sizeof(int64_t)));
-
- case FILE_STRING:
- case FILE_PSTRING:
- case FILE_BESTRING16:
- case FILE_LESTRING16:
- if (m->reln == '=' || m->reln == '!')
- return ms->offset + m->vallen;
- else {
- union VALUETYPE *p = &ms->ms_value;
- uint32_t t;
-
- if (*m->value.s == '\0')
- p->s[strcspn(p->s, "\n")] = '\0';
- t = CAST(uint32_t, (ms->offset + strlen(p->s)));
- if (m->type == FILE_PSTRING)
- t += file_pstring_length_size(m);
- return t;
- }
-
- case FILE_DATE:
- case FILE_BEDATE:
- case FILE_LEDATE:
- case FILE_MEDATE:
- return CAST(int32_t, (ms->offset + sizeof(time_t)));
-
- case FILE_LDATE:
- case FILE_BELDATE:
- case FILE_LELDATE:
- case FILE_MELDATE:
- return CAST(int32_t, (ms->offset + sizeof(time_t)));
-
- case FILE_QDATE:
- case FILE_BEQDATE:
- case FILE_LEQDATE:
- return CAST(int32_t, (ms->offset + sizeof(uint64_t)));
-
- case FILE_QLDATE:
- case FILE_BEQLDATE:
- case FILE_LEQLDATE:
- return CAST(int32_t, (ms->offset + sizeof(uint64_t)));
-
- case FILE_FLOAT:
- case FILE_BEFLOAT:
- case FILE_LEFLOAT:
- return CAST(int32_t, (ms->offset + sizeof(float)));
-
- case FILE_DOUBLE:
- case FILE_BEDOUBLE:
- case FILE_LEDOUBLE:
- return CAST(int32_t, (ms->offset + sizeof(double)));
-
- case FILE_REGEX:
- if ((m->str_flags & REGEX_OFFSET_START) != 0)
- return CAST(int32_t, ms->search.offset);
- else
- return CAST(int32_t, (ms->search.offset +
- ms->search.rm_len));
-
- case FILE_SEARCH:
- if ((m->str_flags & REGEX_OFFSET_START) != 0)
- return CAST(int32_t, ms->search.offset);
- else
- return CAST(int32_t, (ms->search.offset + m->vallen));
-
- case FILE_DEFAULT:
- return ms->offset;
-
- case FILE_INDIRECT:
- return ms->offset;
-
- default:
- return 0;
- }
-}
-
-#define DO_CVT(fld, cast) \
- if (m->num_mask) \
- switch (m->mask_op & FILE_OPS_MASK) { \
- case FILE_OPAND: \
- p->fld &= cast m->num_mask; \
- break; \
- case FILE_OPOR: \
- p->fld |= cast m->num_mask; \
- break; \
- case FILE_OPXOR: \
- p->fld ^= cast m->num_mask; \
- break; \
- case FILE_OPADD: \
- p->fld += cast m->num_mask; \
- break; \
- case FILE_OPMINUS: \
- p->fld -= cast m->num_mask; \
- break; \
- case FILE_OPMULTIPLY: \
- p->fld *= cast m->num_mask; \
- break; \
- case FILE_OPDIVIDE: \
- p->fld /= cast m->num_mask; \
- break; \
- case FILE_OPMODULO: \
- p->fld %= cast m->num_mask; \
- break; \
- } \
- if (m->mask_op & FILE_OPINVERSE) \
- p->fld = ~p->fld \
-
-private void
-cvt_8(union VALUETYPE *p, const struct magic *m)
-{
- DO_CVT(b, (uint8_t));
-}
-
-private void
-cvt_16(union VALUETYPE *p, const struct magic *m)
-{
- DO_CVT(h, (uint16_t));
-}
-
-private void
-cvt_32(union VALUETYPE *p, const struct magic *m)
-{
- DO_CVT(l, (uint32_t));
-}
-
-private void
-cvt_64(union VALUETYPE *p, const struct magic *m)
-{
- DO_CVT(q, (uint64_t));
-}
-
-#define DO_CVT2(fld, cast) \
- if (m->num_mask) \
- switch (m->mask_op & FILE_OPS_MASK) { \
- case FILE_OPADD: \
- p->fld += cast m->num_mask; \
- break; \
- case FILE_OPMINUS: \
- p->fld -= cast m->num_mask; \
- break; \
- case FILE_OPMULTIPLY: \
- p->fld *= cast m->num_mask; \
- break; \
- case FILE_OPDIVIDE: \
- p->fld /= cast m->num_mask; \
- break; \
- } \
-
-private void
-cvt_float(union VALUETYPE *p, const struct magic *m)
-{
- DO_CVT2(f, (float));
-}
-
-private void
-cvt_double(union VALUETYPE *p, const struct magic *m)
-{
- DO_CVT2(d, (double));
-}
-
-/*
- * Convert the byte order of the data we are looking at
- * While we're here, let's apply the mask operation
- * (unless you have a better idea)
- */
-private int
-mconvert(struct magic_set *ms, struct magic *m)
-{
- union VALUETYPE *p = &ms->ms_value;
-
- switch (m->type) {
- case FILE_BYTE:
- cvt_8(p, m);
- return 1;
- case FILE_SHORT:
- cvt_16(p, m);
- return 1;
- case FILE_LONG:
- case FILE_DATE:
- case FILE_LDATE:
- cvt_32(p, m);
- return 1;
- case FILE_QUAD:
- case FILE_QDATE:
- case FILE_QLDATE:
- cvt_64(p, m);
- return 1;
- case FILE_STRING:
- case FILE_BESTRING16:
- case FILE_LESTRING16: {
- /* Null terminate and eat *trailing* return */
- p->s[sizeof(p->s) - 1] = '\0';
- return 1;
- }
- case FILE_PSTRING: {
- char *ptr1 = p->s, *ptr2 = ptr1 + file_pstring_length_size(m);
- size_t len = file_pstring_get_length(m, ptr1);
- if (len >= sizeof(p->s))
- len = sizeof(p->s) - 1;
- while (len--)
- *ptr1++ = *ptr2++;
- *ptr1 = '\0';
- return 1;
- }
- case FILE_BESHORT:
- p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
- cvt_16(p, m);
- return 1;
- case FILE_BELONG:
- case FILE_BEDATE:
- case FILE_BELDATE:
- p->l = (int32_t)
- ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
- cvt_32(p, m);
- return 1;
- case FILE_BEQUAD:
- case FILE_BEQDATE:
- case FILE_BEQLDATE:
- p->q = (uint64_t)
- (((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
- ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
- ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
- ((uint64_t)p->hq[6]<<8)|((uint64_t)p->hq[7]));
- cvt_64(p, m);
- return 1;
- case FILE_LESHORT:
- p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
- cvt_16(p, m);
- return 1;
- case FILE_LELONG:
- case FILE_LEDATE:
- case FILE_LELDATE:
- p->l = (int32_t)
- ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
- cvt_32(p, m);
- return 1;
- case FILE_LEQUAD:
- case FILE_LEQDATE:
- case FILE_LEQLDATE:
- p->q = (uint64_t)
- (((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
- ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
- ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
- ((uint64_t)p->hq[1]<<8)|((uint64_t)p->hq[0]));
- cvt_64(p, m);
- return 1;
- case FILE_MELONG:
- case FILE_MEDATE:
- case FILE_MELDATE:
- p->l = (int32_t)
- ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));
- cvt_32(p, m);
- return 1;
- case FILE_FLOAT:
- cvt_float(p, m);
- return 1;
- case FILE_BEFLOAT:
- p->l = ((uint32_t)p->hl[0]<<24)|((uint32_t)p->hl[1]<<16)|
- ((uint32_t)p->hl[2]<<8) |((uint32_t)p->hl[3]);
- cvt_float(p, m);
- return 1;
- case FILE_LEFLOAT:
- p->l = ((uint32_t)p->hl[3]<<24)|((uint32_t)p->hl[2]<<16)|
- ((uint32_t)p->hl[1]<<8) |((uint32_t)p->hl[0]);
- cvt_float(p, m);
- return 1;
- case FILE_DOUBLE:
- cvt_double(p, m);
- return 1;
- case FILE_BEDOUBLE:
- p->q = ((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
- ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
- ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
- ((uint64_t)p->hq[6]<<8) |((uint64_t)p->hq[7]);
- cvt_double(p, m);
- return 1;
- case FILE_LEDOUBLE:
- p->q = ((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
- ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
- ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
- ((uint64_t)p->hq[1]<<8) |((uint64_t)p->hq[0]);
- cvt_double(p, m);
- return 1;
- case FILE_REGEX:
- case FILE_SEARCH:
- case FILE_DEFAULT:
- return 1;
- default:
- file_magerror(ms, "invalid type %d in mconvert()", m->type);
- return 0;
- }
-}
-
-
-private void
-mdebug(uint32_t offset, const char *str, size_t len)
-{
- (void) fprintf(stderr, "mget @%d: ", offset);
- file_showstr(stderr, str, len);
- (void) fputc('\n', stderr);
- (void) fputc('\n', stderr);
-}
-
-private int
-mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
- const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
-{
- /*
- * Note: FILE_SEARCH and FILE_REGEX do not actually copy
- * anything, but setup pointers into the source
- */
- if (indir == 0) {
- switch (type) {
- case FILE_SEARCH:
- ms->search.s = (const char *)s + offset;
- ms->search.s_len = nbytes - offset;
- ms->search.offset = offset;
- return 0;
-
- case FILE_REGEX: {
- const char *b;
- const char *c;
- const char *last; /* end of search region */
- const char *buf; /* start of search region */
- const char *end;
- size_t lines;
-
- if (s == NULL) {
- ms->search.s_len = 0;
- ms->search.s = NULL;
- return 0;
- }
- buf = (const char *)s + offset;
- end = last = (const char *)s + nbytes;
- /* mget() guarantees buf <= last */
- for (lines = linecnt, b = buf; lines && b < end &&
- ((b = CAST(const char *,
- memchr(c = b, '\n', CAST(size_t, (end - b)))))
- || (b = CAST(const char *,
- memchr(c, '\r', CAST(size_t, (end - c))))));
- lines--, b++) {
- last = b;
- if (b[0] == '\r' && b[1] == '\n')
- b++;
- }
- if (lines)
- last = (const char *)s + nbytes;
-
- ms->search.s = buf;
- ms->search.s_len = last - buf;
- ms->search.offset = offset;
- ms->search.rm_len = 0;
- return 0;
- }
- case FILE_BESTRING16:
- case FILE_LESTRING16: {
- const unsigned char *src = s + offset;
- const unsigned char *esrc = s + nbytes;
- char *dst = p->s;
- char *edst = &p->s[sizeof(p->s) - 1];
-
- if (type == FILE_BESTRING16)
- src++;
-
- /* check for pointer overflow */
- if (src < s) {
- file_magerror(ms, "invalid offset %u in mcopy()",
- offset);
- return -1;
- }
- for (/*EMPTY*/; src < esrc; src += 2, dst++) {
- if (dst < edst)
- *dst = *src;
- else
- break;
- if (*dst == '\0') {
- if (type == FILE_BESTRING16 ?
- *(src - 1) != '\0' :
- *(src + 1) != '\0')
- *dst = ' ';
- }
- }
- *edst = '\0';
- return 0;
- }
- case FILE_STRING: /* XXX - these two should not need */
- case FILE_PSTRING: /* to copy anything, but do anyway. */
- default:
- break;
- }
- }
-
- if (offset >= nbytes) {
- (void)memset(p, '\0', sizeof(*p));
- return 0;
- }
- if (nbytes - offset < sizeof(*p))
- nbytes = nbytes - offset;
- else
- nbytes = sizeof(*p);
-
- (void)memcpy(p, s + offset, nbytes);
-
- /*
- * the usefulness of padding with zeroes eludes me, it
- * might even cause problems
- */
- if (nbytes < sizeof(*p))
- (void)memset(((char *)(void *)p) + nbytes, '\0',
- sizeof(*p) - nbytes);
- return 0;
-}
-
-private int
-mget(struct magic_set *ms, const unsigned char *s,
- struct magic *m, size_t nbytes, unsigned int cont_level)
-{
- uint32_t offset = ms->offset;
- uint32_t count = m->str_range;
- union VALUETYPE *p = &ms->ms_value;
-
- if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
- return -1;
-
- if ((ms->flags & MAGIC_DEBUG) != 0) {
- mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
-#ifndef COMPILE_ONLY
- file_mdump(m);
-#endif
- }
-
- if (m->flag & INDIR) {
- int off = m->in_offset;
- if (m->in_op & FILE_OPINDIRECT) {
- const union VALUETYPE *q = CAST(const union VALUETYPE *,
- ((const void *)(s + offset + off)));
- switch (m->in_type) {
- case FILE_BYTE:
- off = q->b;
- break;
- case FILE_SHORT:
- off = q->h;
- break;
- case FILE_BESHORT:
- off = (short)((q->hs[0]<<8)|(q->hs[1]));
- break;
- case FILE_LESHORT:
- off = (short)((q->hs[1]<<8)|(q->hs[0]));
- break;
- case FILE_LONG:
- off = q->l;
- break;
- case FILE_BELONG:
- case FILE_BEID3:
- off = (int32_t)((q->hl[0]<<24)|(q->hl[1]<<16)|
- (q->hl[2]<<8)|(q->hl[3]));
- break;
- case FILE_LEID3:
- case FILE_LELONG:
- off = (int32_t)((q->hl[3]<<24)|(q->hl[2]<<16)|
- (q->hl[1]<<8)|(q->hl[0]));
- break;
- case FILE_MELONG:
- off = (int32_t)((q->hl[1]<<24)|(q->hl[0]<<16)|
- (q->hl[3]<<8)|(q->hl[2]));
- break;
- }
- }
- switch (m->in_type) {
- case FILE_BYTE:
- if (nbytes < (offset + 1))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = p->b & off;
- break;
- case FILE_OPOR:
- offset = p->b | off;
- break;
- case FILE_OPXOR:
- offset = p->b ^ off;
- break;
- case FILE_OPADD:
- offset = p->b + off;
- break;
- case FILE_OPMINUS:
- offset = p->b - off;
- break;
- case FILE_OPMULTIPLY:
- offset = p->b * off;
- break;
- case FILE_OPDIVIDE:
- offset = p->b / off;
- break;
- case FILE_OPMODULO:
- offset = p->b % off;
- break;
- }
- } else
- offset = p->b;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_BESHORT:
- if (nbytes < (offset + 2))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) &
- off;
- break;
- case FILE_OPOR:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) |
- off;
- break;
- case FILE_OPXOR:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) ^
- off;
- break;
- case FILE_OPADD:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) +
- off;
- break;
- case FILE_OPMINUS:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) -
- off;
- break;
- case FILE_OPMULTIPLY:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) *
- off;
- break;
- case FILE_OPDIVIDE:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) /
- off;
- break;
- case FILE_OPMODULO:
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1])) %
- off;
- break;
- }
- } else
- offset = (short)((p->hs[0]<<8)|
- (p->hs[1]));
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_LESHORT:
- if (nbytes < (offset + 2))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) &
- off;
- break;
- case FILE_OPOR:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) |
- off;
- break;
- case FILE_OPXOR:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) ^
- off;
- break;
- case FILE_OPADD:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) +
- off;
- break;
- case FILE_OPMINUS:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) -
- off;
- break;
- case FILE_OPMULTIPLY:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) *
- off;
- break;
- case FILE_OPDIVIDE:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) /
- off;
- break;
- case FILE_OPMODULO:
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0])) %
- off;
- break;
- }
- } else
- offset = (short)((p->hs[1]<<8)|
- (p->hs[0]));
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_SHORT:
- if (nbytes < (offset + 2))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = p->h & off;
- break;
- case FILE_OPOR:
- offset = p->h | off;
- break;
- case FILE_OPXOR:
- offset = p->h ^ off;
- break;
- case FILE_OPADD:
- offset = p->h + off;
- break;
- case FILE_OPMINUS:
- offset = p->h - off;
- break;
- case FILE_OPMULTIPLY:
- offset = p->h * off;
- break;
- case FILE_OPDIVIDE:
- offset = p->h / off;
- break;
- case FILE_OPMODULO:
- offset = p->h % off;
- break;
- }
- }
- else
- offset = p->h;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_BELONG:
- case FILE_BEID3:
- if (nbytes < (offset + 4))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) &
- off;
- break;
- case FILE_OPOR:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) |
- off;
- break;
- case FILE_OPXOR:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) ^
- off;
- break;
- case FILE_OPADD:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) +
- off;
- break;
- case FILE_OPMINUS:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) -
- off;
- break;
- case FILE_OPMULTIPLY:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) *
- off;
- break;
- case FILE_OPDIVIDE:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) /
- off;
- break;
- case FILE_OPMODULO:
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3])) %
- off;
- break;
- }
- } else
- offset = (int32_t)((p->hl[0]<<24)|
- (p->hl[1]<<16)|
- (p->hl[2]<<8)|
- (p->hl[3]));
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_LELONG:
- case FILE_LEID3:
- if (nbytes < (offset + 4))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) &
- off;
- break;
- case FILE_OPOR:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) |
- off;
- break;
- case FILE_OPXOR:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) ^
- off;
- break;
- case FILE_OPADD:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) +
- off;
- break;
- case FILE_OPMINUS:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) -
- off;
- break;
- case FILE_OPMULTIPLY:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) *
- off;
- break;
- case FILE_OPDIVIDE:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) /
- off;
- break;
- case FILE_OPMODULO:
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0])) %
- off;
- break;
- }
- } else
- offset = (int32_t)((p->hl[3]<<24)|
- (p->hl[2]<<16)|
- (p->hl[1]<<8)|
- (p->hl[0]));
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_MELONG:
- if (nbytes < (offset + 4))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) &
- off;
- break;
- case FILE_OPOR:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) |
- off;
- break;
- case FILE_OPXOR:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) ^
- off;
- break;
- case FILE_OPADD:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) +
- off;
- break;
- case FILE_OPMINUS:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) -
- off;
- break;
- case FILE_OPMULTIPLY:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) *
- off;
- break;
- case FILE_OPDIVIDE:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) /
- off;
- break;
- case FILE_OPMODULO:
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2])) %
- off;
- break;
- }
- } else
- offset = (int32_t)((p->hl[1]<<24)|
- (p->hl[0]<<16)|
- (p->hl[3]<<8)|
- (p->hl[2]));
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- case FILE_LONG:
- if (nbytes < (offset + 4))
- return 0;
- if (off) {
- switch (m->in_op & FILE_OPS_MASK) {
- case FILE_OPAND:
- offset = p->l & off;
- break;
- case FILE_OPOR:
- offset = p->l | off;
- break;
- case FILE_OPXOR:
- offset = p->l ^ off;
- break;
- case FILE_OPADD:
- offset = p->l + off;
- break;
- case FILE_OPMINUS:
- offset = p->l - off;
- break;
- case FILE_OPMULTIPLY:
- offset = p->l * off;
- break;
- case FILE_OPDIVIDE:
- offset = p->l / off;
- break;
- case FILE_OPMODULO:
- offset = p->l % off;
- break;
- }
- } else
- offset = p->l;
- if (m->in_op & FILE_OPINVERSE)
- offset = ~offset;
- break;
- }
-
- switch (m->in_type) {
- case FILE_LEID3:
- case FILE_BEID3:
- offset = ((((offset >> 0) & 0x7f) << 0) |
- (((offset >> 8) & 0x7f) << 7) |
- (((offset >> 16) & 0x7f) << 14) |
- (((offset >> 24) & 0x7f) << 21)) + 10;
- break;
- default:
- break;
- }
-
- if (m->flag & INDIROFFADD) {
- offset += ms->c.li[cont_level-1].off;
- }
- if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
- return -1;
- ms->offset = offset;
-
- if ((ms->flags & MAGIC_DEBUG) != 0) {
- mdebug(offset, (char *)(void *)p,
- sizeof(union VALUETYPE));
-#ifndef COMPILE_ONLY
- file_mdump(m);
-#endif
- }
- }
-
- /* Verify we have enough data to match magic type */
- switch (m->type) {
- case FILE_BYTE:
- if (nbytes < (offset + 1)) /* should alway be true */
- return 0;
- break;
-
- case FILE_SHORT:
- case FILE_BESHORT:
- case FILE_LESHORT:
- if (nbytes < (offset + 2))
- return 0;
- break;
-
- case FILE_LONG:
- case FILE_BELONG:
- case FILE_LELONG:
- case FILE_MELONG:
- case FILE_DATE:
- case FILE_BEDATE:
- case FILE_LEDATE:
- case FILE_MEDATE:
- case FILE_LDATE:
- case FILE_BELDATE:
- case FILE_LELDATE:
- case FILE_MELDATE:
- case FILE_FLOAT:
- case FILE_BEFLOAT:
- case FILE_LEFLOAT:
- if (nbytes < (offset + 4))
- return 0;
- break;
-
- case FILE_DOUBLE:
- case FILE_BEDOUBLE:
- case FILE_LEDOUBLE:
- if (nbytes < (offset + 8))
- return 0;
- break;
-
- case FILE_STRING:
- case FILE_PSTRING:
- case FILE_SEARCH:
- if (nbytes < (offset + m->vallen))
- return 0;
- break;
-
- case FILE_REGEX:
- if (nbytes < offset)
- return 0;
- break;
-
- case FILE_INDIRECT:
- if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
- file_printf(ms, "%s", m->desc) == -1)
- return -1;
- if (nbytes < offset)
- return 0;
- return file_softmagic(ms, s + offset, nbytes - offset,
- BINTEST);
-
- case FILE_DEFAULT: /* nothing to check */
- default:
- break;
- }
- if (!mconvert(ms, m))
- return 0;
- return 1;
-}
-
-private uint64_t
-file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
-{
- /*
- * Convert the source args to unsigned here so that (1) the
- * compare will be unsigned as it is in strncmp() and (2) so
- * the ctype functions will work correctly without extra
- * casting.
- */
- const unsigned char *a = (const unsigned char *)s1;
- const unsigned char *b = (const unsigned char *)s2;
- uint64_t v;
-
- /*
- * What we want here is v = strncmp(s1, s2, len),
- * but ignoring any nulls.
- */
- v = 0;
- if (0L == flags) { /* normal string: do it fast */
- while (len-- > 0)
- if ((v = *b++ - *a++) != '\0')
- break;
- }
- else { /* combine the others */
- while (len-- > 0) {
- if ((flags & STRING_IGNORE_LOWERCASE) &&
- islower(*a)) {
- if ((v = tolower(*b++) - *a++) != '\0')
- break;
- }
- else if ((flags & STRING_IGNORE_UPPERCASE) &&
- isupper(*a)) {
- if ((v = toupper(*b++) - *a++) != '\0')
- break;
- }
- else if ((flags & STRING_COMPACT_WHITESPACE) &&
- isspace(*a)) {
- a++;
- if (isspace(*b++)) {
- if (!isspace(*a))
- while (isspace(*b))
- b++;
- }
- else {
- v = 1;
- break;
- }
- }
- else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
- isspace(*a)) {
- a++;
- while (isspace(*b))
- b++;
- }
- else {
- if ((v = *b++ - *a++) != '\0')
- break;
- }
- }
- }
- return v;
-}
-
-private uint64_t
-file_strncmp16(const char *a, const char *b, size_t len, uint32_t flags)
-{
- /*
- * XXX - The 16-bit string compare probably needs to be done
- * differently, especially if the flags are to be supported.
- * At the moment, I am unsure.
- */
- flags = 0;
- return file_strncmp(a, b, len, flags);
-}
-
-private int
-magiccheck(struct magic_set *ms, struct magic *m)
-{
- uint64_t l = m->value.q;
- uint64_t v;
- float fl, fv;
- double dl, dv;
- int matched;
- union VALUETYPE *p = &ms->ms_value;
-
- switch (m->type) {
- case FILE_BYTE:
- v = p->b;
- break;
-
- case FILE_SHORT:
- case FILE_BESHORT:
- case FILE_LESHORT:
- v = p->h;
- break;
-
- case FILE_LONG:
- case FILE_BELONG:
- case FILE_LELONG:
- case FILE_MELONG:
- case FILE_DATE:
- case FILE_BEDATE:
- case FILE_LEDATE:
- case FILE_MEDATE:
- case FILE_LDATE:
- case FILE_BELDATE:
- case FILE_LELDATE:
- case FILE_MELDATE:
- v = p->l;
- break;
-
- case FILE_QUAD:
- case FILE_LEQUAD:
- case FILE_BEQUAD:
- case FILE_QDATE:
- case FILE_BEQDATE:
- case FILE_LEQDATE:
- case FILE_QLDATE:
- case FILE_BEQLDATE:
- case FILE_LEQLDATE:
- v = p->q;
- break;
-
- case FILE_FLOAT:
- case FILE_BEFLOAT:
- case FILE_LEFLOAT:
- fl = m->value.f;
- fv = p->f;
- switch (m->reln) {
- case 'x':
- matched = 1;
- break;
-
- case '!':
- matched = fv != fl;
- break;
-
- case '=':
- matched = fv == fl;
- break;
-
- case '>':
- matched = fv > fl;
- break;
-
- case '<':
- matched = fv < fl;
- break;
-
- default:
- matched = 0;
- file_magerror(ms, "cannot happen with float: invalid relation `%c'",
- m->reln);
- return -1;
- }
- return matched;
-
- case FILE_DOUBLE:
- case FILE_BEDOUBLE:
- case FILE_LEDOUBLE:
- dl = m->value.d;
- dv = p->d;
- switch (m->reln) {
- case 'x':
- matched = 1;
- break;
-
- case '!':
- matched = dv != dl;
- break;
-
- case '=':
- matched = dv == dl;
- break;
-
- case '>':
- matched = dv > dl;
- break;
-
- case '<':
- matched = dv < dl;
- break;
-
- default:
- matched = 0;
- file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln);
- return -1;
- }
- return matched;
-
- case FILE_DEFAULT:
- l = 0;
- v = 0;
- break;
-
- case FILE_STRING:
- case FILE_PSTRING:
- l = 0;
- v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
- break;
-
- case FILE_BESTRING16:
- case FILE_LESTRING16:
- l = 0;
- v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
- break;
-
- case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
- size_t slen;
- size_t idx;
-
- if (ms->search.s == NULL)
- return 0;
-
- slen = MIN(m->vallen, sizeof(m->value.s));
- l = 0;
- v = 0;
-
- for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
- if (slen + idx > ms->search.s_len)
- break;
-
- v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags);
- if (v == 0) { /* found match */
- ms->search.offset += idx;
- break;
- }
- }
- break;
- }
- case FILE_REGEX: {
- int rc;
- regex_t rx;
- char errmsg[512];
-
- if (ms->search.s == NULL)
- return 0;
-
- l = 0;
- rc = regcomp(&rx, m->value.s,
- REG_EXTENDED|REG_NEWLINE|
- ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
- if (rc) {
- (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
- file_magerror(ms, "regex error %d, (%s)",
- rc, errmsg);
- v = (uint64_t)-1;
- }
- else {
- regmatch_t pmatch[1];
-#ifndef REG_STARTEND
-#define REG_STARTEND 0
- size_t l = ms->search.s_len - 1;
- char c = ms->search.s[l];
- ((char *)(intptr_t)ms->search.s)[l] = '\0';
-#else
- pmatch[0].rm_so = 0;
- pmatch[0].rm_eo = ms->search.s_len;
-#endif
- rc = regexec(&rx, (const char *)ms->search.s,
- 1, pmatch, REG_STARTEND);
-#if REG_STARTEND == 0
- ((char *)(intptr_t)ms->search.s)[l] = c;
-#endif
- switch (rc) {
- case 0:
- ms->search.s += (int)pmatch[0].rm_so;
- ms->search.offset += (size_t)pmatch[0].rm_so;
- ms->search.rm_len =
- (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
- v = 0;
- break;
-
- case REG_NOMATCH:
- v = 1;
- break;
-
- default:
- (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
- file_magerror(ms, "regexec error %d, (%s)",
- rc, errmsg);
- v = (uint64_t)-1;
- break;
- }
- regfree(&rx);
- }
- if (v == (uint64_t)-1)
- return -1;
- break;
- }
- case FILE_INDIRECT:
- return 1;
- default:
- file_magerror(ms, "invalid type %d in magiccheck()", m->type);
- return -1;
- }
-
- v = file_signextend(ms, m, v);
-
- switch (m->reln) {
- case 'x':
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT
- "u == *any* = 1\n", (unsigned long long)v);
- matched = 1;
- break;
-
- case '!':
- matched = v != l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
- INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
- (unsigned long long)l, matched);
- break;
-
- case '=':
- matched = v == l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
- INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
- (unsigned long long)l, matched);
- break;
-
- case '>':
- if (m->flag & UNSIGNED) {
- matched = v > l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT
- "u > %" INT64_T_FORMAT "u = %d\n",
- (unsigned long long)v,
- (unsigned long long)l, matched);
- }
- else {
- matched = (int64_t) v > (int64_t) l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT
- "d > %" INT64_T_FORMAT "d = %d\n",
- (long long)v, (long long)l, matched);
- }
- break;
-
- case '<':
- if (m->flag & UNSIGNED) {
- matched = v < l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT
- "u < %" INT64_T_FORMAT "u = %d\n",
- (unsigned long long)v,
- (unsigned long long)l, matched);
- }
- else {
- matched = (int64_t) v < (int64_t) l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "%" INT64_T_FORMAT
- "d < %" INT64_T_FORMAT "d = %d\n",
- (long long)v, (long long)l, matched);
- }
- break;
-
- case '&':
- matched = (v & l) == l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
- INT64_T_FORMAT "x) == %" INT64_T_FORMAT
- "x) = %d\n", (unsigned long long)v,
- (unsigned long long)l, (unsigned long long)l,
- matched);
- break;
-
- case '^':
- matched = (v & l) != l;
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
- INT64_T_FORMAT "x) != %" INT64_T_FORMAT
- "x) = %d\n", (unsigned long long)v,
- (unsigned long long)l, (unsigned long long)l,
- matched);
- break;
-
- default:
- matched = 0;
- file_magerror(ms, "cannot happen: invalid relation `%c'",
- m->reln);
- return -1;
- }
-
- return matched;
-}
-
-private int
-handle_annotation(struct magic_set *ms, struct magic *m)
-{
- if (ms->flags & MAGIC_APPLE) {
- if (file_printf(ms, "%.8s", m->apple) == -1)
- return -1;
- return 1;
- }
- if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
- if (file_printf(ms, "%s", m->mimetype) == -1)
- return -1;
- return 1;
- }
- return 0;
-}
-
-private int
-print_sep(struct magic_set *ms, int firstline)
-{
- if (ms->flags & MAGIC_MIME)
- return 0;
- if (firstline)
- return 0;
- /*
- * we found another match
- * put a newline and '-' to do some simple formatting
- */
- return file_printf(ms, "\n- ");
-}
Deleted: trunk/contrib/file/strlcat.c
===================================================================
--- trunk/contrib/file/strlcat.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/strlcat.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,58 +0,0 @@
-/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller at courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
-#include "file.h"
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return(dlen + strlen(s));
- while (*s != '\0') {
- if (n != 1) {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return(dlen + (s - src)); /* count does not include NUL */
-}
Deleted: trunk/contrib/file/strlcpy.c
===================================================================
--- trunk/contrib/file/strlcpy.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/strlcpy.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,54 +0,0 @@
-/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller at courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
-#include "file.h"
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0) {
- do {
- if ((*d++ = *s++) == 0)
- break;
- } while (--n != 0);
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
-}
Deleted: trunk/contrib/file/tar.h
===================================================================
--- trunk/contrib/file/tar.h 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/tar.h 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * Header file for public domain tar (tape archive) program.
- *
- * @(#)tar.h 1.20 86/10/29 Public Domain.
- *
- * Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
- *
- * $File: tar.h,v 1.13 2010/11/30 14:58:53 rrt Exp $ # checkin only
- */
-
-/*
- * Header block on tape.
- *
- * I'm going to use traditional DP naming conventions here.
- * A "block" is a big chunk of stuff that we do I/O on.
- * A "record" is a piece of info that we care about.
- * Typically many "record"s fit into a "block".
- */
-#define RECORDSIZE 512
-#define NAMSIZ 100
-#define TUNMLEN 32
-#define TGNMLEN 32
-
-union record {
- unsigned char charptr[RECORDSIZE];
- struct header {
- char name[NAMSIZ];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char chksum[8];
- char linkflag;
- char linkname[NAMSIZ];
- char magic[8];
- char uname[TUNMLEN];
- char gname[TGNMLEN];
- char devmajor[8];
- char devminor[8];
- } header;
-};
-
-/* The magic field is filled with this if uname and gname are valid. */
-#define TMAGIC "ustar" /* 5 chars and a null */
-#define GNUTMAGIC "ustar " /* 7 chars and a null */
Deleted: trunk/contrib/file/test.c
===================================================================
--- trunk/contrib/file/test.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/test.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) Christos Zoulas 2003.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include <stdio.h>
-#include "magic.h"
-
-int
-main(int argc, char **argv)
-{
- struct magic_set *ms;
- const char *m;
- int i;
-
- if(argc < 2)
- return 1;
-
- ms = magic_open(MAGIC_NONE);
- if (ms == NULL) {
- (void) printf("ERROR: out of memory\n");
- return 1;
- }
- if (magic_load(ms, NULL) == -1) {
- (void) printf("ERROR: %s\n", magic_error(ms));
- return 1;
- }
-
- for (i = 1; i < argc; i++) {
- if ((m = magic_file(ms, argv[i])) == NULL)
- (void) printf("ERROR: %s\n", magic_error(ms));
- else
- (void) printf("%s: %s\n", argv[i], m);
- }
-
- magic_close(ms);
- return 0;
-}
Deleted: trunk/contrib/file/vasprintf.c
===================================================================
--- trunk/contrib/file/vasprintf.c 2014-06-30 11:57:06 UTC (rev 6694)
+++ trunk/contrib/file/vasprintf.c 2014-06-30 11:57:27 UTC (rev 6695)
@@ -1,642 +0,0 @@
-/*
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*###########################################################################
- # #
- # vasprintf #
- # #
- # Copyright (c) 2002-2005 David TAILLANDIER #
- # #
- ###########################################################################*/
-
-/*
-
-This software is distributed under the "modified BSD licence".
-
-This software is also released with GNU license (GPL) in another file (same
-source-code, only license differ).
-
-
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer. Redistributions in binary
-form must reproduce the above copyright notice, this list of conditions and
-the following disclaimer in the documentation and/or other materials
-provided with the distribution. The name of the author may not be used to
-endorse or promote products derived from this software without specific
-prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-====================
-
-Hacked from xnprintf version of 26th February 2005 to provide only
-vasprintf by Reuben Thomas <rrt at sc3d.org>.
-
-====================
-
-
-'printf' function family use the following format string:
-
-%[flag][width][.prec][modifier]type
-
-%% is the escape sequence to print a '%'
-% followed by an unknown format will print the characters without
-trying to do any interpretation
-
-flag: none + - # (blank)
-width: n 0n *
-prec: none .0 .n .*
-modifier: F N L h l ll ('F' and 'N' are ms-dos/16-bit specific)
-type: d i o u x X f e g E G c s p n
-
-
-The function needs to allocate memory to store the full text before to
-actually writting it. i.e if you want to fnprintf() 1000 characters, the
-functions will allocate 1000 bytes.
-This behaviour can be modified: you have to customise the code to flush the
-internal buffer (writing to screen or file) when it reach a given size. Then
-the buffer can have a shorter length. But what? If you really need to write
-HUGE string, don't use printf!
-During the process, some other memory is allocated (1024 bytes minimum)
-to handle the output of partial sprintf() calls. If you have only 10000 bytes
-free in memory, you *may* not be able to nprintf() a 8000 bytes-long text.
-
-note: if a buffer overflow occurs, exit() is called. This situation should
-never appear ... but if you want to be *really* sure, you have to modify the
-code to handle those situations (only one place to modify).
-A buffer overflow can only occur if your sprintf() do strange things or when
-you use strange formats.
-
-*/
-#include "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: vasprintf.c,v 1.7 2009/02/03 20:27:52 christos Exp $")
-#endif /* lint */
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-
-#define ALLOC_CHUNK 2048
-#define ALLOC_SECURITY_MARGIN 1024 /* big value because some platforms have very big 'G' exponent */
-#if ALLOC_CHUNK < ALLOC_SECURITY_MARGIN
-# error !!! ALLOC_CHUNK < ALLOC_SECURITY_MARGIN !!!
-#endif
-/* note: to have some interest, ALLOC_CHUNK should be much greater than ALLOC_SECURITY_MARGIN */
-
-/*
- * To save a lot of push/pop, every variable are stored into this
- * structure, which is passed among nearly every sub-functions.
- */
-typedef struct {
- const char * src_string; /* current position into intput string */
- char * buffer_base; /* output buffer */
- char * dest_string; /* current position into output string */
- size_t buffer_len; /* length of output buffer */
- size_t real_len; /* real current length of output text */
- size_t pseudo_len; /* total length of output text if it were not limited in size */
- size_t maxlen;
- va_list vargs; /* pointer to current position into vargs */
- char * sprintf_string;
- FILE * fprintf_file;
-} xprintf_struct;
-
-/*
- * Realloc buffer if needed
- * Return value: 0 = ok
- * EOF = not enought memory
- */
-static int realloc_buff(xprintf_struct *s, size_t len)
-{
- char * ptr;
-
- if (len + ALLOC_SECURITY_MARGIN + s->real_len > s->buffer_len) {
- len += s->real_len + ALLOC_CHUNK;
- ptr = (char *)realloc((void *)(s->buffer_base), len);
- if (ptr == NULL) {
- s->buffer_base = NULL;
- return EOF;
- }
-
- s->dest_string = ptr + (size_t)(s->dest_string - s->buffer_base);
- s->buffer_base = ptr;
- s->buffer_len = len;
-
- (s->buffer_base)[s->buffer_len - 1] = 1; /* overflow marker */
- }
-
- return 0;
-}
-
-/*
- * Prints 'usual' characters up to next '%'
- * or up to end of text
- */
-static int usual_char(xprintf_struct * s)
-{
- size_t len;
-
- len = strcspn(s->src_string, "%"); /* reachs the next '%' or end of input string */
- /* note: 'len' is never 0 because the presence of '%' */
- /* or end-of-line is checked in the calling function */
-
- if (realloc_buff(s,len) == EOF)
- return EOF;
-
- memcpy(s->dest_string, s->src_string, len);
- s->src_string += len;
- s->dest_string += len;
- s->real_len += len;
- s->pseudo_len += len;
-
- return 0;
-}
-
-/*
- * Return value: 0 = ok
- * EOF = error
- */
-static int print_it(xprintf_struct *s, size_t approx_len,
- const char *format_string, ...)
-{
- va_list varg;
- int vsprintf_len;
- size_t len;
-
- if (realloc_buff(s,approx_len) == EOF)
- return EOF;
-
- va_start(varg, format_string);
- vsprintf_len = vsprintf(s->dest_string, format_string, varg);
- va_end(varg);
-
- /* Check for overflow */
- assert((s->buffer_base)[s->buffer_len - 1] == 1);
-
- if (vsprintf_len == EOF) /* must be done *after* overflow-check */
- return EOF;
-
- s->pseudo_len += vsprintf_len;
- len = strlen(s->dest_string);
- s->real_len += len;
- s->dest_string += len;
-
- return 0;
-}
-
-/*
- * Prints a string (%s)
- * We need special handling because:
- * a: the length of the string is unknown
- * b: when .prec is used, we must not access any extra byte of the
- * string (of course, if the original sprintf() does... what the
- * hell, not my problem)
- *
- * Return value: 0 = ok
- * EOF = error
- */
-static int type_s(xprintf_struct *s, int width, int prec,
- const char *format_string, const char *arg_string)
-{
- size_t string_len;
-
- if (arg_string == NULL)
- return print_it(s, (size_t)6, "(null)", 0);
-
- /* hand-made strlen() whitch stops when 'prec' is reached. */
- /* if 'prec' is -1 then it is never reached. */
- string_len = 0;
- while (arg_string[string_len] != 0 && (size_t)prec != string_len)
- string_len++;
-
- if (width != -1 && string_len < (size_t)width)
- string_len = (size_t)width;
-
- return print_it(s, string_len, format_string, arg_string);
-}
-
-/*
- * Read a serie of digits. Stop when non-digit is found.
- * Return value: the value read (between 0 and 32767).
- * Note: no checks are made against overflow. If the string contain a big
- * number, then the return value won't be what we want (but, in this case,
- * the programmer don't know whatr he wants, then no problem).
- */
-static int getint(const char **string)
-{
- int i = 0;
-
- while (isdigit((unsigned char)**string) != 0) {
- i = i * 10 + (**string - '0');
- (*string)++;
- }
-
- if (i < 0 || i > 32767)
- i = 32767; /* if we have i==-10 this is not because the number is */
- /* negative; this is because the number is big */
- return i;
-}
-
-/*
- * Read a part of the format string. A part is 'usual characters' (ie "blabla")
- * or '%%' escape sequence (to print a single '%') or any combination of
- * format specifier (ie "%i" or "%10.2d").
- * After the current part is managed, the function returns to caller with
- * everything ready to manage the following part.
- * The caller must ensure than the string is not empty, i.e. the first byte
- * is not zero.
- *
- * Return value: 0 = ok
- * EOF = error
- */
-static int dispatch(xprintf_struct *s)
-{
- const char *initial_ptr;
- char format_string[24]; /* max length may be something like "% +-#032768.32768Ld" */
- char *format_ptr;
- int flag_plus, flag_minus, flag_space, flag_sharp, flag_zero;
- int width, prec, modifier, approx_width;
- char type;
- /* most of those variables are here to rewrite the format string */
-
-#define SRCTXT (s->src_string)
-#define DESTTXT (s->dest_string)
-
- /* incoherent format string. Characters after the '%' will be printed with the next call */
-#define INCOHERENT() do {SRCTXT=initial_ptr; return 0;} while (0) /* do/while to avoid */
-#define INCOHERENT_TEST() do {if(*SRCTXT==0) INCOHERENT();} while (0) /* a null statement */
-
- /* 'normal' text */
- if (*SRCTXT != '%')
- return usual_char(s);
-
- /* we then have a '%' */
- SRCTXT++;
- /* don't check for end-of-string ; this is done later */
-
- /* '%%' escape sequence */
- if (*SRCTXT == '%') {
- if (realloc_buff(s, (size_t)1) == EOF) /* because we can have "%%%%%%%%..." */
- return EOF;
- *DESTTXT = '%';
- DESTTXT++;
- SRCTXT++;
- (s->real_len)++;
- (s->pseudo_len)++;
- return 0;
- }
-
- /* '%' managing */
- initial_ptr = SRCTXT; /* save current pointer in case of incorrect */
- /* 'decoding'. Points just after the '%' so the '%' */
- /* won't be printed in any case, as required. */
-
- /* flag */
- flag_plus = flag_minus = flag_space = flag_sharp = flag_zero = 0;
-
- for (;; SRCTXT++) {
- if (*SRCTXT == ' ')
- flag_space = 1;
- else if (*SRCTXT == '+')
- flag_plus = 1;
- else if (*SRCTXT == '-')
- flag_minus = 1;
- else if (*SRCTXT == '#')
- flag_sharp = 1;
- else if (*SRCTXT == '0')
- flag_zero = 1;
- else
- break;
- }
-
- INCOHERENT_TEST(); /* here is the first test for end of string */
-
- /* width */
- if (*SRCTXT == '*') { /* width given by next argument */
- SRCTXT++;
- width = va_arg(s->vargs, int);
- if ((size_t)width > 0x3fffU) /* 'size_t' to check against negative values too */
- width = 0x3fff;
- } else if (isdigit((unsigned char)*SRCTXT)) /* width given as ASCII number */
- width = getint(&SRCTXT);
- else
- width = -1; /* no width specified */
-
- INCOHERENT_TEST();
-
- /* .prec */
- if (*SRCTXT == '.') {
- SRCTXT++;
- if (*SRCTXT == '*') { /* .prec given by next argument */
- SRCTXT++;
- prec = va_arg(s->vargs, int);
- if ((size_t)prec >= 0x3fffU) /* 'size_t' to check against negative values too */
- prec = 0x3fff;
- } else { /* .prec given as ASCII number */
- if (isdigit((unsigned char)*SRCTXT) == 0)
- INCOHERENT();
- prec = getint(&SRCTXT);
- }
- INCOHERENT_TEST();
- } else
- prec = -1; /* no .prec specified */
-
- /* modifier */
- if (*SRCTXT == 'L' || *SRCTXT == 'h' || *SRCTXT == 'l') {
- modifier = *SRCTXT;
- SRCTXT++;
- if (modifier=='l' && *SRCTXT=='l') {
- SRCTXT++;
- modifier = 'L'; /* 'll' == 'L' long long == long double */
- } /* only for compatibility ; not portable */
- INCOHERENT_TEST();
- } else
- modifier = -1; /* no modifier specified */
-
- /* type */
- type = *SRCTXT;
- if (strchr("diouxXfegEGcspn",type) == NULL)
- INCOHERENT(); /* unknown type */
- SRCTXT++;
-
- /* rewrite format-string */
- format_string[0] = '%';
- format_ptr = &(format_string[1]);
-
- if (flag_plus) {
- *format_ptr = '+';
- format_ptr++;
- }
- if (flag_minus) {
- *format_ptr = '-';
- format_ptr++;
- }
- if (flag_space) {
- *format_ptr = ' ';
- format_ptr++;
- }
- if (flag_sharp) {
- *format_ptr = '#';
- format_ptr++;
- }
- if (flag_zero) {
- *format_ptr = '0';
- format_ptr++;
- } /* '0' *must* be the last one */
-
- if (width != -1) {
- sprintf(format_ptr, "%i", width);
- format_ptr += strlen(format_ptr);
- }
-
- if (prec != -1) {
- *format_ptr = '.';
- format_ptr++;
- sprintf(format_ptr, "%i", prec);
- format_ptr += strlen(format_ptr);
- }
-
- if (modifier != -1) {
- if (modifier == 'L' && strchr("diouxX",type) != NULL) {
- *format_ptr = 'l';
- format_ptr++;
- *format_ptr = 'l';
- format_ptr++;
- } else {
- *format_ptr = modifier;
- format_ptr++;
- }
- }
-
- *format_ptr = type;
- format_ptr++;
- *format_ptr = 0;
-
- /* vague approximation of minimal length if width or prec are specified */
- approx_width = width + prec;
- if (approx_width < 0) /* because width == -1 and/or prec == -1 */
- approx_width = 0;
-
- switch (type) {
- /* int */
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- switch (modifier) {
- case -1 :
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
- case 'L':
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long long int));
- case 'l':
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long int));
- case 'h':
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
- /* 'int' instead of 'short int' because default promotion is 'int' */
- default:
- INCOHERENT();
- }
-
- /* char */
- case 'c':
- if (modifier != -1)
- INCOHERENT();
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
- /* 'int' instead of 'char' because default promotion is 'int' */
-
- /* math */
- case 'e':
- case 'f':
- case 'g':
- case 'E':
- case 'G':
- switch (modifier) {
- case -1 : /* because of default promotion, no modifier means 'l' */
- case 'l':
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, double));
- case 'L':
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long double));
- default:
- INCOHERENT();
- }
-
- /* string */
- case 's':
- return type_s(s, width, prec, format_string, va_arg(s->vargs, const char*));
-
- /* pointer */
- case 'p':
- if (modifier == -1)
- return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, void *));
- INCOHERENT();
-
- /* store */
- case 'n':
- if (modifier == -1) {
- int * p;
- p = va_arg(s->vargs, int *);
- if (p != NULL) {
- *p = s->pseudo_len;
- return 0;
- }
- return EOF;
- }
- INCOHERENT();
-
- } /* switch */
-
- INCOHERENT(); /* unknown type */
-
-#undef INCOHERENT
-#undef INCOHERENT_TEST
-#undef SRCTXT
-#undef DESTTXT
-}
-
-/*
- * Return value: number of *virtually* written characters
- * EOF = error
- */
-static int core(xprintf_struct *s)
-{
- size_t len, save_len;
- char *dummy_base;
-
- /* basic checks */
- if ((int)(s->maxlen) <= 0) /* 'int' to check against some conversion */
- return EOF; /* error for example if value is (int)-10 */
- s->maxlen--; /* because initial maxlen counts final 0 */
- /* note: now 'maxlen' _can_ be zero */
-
- if (s->src_string == NULL)
- s->src_string = "(null)";
-
- /* struct init and memory allocation */
- s->buffer_base = NULL;
- s->buffer_len = 0;
- s->real_len = 0;
- s->pseudo_len = 0;
- if (realloc_buff(s, (size_t)0) == EOF)
- return EOF;
- s->dest_string = s->buffer_base;
-
- /* process source string */
- for (;;) {
- /* up to end of source string */
- if (*(s->src_string) == 0) {
- *(s->dest_string) = 0; /* final 0 */
- len = s->real_len + 1;
- break;
- }
-
- if (dispatch(s) == EOF)
- goto free_EOF;
-
- /* up to end of dest string */
- if (s->real_len >= s->maxlen) {
- (s->buffer_base)[s->maxlen] = 0; /* final 0 */
- len = s->maxlen + 1;
- break;
- }
- }
-
- /* for (v)asnprintf */
- dummy_base = s->buffer_base;
- save_len = 0; /* just to avoid a compiler warning */
-
- dummy_base = s->buffer_base + s->real_len;
- save_len = s->real_len;
-
- /* process the remaining of source string to compute 'pseudo_len'. We
- * overwrite again and again, starting at 'dummy_base' because we don't
- * need the text, only char count. */
- while(*(s->src_string) != 0) { /* up to end of source string */
- s->real_len = 0;
- s->dest_string = dummy_base;
- if (dispatch(s) == EOF)
- goto free_EOF;
- }
-
- s->buffer_base = (char *)realloc((void *)(s->buffer_base), save_len + 1);
- if (s->buffer_base == NULL)
- return EOF; /* should rarely happen because we shrink the buffer */
- return s->pseudo_len;
-
- free_EOF:
- if (s->buffer_base != NULL)
- free(s->buffer_base);
- return EOF;
-}
-
-int vasprintf(char **ptr, const char *format_string, va_list vargs)
-{
- xprintf_struct s;
- int retval;
-
- s.src_string = format_string;
-#ifdef va_copy
- va_copy (s.vargs, vargs);
-#else
-#ifdef __va_copy
- __va_copy (s.vargs, vargs);
-#else
- memcpy (&s.vargs, vargs, sizeof (va_list));
-#endif /* __va_copy */
-#endif /* va_copy */
- s.maxlen = (size_t)INT_MAX;
-
- retval = core(&s);
- va_end(s.vargs);
- if (retval == EOF) {
- *ptr = NULL;
- return EOF;
- }
-
- *ptr = s.buffer_base;
- return retval;
-}
More information about the Midnightbsd-cvs
mailing list