Commit d51dd6b1 by devttys0

Updated C installer to always build libfuzzy

parent 5839cd8d
......@@ -198,11 +198,11 @@ then
pyqtgraph
fi
if [ "$(python -c 'import ctypes.util; print (ctypes.util.find_library("fuzzy"))')" == "None" ]
then
echo "libfuzzy not installed; building from source..."
libfuzzy
fi
#if [ "$(python -c 'import ctypes.util; print (ctypes.util.find_library("fuzzy"))')" == "None" ]
#then
# echo "libfuzzy not installed; building from source..."
# libfuzzy
#fi
# Get and build the firmware mod kit
fmk
......
......@@ -2,15 +2,38 @@
from __future__ import print_function
import os
import sys
import shutil
from distutils.core import setup
from distutils.dir_util import remove_tree
# Python2/3 compliance
try:
raw_input
except:
except NameError:
raw_input = input
def cleanup_build_directory():
# Requires to chdir into the src directory first
try:
remove_tree("build")
except KeyboardInterrupt as e:
raise e
except Exception:
pass
def cleanup_module_directory():
# Installing doesn't remove old files that may have been deleted from the module.
if "install" in sys.argv:
try:
import binwalk
for path in binwalk.__path__:
try:
remove_tree(path + os.path.sep + "*")
except OSError as e:
pass
except ImportError:
pass
# Change to the binwalk src directory
def warning(lines, terminate=True, prompt=True):
WIDTH = 115
......@@ -36,20 +59,7 @@ if "--yes" in sys.argv:
else:
IGNORE_WARNINGS = False
# Look for old installations of binwalk and remove them to prevent conflicts with the new API
try:
import binwalk
for path in binwalk.__path__:
if not os.path.exists(os.path.join(path, "core")):
try:
print ("Cleaning up old installation...")
shutil.rmtree(path)
except:
pass
except:
pass
# Change to the binwalk src directory
# cd into the src directory, no matter where setup.py was invoked from
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "src"))
print("checking pre-requisites")
......@@ -57,14 +67,14 @@ try:
import magic
try:
magic.MAGIC_NO_CHECK_TEXT
except Exception as e:
except AttributeError as e:
msg = ["Pre-requisite failure: " + str(e),
"It looks like you have an old or incompatible magic module installed.",
"Please install the official python-magic module, or download and install it from source: ftp://ftp.astron.com/pub/file/"
]
warning(msg)
except Exception as e:
except ImportError as e:
msg = ["Pre-requisite failure:", str(e),
"Please install the python-magic module, or download and install it from source: ftp://ftp.astron.com/pub/file/",
]
......@@ -73,7 +83,7 @@ except Exception as e:
try:
import pyqtgraph
except Exception as e:
except ImportError as e:
msg = ["Pre-requisite check warning: " + str(e),
"To take advantage of this tool's graphing capabilities, please install the pyqtgraph module.",
]
......@@ -94,23 +104,26 @@ if not os.path.exists(c_lib_makefile):
status |= os.system("make")
if status != 0:
msg = ["Build warning: failed to build compression libraries.",
"Some plugins will not work without these libraries."
msg = ["Build warning: failed to build C libraries.",
"Some features will not work without these libraries."
]
warning(msg, prompt=True)
elif "install" in sys.argv:
if os.system("make install") != 0:
msg = ["Install warning: failed to install compression libraries.",
"Some plugins will not work without these libraries."
msg = ["Install warning: failed to install C libraries.",
"Some features will not work without these libraries."
]
warning(msg, prompt=True)
os.system("make distclean")
os.chdir(working_directory)
cleanup_build_directory()
cleanup_module_directory()
# Generate a new magic file from the files in the magic directory
print("generating binwalk magic file")
print("creating binwalk magic file")
magic_files = os.listdir("magic")
magic_files.sort()
fd = open("binwalk/magic/binwalk", "wb")
......@@ -136,3 +149,5 @@ setup( name = "binwalk",
scripts = ["scripts/binwalk"],
)
cleanup_build_directory()
......@@ -10,18 +10,22 @@ export INSTALL_OPTIONS=@INSTALL_OPTIONS@
all: clean
make -C miniz
make -C compress
make -C fuzzy
install:
make -C miniz install
make -C compress install
make -C fuzzy install
.PHONY: clean distclean
clean:
make -C miniz clean
make -C compress clean
make -C fuzzy clean
distclean:
make -C miniz distclean
make -C compress distclean
make -C fuzzy distclean
rm -rf *.cache config.* Makefile
This source diff could not be displayed because it is too large. You can view the blob instead.
ssdeep was written by Jesse Kornblum and Helmut Grohne.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
2013-07-16: Jesse Kornblum <research@jessekornblum.com>:
* fuzzy.c: Fix heap corruption bug #15.
* dig.c: Removed extra call to GetFileAttributes
2013-07-09: Jesse Kornblum <research@jessekornblum.com>:
* dig.cpp, engine.cpp, helpers.cpp: Created separate directory traversal code
for Win32 systems.
2013-06-01: Jesse Kornblum <research@jessekornblum.com>:
* fuzzy.c: Experimental thread-safe patch from Helmut Grohne.
* fuzzy.h: Experimental thread-safe patch from Helmut Grohne.
2013-05-25: Jesse Kornblum <research@jessekornblum.com>:
* fuzzy.c: Fixed bug on string scoring.
2013-03-12: Jesse Kornblum <research@jessekornblum.com>:
* Changelog: Spelled my own name correctly.
* fuzzy.c: Fixed memory leak, bug 3607641.
2012-07-23: Jesse Kornblum <research@jessekornblum.com>:
* main.cpp, match.cpp: Renamed the match_pretty function for clarity.
2012-07-17: Jesse Kornblum <research@jessekornblum.com>:
* match.cpp: Fixing bugs in matching, clustering modes
* main.cpp: Clarifying comments. Added sanity check for -c, -g
2012-07-16: Jesse Kornblum <research@jessekornblum.com>:
* filedata.cpp: Added includes for *nix compilation
2012-07-14 Jesse Kornblum <research@jessekornblum.com>:
* win.sh: Updated for C++ compiler warnings
* normal.sh: Updated for C++ compiler warnings
* fuzzy.c: Corrected logic error for when sigs don't have filenames
* ui.cpp: Added const to print_error's state variable
* match.cpp: Rewrote to use Filedata class
* filedata.cpp: Created Filedata class
* main.cpp: Adapted to use Filedata class
2012-07-13 Jesse Kornblum <research@jessekornblum.com>:
* fuzzy.c: Fixed major bug regarding incorrect match scores for hashes with long filenames
* dig.cpp: Added warning message when not all data on stdin was hashed. Also increased stdin buffer to 512MB.
* configure.ac: Version bump to 2.9.
* main.cpp: Added flags for clustering mode
* ssdeep.h: Added flags for clustering mode
* match.cpp: Setting up for clustering mode
2012-05-25 Jesse Kornblum <research@jessekornblum.com>:
* main.cpp: Updated command line argument processing
* ssdeep.1: Clarifications on description.
2012-05-24 Jesse Kornblum <research@jessekornblum.com>:
* match.cpp: Convert to C++
2012-04-24 Jesse Kornblum <research@jessekornblum.com>:
* ssdeep.1: Updating support for stdin, clarifying modes
* Makefile.am: LF to CR/LF change now done by zip program
* ssdeep.h: Adding Doxygen comments
* match.cpp: Fixed bug in Win32 filename construction
* fuzzy.h: Cleanup and commenting
* engine.cpp: Added const definitions
* Experimental conversion to C++
* Commented out all references to clustering
* main.cpp: Fixed some bugs in the command line argument processing
2012-04-15: Jesse Kornblum <research@jessekornblum.com>:
* main.c: Fixed error handling in getopt processing
2012-02-16 Jesse Kornblum <research@jessekornblum.com>:
* main.c: Bump copyright to 2012 in usage message. Add flag for clustering
* main.h: Added mode_cluster
* ui.c: Changed Win32 to use fputc instead of _tfprintf for filenames
2012-01-12 Jesse Kornblum <research@jessekornblum>:
* ChangeLog: Clean up
2011-10-17 Jesse Kornblum <research@jessekornblum.com>:
* configure.ac: Added AC_SYS_LARGEFILE to handle large files on 32-bit platforms. See bug 3416762.
2011-09-30 Jesse Kornblum <research@jessekornblum.com>:
* ui.c: Redirected error messages to stderr instead of stdout
* main.c: Added warning message when the program does not process any file large enough to produce meaningful results.
2011-09-27 Jesse Kornblum <research@jessekornblum.com>:
* main.c: Added support to process stdin.
* dig.c: Added process_stdin function
* engine.c: Generalized display functions in display_result.
2011-08-19 Jesse Kornblum <research@jessekornblum.com>:
* edit_dist.c: Accepted patch from Brad Spengler to make
thread safe.
2010-07-15 Jesse Kornblum <research@jessekornblum.com>:
* Added quotes and quote escaping to filenames when
displayed in CSV matching mode.
* Modified FILEFORMAT to reflect quotation marks in filenames.
2010-06-24 Jesse Kornblum <research@jessekornblum.com>:
* Added parameter checking to my_basename.
2010-05-05 Jesse Kornblum <research@jessekornblum.com>:
* Changed logic for reading files of known hashes to look for
the header this version of the program writes instead of
the v1 header. This was done for the DC3 branch of the code.
* Updated README documentation and published version 2.5.
2010-03-20 Jesse Kornblum <research@jessekornblum.com>:
* Fixed define in fuzzy.h to only allow one compilation
2010-03-19 Jesse Kornblum <research@jessekornblum.com>:
* Added 'extern "C"' definitions to fuzzy.h for C++ compatibility
* Added return values indicating errors to API functions.
* Modified sample program to use errors on return values
* Added Doxygen documentation for API function.
* Added inttypes.h include to fuzzy.h.
* Added error checking for NULL strings in API functions.
* Version bump to 2.5
2010-02-24 Jesse Kornblum <research@jessekornblum.com>:
* Experimenting with mode to compare unknown hashes to known
without comparing the unknown against each other.
* Version bump to 2.4
2009-01-20 Jesse Kornblum <research@jessekornblum.com>:
* Added -a mode to display all matches regardless of score.
2009-10-11 Jesse Kornblum <research@jessekornblum.com>:
* Fixed typo in usage page.
2009-07-14 Jesse Kornblum <research@jessekornblum.com>:
* Fixed bug that prevented -x mode from working on Win32
* Added web pages to trunk. Updated quickstart guide with
automatic installation options and -x mode.
* Version bump to 2.2 and updated man page, NEWS
2009-07-11 Jesse Kornblum <research@jessekornblum.com>:
* Cleaned up -x mode to compare two (or more) files of
signatures.
* Cleaned up some code comments and Remove Before Flight tags
2009-04-18 Jesse Kornblum <research@jessekornblum.com>:
* Experimenting with -x mode to compare two (or more)
files of signatures
* Added some parameter validation code
2009-01-01 Jesse Kornblum <research@jessekornblum.com>:
* Added fuzzy_hash_filename function to hash a file given
its filename. This avoids issues passing FILE * structures
on Win32 systems in programs not using the fopen convention.
See feature request 2142005.
* Reconfigured all files using latest autoconf tools
2008-09-23 Jesse Kornblum <research@jessekornblum.com>:
* Reinstated the code to call match_pretty() at the end of
main. This lets the -p and -d modes to display output and
fixes bug 2124423.
* Version bump to 2.1.
2008-04-06 Jesse Kornblum <research@jessekornblum.com>:
* Updated man page to include -t and -c modes.
2008-03-04 Jesse Kornblum <research@jessekornblum.com>:
* Made b64 variable static in fuzzy.c
2008-02-29 Jesse Kornblum <research@jessekornblum.com>:
* Version bump to 2.0, reconfigured.
2008-02-22 Jesse Kornblum <research@jessekornblum.com>:
* Changed reading of known hash files back to using
unsigned char values. This also required updating
the match_compare function to handle Unicode
characters when displaying match results.
* Flipped files in Win32 zip file to have CR/LF
2008-02-18 Jesse Kornblum <research@jessekornblum.com>:
* Added man pages to the EXTRA_DIST Makefile variable.
Still need to reconfigure.
* Added more documentation to the Windows zip file along
with the sample.c file
* Removed extraneous recongfiguration from Makefile.am
2008-02-17 Jesse Kornblum <research@jessekornblum.com>:
* Updated build system to create Win32 DLL, documentation,
and packages.
* Added check in print_error functions to see if the state
is valid.
* Updated documentation, usage message.
* Added signature comparison example to sample program.
2008-02-16 Jesse Kornblum <research@jessekornblum.com>:
* Removed block_size value from state variable.
Nobody was using it.
* Ammended API functions to support hashing either a buffer
or an open file handle
* Moved ssdeep code into engine.c, moved fuzzy hashing
code into fuzzy.c. This will help us create libfuzzy
and fuzzy.dll.
* Lots of cleanup to fuzzy hashing code. This includes removing
types like 'uchar' and replacing them with C99 types like
unsigned char. Less work for mother means less work debugging.
* Moved definition of __progname to ssdeep.h. It's not being
used by the fuzzy hashing library and caused problems on OS X.
* Brought over code to support Unicode from Miss Identify
* Version bump to 2.0 beta1
* Added sample program to demonstrate API features
2008-02-15 Jesse Kornblum <research@jessekornblum.com>:
* Changing Win32 build to create DLL. All other
versions should have library/header files installed
2008-02-14 Jesse Kornblum <research@jessekornblum.com>:
* Moved to autotools structure
SSDEEP FILE FORMAT VERSION 1.1
1. REVISION HISTORY
14 Aug 2006 - Initial version (jk)
15 Jul 2010 - Adding quotation marks to filenames
2. FILE HEADER
The first line of the file is a header, like this:
ssdeep,1.1--blocksize:hash:hash,filename
ssdeep - Identifies the file type
1.1 - The version of the file format, NOT the version of the program
-- - Separator
The remainder of the line identifies the format of the file.
Note that for version 1.1 these values must be given EXACTLY as shown above
3. FILE DATA
Each line represents the hash of one file as listed in the header.
Specifically, we have the blocksize used by the program, the hash
for this blocksize and twice the blocksize, and the filename. Filenames
are enclosed in quotation marks. Filenames which contain a quotation mark
will have those quotes slash escaped. For example, the file ma"in.c
will be listed as:
"ma\"in.c"
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
bin_PROGRAMS=ssdeep
ssdeep_LDADD=libfuzzy.la
ssdeep_LDFLAGS=-static
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES=libfuzzy.la
libfuzzy_la_SOURCES=fuzzy.c edit_dist.c find-file-size.c
libfuzzy_la_LDFLAGS=-no-undefined -version-info 2:0:0
include_HEADERS=fuzzy.h
man_MANS=ssdeep.1
ssdeep_SOURCES = main.cpp match.cpp engine.cpp filedata.cpp \
dig.cpp cycles.cpp helpers.cpp ui.cpp \
main.h fuzzy.h tchar-local.h ssdeep.h filedata.h match.h
dll: $(libfuzzy_la_SOURCES)
$(CC) $(CFLAGS) -shared -o fuzzy.dll $(libfuzzy_la_SOURCES) \
-Wl,--output-def,fuzzy.def,--out-implib,libfuzzy.a
$(STRIP) fuzzy.dll
CLEANFILES=fuzzy.dll fuzzy.def
EXTRA_DIST=$(man_MANS) config.guess config.sub sample.c FILEFORMAT
WINDOWSDOCS=README.TXT API.TXT FILEFORMAT.TXT NEWS.TXT
README.TXT: ssdeep.1
man ./ssdeep.1 | col -bx > README.TXT
API.TXT: README
cp README API.TXT
FILEFORMAT.TXT: FILEFORMAT
cp FILEFORMAT FILEFORMAT.TXT
NEWS.TXT: NEWS
cp NEWS NEWS.TXT
win-docs: $(WINDOWSDOCS)
# flip -d $(WINDOWSDOCS)
# unix2dos $(WINDOWSDOCS)
win-package: win-docs
rm -rf $(distdir).zip $(distdir)
make
make dll
$(STRIP) ssdeep.exe
mkdir $(distdir)
cp $(WINDOWSDOCS) ssdeep.exe fuzzy.dll fuzzy.def sample.c $(distdir)
# flip -d $(distdir)/{sample.c,fuzzy.def}
# unix2dos $(distdir)/{sample.c,fuzzy.def}
zip -lr9 $(distdir).zip $(distdir)
rm -rf $(distdir) $(WINDOWSDOCS)
world: distclean
./configure --host=i386-mingw32
make win-package
make dist
# Only generic routines go below this line
# ------------------------------------------------------------------
nice:
rm -f *~
preflight:
@grep RBF $(DISTFILES)
# Makefile.in generated by automake 1.14 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = ssdeep$(EXEEXT)
subdir = .
DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in depcomp $(include_HEADERS) COPYING TODO \
compile config.guess config.sub install-sh missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(man1dir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libfuzzy_la_LIBADD =
am_libfuzzy_la_OBJECTS = fuzzy.lo edit_dist.lo find-file-size.lo
libfuzzy_la_OBJECTS = $(am_libfuzzy_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libfuzzy_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libfuzzy_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(bin_PROGRAMS)
am_ssdeep_OBJECTS = main.$(OBJEXT) match.$(OBJEXT) engine.$(OBJEXT) \
filedata.$(OBJEXT) dig.$(OBJEXT) cycles.$(OBJEXT) \
helpers.$(OBJEXT) ui.$(OBJEXT)
ssdeep_OBJECTS = $(am_ssdeep_OBJECTS)
ssdeep_DEPENDENCIES = libfuzzy.la
ssdeep_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(ssdeep_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libfuzzy_la_SOURCES) $(ssdeep_SOURCES)
DIST_SOURCES = $(libfuzzy_la_SOURCES) $(ssdeep_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
man1dir = $(mandir)/man1
NROFF = nroff
MANS = $(man_MANS)
HEADERS = $(include_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
AM_RECURSIVE_TARGETS = cscope
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ssdeep_LDADD = libfuzzy.la
ssdeep_LDFLAGS = -static
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libfuzzy.la
libfuzzy_la_SOURCES = fuzzy.c edit_dist.c find-file-size.c
libfuzzy_la_LDFLAGS = -no-undefined -version-info 2:0:0
include_HEADERS = fuzzy.h
man_MANS = ssdeep.1
ssdeep_SOURCES = main.cpp match.cpp engine.cpp filedata.cpp \
dig.cpp cycles.cpp helpers.cpp ui.cpp \
main.h fuzzy.h tchar-local.h ssdeep.h filedata.h match.h
CLEANFILES = fuzzy.dll fuzzy.def
EXTRA_DIST = $(man_MANS) config.guess config.sub sample.c FILEFORMAT
WINDOWSDOCS = README.TXT API.TXT FILEFORMAT.TXT NEWS.TXT
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .lo .o .obj
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libfuzzy.la: $(libfuzzy_la_OBJECTS) $(libfuzzy_la_DEPENDENCIES) $(EXTRA_libfuzzy_la_DEPENDENCIES)
$(AM_V_CCLD)$(libfuzzy_la_LINK) -rpath $(libdir) $(libfuzzy_la_OBJECTS) $(libfuzzy_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
|| test -f $$p1 \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
ssdeep$(EXEEXT): $(ssdeep_OBJECTS) $(ssdeep_DEPENDENCIES) $(EXTRA_ssdeep_DEPENDENCIES)
@rm -f ssdeep$(EXEEXT)
$(AM_V_CXXLD)$(ssdeep_LINK) $(ssdeep_OBJECTS) $(ssdeep_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cycles.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit_dist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filedata.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find-file-size.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzzy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helpers.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/match.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
install-man1: $(man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
list2='$(man_MANS)'; \
test -n "$(man1dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.1[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.1[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) \
config.h
install-binPROGRAMS: install-libLTLIBRARIES
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-includeHEADERS install-man
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man: install-man1
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
uninstall-libLTLIBRARIES uninstall-man
uninstall-man: uninstall-man1
.MAKE: all install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
clean-binPROGRAMS clean-cscope clean-generic \
clean-libLTLIBRARIES clean-libtool cscope cscopelist-am ctags \
ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \
dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-libtool distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-binPROGRAMS install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am \
install-includeHEADERS install-info install-info-am \
install-libLTLIBRARIES install-man install-man1 install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
uninstall-includeHEADERS uninstall-libLTLIBRARIES \
uninstall-man uninstall-man1
dll: $(libfuzzy_la_SOURCES)
$(CC) $(CFLAGS) -shared -o fuzzy.dll $(libfuzzy_la_SOURCES) \
-Wl,--output-def,fuzzy.def,--out-implib,libfuzzy.a
$(STRIP) fuzzy.dll
README.TXT: ssdeep.1
man ./ssdeep.1 | col -bx > README.TXT
API.TXT: README
cp README API.TXT
FILEFORMAT.TXT: FILEFORMAT
cp FILEFORMAT FILEFORMAT.TXT
NEWS.TXT: NEWS
cp NEWS NEWS.TXT
win-docs: $(WINDOWSDOCS)
# flip -d $(WINDOWSDOCS)
# unix2dos $(WINDOWSDOCS)
win-package: win-docs
rm -rf $(distdir).zip $(distdir)
make
make dll
$(STRIP) ssdeep.exe
mkdir $(distdir)
cp $(WINDOWSDOCS) ssdeep.exe fuzzy.dll fuzzy.def sample.c $(distdir)
# flip -d $(distdir)/{sample.c,fuzzy.def}
# unix2dos $(distdir)/{sample.c,fuzzy.def}
zip -lr9 $(distdir).zip $(distdir)
rm -rf $(distdir) $(WINDOWSDOCS)
world: distclean
./configure --host=i386-mingw32
make win-package
make dist
# Only generic routines go below this line
# ------------------------------------------------------------------
nice:
rm -f *~
preflight:
@grep RBF $(DISTFILES)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
** Version 2.10 - 17 Jul 2013
* New Features
- Fuzzy Hashing engine re-written to be thread safe.
* Bug Fixes
- Able to handle long file paths on Win32.
- Fixed bug on comparing signatures with the same block size.
- Fixed crash on comparing short signatures.
- Fixed memory leak
** Version 2.9 - 23 Jul 2012
* New Features
- Added warning message for when some data on stdin is not hashed.
- Can now hash up to 512MB of data on stdin.
- Added clustering mode to group together matching files
* Bug Fixes
- Fixed incorrect match scores for hashes with long filenames.
** Version 2.8 - 25 May 2012
* New Features
- Converted to C++
* Bug Fixes
- Fixed filename display on Win32.
- Fixed support for large files on some platforms.
- Fixed errors in handling command line argument processing.
** Version 2.7 - 30 Sep 2011
* New Features
- Added the capability to process the first 100MB of data
from standard input.
- Added a warning message when the program does not process
any file large enough to produce a meaningful result.
* Bug Fixes
- Standard errors are now sent to stderr, not stdout.
** Version 2.6 - 28 Sep 2010
* New Features
- Modified the output file format to allow for proper escaping of
filenames with quotation marks in them.
* Bug Fixes
- Added quotation marks to filenames in CSV matching mode.
** Version 2.5 - 6 May 2010
* New Features
- Added API documentation
- Added return values indicating errors in API functions
- Added compatibility for compiling with C++
* Bug Fixes
- Added parameter validation to API functions
- Fixed some cosmetic errors in error handling
** Version 2.4 - 25 Feb 2010
* New Features
- Added -k mode to compare unknown signatures against known signatures.
** Version 2.3 - 10 Jan 2010
* New Features
- Added -a mode to display all 'matches', regardless of score.
** Version 2.2 - 22 Jul 2009
* New Features
- Added capability to compare two or more files containing signatures
against one another.
* Bug Fixes
- Changed default behavior to exit program on invalid command line flags
** Version 2.1 - 1 Jan 2009
* New Features
- Added fuzzy_hash_filename function to hash an entire file given
only its filename. Avoids issues on Win32 systems.
* Bug Fixes
- Fixed -p mode to display output
** Version 2.0 - 2 Apr 2008
* New Features
- Created fuzzy hashing API/DLL
- Added support for filenames with Unicode characters on Win32
- Added threshold mode
- Added CSV mode
* Bug Fixes
- Fixed extra characters appearing during verbose mode
** Version 1.1 - 14 Aug 2006
* New Features
- First public release
- Added verbose mode to display filenames as they're being hashed
- Added -d mode to make finding similar files in the same directory tree
both easier and faster. Removes the need for two command lines and
many extraneous lines of output.
- Added -p mode to improve -d mode. Prints bi-directional matches together
and omits self matches.
- Added LARGEFILE_SOURCE define to Linux version to allow processing
of large files. (You never know...)
* Bug Fixes
- Fixed cosmetic errors in usage message. Updated man page.
** Version 1.0 - 31 Mar 2006
* New Features
- Released internally
- Added silent mode, -s. All error messages are suppressed.
* Bug Fixes
- Fixed failure to close files after reading in engine.c
- Fixed routine to read headers of matching hashes on Windows.
- Fixed handling of symbolic links
- Fixed cosmetic bug to display error messages if file open fails
(e.g. Permission denied, etc)
- Removed quotation marks from the signatures but not the file names.
Filenames may contain spaces, but signatures may not. Two bytes
per line adds up when we starting compiling large hash sets.
- Redirected all error messages to stderr instead of stdout
- Removed duplicate defines at the start of engine.c
- Replaced all references to u32 with C99 standard uint32_t
- Added error checking for memory allocation in main.c:main() and
engine.c:hash_file()
- Removed useless logical AND of 0xFFFFFFFF from rolling hash update
** Version 0.1 - 4 Nov 2005
* New Features
- Proof of concept
- This version supports recursion, relative and bare file names, and
can perform positive matching using a previous output.
**** FUZZY HASHING API ****
This file documents the fuzzy hashing API. Information on how to use the
fuzzy hashing program ssdeep can be found in the man page. On *nix
systems you can view this file with:
$ man ./ssdeep.1
Windows users can get the ssdeep usage information from README.TXT.
** Using the API in Your Own Progrms **
You can use the fuzzy hashing API in your own programs by doing
the following:
1. Include the fuzzy hashing header
#include <fuzzy.h>
2. Call one of the functions:
* Fuzzy hashing a buffer of text:
int fuzzy_hash_buf(const unsigned char *buf,
uint32_t buf_len,
char *result);
This function computes the fuzzy hash of the buffer 'buf' and stores the
result in result. You MUST allocate result to hold FUZZY_MAX_RESULT
characters before calling this function. The length of the buffer should
be passed in via buf_len. It is the user's responsibility to append the
filename, if any, to the output. The function returns zero on success,
one on error.
* Fuzzy hashing a file:
There are in fact two ways to fuzzy hash a file. If you already
have an open file handle you can use:
int fuzzy_hash_file(FILE *handle,
char *result);
This function computes the fuzzy hash of the file pointed to by handle
and stores the result in result. You MUST allocate result to hold
FUZZY_MAX_RESULT characters before calling this function. It is the
user's responsibility to append the filename to the output.
The function returns zero on success, one on error.
The other function to hash a file takes a file name:
int fuzzy_hash_filename(const char * filename,
char * result);
Like the function above, this function stores the fuzzy hash result
in the parameter result. You MUST allocate result to hold
FUZZY_MAX_RESULT characters before calling this function.
* Compare two fuzzy hash signatures:
int fuzzy_compare(const char *sig1, const char *sig2);
This function returns a value from 0 to 100 indicating the match
score of the two signatures. A match score of zero indicates the \
sigantures did not match.
3. Compile
To compile the program using gcc:
$ gcc -Wall -I/usr/local/include -L/usr/local/lib sample.c -Lfuzzy
Using mingw:
C:\> gcc -Wall -Ic:\path\to\includes sample.c fuzzy.dll
Using Microsoft Visual C (MSVC):
To paraphrase the MinGW documentation,
http://www.mingw.org/mingwfaq.shtml#faq-msvcdll:
The Windows ssdeep package includes a Win32 DLL and a .def file. Although
MSVC users can't use the DLL directly, they can easily create a .lib file
using the Microsoft LIB tool:
C:\> lib /machine:i386 /def:fuzzy.def
You can then compile your program using the resulting library:
C:\> cl sample.c fuzzy.lib
** Sample Program **
A sample program that uses the API is in sample.c.
** See Also **
- Jesse D. Kornblum, "Identifying almost identical files using context
triggered piecewise hashing", Digital Investigaton, 3(S):91-97,
September 2006, http://dx.doi.org/10.1016/j.diin.2006.06.015,
The Proceedings of the 6th Annual Digital Forensic Research Workshop
\ No newline at end of file
- Update man page
- Update web page, to include new man page
- Write README
- Find a way to estimate device sizes on Windows
Perhaps an IOTCL_DISK_GET_DRIVE_GEOMETRY_EX would work?
- See if Windows Vista's symbolic links create problems for dig.c
This source diff could not be displayed because it is too large. You can view the blob instead.
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
timestamp='2005-12-13'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
trap 'exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
macppc:MirBSD:*:*)
echo powerppc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit ;;
*:z/VM:*:*)
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm:riscos:*:*|arm:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit ;;
DRS?6000:unix:4.0:6*)
echo sparc-icl-nx6
exit ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c &&
dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
SYSTEM_NAME=`$dummy $dummyarg` &&
{ echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos${UNAME_RELEASE}
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
then
echo "$SYSTEM_NAME"
else
echo rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
eval $set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
# generating 64-bit code. GNU and HP use different nomenclature:
#
# $ CC_FOR_BUILD=cc ./config.guess
# => hppa2.0w-hp-hpux11.23
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep __LP64__ >/dev/null
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
exit ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
x86:Interix*:[345]*)
echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
exit ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i586-pc-interix
exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
exit ;;
crisv32:Linux:*:*)
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
mips:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips64
#undef mips64el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mips64el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips64
#else
CPU=
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
exit ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#if defined(__INTEL_COMPILER) || defined(__PGI)
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^LIBC/{s: ::g;p;}'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
}
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit ;;
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
paragon:*:*:*)
echo i860-intel-osf1
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
echo ${UNAME_MACHINE}-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "$cputype" = "386"; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
exit ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
exit ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
exit ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
exit ;;
*:ITS:*:*)
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
esac ;;
*:XENIX:*:SysV)
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include <sys/param.h>
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
c34*)
echo c34-convex-bsd
exit ;;
c38*)
echo c38-convex-bsd
exit ;;
c4*)
echo c4-convex-bsd
exit ;;
esac
fi
cat >&2 <<EOF
$0: unable to guess system type
This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
and
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
pertinent to <config-patches@gnu.org> in order to provide the needed
information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF
exit 1
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/disk.h> header file. */
#undef HAVE_SYS_DISK_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/mount.h> header file. */
#undef HAVE_SYS_MOUNT_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Linux operating system functions */
#undef __LINUX__
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
timestamp='2005-12-11'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit ;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray)
os=
basic_machine=$1
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout)
;;
-wrs)
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| mt \
| msp430 \
| ns16k | ns32k \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m32c)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \
| ymp-* \
| z8k-*)
;;
m32c-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif)
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16c)
basic_machine=cr16c-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
necv70)
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
mon960)
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k)
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rdos)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
st2000)
basic_machine=m68k-tandem
;;
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
basic_machine=hppa1.1-winbond
;;
op50n)
basic_machine=hppa1.1-oki
;;
op60c)
basic_machine=hppa1.1-oki
;;
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
*-winbond)
os=-proelf
;;
*-oki)
os=-proelf
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
os=-coff
;;
*-*bug)
os=-coff
;;
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-aix*)
vendor=ibm
;;
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-hms*)
vendor=hitachi
;;
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
This source diff could not be displayed because it is too large. You can view the blob instead.
AC_INIT([SSDEEP],[2.10],[research@jessekornblum.com])
AM_INIT_AUTOMAKE
AC_CONFIG_FILES([Makefile])
AM_CONFIG_HEADER([config.h])
AC_CANONICAL_HOST
AC_PROG_CC
AC_PROG_CXX
AC_LIBTOOL_WIN32_DLL
#AC_PROG_LIBTOOL
AM_PROG_LIBTOOL
AC_PROG_INSTALL
AC_CONFIG_MACRO_DIR([m4])
case $host in
*-*-*linux*-*) AC_DEFINE([__LINUX__],1,[Linux operating system functions]) ;;
*-*-mingw32) LIBS="-liberty $LIBS" && CPPFLAGS="-DUNICODE -D_UNICODE $CPPFLAGS"
esac
# Bring additional directories where things might be found into our
# search path. I don't know why autoconf doesn't do this by default
for spfx in /usr/local /opt/local /sw ; do
echo checking ${spfx}/include
if test -d ${spfx}/include; then
CPPFLAGS="-I${spfx}/include $CPPFLAGS"
LDFLAGS="-L${spfx}/lib $LDFLAGS"
fi
done
AC_C_BIGENDIAN
AC_SYS_LARGEFILE
AC_CHECK_HEADERS([libgen.h])
AC_CHECK_HEADERS([dirent.h])
AC_CHECK_HEADERS([inttypes.h])
AC_CHECK_HEADERS([fcntl.h sys/types.h sys/ioctl.h sys/param.h wchar.h unistd.h sys/stat.h sys/disk.h])
AC_CHECK_HEADER([inttypes.h],,AC_MSG_ERROR([You must have inttypes.h or some other C99 equivalent]),)
# These includes are required on FreeBSD
AC_CHECK_HEADERS([sys/mount.h],[],[],
[#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif])
AC_FUNC_FSEEKO
AC_OUTPUT
/* MD5DEEP
*
* By Jesse Kornblum
*
* This is a work of the US Government. In accordance with 17 USC 105,
* copyright protection is not available for any work of the US Government.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
// $Id: cycles.cpp 184 2013-07-10 05:24:26Z jessekornblum $
#include "ssdeep.h"
typedef struct dir_table {
TCHAR *name;
struct dir_table *next;
} dir_table;
dir_table *my_table = NULL;
/* This function was used in the dark ages for debugging
static void dump_table(void)
{
struct dir_table *t = my_table;
while (t != NULL)
{
print_status (_TEXT("* %s"), t->name);
t = t->next;
}
print_status ("-- end of table --");
}
*/
int done_processing_dir(TCHAR *fn)
{
dir_table *last, *temp;
TCHAR *d_name = (TCHAR *)malloc(sizeof(TCHAR) * SSDEEP_PATH_MAX);
#ifdef _WIN32
_wfullpath(d_name,fn,SSDEEP_PATH_MAX);
#else
realpath(fn,d_name);
#endif
if (my_table == NULL)
{
internal_error("Table is NULL in done_processing_dir");
// This code never gets executed...
free(d_name);
return FALSE;
}
temp = my_table;
if (!_tcsncmp(d_name,temp->name,SSDEEP_PATH_MAX))
{
my_table = my_table->next;
free(temp->name);
free(temp);
free(d_name);
return TRUE;
}
while (temp->next != NULL)
{
last = temp;
temp = temp->next;
if (!_tcsncmp(d_name,temp->name,SSDEEP_PATH_MAX))
{
last->next = temp->next;
free(temp->name);
free(temp);
free(d_name);
return TRUE;
}
}
internal_error("%s: Directory %s not found in done_processing_dir",
__progname, d_name);
// This code never gets executed...
// free (d_name);
return FALSE;
}
int processing_dir(TCHAR *fn)
{
dir_table *new_dir, *temp;
TCHAR *d_name = (TCHAR *)malloc(sizeof(TCHAR) * SSDEEP_PATH_MAX);
#ifdef _WIN32
_wfullpath(d_name,fn,SSDEEP_PATH_MAX);
#else
realpath(fn,d_name);
#endif
if (my_table == NULL)
{
my_table = (dir_table*)malloc(sizeof(dir_table));
my_table->name = _tcsdup(d_name);
my_table->next = NULL;
free(d_name);
return TRUE;
}
temp = my_table;
while (temp->next != NULL)
{
/* We should never be adding a directory that is already here */
if (!_tcsncmp(temp->name,d_name,SSDEEP_PATH_MAX))
{
internal_error("%s: Attempt to add existing %s in processing_dir",
__progname, d_name);
// Does not execute
free(d_name);
return FALSE;
}
temp = temp->next;
}
new_dir = (dir_table*)malloc(sizeof(dir_table));
new_dir->name = _tcsdup(d_name);
new_dir->next = NULL;
temp->next = new_dir;
free(d_name);
return TRUE;
}
int have_processed_dir(TCHAR *fn)
{
dir_table *temp;
TCHAR *d_name;
if (my_table == NULL)
return FALSE;
d_name = (TCHAR *)malloc(sizeof(TCHAR) * SSDEEP_PATH_MAX);
#ifdef _WIN32
_wfullpath(d_name,fn,SSDEEP_PATH_MAX);
#else
realpath(fn,d_name);
#endif
temp = my_table;
while (temp != NULL)
{
if (!_tcsncmp(temp->name,d_name,SSDEEP_PATH_MAX))
{
free(d_name);
return TRUE;
}
temp = temp->next;
}
free(d_name);
return FALSE;
}
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2006-10-15.18
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:
// MD5DEEP - dig.c
//
// By Jesse Kornblum
//
// This is a work of the US Government. In accordance with 17 USC 105,
// copyright protection is not available for any work of the US Government.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: dig.cpp 191 2013-07-16 17:55:00Z jessekornblum $
#include "ssdeep.h"
#define STATUS_OK FALSE
static int is_special_dir(TCHAR *d)
{
return ((!_tcsncmp(d,_TEXT("."),1) && (_tcslen(d) == 1)) ||
(!_tcsncmp(d,_TEXT(".."),2) && (_tcslen(d) == 2)));
}
#ifndef _WIN32
static TCHAR DOUBLE_DIR[4] =
{ (TCHAR)DIR_SEPARATOR,
(TCHAR)DIR_SEPARATOR,
0
};
static void remove_double_slash(TCHAR *fn)
{
size_t tsize = sizeof(TCHAR);
TCHAR *tmp = fn, *new_str;
new_str = _tcsstr(tmp,DOUBLE_DIR);
while (NULL != new_str)
{
/*
#ifdef _WIN32
// On Windows, we have to allow the first two characters to be slashes
// to account for UNC paths. e.g. \\SERVER\dir\path
if (tmp == fn)
{
++tmp;
}
else
{
#endif // ifdef _WIN32
*/
_tmemmove(new_str,new_str+tsize,_tcslen(new_str));
/*
#ifdef _WIN32
}
#endif // ifdef _WIN32
*/
new_str = _tcsstr(tmp,DOUBLE_DIR);
}
}
static void remove_single_dirs(TCHAR *fn)
{
unsigned int pos, chars_found = 0;
size_t sz = _tcslen(fn), tsize = sizeof(TCHAR);
for (pos = 0 ; pos < sz ; pos++)
{
// Catch strings that end with /. (e.g. /foo/.)
if (pos > 0 &&
fn[pos-1] == _TEXT(DIR_SEPARATOR) &&
fn[pos] == _TEXT('.') &&
fn[pos+1] == 0)
fn[pos] = 0;
if (fn[pos] == _TEXT('.') && fn[pos+1] == _TEXT(DIR_SEPARATOR))
{
if (chars_found && fn[pos-1] == _TEXT(DIR_SEPARATOR))
{
_tmemmove(fn+(pos*tsize),(fn+((pos+2)*tsize)),(sz-pos) * tsize);
// In case we have ././ we shift back one!
--pos;
}
}
else
++chars_found;
}
}
// Removes all "../" references from the absolute path fn
void remove_double_dirs(TCHAR *fn)
{
size_t pos, next_dir, sz = _tcslen(fn), tsize = sizeof(TCHAR);
for (pos = 0; pos < _tcslen(fn) ; pos++)
{
if (fn[pos] == _TEXT('.') && fn[pos+1] == _TEXT('.'))
{
if (pos > 0)
{
/* We have to keep this next if statement and the one above separate.
If not, we can't tell later on if the pos <= 0 or
that the previous character was a DIR_SEPARATOR.
This matters when we're looking at ..foo/ as an input */
if (fn[pos-1] == _TEXT(DIR_SEPARATOR))
{
next_dir = pos + 2;
/* Back up to just before the previous DIR_SEPARATOR
unless we're already at the start of the string */
if (pos > 1)
pos -= 2;
else
pos = 0;
while (fn[pos] != _TEXT(DIR_SEPARATOR) && pos > 0)
--pos;
switch(fn[next_dir])
{
case DIR_SEPARATOR:
_tmemmove(fn+pos,fn+next_dir,((sz - next_dir) + 1) * tsize);
break;
case 0:
/* If we have /.. ending the filename */
fn[pos+1] = 0;
break;
/* If we have ..foo, we should do nothing, but skip
over these double dots */
default:
pos = next_dir;
}
}
}
/* If we have two dots starting off the string, we should prepend
a DIR_SEPARATOR and ignore the two dots. That is:
from the root directory the path ../foo is really just /foo */
else
{
fn[pos] = _TEXT(DIR_SEPARATOR);
_tmemmove(fn+pos+1,fn+pos+3,sz-(pos+3));
}
}
}
}
// We don't need to call these functions when running in Windows
// as we've already called real_path() on them in main.c. These
// functions are necessary in *nix so that we can clean up the
// path names without removing the names of symbolic links. They
// are also called when the user has specified an absolute path
// but has included extra double dots or such.
static void clean_name(state *s, TCHAR *fn)
{
if (not (s->mode & mode_relative)) {
remove_double_slash(fn);
remove_single_dirs(fn);
remove_double_dirs(fn);
}
}
static int process_dir(state *s, TCHAR *fn)
{
int return_value = STATUS_OK;
TCHAR *new_file;
_TDIR *current_dir;
struct _tdirent *entry;
if (have_processed_dir(fn))
{
print_error_unicode(s,fn,"symlink creates cycle");
return STATUS_OK;
}
if (!processing_dir(fn))
internal_error("%s: Cycle checking failed to register directory.", fn);
if ((current_dir = _topendir(fn)) == NULL)
{
print_error_unicode(s,fn,"%s", strerror(errno));
return STATUS_OK;
}
new_file = (TCHAR *)malloc(sizeof(TCHAR) * SSDEEP_PATH_MAX);
if (NULL == new_file)
internal_error("%s: Out of memory", __progname);
while ((entry = _treaddir(current_dir)) != NULL)
{
if (is_special_dir(entry->d_name))
continue;
_sntprintf(new_file,SSDEEP_PATH_MAX,_TEXT("%s%c%s"),
fn,DIR_SEPARATOR,entry->d_name);
return_value = process_normal(s,new_file);
}
free(new_file);
_tclosedir(current_dir);
if (!done_processing_dir(fn))
internal_error("%s: Cycle checking failed to unregister directory.", fn);
return return_value;
}
static int file_type_helper(_tstat_t sb)
{
if (S_ISREG(sb.st_mode))
return file_regular;
if (S_ISDIR(sb.st_mode))
return file_directory;
if (S_ISBLK(sb.st_mode))
return file_block;
if (S_ISCHR(sb.st_mode))
return file_character;
if (S_ISFIFO(sb.st_mode))
return file_pipe;
/* These file types do not exist in Win32 */
#ifndef _WIN32
if (S_ISSOCK(sb.st_mode))
return file_socket;
if (S_ISLNK(sb.st_mode))
return file_symlink;
#endif /* ifndef _WIN32 */
/* Used to detect Solaris doors */
#ifdef S_IFDOOR
#ifdef S_ISDOOR
if (S_ISDOOR(sb.st_mode))
return file_door;
#endif
#endif
return file_unknown;
}
static int file_type(state *s, TCHAR *fn)
{
_tstat_t sb;
if (NULL == s || NULL == fn)
return file_unknown;
if (_lstat(fn,&sb))
{
print_error_unicode(s,fn,"%s", strerror(errno));
return file_unknown;
}
return file_type_helper(sb);
}
static int should_hash_symlink(state *s, TCHAR *fn, int *link_type)
{
int type;
_tstat_t sb;
if (NULL == s || NULL == fn)
fatal_error("%s: Null state passed into should_hash_symlink", __progname);
// We must look at what this symlink points to before we process it.
// The normal file_type function uses lstat to examine the file,
// we use stat to examine what this symlink points to.
if (_sstat(fn,&sb))
{
print_error_unicode(s,fn,"%s",strerror(errno));
return FALSE;
}
type = file_type_helper(sb);
if (type == file_directory)
{
if (s->mode & mode_recursive)
process_dir(s,fn);
else
{
print_error_unicode(s,fn,"Is a directory");
}
return FALSE;
}
if (link_type != NULL)
*link_type = type;
return TRUE;
}
#define RETURN_IF_MODE(A) \
if (s->mode & A) \
return TRUE; \
break;
static int should_hash(state *s, TCHAR *fn)
{
int type = file_type(s, fn);
if (NULL == s || NULL == fn)
fatal_error("%s: Null state passed into should_hash", __progname);
if (type == file_directory)
{
if (s->mode & mode_recursive)
process_dir(s,fn);
else
{
print_error_unicode(s,fn,"Is a directory");
}
return FALSE;
}
if (type == file_symlink)
return should_hash_symlink(s,fn,NULL);
if (type == file_unknown)
return FALSE;
// By default we hash anything we can't identify as a "bad thing"
return TRUE;
}
int process_normal(state *s, TCHAR *fn)
{
clean_name(s,fn);
if (should_hash(s,fn))
return (hash_file(s,fn));
return FALSE;
}
#endif // ifndef _WIN32
/// The largest number of bytes we can process from stdin
/// This limit is arbitrary and can be adjusted at will
#define MAX_STDIN_BUFFER 536870912
#define MAX_STDIN_BUFFER_STR "512 MB"
int process_stdin(state *s)
{
if (NULL == s)
return TRUE;
char sum[FUZZY_MAX_RESULT];
unsigned char * buffer = (unsigned char *)malloc(sizeof(unsigned char ) * MAX_STDIN_BUFFER);
if (NULL == buffer)
return TRUE;
memset(buffer,0,MAX_STDIN_BUFFER);
size_t sz = fread(buffer, 1, MAX_STDIN_BUFFER, stdin);
if (MAX_STDIN_BUFFER == sz)
{
print_error(s,
"%s: Only processed the first %s presented on stdin.",
__progname,
MAX_STDIN_BUFFER_STR);
}
int status = fuzzy_hash_buf(buffer, (uint32_t)sz, sum);
free(buffer);
if (status != 0)
{
print_error_unicode(s,_TEXT("stdin"),"Error processing stdin");
return TRUE;
}
display_result(s,_TEXT("stdin"),sum);
return FALSE;
}
#ifdef _WIN32
static int is_win32_device_file(TCHAR *fn)
{
/* Specifications for device files came from
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/createfile.asp
-- Physical devices (like hard drives) are
\\.\PhysicalDriveX where X is a digit from 0 to 9
-- Tape devices is \\.\tapeX where X is a digit from 0 to 9
-- Logical volumes is \\.\X: where X is a letter */
if (!_tcsnicmp(fn, _TEXT("\\\\.\\physicaldrive"),17) &&
(_tcslen(fn) == 18) &&
isdigit(fn[17]))
return TRUE;
if (!_tcsnicmp(fn, _TEXT("\\\\.\\tape"),8) &&
(_tcslen(fn) == 9) &&
isdigit(fn[8]))
return TRUE;
if ((!_tcsnicmp(fn,_TEXT("\\\\.\\"),4)) &&
(_tcslen(fn) == 6) &&
(isalpha(fn[4])) &&
(fn[5] == ':'))
return TRUE;
return FALSE;
}
bool process_dir_win32(state *s, TCHAR *fn) {
TCHAR new_fn[SSDEEP_PATH_MAX];
if (have_processed_dir(fn)) {
print_error_unicode(s, fn, "Cycle detected");
return true;
}
processing_dir(fn);
_sntprintf(new_fn,
SSDEEP_PATH_MAX,
_TEXT("%s\\*"),
fn);
process_win32(s, new_fn);
done_processing_dir(fn);
return false;
}
bool process_win32(state *s, TCHAR *fn)
{
int rc;
size_t len;
HANDLE hFind;
TCHAR dirname[SSDEEP_PATH_MAX], new_fn[SSDEEP_PATH_MAX], expanded_fn[SSDEEP_PATH_MAX];
WIN32_FIND_DATAW FindFileData;
if (NULL == s or NULL == fn)
return true;
//print_status("process_win32 got %S", fn);
if (is_win32_device_file(fn))
return hash_file(s, fn);
if (is_special_dir(fn))
return false;
// Most Win32 programs reject 'c:'
// as an error or use it to alias the current working directory on c:.
// As a convenience to users, we're going to accept 'c:'. To do this
// we change it into 'c:\'
if (_tcslen(fn) == 2 and isalpha(fn[0]) and fn[1] == _TEXT(':')) {
fn[2] = _TEXT(DIR_SEPARATOR);
fn[3] = 0;
}
// FindFirstFile doesn't accept '\' as the trailing character.
// If we get '\' as a trailing character, we assume this is a directory
// and handle that according. In recursive mode, go through the directory
// entries. Otherwise, return an error.
len = _tcslen(fn);
if (fn[len-1] == _TEXT(DIR_SEPARATOR)) {
if (s->mode & mode_recursive) {
fn[len] = _TEXT('*');
fn[len+1] = 0;
} else {
print_error_unicode(s, fn, "Is a directory");
return false;
}
}
//print_status("cleaned name %S", fn);
// If we don't have it already, create the expanded filename.
// "C:\foo\bar.txt" --> "\\?\C:\foo\bar.txt"
if (not expanded_path(fn) and
not (s->mode & mode_relative)) {
_sntprintf(expanded_fn,
SSDEEP_PATH_MAX,
_TEXT("\\\\?\\%s"),
fn);
}
else {
_tcsncpy(expanded_fn, fn, SSDEEP_PATH_MAX);
}
//print_status("expanded filename %S", expanded_fn);
hFind = FindFirstFile(expanded_fn, &FindFileData);
if (INVALID_HANDLE_VALUE == hFind)
{
// We don't display an error if there was a wildcard anywhere in the
// original filename, e.g. C:\foo\*. When this happens it means we just
// didn't find any matching files.
// Note that we still display errors with the original 'fn'
if (not _tcsstr(fn, _TEXT("*")))
print_error_unicode(s, fn, "No such file or directory");
return false;
}
_tcsncpy(dirname, fn, SSDEEP_PATH_MAX);
my_dirname(dirname);
do {
// The filename we've found doesn't include any path information.
// That is, for the file C:\foo\bar.txt, we have bar.txt.
// We have to add the path information back in manually.
// Thankfully Windows doesn't allow wildcards in the early part
// of the path. For example, we will never see: c:\bin\*\tools
//
// Because the wildcard is always in the last part of the input
// (e.g. c:\bin\*.exe) we can use the original dirname, combined
// with the filename we've found, to make the new filename.
if (not is_special_dir(FindFileData.cFileName)) {
// print_status("Found file: %S", FindFileData.cFileName);
_sntprintf(new_fn,
SSDEEP_PATH_MAX,
_TEXT("%s%s"),
dirname,
FindFileData.cFileName);
if (not expanded_path(new_fn) and
not (s->mode & mode_relative)) {
_sntprintf(expanded_fn,
SSDEEP_PATH_MAX,
_TEXT("\\\\?\\%s"),
new_fn);
} else {
_tcsncpy(expanded_fn, new_fn, SSDEEP_PATH_MAX);
}
// print_status("Getting attributes for %S", expanded_fn);
DWORD dwFileAttributes = FindFileData.dwFileAttributes;
if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) {
print_error_unicode(s, new_fn, "File read error");
} else if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (s->mode & mode_recursive) {
process_dir_win32(s, new_fn);
}
// TODO Add support for symbolic links
/*
} else if (dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
// Generally we skip reparse points (e.g. symbolic links,
// junction points, etc) UNLESS it's part of single
// instance storage. Single Instance Storage "is a system's
// ability to keep one copy of content that multiple users
// or computers share". See
// http://blogs.technet.com/b/filecab/archive/2006/02/03/single-instance-store-sis-in-windows-storage-server-r2.aspx
switch (FindFileData.dwReserved0) {
case IO_REPARSE_TAG_MOUNT_POINT:
print_error_unicode(s, new_fn, "Junction point, skipping.");
break;
case IO_REPARSE_TAG_SYMLINK:
print_error_unicode(s, new_fn, "Symbolic link, skipping.");
break;
case IO_REPARSE_TAG_SIS:
hash_file(s, new_fn);
break;
default:
print_error_unicode(s,
new_fn,
"Unknown reparse point 0x%"PRIx32", skipping. Please report this to the developers",
FindFileData.dwReserved0);
break;
}
*/
} else {
hash_file(s, new_fn);
}
}
rc = FindNextFile(hFind, &FindFileData);
} while (rc != 0);
if (GetLastError() != ERROR_NO_MORE_FILES) {
// The Windows API for getting an intelligible error message
// is beserk. Rather than play their silly games, we
// acknowledge that an unknown error occured and hope we
// can continue.
print_error_unicode(s, new_fn, "Unknown error during directory traversal");
return true;
}
rc = FindClose(hFind);
if (0 == rc) {
print_error_unicode(s, fn, "Unknown error cleaning up directory traversal");
}
return false;
}
#endif
/*
This edit distance code is taken from trn3.6. A few minor
modifications have been made by Andrew Tridgell <tridge@samba.org>
for use in spamsum.
*/
/***************************************************************************/
/* The authors make no claims as to the fitness or correctness of this software
* for any use whatsoever, and it is provided as is. Any use of this software
* is at the user's own risk.
*/
#include <stdio.h>
#include <stdlib.h>
/* edit_dist -- returns the minimum edit distance between two strings
Program by: Mark Maimone CMU Computer Science 13 Nov 89
Last Modified: 28 Jan 90
If the input strings have length n and m, the algorithm runs in time
O(nm) and space O(min(m,n)).
HISTORY
13 Nov 89 (mwm) Created edit_dist() and set_costs().
28 Jan 90 (mwm) Added view_costs(). Should verify that THRESHOLD
computations will work even when THRESHOLD is not a multiple of
sizeof(int).
17 May 93 (mwm) Improved performance when used with trn's newsgroup
processing; assume all costs are 1, and you can terminate when a
threshold is exceeded.
*/
#define MIN_DIST 100
#define TRN_SPEEDUP /* Use a less-general version of the
routine, one that's better for trn.
All change costs are 1, and it's okay
to terminate if the edit distance is
known to exceed MIN_DIST */
#define THRESHOLD 4000 /* worry about allocating more memory only
when this # of bytes is exceeded */
#define STRLENTHRESHOLD ((int) ((THRESHOLD / sizeof (int) - 3) / 2))
#define SAFE_ASSIGN(x,y) (((x) != NULL) ? (*(x) = (y)) : (y))
#define swap_int(x,y) do { int _iswap = (x); (x) = (y); (y) = _iswap; } while (0)
#define swap_char(x,y) do { const char *_cswap = (x); (x) = (y); (y) = _cswap; } while (0)
static inline int min3(int x, int y, int z) {
return x < y ? (x < z ? x : z) : (z < y) ? z : y;
}
static inline int min2(int x, int y)
{
return x < y ? x : y;
}
static int insert_cost = 1;
static int delete_cost = 1;
#ifndef TRN_SPEEDUP
static int change_cost = 1;
static int swap_cost = 1;
#endif
/* edit_distn -- returns the edit distance between two strings, or -1 on
failure */
int
edit_distn(const char *from, int from_len, const char *to, int to_len)
{
#ifndef TRN_SPEEDUP
register int ins, del, ch; /* local copies of edit costs */
#endif
register int row, col, index; /* dynamic programming counters */
register int radix; /* radix for modular indexing */
#ifdef TRN_SPEEDUP
register int low;
#endif
int *buffer; /* pointer to storage for one row
of the d.p. array */
int store[THRESHOLD / sizeof (int)];
/* a small amount of static
storage, to be used when the
input strings are small enough */
/* Handle trivial cases when one string is empty */
if (from == NULL || !from_len)
if (to == NULL || !to_len)
return 0;
else
return to_len * insert_cost;
else if (to == NULL || !to_len)
return from_len * delete_cost;
/* Initialize registers */
radix = 2 * from_len + 3;
#ifdef TRN_SPEEDUP
#define ins 1
#define del 1
#define ch 3
#define swap_cost 5
#else
ins = insert_cost;
del = delete_cost;
ch = change_cost;
#endif
/* Make from short enough to fit in the static storage, if it's at all
possible */
if (from_len > to_len && from_len > STRLENTHRESHOLD) {
swap_int(from_len, to_len);
swap_char(from, to);
#ifndef TRN_SPEEDUP
swap_int(ins, del);
#endif
} /* if from_len > to_len */
/* Allocate the array storage (from the heap if necessary) */
if (from_len <= STRLENTHRESHOLD)
buffer = store;
else
buffer = (int *) malloc(radix * sizeof (int));
/* Here's where the fun begins. We will find the minimum edit distance
using dynamic programming. We only need to store two rows of the matrix
at a time, since we always progress down the matrix. For example,
given the strings "one" and "two", and insert, delete and change costs
equal to 1:
_ o n e
_ 0 1 2 3
t 1 1 2 3
w 2 2 2 3
o 3 2 3 3
The dynamic programming recursion is defined as follows:
ar(x,0) := x * insert_cost
ar(0,y) := y * delete_cost
ar(x,y) := min(a(x - 1, y - 1) + (from[x] == to[y] ? 0 : change),
a(x - 1, y) + insert_cost,
a(x, y - 1) + delete_cost,
a(x - 2, y - 2) + (from[x] == to[y-1] &&
from[x-1] == to[y] ? swap_cost :
infinity))
Since this only looks at most two rows and three columns back, we need
only store the values for the two preceeding rows. In this
implementation, we do not explicitly store the zero column, so only 2 *
from_len + 2 words are needed. However, in the implementation of the
swap_cost check, the current matrix value is used as a buffer; we
can't overwrite the earlier value until the swap_cost check has
been performed. So we use 2 * from_len + 3 elements in the buffer.
*/
#define ar(x,y,index) (((x) == 0) ? (y) * del : (((y) == 0) ? (x) * ins : \
buffer[mod(index)]))
#define NW(x,y) ar(x, y, index + from_len + 2)
#define N(x,y) ar(x, y, index + from_len + 3)
#define W(x,y) ar(x, y, index + radix - 1)
#define NNWW(x,y) ar(x, y, index + 1)
#define mod(x) ((x) % radix)
index = 0;
#ifdef DEBUG_EDITDIST
printf(" ");
for (col = 0; col < from_len; col++)
printf(" %c ", from[col]);
printf("\n ");
for (col = 0; col <= from_len; col++)
printf("%2d ", col * del);
#endif
/* Row 0 is handled implicitly; its value at a given column is col*del.
The loop below computes the values for Row 1. At this point we know the
strings are nonempty. We also don't need to consider swap costs in row
1.
COMMENT: the indicies row and col below point into the STRING, so
the corresponding MATRIX indicies are row+1 and col+1.
*/
buffer[index++] = min2(ins + del, (from[0] == to[0] ? 0 : ch));
#ifdef TRN_SPEEDUP
low = buffer[mod(index + radix - 1)];
#endif
#ifdef DEBUG_EDITDIST
printf("\n %c %2d %2d ", to[0], ins, buffer[index - 1]);
#endif
for (col = 1; col < from_len; col++) {
buffer[index] = min3(
col * del + ((from[col] == to[0]) ? 0 : ch),
(col + 1) * del + ins,
buffer[index - 1] + del);
#ifdef TRN_SPEEDUP
if (buffer[index] < low)
low = buffer[index];
#endif
index++;
#ifdef DEBUG_EDITDIST
printf("%2d ", buffer[index - 1]);
#endif
} /* for col = 1 */
#ifdef DEBUG_EDITDIST
printf("\n %c %2d ", to[1], 2 * ins);
#endif
/* Now handle the rest of the matrix */
for (row = 1; row < to_len; row++) {
for (col = 0; col < from_len; col++) {
buffer[index] = min3(
NW(row, col) + ((from[col] == to[row]) ? 0 : ch),
N(row, col + 1) + ins,
W(row + 1, col) + del);
if (from[col] == to[row - 1] && col > 0 &&
from[col - 1] == to[row])
buffer[index] = min2(buffer[index],
NNWW(row - 1, col - 1) + swap_cost);
#ifdef DEBUG_EDITDIST
printf("%2d ", buffer[index]);
#endif
#ifdef TRN_SPEEDUP
if (buffer[index] < low || col == 0)
low = buffer[index];
#endif
index = mod(index + 1);
} /* for col = 1 */
#ifdef DEBUG_EDITDIST
if (row < to_len - 1)
printf("\n %c %2d ", to[row+1], (row + 2) * ins);
else
printf("\n");
#endif
#ifdef TRN_SPEEDUP
if (low > MIN_DIST)
break;
#endif
} /* for row = 1 */
row = buffer[mod(index + radix - 1)];
if (buffer != store)
free((char *) buffer);
return row;
} /* edit_distn */
// $Id: engine.cpp 184 2013-07-10 05:24:26Z jessekornblum $
#include "main.h"
#include "ssdeep.h"
#include "match.h"
#define MAX_STATUS_MSG 78
bool display_result(state *s, const TCHAR * fn, const char * sum)
{
// Only spend the extra time to make a Filedata object if we need to
if (MODE(mode_match_pretty) or MODE(mode_match) or MODE(mode_directory))
{
Filedata * f;
try
{
f = new Filedata(fn, sum);
}
catch (std::bad_alloc)
{
fatal_error("%s: Unable to create Filedata object in engine.cpp:display_result()", __progname);
}
if (MODE(mode_match_pretty))
{
if (match_add(s,f))
print_error_unicode(s,fn,"Unable to add hash to set of known hashes");
}
else
{
// This block is for MODE(mode_match) or MODE(mode_directory)
match_compare(s,f);
if (MODE(mode_directory))
if (match_add(s,f))
print_error_unicode(s,
fn,
"Unable to add hash to set of known hashes");
}
}
else
{
// No special options selected. Display the hash for this file
if (s->first_file_processed)
{
print_status("%s", OUTPUT_FILE_HEADER);
s->first_file_processed = false;
}
printf ("%s,\"", sum);
display_filename(stdout,fn,TRUE);
print_status("\"");
}
return false;
}
int hash_file(state *s, TCHAR *fn)
{
size_t fn_length;
char *sum;
TCHAR *my_filename, *msg;
FILE *handle;
#ifdef WIN32
TCHAR expanded_fn[SSDEEP_PATH_MAX];
if (not expanded_path(fn)) {
_sntprintf(expanded_fn,
SSDEEP_PATH_MAX,
_TEXT("\\\\?\\%s"),
fn);
} else {
_tcsncpy(expanded_fn, fn, SSDEEP_PATH_MAX);
}
handle = _tfopen(expanded_fn, _TEXT("rb"));
# else
handle = fopen(fn, "rb");
#endif
if (NULL == handle)
{
print_error_unicode(s,fn,"%s", strerror(errno));
return TRUE;
}
if ((sum = (char *)malloc(sizeof(char) * FUZZY_MAX_RESULT)) == NULL)
{
fclose(handle);
print_error_unicode(s,fn,"%s", strerror(errno));
return TRUE;
}
if ((msg = (TCHAR *)malloc(sizeof(TCHAR) * (MAX_STATUS_MSG + 2))) == NULL)
{
free(sum);
fclose(handle);
print_error_unicode(s,fn,"%s", strerror(errno));
return TRUE;
}
if (MODE(mode_verbose))
{
fn_length = _tcslen(fn);
if (fn_length > MAX_STATUS_MSG)
{
// We have to make a duplicate of the string to call basename on it
// We need the original name for the output later on
my_filename = _tcsdup(fn);
my_basename(my_filename);
}
else
my_filename = fn;
_sntprintf(msg,
MAX_STATUS_MSG-1,
_TEXT("Hashing: %s%s"),
my_filename,
_TEXT(BLANK_LINE));
_ftprintf(stderr,_TEXT("%s\r"), msg);
if (fn_length > MAX_STATUS_MSG)
free(my_filename);
}
fuzzy_hash_file(handle,sum);
prepare_filename(s,fn);
display_result(s,fn,sum);
if (find_file_size(handle) > SSDEEP_MIN_FILE_SIZE)
s->found_meaningful_file = true;
s->processed_file = true;
fclose(handle);
free(sum);
free(msg);
return FALSE;
}
// SSDEEP
// $Id: filedata.cpp 163 2012-07-17 19:59:54Z jessekornblum $
// Copyright (C) 2012 Kyrus. See COPYING for details.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "filedata.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
bool Filedata::valid(void) const
{
// A valid fuzzy hash has the form
// [blocksize]:[sig1]:[sig2]
// with no filename at the end
// First find the block size
const char * sig = m_signature.c_str();
unsigned int block_size;
if (-1 == sscanf(sig, "%u:", &block_size))
return false;
// Move past the blocksize
sig = strchr(sig,':');
if (!sig)
return false;
// Move past the first colon and Look for the second colon
++sig;
sig = strchr(sig,':');
if (!sig)
return false;
// Finally, a valid signature does *not* have a filename at the end of it
sig = strchr(sig,',');
if (sig)
return false;
return true;
}
void Filedata::clear_cluster(void)
{
if (NULL == m_cluster)
return;
// We don't want to call the destructors on the individual elements
// so we have to clear the set first.
m_cluster->clear();
m_cluster = NULL;
}
Filedata::Filedata(const TCHAR *fn, const char * sig, const char * match_file)
{
m_signature = std::string(sig);
if (not valid())
throw std::bad_alloc();
m_filename = _tcsdup(fn);
m_cluster = NULL;
if (NULL == match_file)
m_has_match_file = false;
else
{
m_has_match_file = true;
m_match_file = std::string(match_file);
}
}
Filedata::Filedata(const std::string sig, const char * match_file)
{
// Set the easy stuff first
m_cluster = NULL;
if (NULL == match_file)
m_has_match_file = false;
else
{
m_has_match_file = true;
m_match_file = std::string(match_file);
}
// If we don't have a filename included with the sig, that's ok,
// but we should find out now.
// If there is a filename, it should be immediately after the
// first comma and enclosed in quotation marks.
size_t start, stop;
start = sig.find_first_of(",\"");
if (std::string::npos == start)
{
// There is no filename. Ok. We still have a valid Filedata.
m_filename = _tcsdup(_TEXT("[NO FILENAME]"));
m_signature = std::string(sig);
// We still have to check the validity of the signature
if (not valid())
throw std::bad_alloc();
return;
}
// There is a filename. Ok.
// Advance past the comma and quotation mark.
start += 2;
// Look for the second quotation mark, which should be at the end
// of the string.
stop = sig.find_last_of('"');
if (stop != sig.size() - 1)
throw std::bad_alloc();
// Strip off the final quotation mark and record the filename
std::string tmp = sig.substr(start,(stop - start));
// Strip off the filename from the signature. Remember that "start"
// now points to two characters ahead of the comma
m_signature = sig.substr(0,start-2);
// Unescape any quotation marks in the filename
while (tmp.find(std::string("\\\"")) != std::string::npos)
tmp.replace(tmp.find(std::string("\\\"")),2,std::string("\""));
#ifndef _WIN32
m_filename = strdup(tmp.c_str());
#else
char * tmp2 = strdup(tmp.c_str());
// On Win32 we have to do a kludgy cast from ordinary char
// values to the TCHAR values we use internally. Because we may have
// reset the string length, get it again.
// The extra +1 is for the terminating newline
size_t i, sz = strlen(tmp2);
m_filename = (TCHAR *)malloc(sizeof(TCHAR) * (sz + 1));
if (NULL == m_filename)
throw std::bad_alloc();
for (i = 0 ; i < sz ; i++)
m_filename[i] = (TCHAR)(tmp2[i]);
m_filename[i] = 0;
#endif
}
std::ostream& operator<<(std::ostream& o, const Filedata& f)
{
return o << f.get_signature() << "," << f.get_filename() << ",";
}
bool operator==(const Filedata& a, const Filedata& b)
{
if (a.get_signature() != b.get_signature())
return false;
if (a.has_match_file() and not b.has_match_file())
return false;
if (not a.has_match_file() and b.has_match_file())
return false;
if (a.has_match_file() and b.has_match_file())
{
if (a.get_match_file() != b.get_match_file())
return false;
}
return true;
}
#ifndef __FILEDATA_H
#define __FILEDATA_H
/// @file filedata.h
// Copyright (C) 2012 Kyrus. See COPYING for details
// $Id: filedata.h 160 2012-07-17 01:00:07Z jessekornblum $
#include <set>
#include <string>
#include <iostream>
#include "tchar-local.h"
/// Contains a fuzzy hash and associated metadata for file
class Filedata
{
public:
Filedata() : m_has_match_file(false) {}
/// Creates a new Filedata object with the given filename and signature
///
/// If sig is not valid, throws std::bad_alloc
Filedata(const TCHAR * fn, const char * sig, const char * match_file = NULL);
/// Creates a new Filedata object with the given filename and signature
///
/// If sig is not valid, throws std::bad_alloc
Filedata(const std::string sig, const char * match_file = NULL);
/// Returns the file's fuzzy hash without a filename.
/// std::string("[blocksize]:[sig1]:[sig2]")
std::string get_signature(void) const { return m_signature; }
/// Returns the file's name
/// RBF - Should this be a std::wstring?
TCHAR * get_filename(void) const { return m_filename; }
/// Returns true if this file came from a file of known files on the disk
bool has_match_file(void) const { return m_has_match_file; }
/// Returns the name of the file on the disk from which this file came
/// RBF - Should this be a std::wstring?
std::string get_match_file(void) const { return m_match_file; }
/// Returns true if this file belongs to a cluster of similar files
bool has_cluster(void) const { return (m_cluster != NULL); }
void set_cluster(std::set<Filedata *> *c) { m_cluster = c; }
std::set<Filedata* >* get_cluster(void) const { return m_cluster; }
void clear_cluster(void);
private:
std::set<Filedata *> * m_cluster;
/// Original signature in the form [blocksize]:[sig1]:[sig2]
/// It may also contain the filename, but there is no guarantee of that
/// one way or the other.
std::string m_signature;
/// RBF - Should this be a std::wstring?
TCHAR * m_filename;
/// File of hashes where we got this known file from, if any
std::string m_match_file;
bool m_has_match_file;
/// Returns true if the m_signature field contains a valid fuzzy hash
bool valid(void) const;
};
/// Display [blocksize]:[sig1]:[sig2],"filename"
std::ostream& operator<<(std::ostream& o, const Filedata& f);
/// RBF - We can use this IF AND ONLY IF get_filename() returns a std::wstring
//bool operator==(const Filedata& a, const Filedata& b);
#endif // ifndef __FILEDATA_H
// Fuzzy Hashing by Jesse Kornblum
// Copyright (C) 2012 Kyrus
// Copyright (C) 2008 ManTech International Corporation
//
// $Id: find-file-size.c 144 2012-04-24 14:59:33Z jessekornblum $
//
#include "main.h"
#ifndef _WIN32
// Return the size, in bytes of an open file stream. On error, return 0
#if defined (__LINUX__)
off_t find_file_size(FILE *f)
{
off_t num_sectors = 0, sector_size = 0;
int fd = fileno(f);
struct stat sb;
if (fstat(fd,&sb))
return 0;
if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode))
return sb.st_size;
#ifdef HAVE_SYS_IOCTL_H
#ifdef HAVE_SYS_MOUNT_H
if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode))
{
#if defined(_IO) && defined(BLKGETSIZE)
if (ioctl(fd, BLKGETSIZE, &num_sectors))
{
return 0;
}
#else
// If we can't run the ioctl call, we can't do anything here
return 0;
#endif // ifdefined _IO and BLKGETSIZE
#if defined(_IO) && defined(BLKSSZGET)
if (ioctl(fd, BLKSSZGET, &sector_size))
{
return 0;
}
if (0 == sector_size)
sector_size = 512;
#else
sector_size = 512;
#endif // ifdef _IO and BLKSSZGET
return (num_sectors * sector_size);
}
#endif // #ifdef HAVE_SYS_MOUNT_H
#endif // #ifdef HAVE_SYS_IOCTL_H
return 0;
}
#elif defined (__APPLE__)
off_t find_file_size(FILE *f) {
struct stat info;
off_t total = 0;
off_t original = ftello(f);
int fd = fileno(f);
uint32_t blocksize = 0;
uint64_t blockcount = 0;
// I'd prefer not to use fstat as it will follow symbolic links. We don't
// follow symbolic links. That being said, all symbolic links *should*
// have been caught before we got here.
if (fstat(fd, &info))
{
return 0;
}
#ifdef HAVE_SYS_IOCTL_H
// Block devices, like /dev/hda, don't return a normal filesize.
// If we are working with a block device, we have to ask the operating
// system to tell us the true size of the device.
//
// This isn't the recommended way to do check for block devices,
// but using S_ISBLK(info.stmode) wasn't working.
if (info.st_mode & S_IFBLK)
{
// Get the block size
if (ioctl(fd, DKIOCGETBLOCKSIZE,&blocksize) < 0)
{
return 0;
}
// Get the number of blocks
if (ioctl(fd, DKIOCGETBLOCKCOUNT, &blockcount) < 0)
{
}
total = blocksize * blockcount;
}
#endif // ifdef HAVE_IOCTL_H
else
{
if ((fseeko(f,0,SEEK_END)))
return 0;
total = ftello(f);
if ((fseeko(f,original,SEEK_SET)))
return 0;
}
return (total - original);
}
#else // ifdef __APPLE__
// This is code for general UNIX systems
// (e.g. NetBSD, FreeBSD, OpenBSD, etc)
static off_t
midpoint (off_t a, off_t b, long blksize)
{
off_t aprime = a / blksize;
off_t bprime = b / blksize;
off_t c, cprime;
cprime = (bprime - aprime) / 2 + aprime;
c = cprime * blksize;
return c;
}
off_t find_dev_size(int fd, int blk_size)
{
off_t curr = 0, amount = 0;
void *buf;
if (blk_size == 0)
return 0;
buf = malloc(blk_size);
for (;;) {
ssize_t nread;
lseek(fd, curr, SEEK_SET);
nread = read(fd, buf, blk_size);
if (nread < blk_size)
{
if (nread <= 0)
{
if (curr == amount)
{
free(buf);
lseek(fd, 0, SEEK_SET);
return amount;
}
curr = midpoint(amount, curr, blk_size);
}
else
{ // 0 < nread < blk_size
free(buf);
lseek(fd, 0, SEEK_SET);
return amount + nread;
}
}
else
{
amount = curr + blk_size;
curr = amount * 2;
}
}
free(buf);
lseek(fd, 0, SEEK_SET);
return amount;
}
off_t find_file_size(FILE *f)
{
int fd = fileno(f);
struct stat sb;
if (fstat(fd,&sb))
return 0;
if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode))
return sb.st_size;
else if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode))
return find_dev_size(fd,sb.st_blksize);
return 0;
}
#endif // ifdef __LINUX__
#endif // ifndef _WIN32
#if defined(_WIN32)
off_t find_file_size(FILE *f)
{
off_t total = 0, original = ftello(f);
// Windows does not support running fstat on block devices,
// so there's no point in mucking about with them.
if ((fseeko(f,0,SEEK_END)))
return 0;
total = ftello(f);
if ((fseeko(f,original,SEEK_SET)))
return 0;
return total;
}
#endif // ifdef _WIN32
/* ssdeep
* Copyright (C) 2002 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2006 ManTech International Corporation
* Copyright (C) 2013 Helmut Grohne <helmut@subdivi.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Earlier versions of this code were named fuzzy.c and can be found at:
* http://www.samba.org/ftp/unpacked/junkcode/spamsum/
* http://ssdeep.sf.net/
*/
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fuzzy.h"
#if defined(__GNUC__) && __GNUC__ >= 3
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) x
#define unlikely(x) x
#endif
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#define ROLLING_WINDOW 7
#define MIN_BLOCKSIZE 3
#define HASH_PRIME 0x01000193
#define HASH_INIT 0x28021967
#define NUM_BLOCKHASHES 31
struct roll_state {
unsigned char window[ROLLING_WINDOW];
uint32_t h1, h2, h3;
uint32_t n;
};
static void roll_init(/*@out@*/ struct roll_state *self) {
memset(self, 0, sizeof(struct roll_state));
}
/*
* a rolling hash, based on the Adler checksum. By using a rolling hash
* we can perform auto resynchronisation after inserts/deletes
* internally, h1 is the sum of the bytes in the window and h2
* is the sum of the bytes times the index
* h3 is a shift/xor based rolling hash, and is mostly needed to ensure that
* we can cope with large blocksize values
*/
static void roll_hash(struct roll_state *self, unsigned char c)
{
self->h2 -= self->h1;
self->h2 += ROLLING_WINDOW * (uint32_t)c;
self->h1 += (uint32_t)c;
self->h1 -= (uint32_t)self->window[self->n % ROLLING_WINDOW];
self->window[self->n % ROLLING_WINDOW] = c;
self->n++;
/* The original spamsum AND'ed this value with 0xFFFFFFFF which
* in theory should have no effect. This AND has been removed
* for performance (jk) */
self->h3 <<= 5;
self->h3 ^= c;
}
static uint32_t roll_sum(const struct roll_state *self)
{
return self->h1 + self->h2 + self->h3;
}
/* A simple non-rolling hash, based on the FNV hash. */
static uint32_t sum_hash(unsigned char c, uint32_t h)
{
return (h * HASH_PRIME) ^ c;
}
/* A blockhash contains a signature state for a specific (implicit) blocksize.
* The blocksize is given by SSDEEP_BS(index). The h and halfh members are the
* FNV hashes, where halfh stops to be reset after digest is SPAMSUM_LENGTH/2
* long. The halfh hash is needed be able to truncate digest for the second
* output hash to stay compatible with ssdeep output. */
struct blockhash_context
{
uint32_t h, halfh;
char digest[SPAMSUM_LENGTH];
unsigned int dlen;
};
struct fuzzy_state
{
unsigned int bhstart, bhend;
struct blockhash_context bh[NUM_BLOCKHASHES];
size_t total_size;
struct roll_state roll;
};
#define SSDEEP_BS(index) (((uint32_t)MIN_BLOCKSIZE) << (index))
/*@only@*/ /*@null@*/ struct fuzzy_state *fuzzy_new(void)
{
struct fuzzy_state *self;
if(NULL == (self = malloc(sizeof(struct fuzzy_state))))
/* malloc sets ENOMEM */
return NULL;
self->bhstart = 0;
self->bhend = 1;
self->bh[0].h = HASH_INIT;
self->bh[0].halfh = HASH_INIT;
self->bh[0].dlen = 0;
self->total_size = 0;
roll_init(&self->roll);
return self;
}
static void fuzzy_try_fork_blockhash(struct fuzzy_state *self)
{
struct blockhash_context *obh, *nbh;
if (self->bhend >= NUM_BLOCKHASHES)
return;
assert(self->bhend > 0);
obh = self->bh + (self->bhend - 1);
nbh = obh + 1;
nbh->h = obh->h;
nbh->halfh = obh->halfh;
nbh->dlen = 0;
++self->bhend;
}
static void fuzzy_try_reduce_blockhash(struct fuzzy_state *self)
{
assert(self->bhstart < self->bhend);
if (self->bhend - self->bhstart < 2)
/* Need at least two working hashes. */
return;
if ((size_t)SSDEEP_BS(self->bhstart) * SPAMSUM_LENGTH >=
self->total_size)
/* Initial blocksize estimate would select this or a smaller
* blocksize. */
return;
if (self->bh[self->bhstart + 1].dlen < SPAMSUM_LENGTH / 2)
/* Estimate adjustment would select this blocksize. */
return;
/* At this point we are clearly no longer interested in the
* start_blocksize. Get rid of it. */
++self->bhstart;
}
static const char *b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void fuzzy_engine_step(struct fuzzy_state *self, unsigned char c)
{
size_t h;
unsigned int i;
/* At each character we update the rolling hash and the normal hashes.
* When the rolling hash hits a reset value then we emit a normal hash
* as a element of the signature and reset the normal hash. */
roll_hash(&self->roll, c);
h = roll_sum(&self->roll);
for (i = self->bhstart; i < self->bhend; ++i)
{
self->bh[i].h = sum_hash(c, self->bh[i].h);
self->bh[i].halfh = sum_hash(c, self->bh[i].halfh);
}
for (i = self->bhstart; i < self->bhend; ++i)
{
/* With growing blocksize almost no runs fail the next test. */
if (likely(h % SSDEEP_BS(i) != SSDEEP_BS(i) - 1))
/* Once this condition is false for one bs, it is
* automatically false for all further bs. I.e. if
* h === -1 (mod 2*bs) then h === -1 (mod bs). */
break;
/* We have hit a reset point. We now emit hashes which are
* based on all characters in the piece of the message between
* the last reset point and this one */
if (unlikely(0 == self->bh[i].dlen)) {
/* Can only happen 30 times. */
/* First step for this blocksize. Clone next. */
fuzzy_try_fork_blockhash(self);
}
if (self->bh[i].dlen < SPAMSUM_LENGTH - 1) {
/* We can have a problem with the tail overflowing. The
* easiest way to cope with this is to only reset the
* normal hash if we have room for more characters in
* our signature. This has the effect of combining the
* last few pieces of the message into a single piece
* */
self->bh[i].digest[self->bh[i].dlen++] =
b64[self->bh[i].h % 64];
self->bh[i].h = HASH_INIT;
if (self->bh[i].dlen < SPAMSUM_LENGTH / 2)
self->bh[i].halfh = HASH_INIT;
} else
fuzzy_try_reduce_blockhash(self);
}
}
int fuzzy_update(struct fuzzy_state *self,
const unsigned char *buffer,
size_t buffer_size) {
self->total_size += buffer_size;
for ( ;buffer_size > 0; ++buffer, --buffer_size)
fuzzy_engine_step(self, *buffer);
return 0;
}
static int memcpy_eliminate_sequences(char *dst,
const char *src,
int n)
{
const char *srcend = src + n;
assert(n >= 0);
if (src < srcend) *dst++ = *src++;
if (src < srcend) *dst++ = *src++;
if (src < srcend) *dst++ = *src++;
while (src < srcend)
if (*src == dst[-1] && *src == dst[-2] && *src == dst[-3])
{
++src;
--n;
} else
*dst++ = *src++;
return n;
}
#ifdef S_SPLINT_S
extern const int EOVERFLOW;
#endif
// We need some extra help on Win32
#ifdef _WIN32
# define EOVERFLOW 84
# define ftello ftell
# define fseeko fseek
#endif
int fuzzy_digest(const struct fuzzy_state *self,
/*@out@*/ char *result,
unsigned int flags)
{
unsigned int bi = self->bhstart;
uint32_t h = roll_sum(&self->roll);
int i, remain = FUZZY_MAX_RESULT - 1; /* Exclude terminating '\0'. */
/* Verify that our elimination was not overeager. */
assert(bi == 0 || (size_t)SSDEEP_BS(bi) / 2 * SPAMSUM_LENGTH <
self->total_size);
/* Initial blocksize guess. */
while ((size_t)SSDEEP_BS(bi) * SPAMSUM_LENGTH < self->total_size) {
++bi;
if (bi >= NUM_BLOCKHASHES) {
/* The input exceeds data types. */
errno = EOVERFLOW;
return -1;
}
}
/* Adapt blocksize guess to actual digest length. */
while (bi >= self->bhend)
--bi;
while (bi > self->bhstart && self->bh[bi].dlen < SPAMSUM_LENGTH / 2)
--bi;
assert (!(bi > 0 && self->bh[bi].dlen < SPAMSUM_LENGTH / 2));
i = snprintf(result, (size_t)remain, "%u:", SSDEEP_BS(bi));
if (i <= 0)
/* Maybe snprintf has set errno here? */
return -1;
assert(i < remain);
remain -= i;
result += i;
i = (int)self->bh[bi].dlen;
assert(i <= remain);
if ((flags & FUZZY_FLAG_ELIMSEQ) != 0)
i = memcpy_eliminate_sequences(result, self->bh[bi].digest, i);
else
memcpy(result, self->bh[bi].digest, (size_t)i);
result += i;
remain -= i;
if (h != 0)
{
assert(remain > 0);
*result = b64[self->bh[bi].h % 64];
if((flags & FUZZY_FLAG_ELIMSEQ) == 0 || i < 3 ||
*result != result[-1] ||
*result != result[-2] ||
*result != result[-3]) {
++result;
--remain;
}
}
assert(remain > 0);
*result++ = ':';
--remain;
if (bi < self->bhend - 1)
{
++bi;
i = (int)self->bh[bi].dlen;
if ((flags & FUZZY_FLAG_NOTRUNC) == 0 &&
i > SPAMSUM_LENGTH / 2 - 1)
i = SPAMSUM_LENGTH / 2 - 1;
assert(i <= remain);
if ((flags & FUZZY_FLAG_ELIMSEQ) != 0)
i = memcpy_eliminate_sequences(result,
self->bh[bi].digest, i);
else
memcpy(result, self->bh[bi].digest, (size_t)i);
result += i;
remain -= i;
if (h != 0) {
assert(remain > 0);
h = (flags & FUZZY_FLAG_NOTRUNC) != 0 ? self->bh[bi].h :
self->bh[bi].halfh;
*result = b64[h % 64];
if ((flags & FUZZY_FLAG_ELIMSEQ) == 0 || i < 3 ||
*result != result[-1] ||
*result != result[-2] ||
*result != result[-3])
{
++result;
--remain;
}
}
} else if (h != 0)
{
assert(self->bh[bi].dlen == 0);
assert(remain > 0);
*result++ = b64[self->bh[bi].h % 64];
/* No need to bother with FUZZY_FLAG_ELIMSEQ, because this
* digest has length 1. */
--remain;
}
*result = '\0';
return 0;
}
void fuzzy_free(/*@only@*/ struct fuzzy_state *self)
{
free(self);
}
int fuzzy_hash_buf(const unsigned char *buf,
uint32_t buf_len,
/*@out@*/ char *result)
{
struct fuzzy_state *ctx;
int ret = -1;
if (NULL == (ctx = fuzzy_new()))
return -1;
if (fuzzy_update(ctx, buf, buf_len) < 0)
goto out;
if (fuzzy_digest(ctx, result, 0) < 0)
goto out;
ret = 0;
out:
fuzzy_free(ctx);
return ret;
}
int fuzzy_hash_stream(FILE *handle, /*@out@*/ char *result)
{
struct fuzzy_state *ctx;
unsigned char buffer[4096];
size_t n;
int ret = -1;
if (NULL == (ctx = fuzzy_new()))
return -1;
for(;;)
{
n = fread(buffer, 1, 4096, handle);
if (0 == n)
break;
if (fuzzy_update(ctx, buffer, n) < 0)
goto out;
}
if (ferror(handle) != 0)
goto out;
if (fuzzy_digest(ctx, result, 0) < 0)
goto out;
ret = 0;
out:
fuzzy_free(ctx);
return ret;
}
#ifdef S_SPLINT_S
typedef size_t off_t;
int fseeko(FILE *, off_t, int);
off_t ftello(FILE *);
#endif
int fuzzy_hash_file(FILE *handle, /*@out@*/ char *result)
{
off_t fpos;
int status;
fpos = ftello(handle);
if (fseek(handle, 0, SEEK_SET) < 0)
return -1;
status = fuzzy_hash_stream(handle, result);
if (status == 0)
{
if (fseeko(handle, fpos, SEEK_SET) < 0)
return -1;
}
return status;
}
int fuzzy_hash_filename(const char *filename, /*@out@*/ char *result)
{
int status;
FILE *handle = fopen(filename, "rb");
if (NULL == handle)
return -1;
status = fuzzy_hash_stream(handle, result);
/* We cannot do anything about an fclose failure. */
(void)fclose(handle);
return status;
}
//
// We only accept a match if we have at least one common substring in
// the signature of length ROLLING_WINDOW. This dramatically drops the
// false positive rate for low score thresholds while having
// negligable affect on the rate of spam detection.
//
// return 1 if the two strings do have a common substring, 0 otherwise
//
static int has_common_substring(const char *s1, const char *s2)
{
int i, j;
int num_hashes;
uint32_t hashes[SPAMSUM_LENGTH];
// there are many possible algorithms for common substring
// detection. In this case I am re-using the rolling hash code
// to act as a filter for possible substring matches
memset(hashes, 0, sizeof(hashes));
// first compute the windowed rolling hash at each offset in
// the first string
struct roll_state state;
roll_init (&state);
for (i=0;s1[i];i++)
{
roll_hash(&state, (unsigned char)s1[i]);
hashes[i] = roll_sum(&state);
}
num_hashes = i;
roll_init(&state);
// now for each offset in the second string compute the
// rolling hash and compare it to all of the rolling hashes
// for the first string. If one matches then we have a
// candidate substring match. We then confirm that match with
// a direct string comparison */
for (i=0;s2[i];i++)
{
roll_hash(&state, (unsigned char)s2[i]);
uint32_t h = roll_sum(&state);
if (i < ROLLING_WINDOW-1) continue;
for (j=ROLLING_WINDOW-1;j<num_hashes;j++)
{
if (hashes[j] != 0 && hashes[j] == h)
{
// we have a potential match - confirm it
if (strlen(s2+i-(ROLLING_WINDOW-1)) >= ROLLING_WINDOW &&
strncmp(s2+i-(ROLLING_WINDOW-1),
s1+j-(ROLLING_WINDOW-1),
ROLLING_WINDOW) == 0)
{
return 1;
}
}
}
}
return 0;
}
// eliminate sequences of longer than 3 identical characters. These
// sequences contain very little information so they tend to just bias
// the result unfairly
static char *eliminate_sequences(const char *str)
{
char *ret;
size_t i, j, len;
ret = strdup(str);
if (!ret)
return NULL;
len = strlen(str);
if (len < 3)
return ret;
for (i=j=3 ; i<len ; i++)
{
if (str[i] != str[i-1] ||
str[i] != str[i-2] ||
str[i] != str[i-3])
{
ret[j++] = str[i];
}
}
ret[j] = 0;
return ret;
}
//
// this is the low level string scoring algorithm. It takes two strings
// and scores them on a scale of 0-100 where 0 is a terrible match and
// 100 is a great match. The block_size is used to cope with very small
// messages.
//
static uint32_t score_strings(const char *s1,
const char *s2,
unsigned int block_size)
{
uint32_t score;
size_t len1, len2;
int edit_distn(const char *from, int from_len, const char *to, int to_len);
len1 = strlen(s1);
len2 = strlen(s2);
if (len1 > SPAMSUM_LENGTH || len2 > SPAMSUM_LENGTH) {
// not a real spamsum signature?
return 0;
}
// the two strings must have a common substring of length
// ROLLING_WINDOW to be candidates
if (has_common_substring(s1, s2) == 0) {
return 0;
}
// compute the edit distance between the two strings. The edit distance gives
// us a pretty good idea of how closely related the two strings are
score = edit_distn(s1, len1, s2, len2);
// scale the edit distance by the lengths of the two
// strings. This changes the score to be a measure of the
// proportion of the message that has changed rather than an
// absolute quantity. It also copes with the variability of
// the string lengths.
score = (score * SPAMSUM_LENGTH) / (len1 + len2);
// at this stage the score occurs roughly on a 0-64 scale,
// with 0 being a good match and 64 being a complete
// mismatch
// rescale to a 0-100 scale (friendlier to humans)
score = (100 * score) / 64;
// it is possible to get a score above 100 here, but it is a
// really terrible match
if (score >= 100)
return 0;
// now re-scale on a 0-100 scale with 0 being a poor match and
// 100 being a excellent match.
score = 100 - score;
// printf ("len1: %"PRIu32" len2: %"PRIu32"\n", len1, len2);
// when the blocksize is small we don't want to exaggerate the match size
if (score > block_size/MIN_BLOCKSIZE * MIN(len1, len2))
{
score = block_size/MIN_BLOCKSIZE * MIN(len1, len2);
}
return score;
}
//
// Given two spamsum strings return a value indicating the degree
// to which they match.
//
int fuzzy_compare(const char *str1, const char *str2)
{
unsigned int block_size1, block_size2;
uint32_t score = 0;
char *s1, *s2;
char *s1_1, *s1_2, *s1_3;
char *s2_1, *s2_2, *s2_3;
if (NULL == str1 || NULL == str2)
return -1;
// each spamsum is prefixed by its block size
if (sscanf(str1, "%u:", &block_size1) != 1 ||
sscanf(str2, "%u:", &block_size2) != 1) {
return -1;
}
// if the blocksizes don't match then we are comparing
// apples to oranges. This isn't an 'error' per se. We could
// have two valid signatures, but they can't be compared.
if (block_size1 != block_size2 &&
block_size1 != block_size2*2 &&
block_size2 != block_size1*2) {
return 0;
}
// move past the prefix
str1 = strchr(str1, ':');
str2 = strchr(str2, ':');
if (!str1 || !str2) {
// badly formed ...
return -1;
}
// there is very little information content is sequences of
// the same character like 'LLLLL'. Eliminate any sequences
// longer than 3. This is especially important when combined
// with the has_common_substring() test below.
// NOTE: This function duplciates str1 and str2
s1 = eliminate_sequences(str1+1);
if (!s1)
return 0;
s2 = eliminate_sequences(str2+1);
if (!s2)
{
free(s1);
return 0;
}
// now break them into the two pieces
s1_1 = s1;
s2_1 = s2;
s1_2 = strchr(s1, ':');
s2_2 = strchr(s2, ':');
if (!s1_2 || !s2_2) {
// a signature is malformed - it doesn't have 2 parts
free(s1); free(s2);
return -1;
}
// Chop the first substring. We terminate the first substring
// and then advance the pointer to the start of the second substring.
*s1_2 = 0;
s1_2++;
*s2_2 = 0;
s2_2++;
// Chop the second string at the comma--just before the filename.
// If the strings don't have a comma (i.e. don't have a filename)
// that's ok. It's not an error. This function can be called on
// signatures which don't have filenames attached.
// We also don't have to advance past the comma however. We don't care
// about the filename
s1_3 = strchr(s1_2, ',');
s2_3 = strchr(s2_2, ',');
if (s1_3 != NULL)
*s1_3 = 0;
if (s2_3 != NULL)
*s2_3 = 0;
// each signature has a string for two block sizes. We now
// choose how to combine the two block sizes. We checked above
// that they have at least one block size in common
if (block_size1 == block_size2)
{
uint32_t score1, score2;
score1 = score_strings(s1_1, s2_1, block_size1);
score2 = score_strings(s1_2, s2_2, block_size1*2);
score = MAX(score1, score2);
}
else if (block_size1 == block_size2*2)
{
score = score_strings(s1_1, s2_2, block_size1);
}
else
{
score = score_strings(s1_2, s2_1, block_size2);
}
free(s1);
free(s2);
return (int)score;
}
/*
* Copyright (C) ManTech International Corporation 2010
* Copyright (C) Kyrus 2012
* Copyright (C) 2013 Helmut Grohne <helmut@subdivi.de>
*
* $Id: fuzzy.h 180 2013-06-10 23:24:26Z jessekornblum $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Earlier versions of this code can be found at:
* http://ssdeep.sf.net/
*/
/// \mainpage
/// This is the documentation for the fuzzy hashing API from ssdeep.
///
/// There is a complete function reference in fuzzy.h.
///
/// The most recent version of this documentation can be found
/// at http://ssdeep.sourceforge.net/.
///
/// \copydoc fuzzy.h
///
/// \version 3.0
///
/// \author Jesse Kornblum, research@jessekornblum.com
/// \author Helmut Grohne, helmut@subdivi.de
/// \file fuzzy.h
/// \brief
/// These functions allow a programmer to compute the fuzzy hashes
/// (also called the context-triggered piecewise hashes) of
/// \link fuzzy_hash_buf() a buffer
/// of text @endlink,
/// \link fuzzy_hash_filename() the contents of a file on the disk @endlink,
/// and
/// @link fuzzy_hash_file() the contents of
/// an open file handle @endlink .
/// There is also a function to
/// @link fuzzy_compare() compute the
/// similarity between any two fuzzy signatures @endlink.
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FUZZY_H
#define FUZZY_H
/**
* @brief fuzzy_digest flag indicating to eliminate sequences of more than
* three identical characters
*/
#define FUZZY_FLAG_ELIMSEQ 0x1u
/**
* @brief fuzzy_digest flag indicating not to truncate the second part to
* SPAMSUM_LENGTH/2 characters.
*/
#define FUZZY_FLAG_NOTRUNC 0x2u
struct fuzzy_state;
/**
* @brief Construct a fuzzy_state object and return it.
*
* To use it call fuzzy_update and fuzzy_digest on it. It must be disposed
* with fuzzy_free.
* @return the constructed fuzzy_state or NULL on failure
*/
extern /*@only@*/ /*@null@*/ struct fuzzy_state *fuzzy_new(void);
/**
* @brief Feed the data contained in the given buffer to the state.
*
* When an error occurs, the state is undefined. In that case it must not be
* passed to any function besides fuzzy_free.
* @param buffer The data to be hashes
* @param buffer_size The length of the given buffer
* @return zero on success, non-zero on error
*/
extern int fuzzy_update(struct fuzzy_state *state,
const unsigned char *buffer,
size_t buffer_size);
/**
* @brief Obtain the fuzzy hash from the state.
*
* This operation does not change the state at all. It reports the hash for the
* concatenation of the data previously fed using fuzzy_update.
* @param result Where the fuzzy hash is stored. This variable
* must be allocated to hold at least FUZZY_MAX_RESULT bytes.
* @param flags is a bitwise or of FUZZY_FLAG_* macros. The absence of flags is
* represented by a zero.
* @return zero on success, non-zero on error
*/
extern int fuzzy_digest(const struct fuzzy_state *state,
/*@out@*/ char *result,
unsigned int flags);
/**
* @brief Dispose a fuzzy state.
*/
extern void fuzzy_free(/*@only@*/ struct fuzzy_state *state);
/**
* @brief Compute the fuzzy hash of a buffer
*
* The computes the fuzzy hash of the first buf_len bytes of the buffer.
* It is the caller's responsibility to append the filename,
* if any, to result after computation.
* @param buf The data to be fuzzy hashed
* @param buf_len The length of the data being hashed
* @param result Where the fuzzy hash of buf is stored. This variable
* must be allocated to hold at least FUZZY_MAX_RESULT bytes.
* @return Returns zero on success, non-zero on error.
*/
extern int fuzzy_hash_buf(const unsigned char *buf,
uint32_t buf_len,
/*@out@*/ char *result);
/**
* @brief Compute the fuzzy hash of a file using an open handle
*
* Computes the fuzzy hash of the contents of the open file, starting
* at the beginning of the file. When finished, the file pointer is
* returned to its original position. If an error occurs, the file
* pointer's value is undefined.
* It is the callers's responsibility to append the filename
* to the result after computation.
* @param handle Open handle to the file to be hashed
* @param result Where the fuzzy hash of the file is stored. This
* variable must be allocated to hold at least FUZZY_MAX_RESULT bytes.
* @return Returns zero on success, non-zero on error
*/
extern int fuzzy_hash_file(FILE *handle, /*@out@*/ char *result);
/**
* @brief Compute the fuzzy hash of a stream using an open handle
*
* Computes the fuzzy hash of the contents of the open stream, starting at the
* current file position until reaching EOF. Unlike fuzzy_hash_file the stream
* is never seeked. If an error occurs, the result as well as the file position
* are undefined.
* It is the callers's responsibility to append the filename
* to the result after computation.
* @param handle Open handle to the stream to be hashed
* @param result Where the fuzzy hash of the file is stored. This
* variable must be allocated to hold at least FUZZY_MAX_RESULT bytes.
* @return Returns zero on success, non-zero on error
*/
extern int fuzzy_hash_stream(FILE *handle, /*@out@*/ char *result);
/**
* @brief Compute the fuzzy hash of a file
*
* Opens, reads, and hashes the contents of the file 'filename'
* The result must be allocated to hold FUZZY_MAX_RESULT characters.
* It is the caller's responsibility to append the filename
* to the result after computation.
* @param filename The file to be hashed
* @param result Where the fuzzy hash of the file is stored. This
* variable must be allocated to hold at least FUZZY_MAX_RESULT bytes.
* @return Returns zero on success, non-zero on error.
*/
extern int fuzzy_hash_filename(const char *filename, /*@out@*/ char * result);
/// Computes the match score between two fuzzy hash signatures.
/// @return Returns a value from zero to 100 indicating the
/// match score of the
/// two signatures. A match score of zero indicates the sigantures
/// did not match. When an error occurs, such as if one of the
/// inputs is NULL, returns -1.
extern int fuzzy_compare(const char *sig1, const char *sig2);
/** Length of an individual fuzzy hash signature component. */
#define SPAMSUM_LENGTH 64
/** The longest possible length for a fuzzy hash signature
* (without the filename) */
#define FUZZY_MAX_RESULT (2 * SPAMSUM_LENGTH + 20)
#ifdef __cplusplus
}
#endif
#endif
// ssdeep
// Copyright (C) 2012 Kyrus
// Copyright (C) 2006 ManTech International Corporation
//
// $Id: helpers.cpp 184 2013-07-10 05:24:26Z jessekornblum $
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "ssdeep.h"
void try_msg(void)
{
fprintf (stderr,"Try `%s -h` for more information.%s", __progname, NEWLINE);
}
bool expanded_path(TCHAR *p)
{
if (_tcsncmp(p,_TEXT("\\\\?\\"),4))
return false;
return true;
}
void sanity_check(state *s, int condition, const char *msg)
{
if (NULL == s)
exit(EXIT_FAILURE);
if (condition)
{
if (!(s->mode & mode_silent))
{
print_status("%s: %s", __progname, msg);
try_msg();
}
exit (EXIT_FAILURE);
}
}
// The basename function kept misbehaving on OS X, so I rewrote it.
// This function isn't perfect, nor is it designed to be. Because
// we're guaranteed to be working with a filename here, there's no way
// that s will end with a DIR_SEPARATOR (e.g. /foo/bar/). This function
// will not work properly for a string that ends in a DIR_SEPARATOR */
int my_basename(TCHAR *s)
{
size_t len;
TCHAR * tmp;
if (NULL == s)
return TRUE;
tmp = _tcsrchr(s,DIR_SEPARATOR);
if (NULL == tmp)
return FALSE;
len = _tcslen(tmp);
// We advance tmp one character to move us past the DIR_SEPARATOR
_tmemmove(s,tmp+1,len);
return FALSE;
}
int my_dirname(TCHAR *c)
{
TCHAR *tmp;
if (NULL == c)
return TRUE;
// If there are no DIR_SEPARATORs in the directory name, then the
// directory name should be the empty string
tmp = _tcsrchr(c,DIR_SEPARATOR);
if (NULL != tmp)
tmp[1] = 0;
else
c[0] = 0;
return FALSE;
}
void prepare_filename(state *s, TCHAR *fn)
{
if (s->mode & mode_barename)
{
if (my_basename(fn))
{
print_error_unicode(s,fn,"Unable to shorten filename");
return;
}
}
}
// Remove the newlines, if any. Works on both DOS and *nix newlines
void chop_line_tchar(TCHAR *s)
{
size_t pos = _tcslen(s);
while (pos > 0)
{
// We split up the two checks because we can never know which
// condition the computer will examine if first. If pos == 0, we
// don't want to be checking s[pos-1] under any circumstances!
if (!(s[pos-1] == _TEXT('\r') || s[pos-1] == _TEXT('\n')))
return;
s[pos-1] = 0;
--pos;
}
}
// Remove the newlines, if any. Works on both DOS and *nix newlines
void chop_line(char *s)
{
size_t pos = strlen(s);
while (pos > 0)
{
// We split up the two checks because we can never know which
// condition the computer will examine if first. If pos == 0, we
// don't want to be checking s[pos-1] under any circumstances!
if (!(s[pos-1] == _TEXT('\r') || s[pos-1] == _TEXT('\n')))
return;
s[pos-1] = 0;
--pos;
}
}
// Shift the contents of a string so that the values after 'new_start'
// will now begin at location 'start'
void shift_string_tchar(TCHAR *fn, unsigned int start, unsigned int new_start)
{
size_t sz = _tcslen(fn);
if (start > sz || new_start < start)
return;
while (new_start < sz)
{
fn[start] = fn[new_start];
new_start++;
start++;
}
fn[start] = 0;
}
// Find the index of the next comma in the string s starting at index start.
// If there is no next comma, returns -1.
int find_next_comma_tchar(TCHAR *s, unsigned int start)
{
size_t size = _tcslen(s);
unsigned int pos = start;
int in_quote = FALSE;
while (pos < size)
{
switch (s[pos]) {
case _TEXT('"'):
in_quote = !in_quote;
break;
case _TEXT(','):
if (in_quote)
break;
// Although it's potentially unwise to cast an unsigned int back
// to an int, problems will only occur when the value is beyond
// the range of int. Because we're working with the index of a
// string that is probably less than 32,000 characters, we should
// be okay.
return (int)pos;
}
++pos;
}
return -1;
}
void mm_magic(void){MM_INIT("%s\n","\x49\x20\x64\x6f\x20\x6e\x6f\x74\x20\x62\x65\x6c\x69\x65\x76\x65\x20\x77\x65\x20\x77\x69\x6c\x6c\x20\x67\x65\x74\x20\x45\x64\x64\x69\x65\x20\x56\x61\x6e\x20\x48\x61\x6c\x65\x6e\x20\x75\x6e\x74\x69\x6c\x20\x77\x65\x20\x68\x61\x76\x65\x20\x61\x20\x74\x72\x69\x75\x6d\x70\x68\x61\x6e\x74\x20\x76\x69\x64\x65\x6f\x2e");}
// Returns the string after the nth comma in the string s. If that
// string is quoted, the quotes are removed. If there is no valid
// string to be found, returns TRUE. Otherwise, returns FALSE
int find_comma_separated_string_tchar(TCHAR *s, unsigned int n)
{
int start = 0, end;
unsigned int count = 0;
while (count < n)
{
if ((start = find_next_comma_tchar(s,start)) == -1)
return TRUE;
++count;
// Advance the pointer past the current comma
++start;
}
// It's okay if there is no next comma, it just means that this is
// the last comma separated value in the string
if ((end = find_next_comma_tchar(s,start)) == -1)
end = _tcslen(s);
// Strip off the quotation marks, if necessary. We don't have to worry
// about uneven quotation marks (i.e quotes at the start but not the end
// as they are handled by the the find_next_comma function.
if (s[start] == _TEXT('"'))
++start;
if (s[end - 1] == _TEXT('"'))
end--;
s[end] = 0;
shift_string_tchar(s,0,start);
return FALSE;
}
// Shift the contents of a string so that the values after 'new_start'
// will now begin at location 'start'
void shift_string(char *fn, size_t start, size_t new_start)
{
// TODO: Can shift_string be replaced with memmove?
if (start > strlen(fn) || new_start < start)
return;
while (new_start < strlen(fn))
{
fn[start] = fn[new_start];
new_start++;
start++;
}
fn[start] = 0;
}
// Find the index of the next comma in the string s starting at index start.
// If there is no next comma, returns -1
int find_next_comma(char *s, unsigned int start)
{
size_t size=strlen(s);
unsigned int pos = start;
int in_quote = FALSE;
while (pos < size)
{
switch (s[pos]) {
case '"':
in_quote = !in_quote;
break;
case ',':
if (in_quote)
break;
// Although it's potentially unwise to cast an unsigned int back
// to an int, problems will only occur when the value is beyond
// the range of int. Because we're working with the index of a
// string that is probably less than 32,000 characters, we should
// be okay.
return (int)pos;
}
++pos;
}
return -1;
}
/// Returns the string after the nth comma in the string s. If that
/// string is quoted, the quotes are removed. If there is no valid
/// string to be found, returns TRUE. Otherwise, returns FALSE
int find_comma_separated_string(char *s, unsigned int n)
{
int start = 0, end;
unsigned int count = 0;
while (count < n)
{
if ((start = find_next_comma(s,start)) == -1)
return TRUE;
++count;
// Advance the pointer past the current comma
++start;
}
// It's okay if there is no next comma, it just means that this is
// the last comma separated value in the string
if ((end = find_next_comma(s,start)) == -1)
end = strlen(s);
// Strip off the quotation marks, if necessary. We don't have to worry
// about uneven quotation marks (i.e quotes at the start but not the end
// as they are handled by the the find_next_comma function.
if (s[start] == '"')
++start;
if (s[end - 1] == '"')
end--;
s[end] = 0;
shift_string(s,0,start);
return FALSE;
}
int remove_escaped_quotes(char * str)
{
if (NULL == str)
return TRUE;
size_t pos = 0;
while (str[pos] != 0)
{
if ('\\' == str[pos] && '"' == str[pos+1])
shift_string(str,pos,pos+1);
++pos;
}
return FALSE;
}
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2006-10-14.15
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
posix_glob=
posix_mkdir=
# Desired mode of installed file.
mode=0755
chmodcmd=$chmodprog
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
shift
shift
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
done
if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix=/ ;;
-*) prefix=./ ;;
*) prefix= ;;
esac
case $posix_glob in
'')
if (set -f) 2>/dev/null; then
posix_glob=true
else
posix_glob=false
fi ;;
esac
oIFS=$IFS
IFS=/
$posix_glob && set -f
set fnord $dstdir
shift
$posix_glob && set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dst"; then
$doit $rmcmd -f "$dst" 2>/dev/null \
|| { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
&& { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
|| {
echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
} || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:
This source diff could not be displayed because it is too large. You can view the blob instead.
// Fuzzy Hashing by Jesse Kornblum
// Copyright (C) 2013 Facebook
// Copyright (C) 2012 Kyrus
// Copyright (C) 2010 ManTech International Corporation
//
// $Id: main.cpp 187 2013-07-10 06:56:14Z jessekornblum $
//
// This program is licensed under version 2 of the GNU Public License.
// See the file COPYING for details.
#include "ssdeep.h"
#include "match.h"
#ifdef _WIN32
// This can't go in main.h or we get multiple definitions of it
// Allows us to open standard input in binary mode by default
// See http://gnuwin32.sourceforge.net/compile.html for more
int _CRT_fmode = _O_BINARY;
#endif
static bool initialize_state(state *s)
{
if (NULL == s)
return true;
s->mode = mode_none;
s->first_file_processed = true;
s->found_meaningful_file = false;
s->processed_file = false;
s->threshold = 0;
return false;
}
// In order to fit on one Win32 screen this function should produce
// no more than 22 lines of output.
static void usage(void)
{
print_status ("%s version %s by Jesse Kornblum", __progname, VERSION);
print_status ("Copyright (C) 2013 Facebook");
print_status ("");
print_status ("Usage: %s [-m file] [-k file] [-dpgvrsblcxa] [-t val] [-h|-V] [FILES]",
__progname);
print_status ("-m - Match FILES against known hashes in file");
print_status ("-k - Match signatures in FILES against signatures in file");
print_status ("-d - Directory mode, compare all files in a directory");
print_status ("-p - Pretty matching mode. Similar to -d but includes all matches");
print_status ("-g - Cluster matches together");
print_status ("-v - Verbose mode. Displays filename as its being processed");
print_status ("-r - Recursive mode");
print_status ("-s - Silent mode; all errors are supressed");
print_status ("-b - Uses only the bare name of files; all path information omitted");
print_status ("-l - Uses relative paths for filenames");
print_status ("-c - Prints output in CSV format");
print_status ("-x - Compare FILES as signature files");
print_status ("-a - Display all matches, regardless of score");
print_status ("-t - Only displays matches above the given threshold");
print_status ("-h - Display this help message");
print_status ("-V - Display version number and exit");
}
static void process_cmd_line(state *s, int argc, char **argv)
{
int i, match_files_loaded = FALSE;
while ((i=getopt(argc,argv,"gavhVpdsblcxt:rm:k:")) != -1) {
switch(i) {
case 'g':
s->mode |= mode_cluster;
break;
case 'a':
s->mode |= mode_display_all;
break;
case 'v':
if (MODE(mode_verbose))
{
print_error(s,"%s: Already at maximum verbosity", __progname);
print_error(s,
"%s: Error message displayed to user correctly",
__progname);
}
else
s->mode |= mode_verbose;
break;
case 'p':
s->mode |= mode_match_pretty;
break;
case 'd':
s->mode |= mode_directory;
break;
case 's':
s->mode |= mode_silent; break;
case 'b':
s->mode |= mode_barename; break;
case 'l':
s->mode |= mode_relative; break;
case 'c':
s->mode |= mode_csv; break;
case 'x':
s->mode |= mode_sigcompare; break;
case 'r':
s->mode |= mode_recursive; break;
case 't':
s->threshold = (uint8_t)atol(optarg);
if (s->threshold > 100)
fatal_error("%s: Illegal threshold", __progname);
s->mode |= mode_threshold;
break;
case 'm':
if (MODE(mode_compare_unknown) || MODE(mode_sigcompare))
fatal_error("Positive matching cannot be combined with other matching modes");
s->mode |= mode_match;
if (not match_load(s,optarg))
match_files_loaded = TRUE;
break;
case 'k':
if (MODE(mode_match) || MODE(mode_sigcompare))
fatal_error("Signature matching cannot be combined with other matching modes");
s->mode |= mode_compare_unknown;
if (not match_load(s,optarg))
match_files_loaded = TRUE;
break;
case 'h':
usage();
exit (EXIT_SUCCESS);
case 'V':
print_status ("%s", VERSION);
exit (EXIT_SUCCESS);
default:
try_msg();
exit (EXIT_FAILURE);
}
}
// We don't include mode_sigcompare in this list as we haven't loaded
// the matching files yet. In that mode the matching files are in fact
// the command line arguments.
sanity_check(s,
((MODE(mode_match) || MODE(mode_compare_unknown))
&& not match_files_loaded),
"No matching files loaded");
sanity_check(s,
((s->mode & mode_barename) && (s->mode & mode_relative)),
"Relative paths and bare names are mutually exclusive");
sanity_check(s,
((s->mode & mode_match_pretty) && (s->mode & mode_directory)),
"Directory mode and pretty matching are mutually exclusive");
sanity_check(s,
MODE(mode_csv) and MODE(mode_cluster),
"CSV and clustering modes cannot be combined");
// -m, -p, and -d are incompatible with -k and -x
// The former treat FILES as raw files. The latter require them to be sigs
sanity_check(s,
((MODE(mode_match) or MODE(mode_match_pretty) or MODE(mode_directory))
and
(MODE(mode_compare_unknown) or MODE(mode_sigcompare))),
"Incompatible matching modes");
}
#ifdef _WIN32
static int prepare_windows_command_line(state *s)
{
int argc;
TCHAR **argv;
argv = CommandLineToArgvW(GetCommandLineW(),&argc);
s->argc = argc;
s->argv = argv;
return FALSE;
}
#endif
static int is_absolute_path(TCHAR *fn)
{
if (NULL == fn)
internal_error("Unknown error in is_absolute_path");
#ifdef _WIN32
return (isalpha(fn[0]) and _TEXT(':') == fn[1]);
# else
return (DIR_SEPARATOR == fn[0]);
#endif
}
static void generate_filename(state *s, TCHAR *fn, TCHAR *cwd, TCHAR *input)
{
if (NULL == fn || NULL == input)
internal_error("Error calling generate_filename");
if ((s->mode & mode_relative) || is_absolute_path(input))
_tcsncpy(fn, input, SSDEEP_PATH_MAX);
else {
// Windows systems don't have symbolic links, so we don't
// have to worry about carefully preserving the paths
// they follow. Just use the system command to resolve the paths
#ifdef _WIN32
_wfullpath(fn, input, SSDEEP_PATH_MAX);
#else
if (NULL == cwd)
// If we can't get the current working directory, we're not
// going to be able to build the relative path to this file anyway.
// So we just call realpath and make the best of things
realpath(input, fn);
else
snprintf(fn, SSDEEP_PATH_MAX, "%s%c%s", cwd, DIR_SEPARATOR, input);
#endif
}
}
int main(int argc, char **argv)
{
int count, status, goal = argc;
state *s;
TCHAR *fn, *cwd;
#ifndef __GLIBC__
// __progname = basename(argv[0]);
#endif
s = new state;
if (initialize_state(s))
fatal_error("%s: Unable to initialize state variable", __progname);
process_cmd_line(s,argc,argv);
#ifdef _WIN32
if (prepare_windows_command_line(s))
fatal_error("%s: Unable to process command line arguments", __progname);
#else
s->argc = argc;
s->argv = argv;
#endif
// Anything left on the command line at this point is a file
// or directory we're supposed to process. If there's nothing
// specified, we should tackle standard input
if (optind == argc) {
status = process_stdin(s);
}
else {
MD5DEEP_ALLOC(TCHAR, fn, SSDEEP_PATH_MAX);
MD5DEEP_ALLOC(TCHAR, cwd, SSDEEP_PATH_MAX);
cwd = _tgetcwd(cwd, SSDEEP_PATH_MAX);
if (NULL == cwd)
fatal_error("%s: %s", __progname, strerror(errno));
count = optind;
// The signature comparsion mode needs to use the command line
// arguments and argument count. We don't do wildcard expansion
// on it on Win32 (i.e. where it matters). The setting of 'goal'
// to the original argc occured at the start of main(), so we just
// need to update it if we're *not* in signature compare mode.
if (not (s->mode & mode_sigcompare)) {
goal = s->argc;
}
while (count < goal)
{
if (MODE(mode_sigcompare))
match_load(s,argv[count]);
else if (MODE(mode_compare_unknown))
match_compare_unknown(s,argv[count]);
else {
generate_filename(s, fn, cwd, s->argv[count]);
#ifdef _WIN32
status = process_win32(s, fn);
#else
status = process_normal(s, fn);
#endif
}
++count;
}
// If we processed files, but didn't find anything large enough
// to be meaningful, we should display a warning message to the user.
// This happens mostly when people are testing very small files
// e.g. $ echo "hello world" > foo && ssdeep foo
if ((not s->found_meaningful_file) and s->processed_file)
{
print_error(s,"%s: Did not process files large enough to produce meaningful results", __progname);
}
}
// If the user has requested us to compare signature files, use
// our existng code to pretty-print directory matching to do the
// work for us.
if (MODE(mode_sigcompare))
s->mode |= mode_match_pretty;
if (MODE(mode_match_pretty) or MODE(mode_sigcompare) or MODE(mode_cluster))
find_matches_in_known(s);
if (MODE(mode_cluster))
display_clusters(s);
return (EXIT_SUCCESS);
}
// ssdeep
// Copyright (C) 2012 Kyrus
//
// $Id: main.h 144 2012-04-24 14:59:33Z jessekornblum $
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef __MAIN_H
#define __MAIN_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <inttypes.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
#ifdef HAVE_SYS_DISK_H
# include <sys/disk.h>
#endif
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
// This allows us to open standard input in binary mode by default
// See http://gnuwin32.sourceforge.net/compile.html for more.
// Technically it isn't needed in ssdeep as we don't process standard
// input. But it was part of Jesse's template, so in it goes!
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifndef HAVE_FSEEKO
# define fseeko fseek
# define ftello ftell
#endif
#define FALSE 0
#define TRUE 1
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#endif // #ifndef __MAIN_H
// ssdeep
// (C) Copyright 2012 Kyrus
//
// $Id: match.cpp 164 2012-07-23 16:12:36Z jessekornblum $
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "match.h"
// The longest line we should encounter when reading files of known hashes
#define MAX_STR_LEN 2048
#define MIN_SUBSTR_LEN 7
// ------------------------------------------------------------------
// SIGNATURE FILE FUNCTIONS
// ------------------------------------------------------------------
/// Open a file of known hashes and determine if it's valid
///
/// @param s State variable
/// @param fn filename to open
///
/// @return Returns false success, true on error
bool sig_file_open(state *s, const char * fn)
{
if (NULL == s or NULL == fn)
return true;
s->known_handle = fopen(fn,"rb");
if (NULL == s->known_handle)
{
if ( ! (MODE(mode_silent)) )
perror(fn);
return true;
}
// The first line of the file should contain a valid ssdeep header.
char buffer[MAX_STR_LEN];
if (NULL == fgets(buffer,MAX_STR_LEN,s->known_handle))
{
if ( ! (MODE(mode_silent)) )
perror(fn);
fclose(s->known_handle);
return true;
}
chop_line(buffer);
if (strncmp(buffer,SSDEEPV1_0_HEADER,MAX_STR_LEN) and
strncmp(buffer,SSDEEPV1_1_HEADER,MAX_STR_LEN))
{
if ( ! (MODE(mode_silent)) )
print_error(s,"%s: Invalid file header.", fn);
fclose(s->known_handle);
return true;
}
// We've now read the first line
s->line_number = 1;
s->known_fn = strdup(fn);
return false;
}
/// @brief Read the next entry in a file of known hashes and convert
/// it to a Filedata
///
/// @param s State variable
/// @param f Structure where to store the data we read
///
/// @return Returns true if there is no entry to read or on error.
/// Otherwise, false.
bool sig_file_next(state *s, Filedata ** f)
{
if (NULL == s or NULL == f or NULL == s->known_handle)
return true;
char buffer[MAX_STR_LEN];
memset(buffer,0,MAX_STR_LEN);
if (NULL == fgets(buffer,MAX_STR_LEN,s->known_handle))
return true;
s->line_number++;
chop_line(buffer);
try
{
*f = new Filedata(std::string(buffer),s->known_fn);
}
catch (std::bad_alloc)
{
// This can happen on a badly formatted line, or a blank one.
// We don't display errors on blank lines.
if (strlen(buffer) > 0)
print_error(s,
"%s: Bad hash in line %llu",
s->known_fn,
s->line_number);
return true;
}
return false;
}
bool sig_file_close(state *s)
{
if (NULL == s)
return true;
free(s->known_fn);
if (s->known_handle != NULL)
return true;
if (fclose(s->known_handle))
return true;
return false;
}
bool sig_file_end(state *s)
{
return (feof(s->known_handle));
}
// ------------------------------------------------------------------
// MATCHING FUNCTIONS
// ------------------------------------------------------------------
void display_clusters(const state *s)
{
if (NULL == s)
return;
std::set<std::set<Filedata *> *>::const_iterator it;
for (it = s->all_clusters.begin(); it != s->all_clusters.end() ; ++it)
{
print_status("** Cluster size %u", (*it)->size());
std::set<Filedata *>::const_iterator cit;
for (cit = (*it)->begin() ; cit != (*it)->end() ; ++cit)
{
display_filename(stdout,(*cit)->get_filename(),FALSE);
print_status("");
}
print_status("");
}
}
void cluster_add(Filedata * dest, Filedata * src)
{
dest->get_cluster()->insert(src);
src->set_cluster(dest->get_cluster());
}
void cluster_join(state *s, Filedata * a, Filedata * b)
{
// If these items are already in the same cluster there is nothing to do
if (a->get_cluster() == b->get_cluster())
return;
Filedata * dest, * src;
// Combine the smaller cluster into the larger cluster for speed
// (fewer items to move)
if (a->get_cluster()->size() > b->get_cluster()->size())
{
dest = a;
src = b;
}
else
{
dest = b;
src = a;
}
// Add members of src to dest
std::set<Filedata *>::const_iterator it;
for (it = src->get_cluster()->begin() ;
it != src->get_cluster()->end() ;
++it)
{
dest->get_cluster()->insert(*it);
}
// Remove the old cluster
s->all_clusters.erase(src->get_cluster());
// This call sets the cluster to NULL. Do not access the src
// cluster after this call!
src->clear_cluster();
src->set_cluster(dest->get_cluster());
}
void handle_clustering(state *s, Filedata *a, Filedata *b)
{
bool a_has = a->has_cluster(), b_has = b->has_cluster();
// In the easiest case, one of these has a cluster and one doesn't
if (a_has and not b_has)
{
cluster_add(a,b);
return;
}
if (b_has and not a_has)
{
cluster_add(b,a);
return;
}
// Combine existing clusters
if (a_has and b_has)
{
cluster_join(s,a,b);
return;
}
// Create a new cluster
std::set<Filedata *> * cluster = new std::set<Filedata *>();
cluster->insert(a);
cluster->insert(b);
s->all_clusters.insert(cluster);
a->set_cluster(cluster);
b->set_cluster(cluster);
}
void handle_match(state *s,
Filedata *a,
Filedata *b,
int score)
{
if (s->mode & mode_csv)
{
printf("\"");
display_filename(stdout,a->get_filename(),TRUE);
printf("\",\"");
display_filename(stdout,b->get_filename(),TRUE);
print_status("\",%u", score);
}
else if (s->mode & mode_cluster)
{
handle_clustering(s,a,b);
}
else
{
// The match file names may be empty. If so, we don't print them
// or the colon which separates them from the filename
if (a->has_match_file())
printf ("%s:", a->get_match_file().c_str());
display_filename(stdout,a->get_filename(),FALSE);
printf (" matches ");
if (b->has_match_file())
printf ("%s:", b->get_match_file().c_str());
display_filename(stdout,b->get_filename(),FALSE);
print_status(" (%u)", score);
}
}
bool match_compare(state *s, Filedata * f)
{
if (NULL == s)
fatal_error("%s: Null state passed into match_compare", __progname);
bool status = false;
size_t fn_len = _tcslen(f->get_filename());
std::vector<Filedata* >::const_iterator it;
for (it = s->all_files.begin() ; it != s->all_files.end() ; ++it)
{
// When in pretty mode, we still want to avoid printing
// A matches A (100).
if (s->mode & mode_match_pretty)
{
if (!(_tcsncmp(f->get_filename(),
(*it)->get_filename(),
std::max(fn_len,_tcslen((*it)->get_filename())))) and
(f->get_signature() == (*it)->get_signature()))
{
// Unless these results from different matching files (such as
// what happens in sigcompare mode). That being said, we have to
// be careful to avoid NULL values such as when working in
// normal pretty print mode.
if (not(f->has_match_file()) or
f->get_match_file() == (*it)->get_match_file())
continue;
}
}
int score = fuzzy_compare(f->get_signature().c_str(),
(*it)->get_signature().c_str());
if (-1 == score)
print_error(s, "%s: Bad hashes in comparison", __progname);
else
{
if (score > s->threshold or MODE(mode_display_all))
{
handle_match(s,f,(*it),score);
status = true;
}
}
}
return status;
}
bool find_matches_in_known(state *s)
{
if (NULL == s)
return true;
// Walk the vector which contains all of the known files
std::vector<Filedata *>::const_iterator it;
for (it = s->all_files.begin() ; it != s->all_files.end() ; ++it)
{
bool status = match_compare(s,*it);
// In pretty mode and sigcompare mode we need to display a blank
// line after each file. In clustering mode we don't display anything
// right now.
if (status and not(MODE(mode_cluster)))
print_status("");
}
return false;
}
bool match_add(state *s, Filedata * f)
{
if (NULL == s)
return true;
s->all_files.push_back(f);
return false;
}
bool match_load(state *s, const char *fn)
{
if (NULL == s or NULL == fn)
return true;
if (sig_file_open(s,fn))
return true;
bool status;
do
{
Filedata * f;
status = sig_file_next(s,&f);
if (not status)
{
if (match_add(s,f))
{
// One bad hash doesn't mean this load was a failure.
// We don't change the return status because match_add failed.
print_error(s,"%s: unable to insert hash", fn);
break;
}
}
} while (not sig_file_end(s));
sig_file_close(s);
return false;
}
bool match_compare_unknown(state *s, const char * fn)
{
if (NULL == s or NULL == fn)
return true;
if (sig_file_open(s,fn))
return true;
bool status;
do
{
Filedata *f;
status = sig_file_next(s,&f);
if (not status)
match_compare(s,f);
} while (not sig_file_end(s));
sig_file_close(s);
return false;
}
#ifndef __MATCH_H
#define __MATCH_H
// SSDEEP
// $Id$
// Copyright (C) 2012 Kyrus.
#include "ssdeep.h"
#include "filedata.h"
// *********************************************************************
// Matching functions
// *********************************************************************
/// @brief Match the file f against the set of knowns
///
/// @return Returns false if there are no matches, true if at least one match
/// @param s State variable
/// @param f Filedata structure for the file.
bool match_compare(state *s, Filedata * f);
/// @brief Load a file of known hashes
///
/// @return Returns false on success, true on error
bool match_load(state *s, const char *fn);
/// @brief Add a single new hash to the set of known hashes
///
/// @return Returns false on success, true on error
bool match_add(state *s, Filedata * f);
/// Find and display all matches in the set of known hashes
bool find_matches_in_known(state *s);
/// Load the known hashes from the file fn and compare them to the
/// set of known hashes
bool match_compare_unknown(state *s, const char * fn);
/// Display the results of clustering operations
void display_clusters(const state *s);
#endif // ifndef __MATCH_H
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
/* Fuzzy Hashing by Jesse Kornblum
Copyright (C) 2010 ManTech International Corporation
This program demonstrates some of the capabilities of
the fuzzy hashing library.
To compile the program using gcc:
$ gcc -Wall -I/usr/local/include -L/usr/local/lib sample.c -Lfuzzy
Using mingw:
C:\> gcc -Wall -Ic:\path\to\includes sample.c fuzzy.dll
Using Microsoft Visual C:
C:\> lib /machine:i386 /def:fuzzy.def
C:\> cl sample.c fuzzy.lib
See the README that came with this file for more details on using
the library on Windows systems with Microsoft Visual C.
The functions generate_random and write_data are generic routines to make
random data for hashing. The real magic happens in the main() function.
THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). THE AUTHOR
SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
HIGH RISK ACTIVITIES. */
// $Id: sample.c 97 2010-03-19 15:10:06Z jessekornblum $
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <fuzzy.h>
#define FILENAME "foo.dat"
#define SIZE 0x50000
void generate_random(unsigned char *buf, uint32_t sz)
{
uint32_t i;
for (i = 0 ; i < sz ; ++i)
buf[i] = (unsigned char)(rand() % 255);
buf[(sz-1)] = 0;
}
int write_data(const unsigned char *buf,
const uint32_t sz,
const char *fn)
{
printf ("Writing to %s\n", fn);
FILE * handle = fopen(fn,"wb");
if (NULL == handle)
return 1;
fwrite(buf,sz,1,handle);
fclose(handle);
return 0;
}
int main(int argc, char **argv)
{
unsigned char * buf;
char * result, * result2;
FILE *handle;
srand(1);
buf = (unsigned char *)malloc(SIZE);
result = (char *)malloc(FUZZY_MAX_RESULT);
result2 = (char *)malloc(FUZZY_MAX_RESULT);
if (NULL == result || NULL == buf || NULL == result2)
{
fprintf (stderr,"%s: Out of memory\n", argv[0]);
return EXIT_FAILURE;
}
generate_random(buf,SIZE);
if (write_data(buf,SIZE,FILENAME))
return EXIT_FAILURE;
printf ("Hashing buffer\n");
int status = fuzzy_hash_buf(buf,SIZE,result);
if (status)
printf ("Error during buf hash\n");
else
printf ("%s\n", result);
handle = fopen(FILENAME,"rb");
if (NULL == handle)
{
perror(FILENAME);
return EXIT_FAILURE;
}
printf ("Hashing file\n");
status = fuzzy_hash_file(handle,result);
if (status)
printf ("Error during file hash\n");
else
printf ("%s\n", result);
fclose(handle);
printf ("Modifying buffer and comparing to file\n");
int i;
for (i = 0x100 ; i < 0x110 ; ++i)
buf[i] = 37;
status = fuzzy_hash_buf(buf,SIZE,result2);
if (status)
printf ("Error during buffer hash\n");
else
printf ("%s\n", result2);
i = fuzzy_compare(result,result2);
if (-1 == i)
printf ("An error occured during matching\n");
else
{
if (i != 0)
printf ("MATCH: score = %d\n", i);
else
printf ("did not match\n");
}
return EXIT_SUCCESS;
}
.TH SSDEEP "1" "Version 2.10 \- 17 Jul 2013" "Facebook" "Facebook"
.SH NAME
ssdeep - Computes context triggered piecewise hashes (fuzzy hashes)
.SH SYNOPSIS
.B ssdeep [-m <file>] [-k <file>] [-vdprgsblcxa] [-t val] [FILES]
.br
.B ssdeep [-V|h]
.SH DESCRIPTION
.PP
Computes a signature based on context triggered piecewise hashes
for each input file, also called a fuzzy hash.
If requested, the program matches those signatures against
a file of known signatures and reports any possible matches.
It can also examine one or more files of signatures and find any
matches in those files.
Output is written to standard out and errors to standard error.
The program only accepts the first 100MB of data presented
via standard input.
.TP
\fB\-m <file>\fR
Loads the specified file of known hashes to be used for matching. This file must
be a previous output of the program. The program
then hashes each entry in FILES and compares these signatures to the known signatures.
Any matches which score above the threshold are displayed.
This flag may be used multiple times to load more known signatures.
This flag may not be used with the \-k or \-x flags.
.TP
\fB\-k <file>\fR
Load the specified file of known hashes to be used for matching. This file must
be a previous output of the program. The program
then treats each entry in FILES as a set of known hashes as well. The hashes in these
FILES are compared to the known hashes from this file. Matches which score
above the threshold are displayed. Both the file specified here and the
input FILES should contain fuzzy hashes.
This flag may be used multiple times to load more known signatures.
This flag may not be used with the \-m, \-d, or \-p flags.
.TP
\fB\-v\fR
Verbose mode. The name of each file is printed to standard error
as it is being hashed.
.TP
\fB\-d\fR
Computes a signature for each entry in the FILES and compares it to the set
of known signatures. Matches which score above the threshold are displayed. The
computed signature is then added to the set of known signatures.
This flag may not be used with the \-k or \-x flags.
.TP
\fB\-p\fR
Works like the \-d flag, but displays all matches for each file. That is,
for two files A and B which match score above the threshold, displays
"A matches B" and "B matches A".
This flag may not be used with the \-k or \-x flags.
.TP
\fB\-r\fR
Enables recursive mode. All subdirectories are traversed.
Please note that recursive mode cannot be used to examine all
files of a given file extension. For example, invoking the program with
\fB\-r *.txt\fR will examine all files in directories that end in .txt.
If you want to process all files in a directory tree with the .txt suffix,
try using the \fBfind(1)\fR command.
.TP
\fB\-g\fR
Similar files are grouped together into clusters. This can be handy
for finding more similar files. That is, if you are searching for file
A, which matches B, anything which matches B will also be included in
the cluster.
.TP
\fB\-s\fR
Silent mode. All error messages are suppressed.
.TP
\fB\-b\fR
Enables bare mode. Strips any leading directory information from
displayed filenames.
This flag may not be used in conjunction with the \fB\-l\fR flag.
.TP
\fB\-l\fR
Enables relative file paths. Instead of printing the absolute path for
each file, displays the relative file path as indicated on the command
line. This flag may not be used in conjunction with the \fB\-b\fR flag.
.TP
\fB\-c\fR
Enables comma separated output mode. In any of the matching modes
\-d, \-p, or \-m,
displays the results as input file, known file, matching score.
.TP
\fB\-x\fR
Signature file matching.
Each entry in FILES must contain signatures generated by a previous output
of the program. Each signature is loaded and compared against the set of
known hashes. Match scores above the threshold are displayed. Each signature
is then added to the set of knowns.
This flag may not be used with the \-m, \-d, or \-p flags.
.TP
\fB\-a\fR
Displays all matches in any of the matching mode, regardless of score.
Using the \-a flag displays all results, even if the match score is zero.
.TP
\fB\-t <val>\fR
In any of the matching modes, only display matches when match
score is greater than the given value. The default threshold value is zero.
.TP
\fB\-h\fR
Show a help screen and exit.
.TP
\fB\-V\fR
Show the version number and exit.
.SH RETURN VALUE
Returns 0 on success, 1 if there is a problem.
Read errors, permission denied, and encountering directories while
not in recursive mode are still considered successes. Problems are
things like being unable to load the matching file, specifying
both bare and relative paths, etc.
.SH AUTHOR
ssdeep was written by Jesse Kornblum of Facebook,
.br
research@jessekornblum.com
.PP
.SH COPYRIGHT
This program is Copyright (C) 2013 Facebook and is licensed under the terms
of the General Public License. See the file COPYING for details.
.SH SEE ALSO
This program is based on SpamSum by Dr. Andrews Tridgell.
.br
http://www.samba.org/ftp/unpacked/junkcode/spamsum/
#ifndef __SSDEEP_H
#define __SSDEEP_H
// Fuzzy Hashing by Jesse Kornblum
// Copyright (C) 2013 Facebook
// Copyright (C) 2012 Kyrus
// Copyright (C) 2008 ManTech International Corporation
//
// $Id: ssdeep.h 190 2013-07-11 00:40:22Z jessekornblum $
//
#include "main.h"
#include <string>
#include <map>
#include <set>
#include <vector>
#include "fuzzy.h"
#include "tchar-local.h"
#include "filedata.h"
// This is a kludge, but it works.
#define __progname "ssdeep"
#define SSDEEPV1_0_HEADER "ssdeep,1.0--blocksize:hash:hash,filename"
#define SSDEEPV1_1_HEADER "ssdeep,1.1--blocksize:hash:hash,filename"
#define OUTPUT_FILE_HEADER SSDEEPV1_1_HEADER
// We print a warning for files smaller than this size
#define SSDEEP_MIN_FILE_SIZE 4096
// The default 'PATH_MAX' on Windows is about 255 bytes. We can expand
// this limit to 32,767 characters by prepending filenames with "\\?\"
#define SSDEEP_PATH_MAX 32767
#define MD5DEEP_ALLOC(TYPE,VAR,SIZE) \
VAR = (TYPE *)malloc(sizeof(TYPE) * SIZE); \
if (NULL == VAR) \
return EXIT_FAILURE; \
memset(VAR,0,SIZE * sizeof(TYPE));
// These are the types of files we can encounter while hashing
#define file_regular 0
#define file_directory 1
#define file_door 2
#define file_block 3
#define file_character 4
#define file_pipe 5
#define file_socket 6
#define file_symlink 7
#define file_unknown 254
typedef struct _filedata_t
{
uint64_t id;
/// Original signature in the form [blocksize]:[sig1]:[sig2]
std::string signature;
uint64_t blocksize;
/// Holds signature equal to blocksize
std::string s1;
/// Holds signature equal to blocksize * 2
std::string s2;
TCHAR * filename;
/// File of hashes where we got this known file from.
std::string match_file;
/// Cluster which contains this file
std::set<_filedata_t> * cluster;
} filedata_t;
typedef struct {
uint64_t mode;
bool first_file_processed;
// Known hashes
std::vector<Filedata *> all_files;
// Known clusters
std::set< std::set<Filedata *> * > all_clusters;
/// Display files who score above the threshold
uint8_t threshold;
bool found_meaningful_file;
bool processed_file;
int argc;
TCHAR **argv;
/// Current line number in file of known hashes
uint64_t line_number;
/// File handle to file of known hashes
FILE * known_handle;
/// Filename of known hashes
char * known_fn;
} state;
#define MM_INIT printf
// Things required when cross compiling for Microsoft Windows
#ifdef _WIN32
// We create macros for the Windows equivalent UNIX functions.
// No worries about lstat to stat; Windows doesn't have symbolic links
#define lstat(A,B) stat(A,B)
#define realpath(A,B) _fullpath(B,A,PATH_MAX)
#define snprintf _snprintf
char *basename(char *a);
extern char *optarg;
extern int optind;
int getopt(int argc, char *const argv[], const char *optstring);
#define NEWLINE "\r\n"
#define DIR_SEPARATOR '\\'
#else // ifdef _WIN32
// For all other operating systems
#define NEWLINE "\n"
#define DIR_SEPARATOR '/'
#endif // ifdef _WIN32/else
// Because the modes are stored in a uint64_t variable, they must
// be less than or equal to 1<<63
#define mode_none 0
#define mode_recursive 1
#define mode_match 1<<1
#define mode_barename 1<<2
#define mode_relative 1<<3
#define mode_silent 1<<4
#define mode_directory 1<<5
#define mode_match_pretty 1<<6
#define mode_verbose 1<<7
#define mode_csv 1<<8
#define mode_threshold 1<<9
#define mode_sigcompare 1<<10
#define mode_display_all 1<<11
#define mode_compare_unknown 1<<12
#define mode_cluster 1<<13
#define mode_recursive_cluster 1<<14
#define MODE(A) (s->mode & A)
#define BLANK_LINE \
" "
// *********************************************************************
// Checking for cycles
// *********************************************************************
int done_processing_dir(TCHAR *fn);
int processing_dir(TCHAR *fn);
int have_processed_dir(TCHAR *fn);
bool process_win32(state *s, TCHAR *fn);
int process_normal(state *s, TCHAR *fn);
int process_stdin(state *s);
// *********************************************************************
// Fuzzy Hashing Engine
// *********************************************************************
int hash_file(state *s, TCHAR *fn);
bool display_result(state *s, const TCHAR * fn, const char * sum);
// *********************************************************************
// Helper functions
// *********************************************************************
void try_msg(void);
bool expanded_path(TCHAR *p);
void sanity_check(state *s, int condition, const char *msg);
// The basename function kept misbehaving on OS X, so I rewrote it.
// This function isn't perfect, nor is it designed to be. Because
// we're guarenteed to be working with a filename here, there's no way
// that s will end with a DIR_SEPARATOR (e.g. /foo/bar/). This function
// will not work properly for a string that ends in a DIR_SEPARATOR
int my_basename(TCHAR *s);
int my_dirname(TCHAR *s);
// Remove the newlines, if any, from the string. Works with both
// \r and \r\n style newlines
void chop_line_tchar(TCHAR *s);
void chop_line(char *s);
int find_comma_separated_string_tchar(TCHAR *s, unsigned int n);
void shift_string_tchar(TCHAR *fn, unsigned int start, unsigned int new_start);
int find_comma_separated_string(char *s, unsigned int n);
void shift_string(char *fn, size_t start, size_t new_start);
int remove_escaped_quotes(char * str);
void prepare_filename(state *s, TCHAR *fn);
// Returns the size of the given file, in bytes.
#ifdef __cplusplus
extern "C" {
#endif
off_t find_file_size(FILE *h);
#ifdef __cplusplus
}
#endif
// *********************************************************************
// User Interface Functions
// *********************************************************************
void print_status(const char *fmt, ...);
void print_error(const state *s, const char *fmt, ...);
void print_error_unicode(state *s, const TCHAR *fn, const char *fmt, ...);
void internal_error(const char *fmt, ... );
void fatal_error(const char *fmt, ... );
void display_filename(FILE *out, const TCHAR *fn, int escape_quotes);
#endif // #ifndef __SSDEEP_H
/* $Id: tchar-local.h 61 2008-02-22 23:18:59Z jessekornblum $ */
#ifndef __TCHAR_LOCAL_H
#define __TCHAR_LOCAL_H
/* Unicode support */
#ifdef _WIN32
// This says that we require Windows NT 4.0 to run
#define _WIN32_WINNT 0x0400
# include <windows.h>
# include <wchar.h>
# include <tchar.h>
/* The PRINTF_S character is used in situations where we have a string
with one TCHAR and one char argument. It's impossible to use the
_TEXT macro because we don't know which will be which. */
#define PRINTF_S "S"
#define _tmemmove wmemmove
/* The Win32 API does have lstat, just stat. As such, we don't have to
worry about the difference between the two. */
#define _lstat _tstat
#define _sstat _tstat
#define _tstat_t struct _stat
#else // ifdef _WIN32
#define PRINTF_S "s"
/* The next few paragraphs are similar to tchar.h when UNICODE
is not defined. They define all of the _t* functions to use
the standard char * functions. This works just fine on Linux and OS X */
#define TCHAR char
#define _TDIR DIR
#define _TEXT(A) A
#define _sntprintf snprintf
#define _tprintf printf
#define _ftprintf fprintf
#define _lstat lstat
#define _sstat stat
#define _tstat_t struct stat
#define _tgetcwd getcwd
#define _tfopen fopen
#define _fgetts fgets
#define _topendir opendir
#define _treaddir readdir
#define _tdirent dirent
#define _tclosedir closedir
#define _tcsncpy strncpy
#define _tcslen strlen
#define _tcsnicmp strncasecmp
#define _tcsncmp strncmp
#define _tcsrchr strrchr
#define _tmemmove memmove
#define _tcsdup strdup
#define _tcsstr strstr
#endif
#endif // __TCHAR_LOCAL_H
/* $Id: ui.cpp 152 2012-07-14 18:09:45Z jessekornblum $ */
#include "ssdeep.h"
#include <stdarg.h>
void print_status(const char *fmt, ...)
{
va_list(ap);
va_start(ap,fmt);
vprintf(fmt,ap);
va_end(ap);
printf ("%s", NEWLINE);
}
void print_error(const state *s, const char *fmt, ...)
{
if (NULL == s)
internal_error("%s: NULL state passed to print_error", __progname);
if (s->mode & mode_silent)
return;
va_list(ap);
va_start(ap,fmt);
vfprintf(stderr,fmt,ap);
va_end(ap);
fprintf (stderr,"%s", NEWLINE);
}
#define MD5DEEP_PRINT_MSG(HANDLE,MSG) \
va_list(ap); \
va_start(ap,MSG); \
if (vfprintf(HANDLE,MSG,ap) < 0) \
{ \
fprintf(stderr, "%s: %s", __progname, strerror(errno)); \
exit(EXIT_FAILURE); \
} \
va_end(ap); fprintf (HANDLE,"%s", NEWLINE);
void print_error_unicode(state *s, const TCHAR *fn, const char *fmt, ...)
{
if (NULL == s)
internal_error("%s: NULL state passed to print_error_unicode", __progname);
if (!(s->mode & mode_silent))
{
display_filename(stderr,fn,FALSE);
fprintf(stderr,": ");
MD5DEEP_PRINT_MSG(stderr,fmt);
}
}
/* Internal errors are so serious that we ignore the user's wishes
about silent mode. Our need to debug the program outweighs their
preferences. Besides, the program is probably crashing anyway... */
void internal_error(const char *fmt, ... )
{
MD5DEEP_PRINT_MSG(stderr,fmt);
print_status ("%s: Internal error. Contact developer!", __progname);
exit (EXIT_FAILURE);
}
void fatal_error(const char *fmt, ... )
{
va_list(ap);
va_start(ap,fmt);
vprintf(fmt,ap);
va_end(ap);
printf ("%s", NEWLINE);
exit (EXIT_FAILURE);
}
#ifdef _WIN32
void display_filename(FILE *out, const TCHAR *fn, int escape_quotes)
{
size_t pos,len;
if (NULL == fn || NULL == out)
return;
len = _tcslen(fn);
for (pos = 0 ; pos < len ; ++pos)
{
// If desired, escape quotation marks. Used for CSV modes
if (escape_quotes && ('"' == ((fn[pos] & 0xff00) >> 16)))
{
fprintf(out,"\\\"");
}
else
{
// Windows can only display the English (00) code page
// on the command line.
if (0 == (fn[pos] & 0xff00))
fputc(fn[pos],out);
// _ftprintf(out, _TEXT("%c"), fn[pos]);
else
fputc('?',out);
// _ftprintf(out, _TEXT("?"));
}
}
}
#else
void display_filename(FILE *out, const TCHAR *fn, int escape_quotes)
{
size_t pos, len;
if (NULL == fn || NULL == out)
return;
len = _tcslen(fn);
for (pos = 0 ; pos < len ; ++pos)
{
if (escape_quotes && '"' == fn[pos])
_ftprintf(out, _TEXT("\\\""));
else
_ftprintf(out, _TEXT("%c"), fn[pos]);
}
}
#endif
......@@ -29,8 +29,9 @@
# MIPS16e
# nop (x4)
0 string \x65\x00\x65\x00\x65\x00\x65\x00 MIPS16e instructions, nops{jump-to-offset:8}
0 string \x00\x65\x00\x65\x00\x65\x00\x65 MIPSEL16e instructions, nops{jump-to-offset:8}
# TODO: Produces false positives when scanning ARM Thumb code
#0 string \x65\x00\x65\x00\x65\x00\x65\x00 MIPS16e instructions, nops{jump-to-offset:8}
#0 string \x00\x65\x00\x65\x00\x65\x00\x65 MIPSEL16e instructions, nops{jump-to-offset:8}
# save a0-a1, XX
# addiu XX, XX
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment