Updating hahsers INC files and Acknowledgements
INC files have been updated changing the information, adding new details. Acknowledgements file includes now Hashing Librarying license. Spacing consistency has been fixed in CPP Hashing files. Testsuite plug-in has been rewritten, now using Server Commands.
This commit is contained in:
parent
c071f53f2c
commit
38db4d3ae0
|
@ -457,18 +457,18 @@ enum AdminProp
|
||||||
*/
|
*/
|
||||||
enum HashType
|
enum HashType
|
||||||
{
|
{
|
||||||
Hash_Crc32 = 0, // Provides CRC32 hashing
|
Hash_Crc32 = 0, // Provides CRC32 hashing
|
||||||
Hash_Md5, // Provides MD5 hashing
|
Hash_Md5, // Provides MD5 hashing
|
||||||
Hash_Sha1, // Provides SHA1 hashing
|
Hash_Sha1, // Provides SHA1 hashing
|
||||||
Hash_Sha256, // Provides SHA256 hashing
|
Hash_Sha256, // Provides SHA256 hashing
|
||||||
|
|
||||||
Hash_Sha3_224, // Provides SHA3 224 bit hashing
|
Hash_Sha3_224, // Provides SHA3 224 bit hashing
|
||||||
Hash_Sha3_256, // Provides SHA3 256 bit hashing
|
Hash_Sha3_256, // Provides SHA3 256 bit hashing
|
||||||
Hash_Sha3_384, // Provides SHA3 384 bit hashing
|
Hash_Sha3_384, // Provides SHA3 384 bit hashing
|
||||||
Hash_Sha3_512, // Provides SHA3 512 bit hashing
|
Hash_Sha3_512, // Provides SHA3 512 bit hashing
|
||||||
|
|
||||||
Hash_Keccak_224, // Provides Keccak 224 bit hashing
|
Hash_Keccak_224, // Provides Keccak 224 bit hashing
|
||||||
Hash_Keccak_256, // Provides Keccak 256 bit hashing
|
Hash_Keccak_256, // Provides Keccak 256 bit hashing
|
||||||
Hash_Keccak_384, // Provides Keccak 384 bit hashing
|
Hash_Keccak_384, // Provides Keccak 384 bit hashing
|
||||||
Hash_Keccak_512 // Provides Keccak 512 bit hashing
|
Hash_Keccak_512 // Provides Keccak 512 bit hashing
|
||||||
};
|
};
|
||||||
|
|
|
@ -2310,7 +2310,7 @@ native force_unmodified(force_type, const mins[3], const maxs[3], const filename
|
||||||
*
|
*
|
||||||
* @return Number of cells written to the buffer (always 32)
|
* @return Number of cells written to the buffer (always 32)
|
||||||
*/
|
*/
|
||||||
#pragma deprecated Use now hash_string() function. Also, see Hash_* constants.
|
#pragma deprecated Use hash_string() function. Also, see Hash_* constants.
|
||||||
native md5(const szString[], md5buffer[34]);
|
native md5(const szString[], md5buffer[34]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2322,14 +2322,14 @@ native md5(const szString[], md5buffer[34]);
|
||||||
* @return Number of cells written to the buffer (always 32)
|
* @return Number of cells written to the buffer (always 32)
|
||||||
* @error If the file can not be opened, and error is thrown.
|
* @error If the file can not be opened, and error is thrown.
|
||||||
*/
|
*/
|
||||||
#pragma deprecated Use now hash_file() function. Also, see Hash_* constants.
|
#pragma deprecated Use hash_file() function. Also, see Hash_* constants.
|
||||||
native md5_file(const file[], md5buffer[34]);
|
native md5_file(const file[], md5buffer[34]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes a string.
|
* Generate a hash value (message digest)
|
||||||
*
|
*
|
||||||
* @param string String to hash.
|
* @param string String to be hashed.
|
||||||
* @param type Type of hash. See Hash_* constants in amxconst.inc file.
|
* @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file.
|
||||||
* @param output Output string to store hash in.
|
* @param output Output string to store hash in.
|
||||||
* @param outputSize The maximum size of the output string to store hash in.
|
* @param outputSize The maximum size of the output string to store hash in.
|
||||||
*
|
*
|
||||||
|
@ -2338,10 +2338,10 @@ native md5_file(const file[], md5buffer[34]);
|
||||||
native hash_string(const string[], const HashType:type, output[], const outputSize);
|
native hash_string(const string[], const HashType:type, output[], const outputSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes a file's content (bytes).
|
* Generate a hash value using the contents of a given file
|
||||||
*
|
*
|
||||||
* @param fileName File to hash.
|
* @param fileName Path of file to be hashed.
|
||||||
* @param type Type of hash. See Hash_* constants in amxconst.inc file.
|
* @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file.
|
||||||
* @param output Output string to store hash in.
|
* @param output Output string to store hash in.
|
||||||
* @param outputSize The maximum size of the output string to store hash in.
|
* @param outputSize The maximum size of the output string to store hash in.
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,39 +9,71 @@
|
||||||
|
|
||||||
#include <amxmodx>
|
#include <amxmodx>
|
||||||
|
|
||||||
|
new const g_hashTypes[HashType][] =
|
||||||
|
{
|
||||||
|
"CRC32",
|
||||||
|
"MD5",
|
||||||
|
"SHA1",
|
||||||
|
"SHA256",
|
||||||
|
"SHA3 224",
|
||||||
|
"SHA3 256",
|
||||||
|
"SHA3 384",
|
||||||
|
"SHA3 512",
|
||||||
|
"Keccak 224",
|
||||||
|
"Keccak 256",
|
||||||
|
"Keccak 384",
|
||||||
|
"Keccak 512"
|
||||||
|
};
|
||||||
|
|
||||||
public plugin_init()
|
public plugin_init()
|
||||||
{
|
{
|
||||||
register_plugin("Hashing Test", "1.0", "Hattrick (Claudiu HKS)");
|
register_plugin("Hashing Test", "1.0", "Hattrick (Claudiu HKS)");
|
||||||
|
register_srvcmd("hash_string", "cmdHashString");
|
||||||
|
register_srvcmd("hash_file", "cmdHashFile");
|
||||||
}
|
}
|
||||||
|
|
||||||
public client_command(Id)
|
public cmdHashString()
|
||||||
{
|
{
|
||||||
new Command[64], StringOrFile[8], Data[64], HashTypeStr[4], Output[256], HashType:Type;
|
if (read_argc() < 2)
|
||||||
|
|
||||||
if (is_user_connected(Id) && !is_user_bot(Id) && !is_user_hltv(Id))
|
|
||||||
{
|
{
|
||||||
read_argv(0, Command, charsmax(Command));
|
server_print("Specify string to be hashed.");
|
||||||
read_argv(1, StringOrFile, charsmax(StringOrFile));
|
return PLUGIN_HANDLED;
|
||||||
read_argv(2, Data, charsmax(Data));
|
|
||||||
read_argv(3, HashTypeStr, charsmax(HashTypeStr));
|
|
||||||
|
|
||||||
if (equali(Command, "Hash"))
|
|
||||||
{
|
|
||||||
if (equali(StringOrFile, "File"))
|
|
||||||
{
|
|
||||||
Type = HashType:str_to_num(HashTypeStr);
|
|
||||||
|
|
||||||
hash_file(Data, Type, Output, charsmax(Output));
|
|
||||||
log_amx("Original: %s Hashed: %s", Data, Output);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (equali(StringOrFile, "String"))
|
|
||||||
{
|
|
||||||
Type = HashType:str_to_num(HashTypeStr);
|
|
||||||
|
|
||||||
hash_string(Data, Type, Output, charsmax(Output));
|
|
||||||
log_amx("Original: %s Hashed: %s", Data, Output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new String[256], Output[256], HashType:Type;
|
||||||
|
read_argv(1, String, charsmax(String));
|
||||||
|
|
||||||
|
log_amx("Hashing string %s...", String);
|
||||||
|
log_amx("-----------------------------------");
|
||||||
|
|
||||||
|
for (Type = Hash_Crc32; Type < any:sizeof g_hashTypes; Type++)
|
||||||
|
{
|
||||||
|
hash_string(String, Type, Output, charsmax(Output));
|
||||||
|
log_amx("%s : %s", g_hashTypes[Type], Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PLUGIN_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public cmdHashFile()
|
||||||
|
{
|
||||||
|
if (read_argc() < 2)
|
||||||
|
{
|
||||||
|
server_print("Specify file to be hashed.");
|
||||||
|
return PLUGIN_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
new File[256], Output[256], HashType:Type;
|
||||||
|
read_argv(1, File, charsmax(File));
|
||||||
|
|
||||||
|
log_amx("Hashing file %s...", File);
|
||||||
|
log_amx("-----------------------------------");
|
||||||
|
|
||||||
|
for (Type = Hash_Crc32; Type < any:sizeof g_hashTypes; Type++)
|
||||||
|
{
|
||||||
|
hash_file(File, Type, Output, charsmax(Output));
|
||||||
|
log_amx("%s : %s", g_hashTypes[Type], Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PLUGIN_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes a file content (bytes)
|
* Hashes a file content (bytes)
|
||||||
* @note Returns NULL if "fileName" does not represent a file name
|
* @note Returns NULL if "fileName" does not represent a file name
|
||||||
* @note Returns NULL if file could not be opened
|
* @note Returns NULL if file could not be opened
|
||||||
* @note Returns NULL if invalid "Type" is specified
|
* @note Returns NULL if invalid "Type" is specified
|
||||||
*/
|
*/
|
||||||
const char* hashFile(const char* fileName, HashType Type)
|
const char* hashFile(const char* fileName, HashType Type)
|
||||||
{
|
{
|
||||||
|
@ -46,12 +46,12 @@ const char* hashFile(const char* fileName, HashType Type)
|
||||||
*/
|
*/
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case Hash_Sha3_224: Sha3.changeBits(SHA3::Bits224); break;
|
case Hash_Sha3_224: Sha3.changeBits(SHA3::Bits224); break;
|
||||||
case Hash_Sha3_384: Sha3.changeBits(SHA3::Bits384); break;
|
case Hash_Sha3_384: Sha3.changeBits(SHA3::Bits384); break;
|
||||||
case Hash_Sha3_512: Sha3.changeBits(SHA3::Bits512); break;
|
case Hash_Sha3_512: Sha3.changeBits(SHA3::Bits512); break;
|
||||||
case Hash_Keccak_224: Kec.changeBits(Keccak::Keccak224); break;
|
case Hash_Keccak_224: Kec.changeBits(Keccak::Keccak224); break;
|
||||||
case Hash_Keccak_384: Kec.changeBits(Keccak::Keccak384); break;
|
case Hash_Keccak_384: Kec.changeBits(Keccak::Keccak384); break;
|
||||||
case Hash_Keccak_512: Kec.changeBits(Keccak::Keccak512); break;
|
case Hash_Keccak_512: Kec.changeBits(Keccak::Keccak512); break;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,18 +63,18 @@ const char* hashFile(const char* fileName, HashType Type)
|
||||||
{
|
{
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case Hash_Crc32: Crc32.add(Bytes, Count); break;
|
case Hash_Crc32: Crc32.add(Bytes, Count); break;
|
||||||
case Hash_Md5: Md5.add(Bytes, Count); break;
|
case Hash_Md5: Md5.add(Bytes, Count); break;
|
||||||
case Hash_Sha1: Sha1.add(Bytes, Count); break;
|
case Hash_Sha1: Sha1.add(Bytes, Count); break;
|
||||||
case Hash_Sha256: Sha256.add(Bytes, Count); break;
|
case Hash_Sha256: Sha256.add(Bytes, Count); break;
|
||||||
case Hash_Sha3_224:
|
case Hash_Sha3_224:
|
||||||
case Hash_Sha3_256:
|
case Hash_Sha3_256:
|
||||||
case Hash_Sha3_384:
|
case Hash_Sha3_384:
|
||||||
case Hash_Sha3_512: Sha3.add(Bytes, Count); break;
|
case Hash_Sha3_512: Sha3.add(Bytes, Count); break;
|
||||||
case Hash_Keccak_224:
|
case Hash_Keccak_224:
|
||||||
case Hash_Keccak_256:
|
case Hash_Keccak_256:
|
||||||
case Hash_Keccak_384:
|
case Hash_Keccak_384:
|
||||||
case Hash_Keccak_512: Kec.add(Bytes, Count); break;
|
case Hash_Keccak_512: Kec.add(Bytes, Count); break;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,18 +88,18 @@ const char* hashFile(const char* fileName, HashType Type)
|
||||||
*/
|
*/
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case Hash_Crc32: return Crc32.getHash();
|
case Hash_Crc32: return Crc32.getHash();
|
||||||
case Hash_Md5: return Md5.getHash();
|
case Hash_Md5: return Md5.getHash();
|
||||||
case Hash_Sha1: return Sha1.getHash();
|
case Hash_Sha1: return Sha1.getHash();
|
||||||
case Hash_Sha256: return Sha256.getHash();
|
case Hash_Sha256: return Sha256.getHash();
|
||||||
case Hash_Sha3_224:
|
case Hash_Sha3_224:
|
||||||
case Hash_Sha3_256:
|
case Hash_Sha3_256:
|
||||||
case Hash_Sha3_384:
|
case Hash_Sha3_384:
|
||||||
case Hash_Sha3_512: return Sha3.getHash();
|
case Hash_Sha3_512: return Sha3.getHash();
|
||||||
case Hash_Keccak_224:
|
case Hash_Keccak_224:
|
||||||
case Hash_Keccak_256:
|
case Hash_Keccak_256:
|
||||||
case Hash_Keccak_384:
|
case Hash_Keccak_384:
|
||||||
case Hash_Keccak_512: return Kec.getHash();
|
case Hash_Keccak_512: return Kec.getHash();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,8 +110,8 @@ const char* hashFile(const char* fileName, HashType Type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes a string
|
* Hashes a string
|
||||||
* @note Returns NULL if "String" does not represent a string
|
* @note Returns NULL if "String" does not represent a string
|
||||||
* @note Returns NULL if invalid "Type" is specified
|
* @note Returns NULL if invalid "Type" is specified
|
||||||
*/
|
*/
|
||||||
const char* hashString(const char* String, size_t stringLen, HashType Type)
|
const char* hashString(const char* String, size_t stringLen, HashType Type)
|
||||||
{
|
{
|
||||||
|
@ -136,12 +136,12 @@ const char* hashString(const char* String, size_t stringLen, HashType Type)
|
||||||
*/
|
*/
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case Hash_Sha3_224: Sha3.changeBits(SHA3::Bits224); break;
|
case Hash_Sha3_224: Sha3.changeBits(SHA3::Bits224); break;
|
||||||
case Hash_Sha3_384: Sha3.changeBits(SHA3::Bits384); break;
|
case Hash_Sha3_384: Sha3.changeBits(SHA3::Bits384); break;
|
||||||
case Hash_Sha3_512: Sha3.changeBits(SHA3::Bits512); break;
|
case Hash_Sha3_512: Sha3.changeBits(SHA3::Bits512); break;
|
||||||
case Hash_Keccak_224: Kec.changeBits(Keccak::Keccak224); break;
|
case Hash_Keccak_224: Kec.changeBits(Keccak::Keccak224); break;
|
||||||
case Hash_Keccak_384: Kec.changeBits(Keccak::Keccak384); break;
|
case Hash_Keccak_384: Kec.changeBits(Keccak::Keccak384); break;
|
||||||
case Hash_Keccak_512: Kec.changeBits(Keccak::Keccak512); break;
|
case Hash_Keccak_512: Kec.changeBits(Keccak::Keccak512); break;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,18 +149,18 @@ const char* hashString(const char* String, size_t stringLen, HashType Type)
|
||||||
*/
|
*/
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case Hash_Crc32: return Crc32(String, stringLen);
|
case Hash_Crc32: return Crc32(String, stringLen);
|
||||||
case Hash_Md5: return Md5(String, stringLen);
|
case Hash_Md5: return Md5(String, stringLen);
|
||||||
case Hash_Sha1: return Sha1(String, stringLen);
|
case Hash_Sha1: return Sha1(String, stringLen);
|
||||||
case Hash_Sha256: return Sha256(String, stringLen);
|
case Hash_Sha256: return Sha256(String, stringLen);
|
||||||
case Hash_Sha3_224:
|
case Hash_Sha3_224:
|
||||||
case Hash_Sha3_256:
|
case Hash_Sha3_256:
|
||||||
case Hash_Sha3_384:
|
case Hash_Sha3_384:
|
||||||
case Hash_Sha3_512: return Sha3(String, stringLen);
|
case Hash_Sha3_512: return Sha3(String, stringLen);
|
||||||
case Hash_Keccak_224:
|
case Hash_Keccak_224:
|
||||||
case Hash_Keccak_256:
|
case Hash_Keccak_256:
|
||||||
case Hash_Keccak_384:
|
case Hash_Keccak_384:
|
||||||
case Hash_Keccak_512: return Kec(String, stringLen);
|
case Hash_Keccak_512: return Kec(String, stringLen);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,15 +24,15 @@
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#define __BYTE_ORDER BYTE_ORDER
|
#define __BYTE_ORDER BYTE_ORDER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BIG_ENDIAN)
|
#if !defined(BIG_ENDIAN)
|
||||||
#define BIG_ENDIAN 4321
|
#define BIG_ENDIAN 4321
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(LITTLE_ENDIAN)
|
#if !defined(LITTLE_ENDIAN)
|
||||||
#define LITTLE_ENDIAN 1234
|
#define LITTLE_ENDIAN 1234
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,35 +51,35 @@
|
||||||
*/
|
*/
|
||||||
enum HashType
|
enum HashType
|
||||||
{
|
{
|
||||||
Hash_Crc32 = 0, // Provides CRC32 hashing
|
Hash_Crc32 = 0, // Provides CRC32 hashing
|
||||||
Hash_Md5, // Provides MD5 hashing
|
Hash_Md5, // Provides MD5 hashing
|
||||||
Hash_Sha1, // Provides SHA1 hashing
|
Hash_Sha1, // Provides SHA1 hashing
|
||||||
Hash_Sha256, // Provides SHA256 hashing
|
Hash_Sha256, // Provides SHA256 hashing
|
||||||
|
|
||||||
Hash_Sha3_224, // Provides SHA3 224 bit hashing
|
Hash_Sha3_224, // Provides SHA3 224 bit hashing
|
||||||
Hash_Sha3_256, // Provides SHA3 256 bit hashing
|
Hash_Sha3_256, // Provides SHA3 256 bit hashing
|
||||||
Hash_Sha3_384, // Provides SHA3 384 bit hashing
|
Hash_Sha3_384, // Provides SHA3 384 bit hashing
|
||||||
Hash_Sha3_512, // Provides SHA3 512 bit hashing
|
Hash_Sha3_512, // Provides SHA3 512 bit hashing
|
||||||
|
|
||||||
Hash_Keccak_224, // Provides KECCAK 224 bit hashing
|
Hash_Keccak_224, // Provides KECCAK 224 bit hashing
|
||||||
Hash_Keccak_256, // Provides KECCAK 256 bit hashing
|
Hash_Keccak_256, // Provides KECCAK 256 bit hashing
|
||||||
Hash_Keccak_384, // Provides KECCAK 384 bit hashing
|
Hash_Keccak_384, // Provides KECCAK 384 bit hashing
|
||||||
Hash_Keccak_512, // Provides KECCAK 512 bit hashing
|
Hash_Keccak_512, // Provides KECCAK 512 bit hashing
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes a file content (bytes)
|
* Hashes a file content (bytes)
|
||||||
* @note Returns NULL if "fileName" does not represent a file name
|
* @note Returns NULL if "fileName" does not represent a file name
|
||||||
* @note Returns NULL if file could not be opened
|
* @note Returns NULL if file could not be opened
|
||||||
* @note Returns NULL if invalid "Type" is specified
|
* @note Returns NULL if invalid "Type" is specified
|
||||||
*/
|
*/
|
||||||
const char* hashFile(const char* fileName, HashType Type);
|
const char* hashFile(const char* fileName, HashType Type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes a string
|
* Hashes a string
|
||||||
* @note Returns NULL if "String" does not represent a string
|
* @note Returns NULL if "String" does not represent a string
|
||||||
* @note Returns NULL if the string has no bytes to hash
|
* @note Returns NULL if the string has no bytes to hash
|
||||||
* @note Returns NULL if invalid "Type" is specified
|
* @note Returns NULL if invalid "Type" is specified
|
||||||
*/
|
*/
|
||||||
const char* hashString(const char* String, size_t stringLen, HashType Type);
|
const char* hashString(const char* String, size_t stringLen, HashType Type);
|
||||||
|
|
||||||
|
|
|
@ -90,3 +90,27 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
|
--------------------------------------------------------------
|
||||||
|
Portable C++ Hashing Library, as used in AMX Mod X Core module
|
||||||
|
--------------------------------------------------------------
|
||||||
|
Copyright (c) 2014 Stephan Brumme
|
||||||
|
|
||||||
|
All source code published on http://create.stephan-brumme.com
|
||||||
|
and its sub-pages is licensed similar to the zlib license:
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
In no event will the author be held liable for any damages arising from
|
||||||
|
the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
subject to the following restrictions:
|
||||||
|
|
||||||
|
* The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software.
|
||||||
|
* If you use this software in a product, an acknowledgment in the product
|
||||||
|
documentation would be appreciated but is not required.
|
||||||
|
* Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user