// ***************************************************************** -*- C++ -*- /* * Copyright (C) 2004-2015 Andreas Huggel * * This program is part of the Exiv2 distribution. * * 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, 5th Floor, Boston, MA 02110-1301 USA. */ /* File: version.cpp Version: $Rev$ Author(s): Andreas Huggel (ahu) History: 06-Mar-07, ahu: created */ // ***************************************************************************** #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") // ***************************************************************************** #include "config.h" #ifndef EXV_USE_SSH #define EXV_USE_SSH 0 #endif #ifndef EXV_USE_CURL #define EXV_USE_CURL 0 #endif #if EXV_USE_CURL == 1 #include #endif #if defined(__CYGWIN__) || defined(__MINGW__) #include # if __LP64__ # ifdef _WIN64 # undef _WIN64 # endif # define _WIN64 1 # endif #endif #ifndef EXV_HAVE_XMP_TOOLKIT #define EXV_HAVE_XMP_TOOLKIT 0 #endif #ifndef EXV_HAVE_STRINGS #define EXV_HAVE_STRINGS 0 #endif #ifndef EXV_SYS_TYPES #define EXV_SYS_TYPES 0 #endif #ifndef EXV_HAVE_UNISTD #define EXV_HAVE_UNISTD 0 #endif #ifndef EXV_UNICODE_PATH #define EXV_UNICODE_PATH 0 #endif #ifndef EXV_ENABLE_VIDEO #define EXV_ENABLE_VIDEO 0 #endif #ifndef EXV_ENABLE_WEBREADY #define EXV_ENABLE_WEBREADY 0 #endif #include "http.hpp" #include "svn_version.h" #include "version.hpp" // Adobe XMP Toolkit #if EXV_HAVE_XMP_TOOLKIT #include "xmp.hpp" #endif // + standard includes #include #include #include #include #include #include // #1147 #ifndef WIN32 #include #include #endif namespace Exiv2 { int versionNumber() { return EXIV2_MAKE_VERSION(EXIV2_MAJOR_VERSION, EXIV2_MINOR_VERSION, EXIV2_PATCH_VERSION); } std::string versionString() { std::ostringstream os; os << EXIV2_MAJOR_VERSION << '.' << EXIV2_MINOR_VERSION << '.' << EXIV2_PATCH_VERSION; return os.str(); } std::string versionNumberHexString() { std::ostringstream os; os << std::hex << std::setw(6) << std::setfill('0') << Exiv2::versionNumber(); return os.str(); } const char* version() { return EXV_PACKAGE_VERSION; } bool testVersion(int major, int minor, int patch) { return versionNumber() >= EXIV2_MAKE_VERSION(major,minor,patch); } } // namespace Exiv2 #ifndef lengthof #define lengthof(x) sizeof(x)/sizeof(x[0]) #endif #ifndef _MAX_PATH #define _MAX_PATH 512 #endif // platform specific support for dumpLibraryInfo #if defined(WIN32) # include # include // tell MSVC to link psapi. #ifdef _MSC_VER #pragma comment( lib, "psapi" ) #endif #elif defined(__APPLE__) # include #elif defined(__linux__) # include // http://syprog.blogspot.com/2011/12/listing-loaded-shared-objects-in-linux.html # include struct something { void* pointers[3]; struct something* ptr; }; struct lmap { void* base_address; /* Base address of the shared object */ char* path; /* Absolute file name (path) of the shared object */ void* not_needed1; /* Pointer to the dynamic section of the shared object */ struct lmap *next, *prev;/* chain of loaded objects */ }; #endif static bool shouldOutput(const exv_grep_keys_t& greps,const char* key,const std::string& value) { bool bPrint = greps.empty(); for( exv_grep_keys_t::const_iterator g = greps.begin(); !bPrint && g != greps.end() ; ++g ) { #if __cplusplus >= CPLUSPLUS11 std::smatch m; bPrint = std::regex_search(std::string(key),m,*g) || std::regex_search(value,m,*g); #else #if EXV_HAVE_REGEX bPrint = ( 0 == regexec( &(*g), key , 0, NULL, 0) || 0 == regexec( &(*g), value.c_str(), 0, NULL, 0) ); #else std::string Pattern(g->pattern_); std::string Key(key); std::string Value(value); if ( g->bIgnoreCase_ ) { // https://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/ std::transform(Pattern.begin(), Pattern.end(),Pattern.begin(), ::tolower); std::transform(Key.begin() , Key.end() ,Key.begin() , ::tolower); std::transform(Value.begin() , Value.end() ,Value.begin() , ::tolower); } bPrint = Key.find(Pattern) != std::string::npos || Value.find(Pattern) != std::string::npos; #endif #endif } return bPrint; } static void output(std::ostream& os,const exv_grep_keys_t& greps,const char* name,const std::string& value) { if ( shouldOutput(greps,name,value) ) os << name << "=" << value << std::endl; } static void output(std::ostream& os,const exv_grep_keys_t& greps,const char* name,int value) { std::ostringstream stringStream; stringStream << value; output(os,greps,name,stringStream.str()); } void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys) { Exiv2::StringVector libs; // libs[0] == executable int bits = 8*sizeof(void*); #if defined(_DEBUG) || defined(DEBUG) int debug=1; #else int debug=0; #endif #if defined(DLL_EXPORT) || defined(EXV_HAVE_DLL) int dll=1; #else int dll=0; #endif const char* compiler = #if defined(_MSC_VER) "MSVC" ; #ifndef __VERSION__ char version[40]; sprintf(version,"%d.%02d",(_MSC_VER-600)/100,_MSC_VER%100); // add edition in brackets // 7.10 = 2003 8.00 = 2005 etc 12.00 = 2013 13.00 = 2015 (yet the installer labels it as 14.0!) size_t edition = (_MSC_VER-600)/100; const char* editions[] = { "0","1","2","3","4","5","6","2003", "2005", "2008", "2010", "2012","2013","2015"}; if ( edition > lengthof(editions) ) edition = 0 ; if ( edition ) sprintf(version+::strlen(version)," (%s/%s)",editions[edition],bits==64?"x64":"x86"); #define __VERSION__ version #endif #elif defined(__clang__) "Clang" ; #elif defined(__GNUG__) "G++" ; #elif defined(__GNUC__) "GCC" ; #elif defined(__SUNPRO_CC) "CC (oracle)"; #elif defined (__SUNPRO_C) "cc (oracle)"; #else "unknown" ; #endif #if defined(__SUNPRO_CC) || defined (__SUNPRO_C) #define __oracle__ #endif #ifndef __VERSION__ #ifdef __clang__version__ #define __VERSION__ __clang__version__ #else #define __VERSION__ "unknown" #endif #endif const char* platform = #if defined(__CYGWIN__) "cygwin"; #elif defined(_MSC_VER) "windows"; #elif defined(__APPLE__) "apple"; #elif defined(__MINGW64__) "mingw64"; #elif defined(__MINGW32__) "mingw32"; #elif defined(__linux__) "linux"; #else "unknown"; #endif int have_regex =0; int have_gmtime_r =0; int have_inttypes =0; int have_libintl =0; int have_lensdata =0; int have_iconv =0; int have_memory =0; int have_memset =0; int have_lstat =0; int have_stdbool =0; int have_stdint =0; int have_stdlib =0; int have_strlib =0; int have_strchr =0; int have_strerror =0; int have_strerror_r =0; int have_strings_h =0; int have_strtol =0; int have_mmap =0; int have_munmap =0; int have_sys_stat =0; int have_timegm =0; int have_unistd_h =0; int have_sys_mman =0; int have_libz =0; int have_xmptoolkit =0; int have_bool =0; int have_strings =0; int have_sys_types =0; int have_unistd =0; int have_unicode_path=0; int enable_video =0; int enable_webready =0; #if EXV_HAVE_DECL_STRERROR_R have_strerror_r=1; #endif #if EXV_HAVE_GMTIME_R have_gmtime_r=1; #endif #if EXV_HAVE_INTTYPES_H have_inttypes=1; #endif #if EXV_HAVE_LIBINTL_H have_libintl=1; #endif #if EXV_HAVE_LENSDATA have_lensdata=1; #endif #if EXV_HAVE_ICONV have_iconv=1; #endif #if EXV_HAVE_LIBINTL_H have_libintl=1; #endif #if EXV_HAVE_REGEX have_regex=1; #endif #if EXV_HAVE_MEMORY_H have_memory=1; #endif #if EXV_HAVE_MEMSET have_memset=1; #endif #if EXV_HAVE_LSTAT have_lstat=1; #endif #if EXV_HAVE_STDBOOL_H have_stdbool=1; #endif #if EXV_HAVE_STDINT_H have_stdint=1; #endif #if EXV_HAVE_STDLIB_H have_stdlib=1; #endif #if EXV_HAVE_STRCHR have_strchr=1; #endif #if EXV_HAVE_STRERROR have_strerror=1; #endif #if EXV_HAVE_STRERROR_R have_strerror_r=1; #endif #if EXV_HAVE_STRINGS_H have_strings=1; #endif #if EXV_HAVE_STRTOL have_strtol=1; #endif #if EXV_HAVE_MMAP have_mmap=1; #endif #if EXV_HAVE_MUNMAP have_munmap=1; #endif #if EXV_HAVE_SYS_STAT_H have_sys_stat=1; #endif #if EXV_HAVE_SYS_TYPES_H have_sys_types=1; #endif #if EXV_HAVE_TIMEGM have_timegm=1; #endif #if EXV_HAVE_UNISTD_H have_unistd=1; #endif #if EXV_HAVE_SYS_MMAN_H have_sys_mman=1; #endif #if EXV_HAVE_LIBZ have_libz=1; #endif #if EXV_HAVE_XMP_TOOLKIT have_xmptoolkit=1; #endif #if EXV_HAVE__BOOL have_bool=1; #endif #if EXV_HAVE_STRINGS have_strings=1; #endif #if EXV_SYS_TYPES have_sys_types=1; #endif #if EXV_HAVE_UNISTD have_unistd=1; #endif #if EXV_UNICODE_PATH have_unicode_path=1; #endif #if EXV_ENABLE_VIDEO enable_video=1; #endif #if EXV_ENABLE_WEBREADY enable_webready=1; #endif #if defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW__) // enumerate loaded libraries and determine path to executable HMODULE handles[200]; DWORD cbNeeded; if ( EnumProcessModules(GetCurrentProcess(),handles,lengthof(handles),&cbNeeded)) { char szFilename[_MAX_PATH]; for ( DWORD h = 0 ; h < cbNeeded/sizeof(handles[0]) ; h++ ) { GetModuleFileNameA(handles[h],szFilename,lengthof(szFilename)) ; libs.push_back(szFilename); } } #elif defined(__APPLE__) // man 3 dyld uint32_t count = _dyld_image_count(); for (uint32_t image = 0 ; image < count ; image++ ) { const char* image_path = _dyld_get_image_name(image); libs.push_back(image_path); } #elif defined(__linux__) // http://stackoverflow.com/questions/606041/how-do-i-get-the-path-of-a-process-in-unix-linux char proc[100]; char path[500]; sprintf(proc,"/proc/%d/exe", getpid()); int l = readlink (proc, path,sizeof(path)-1); if (l>0) { path[l]=0; libs.push_back(path); } else { libs.push_back("unknown"); } // http://syprog.blogspot.com/2011/12/listing-loaded-shared-objects-in-linux.html struct lmap* pl; void* ph = dlopen(NULL, RTLD_NOW); struct something* p = (struct something*) ph; p = p->ptr; pl = (struct lmap*)p->ptr; while ( pl ) { libs.push_back(pl->path); pl = pl->next; } #endif output(os,keys,"exiv2",Exiv2::versionString()); output(os,keys,"platform" , platform ); output(os,keys,"compiler" , compiler ); output(os,keys,"bits" , bits ); output(os,keys,"dll" , dll ); output(os,keys,"debug" , debug ); output(os,keys,"cplusplus" , __cplusplus); output(os,keys,"cplusplus11" , __cplusplus >= CPLUSPLUS11 ); output(os,keys,"version" , __VERSION__); output(os,keys,"date" , __DATE__ ); output(os,keys,"time" , __TIME__ ); output(os,keys,"svn" , SVN_VERSION); output(os,keys,"ssh" , EXV_USE_SSH); #if EXV_USE_CURL == 1 std::string curl_protocols; curl_version_info_data* vinfo = curl_version_info(CURLVERSION_NOW); for (int i = 0; vinfo->protocols[i]; i++) { curl_protocols += vinfo->protocols[i]; curl_protocols += " " ; } output(os,keys,"curlprotocols" ,curl_protocols); #else output(os,keys,"curl" , EXV_USE_CURL); #endif output(os,keys,"id" , "$Id$"); if ( libs.begin() != libs.end() ) { output(os,keys,"executable" ,*libs.begin()); for ( Exiv2::StringVector_i lib = libs.begin()+1 ; lib != libs.end() ; lib++ ) output(os,keys,"library",*lib); } output(os,keys,"have_regex" ,have_regex ); output(os,keys,"have_strerror_r" ,have_strerror_r ); output(os,keys,"have_gmtime_r" ,have_gmtime_r ); output(os,keys,"have_inttypes" ,have_inttypes ); output(os,keys,"have_libintl" ,have_libintl ); output(os,keys,"have_lensdata" ,have_lensdata ); output(os,keys,"have_iconv" ,have_iconv ); output(os,keys,"have_memory" ,have_memory ); output(os,keys,"have_memset" ,have_memset ); output(os,keys,"have_lstat" ,have_lstat ); output(os,keys,"have_stdbool" ,have_stdbool ); output(os,keys,"have_stdint" ,have_stdint ); output(os,keys,"have_stdlib" ,have_stdlib ); output(os,keys,"have_strlib" ,have_strlib ); output(os,keys,"have_strchr" ,have_strchr ); output(os,keys,"have_strerror" ,have_strerror ); output(os,keys,"have_strerror_r" ,have_strerror_r ); output(os,keys,"have_strings_h" ,have_strings_h ); output(os,keys,"have_strtol" ,have_strtol ); output(os,keys,"have_mmap" ,have_mmap ); output(os,keys,"have_munmap" ,have_munmap ); output(os,keys,"have_sys_stat" ,have_sys_stat ); output(os,keys,"have_timegm" ,have_timegm ); output(os,keys,"have_unistd_h" ,have_unistd_h ); output(os,keys,"have_sys_mman" ,have_sys_mman ); output(os,keys,"have_libz" ,have_libz ); output(os,keys,"have_xmptoolkit" ,have_xmptoolkit ); output(os,keys,"have_bool" ,have_bool ); output(os,keys,"have_strings" ,have_strings ); output(os,keys,"have_sys_types" ,have_sys_types ); output(os,keys,"have_unistd" ,have_unistd ); output(os,keys,"have_unicode_path" ,have_unicode_path); output(os,keys,"enable_video" ,enable_video ); output(os,keys,"enable_webready" ,enable_webready ); // #1147 #ifndef WIN32 uid_t uid = getuid() ; output(os,keys,"uid" , uid ); uid_t euid = geteuid() ; output(os,keys,"euid", euid ); uid_t gid = getgid() ; output(os,keys,"gid" , gid ); #endif #if EXV_HAVE_XMP_TOOLKIT const char* name = "xmlns"; Exiv2::Dictionary ns; Exiv2::XmpProperties::registeredNamespaces(ns); for ( Exiv2::Dictionary_i it = ns.begin(); it != ns.end() ; it++ ) { std::string xmlns = (*it).first; std::string uri = (*it).second; output(os,keys,name,xmlns+":"+uri); } #endif #if defined(__linux__) dlclose(ph); ph=NULL; #endif }