NetBSD/FreeBSD Support
This commit is contained in:
parent
6a44698abc
commit
b0a9cb5624
38
README.md
38
README.md
@ -33,6 +33,7 @@
|
||||
3. [MinGW](#5-3)
|
||||
4. [Cygwin](#5-4)
|
||||
5. [Microsoft Visual C++](#5-5)
|
||||
6. [Unix](#5-6)
|
||||
|
||||
<div id="1">
|
||||
|
||||
@ -803,7 +804,6 @@ set "PS1=\! CYGWIN64:\u@\h:\w \$ "
|
||||
bash.exe -norc
|
||||
```
|
||||
|
||||
|
||||
[TOC](#TOC)
|
||||
<div id="5-5">
|
||||
|
||||
@ -827,8 +827,42 @@ set "PATH=C:\Python37\;C:\Python27\;C:\Python27\Scripts;C:\Perl64\site\bin;C:\Pe
|
||||
cmd
|
||||
```
|
||||
|
||||
[TOC](#TOC)
|
||||
<div id="5-6">
|
||||
|
||||
### Unix
|
||||
|
||||
Exiv2 can be built on many Unix and Linux distros. We actively support the Unix Distributions NetBSD and FreeBSD
|
||||
|
||||
#### NetBSD
|
||||
|
||||
NetBSD uses pkgsrc as the package manager. You can build exiv2 with the commands:
|
||||
|
||||
```bash
|
||||
$ cd /usr/pkgsrc/graphics/exiv2
|
||||
$ make install
|
||||
```
|
||||
|
||||
You can build exiv2 from source using the methods described for linux. I build and installed exiv2 using "Pure CMake" and didn't require conan.
|
||||
You will want to use `pkgsrc` to build/install
|
||||
|
||||
1) gcc (currently GCC 5.5.0)<br>
|
||||
2) python3<br>
|
||||
3) cmake<br>
|
||||
4) bash<br>
|
||||
5) sudo<br>
|
||||
6) chksum
|
||||
7) gettext<br>
|
||||
|
||||
I entered links into the file system `# ln -s /usr/pkg/bin/python37 /usr/local/bin/python3` and `# ln -s /usr/pkg/bin/bash /bin/bash`
|
||||
It's important to ensure that `LD_LIBRARY_PATH` includes /usr/local/lib and /usr/pkg/lib. It's important to ensure that PATH includes `/usr/local/bin`, `/usr/pkg/bin` and`/usr/pkg/sbin`.
|
||||
|
||||
#### FreeBSD
|
||||
|
||||
FreeBSD uses pkg as the package manager. You should install the dependency expat. libz is already installed. As with NetBSD, you should use pkg to install python3, cmake, bash, sudo, gettext and gcc. The default GCC compiler is currently 8.3.0.
|
||||
|
||||
[TOC](#TOC)
|
||||
|
||||
Written by Robin Mills<br>
|
||||
robin@clanmills.com<br>
|
||||
Revised: 2019-04-28
|
||||
Revised: 2019-05-09
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
/* Define to `const' or to empty, depending on the second argument of `iconv'. */
|
||||
#cmakedefine ICONV_ACCEPTS_CONST_INPUT
|
||||
#if defined ICONV_ACCEPTS_CONST_INPUT
|
||||
#if defined(ICONV_ACCEPTS_CONST_INPUT) || defined(__NetBSD__)
|
||||
#define EXV_ICONV_CONST const
|
||||
#else
|
||||
#define EXV_ICONV_CONST
|
||||
|
||||
@ -41,12 +41,19 @@ elseif ( APPLE )
|
||||
set (PACKDIR Darwin)
|
||||
elseif ( LINUX )
|
||||
set (PACKDIR Linux)
|
||||
elseif ( CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" )
|
||||
set (PACKDIR Unix)
|
||||
else()
|
||||
set (PACKDIR Linux) # unsupported systems such as FreeBSD
|
||||
set (PACKDIR Linux) # Linux and unsupported systems
|
||||
endif()
|
||||
|
||||
set (BUNDLE_NAME ${PACKDIR})
|
||||
if ( CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" )
|
||||
set (BUNDLE_NAME ${CMAKE_SYSTEM_NAME})
|
||||
endif()
|
||||
|
||||
set (CC "") # Compiler
|
||||
if ( NOT APPLE )
|
||||
if ( NOT APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" )
|
||||
if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||
set (CC Clang)
|
||||
endif()
|
||||
@ -64,7 +71,11 @@ endif()
|
||||
|
||||
set (VS "") # VisualStudio
|
||||
if ( MSVC )
|
||||
if ( MSVC_VERSION STREQUAL 1900 )
|
||||
if ( MSVC_VERSION STREQUAL 2100 )
|
||||
set(VS 2019)
|
||||
elseif ( MSVC_VERSION STREQUAL 2000 )
|
||||
set(VS 2017)
|
||||
elseif ( MSVC_VERSION STREQUAL 1900 )
|
||||
set(VS 2015)
|
||||
elseif ( MSVC_VERSION STREQUAL 1800 )
|
||||
set(VS 2013)
|
||||
@ -77,7 +88,7 @@ if ( MSVC )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${VS}${PACKDIR}${BS}${CC}${LT}${BT}${VI}${WR})
|
||||
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${VS}${BUNDLE_NAME}${BS}${CC}${LT}${BT}${VI}${WR})
|
||||
|
||||
# https://stackoverflow.com/questions/17495906/copying-files-and-including-them-in-a-cpack-archive
|
||||
install(FILES "${PROJECT_SOURCE_DIR}/samples/exifprint.cpp" DESTINATION "samples")
|
||||
@ -94,8 +105,14 @@ set( DOCS
|
||||
foreach(doc ${DOCS})
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${doc} DESTINATION .)
|
||||
endforeach()
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/build/logs/build.txt DESTINATION "logs")
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/build/logs/test.txt DESTINATION "logs")
|
||||
|
||||
# copy build/test logs which are only present on Jenkins builds
|
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/build/logs/build.txt)
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/build/logs/build.txt DESTINATION "logs")
|
||||
endif()
|
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/build/logs/test.txt)
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/build/logs/test.txt DESTINATION "logs")
|
||||
endif()
|
||||
|
||||
# Copy releasenotes.txt and appropriate ReadMe.txt (eg releasenotes/${PACKDIR}/ReadMe.txt)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/releasenotes/${PACKDIR}/ReadMe.txt DESTINATION .)
|
||||
|
||||
59
releasenotes/Unix/ReadMe.txt
Normal file
59
releasenotes/Unix/ReadMe.txt
Normal file
@ -0,0 +1,59 @@
|
||||
Unix Exiv2 v0.27.1 Release Bundle (FreeBSD and NetBSD)
|
||||
------------------------------------------------------
|
||||
|
||||
Structure of the bundle:
|
||||
------------------------
|
||||
|
||||
bin/exiv2 exiv2 and sample applications
|
||||
lib/libexiv2.so.0.27.1.0 & libexiv2-xmp.a libraries
|
||||
lib/pkgconfig/exiv2.pc pkg-config file
|
||||
lib/cmake/exiv2 CMake support/consume files
|
||||
include/exiv2/ include files
|
||||
share/man/ man pages
|
||||
share/locale/ localisation files
|
||||
samples/exifprint.cpp sample code
|
||||
logs/ build and test logs
|
||||
|
||||
ReadMe.txt This file
|
||||
license.txt GPLv2.0 Software License
|
||||
releasenotes.txt Late breaking news
|
||||
README.md Developer Manual
|
||||
README-CONAN.md Developer Manual Appendix
|
||||
exiv2.png Exiv2 Logo
|
||||
|
||||
To run exiv2 from the bundle
|
||||
----------------------------
|
||||
$ cd <bundle>
|
||||
$ bin/exiv2
|
||||
|
||||
To build samples/exiftool.cpp from the bundle
|
||||
---------------------------------------------
|
||||
$ g++ -std=c++98 samples/exifprint.cpp -L$PWD/lib -I$PWD/include -lexiv2 -o exifprint
|
||||
$ env LD_LIBRARY_PATH="$PWD/lib:$LD_LIBRARY_PATH" ./exifprint
|
||||
|
||||
To install for use by all users
|
||||
-------------------------------
|
||||
$ for i in bin include lib share ; do sudo mkdir -p /usr/local/$i ; sudo cp -R $i/* /usr/local/$i ; done
|
||||
|
||||
To compile and link your own code using installed library and include files
|
||||
---------------------------------------------------------------------------
|
||||
Method 1: Explicitly set include and linking options
|
||||
$ cd <bundle>
|
||||
$ g++ -std=c++98 samples/exifprint.cpp -I/usr/local/include -L/usr/local/lib -lexiv2 -o exifprint
|
||||
$ export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
|
||||
$ ./exifprint --version
|
||||
exiv2=0.27.1
|
||||
...
|
||||
xmlns=xmpidq:http://ns.adobe.com/xmp/Identifier/qual/1.0/
|
||||
$
|
||||
|
||||
Method 2: Use pkg-config to set include and linking options
|
||||
$ cd <bundle>
|
||||
$ export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
$ export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
|
||||
$ g++ -std=c++98 samples/exifprint.cpp -o exifprint $(pkg-config exiv2 --libs --cflags)
|
||||
$ ./exifprint
|
||||
|
||||
Method 3: Use the CMake support/consume files
|
||||
See file: README.md Section: 2.6 "Consuming Exiv2 with CMake"
|
||||
|
||||
@ -201,6 +201,10 @@ if (NOT MSVC)
|
||||
target_link_libraries( exiv2lib PRIVATE ${CMAKE_DL_LIBS}) # -ldl = dynamic loader used by src/version.cpp
|
||||
endif()
|
||||
|
||||
if ( CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" )
|
||||
target_link_libraries( exiv2lib PRIVATE -lprocstat)
|
||||
endif()
|
||||
|
||||
if (CYGWIN OR MINGW OR MSYS)
|
||||
target_link_libraries( exiv2lib PRIVATE psapi ws2_32 )
|
||||
endif()
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "futils.hpp"
|
||||
#include "datasets.hpp"
|
||||
#include "enforce.hpp"
|
||||
|
||||
// + standard includes
|
||||
@ -48,6 +49,19 @@
|
||||
#include <libproc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/mount.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <libprocstat.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Exiv2 {
|
||||
const char* ENVARDEF[] = {"/exiv2.php", "40"}; //!< @brief default URL for http exiv2 handler and time-out
|
||||
const char* ENVARKEY[] = {"EXIV2_HTTP_POST", "EXIV2_TIMEOUT"}; //!< @brief request keys for http exiv2 handler and time-out
|
||||
@ -466,12 +480,22 @@ namespace Exiv2 {
|
||||
if (proc_pidpath (pid, pathbuf, sizeof(pathbuf)) > 0) {
|
||||
ret = pathbuf;
|
||||
}
|
||||
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__MSYS__)
|
||||
#elif defined(__FreeBSD__)
|
||||
unsigned int n;
|
||||
char buffer[PATH_MAX] = {};
|
||||
struct procstat* procstat = procstat_open_sysctl();
|
||||
struct kinfo_proc* procs = procstat ? procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &n) : NULL;
|
||||
if ( procs ) {
|
||||
procstat_getpathname(procstat, procs, buffer, PATH_MAX);
|
||||
ret = std::string(buffer);
|
||||
}
|
||||
// release resources
|
||||
if ( procs ) procstat_freeprocs(procstat, procs);
|
||||
if ( procstat ) procstat_close(procstat);
|
||||
#elif defined(__unix__)
|
||||
// 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());
|
||||
ssize_t l = readlink (proc, path,sizeof(path)-1);
|
||||
ssize_t l = readlink ("/proc/self/exe", path,sizeof(path)-1);
|
||||
if (l>0) {
|
||||
path[l]=0;
|
||||
ret = path;
|
||||
|
||||
119
src/version.cpp
119
src/version.cpp
@ -55,6 +55,7 @@
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
// #1147
|
||||
#ifndef WIN32
|
||||
@ -114,23 +115,18 @@ namespace Exiv2 {
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
# include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#elif defined(__linux__)
|
||||
# include <unistd.h>
|
||||
// http://syprog.blogspot.com/2011/12/listing-loaded-shared-objects-in-linux.html
|
||||
# include <dlfcn.h>
|
||||
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 */
|
||||
};
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/mount.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <libprocstat.h>
|
||||
#endif
|
||||
|
||||
static bool shouldOutput(const exv_grep_keys_t& greps,const char* key,const std::string& value)
|
||||
@ -247,6 +243,10 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
"mingw64";
|
||||
#elif defined(__MINGW32__)
|
||||
"mingw32";
|
||||
#elif defined(__NetBSD__)
|
||||
"netbsd";
|
||||
#elif defined(__FreeBSD__)
|
||||
"freebsd";
|
||||
#elif defined(__linux__)
|
||||
"linux";
|
||||
#else
|
||||
@ -260,6 +260,8 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
int have_iconv =0;
|
||||
int have_memory =0;
|
||||
int have_lstat =0;
|
||||
int have_regex =0;
|
||||
int have_regex_h =0;
|
||||
int have_stdbool =0;
|
||||
int have_stdint =0;
|
||||
int have_stdlib =0;
|
||||
@ -279,7 +281,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
int have_sys_types =0;
|
||||
int have_unistd =0;
|
||||
int have_unicode_path=0;
|
||||
int have_regex =0;
|
||||
|
||||
int enable_video =0;
|
||||
int enable_webready =0;
|
||||
@ -319,6 +320,14 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
have_lstat=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_HAVE_REGEX
|
||||
have_regex=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_HAVE_REGEX_H
|
||||
have_regex_h=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_HAVE_STDBOOL_H
|
||||
have_stdbool=1;
|
||||
#endif
|
||||
@ -415,10 +424,13 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
use_ssh=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_HAVE_REGEX_H
|
||||
have_regex=1;
|
||||
#endif
|
||||
#define PUSH_PATH(path,libs,paths) \
|
||||
if ( Exiv2::fileExists(path,true) && paths.find(path) == paths.end() && path != "/" ) { \
|
||||
paths.insert(path); \
|
||||
libs.push_back(path); \
|
||||
}
|
||||
|
||||
Exiv2::StringSet paths;
|
||||
#if defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW__)
|
||||
// enumerate loaded libraries and determine path to executable
|
||||
HMODULE handles[200];
|
||||
@ -427,43 +439,49 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
char szFilename[_MAX_PATH];
|
||||
for ( DWORD h = 0 ; h < cbNeeded/sizeof(handles[0]) ; h++ ) {
|
||||
GetModuleFileNameA(handles[h],szFilename,lengthof(szFilename)) ;
|
||||
libs.push_back(szFilename);
|
||||
std::string path(szFilename);
|
||||
PUSH_PATH(path,libs,paths);
|
||||
}
|
||||
}
|
||||
#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);
|
||||
std::string path(_dyld_get_image_name(image));
|
||||
PUSH_PATH(path,libs,paths);
|
||||
}
|
||||
#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");
|
||||
#elif defined(__FreeBSD__)
|
||||
unsigned int n;
|
||||
struct procstat* procstat = procstat_open_sysctl();
|
||||
struct kinfo_proc* procs = procstat ? procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &n) : NULL;
|
||||
struct filestat_list* files = procs ? procstat_getfiles(procstat, procs, true) : NULL;
|
||||
if ( files ) {
|
||||
filestat* entry;
|
||||
STAILQ_FOREACH(entry, files, next) {
|
||||
std::string path(entry->fs_path);
|
||||
PUSH_PATH(path,libs,paths);
|
||||
}
|
||||
}
|
||||
// free resources
|
||||
if ( files ) procstat_freefiles(procstat, files);
|
||||
if ( procs ) procstat_freeprocs(procstat, procs);
|
||||
if ( procstat ) procstat_close (procstat);
|
||||
|
||||
// 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;
|
||||
#elif defined(__unix__)
|
||||
// read file /proc/self/maps which has a list of files in memory
|
||||
std::ifstream maps("/proc/self/maps",std::ifstream::in);
|
||||
std::string string ;
|
||||
while ( std::getline(maps,string) ) {
|
||||
std::size_t pos = string.find_last_of(' ');
|
||||
if ( pos != std::string::npos ) {
|
||||
std::string path = string.substr(pos+1);
|
||||
PUSH_PATH(path,libs,paths);
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED(paths);
|
||||
#endif
|
||||
|
||||
output(os,keys,"exiv2",Exiv2::versionString());
|
||||
output(os,keys,"platform" , platform );
|
||||
output(os,keys,"compiler" , compiler );
|
||||
@ -505,6 +523,8 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
output(os,keys,"have_iconv" ,have_iconv );
|
||||
output(os,keys,"have_memory" ,have_memory );
|
||||
output(os,keys,"have_lstat" ,have_lstat );
|
||||
output(os,keys,"have_regex" ,have_regex );
|
||||
output(os,keys,"have_regex_h" ,have_regex_h );
|
||||
output(os,keys,"have_stdbool" ,have_stdbool );
|
||||
output(os,keys,"have_stdint" ,have_stdint );
|
||||
output(os,keys,"have_stdlib" ,have_stdlib );
|
||||
@ -529,7 +549,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
output(os,keys,"enable_nls" ,enable_nls );
|
||||
output(os,keys,"use_curl" ,use_curl );
|
||||
output(os,keys,"use_ssh" ,use_ssh );
|
||||
output(os,keys,"have_regex" ,have_regex );
|
||||
|
||||
output(os,keys,"config_path" ,Exiv2::Internal::getExiv2ConfigPath());
|
||||
|
||||
@ -551,10 +570,4 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
output(os,keys,name,xmlns+":"+uri);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
dlclose(ph);
|
||||
ph=NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -421,7 +421,12 @@ checkSum()
|
||||
{
|
||||
# cygwin checksum: http://esrg.sourceforge.net/utils_win_up/md5sum/
|
||||
# macosx - built/installed coreutils 8.25 http://ftp.gnu.org/gnu/coreutils/
|
||||
md5sum $1 | cut -d' ' -f 1
|
||||
platform=$(uname)
|
||||
if [ "$platform" == 'NetBSD' -o "$platform" == 'FreeBSD' ]; then
|
||||
md5 -q $1
|
||||
else
|
||||
md5sum $1 | cut -d' ' -f 1
|
||||
fi
|
||||
}
|
||||
|
||||
##
|
||||
|
||||
Loading…
Reference in New Issue
Block a user