2015-11-24 17:58:32 +01:00
|
|
|
/*
|
|
|
|
The MIT License (MIT)
|
|
|
|
|
|
|
|
Copyright (c) 2015 LE Xuan Sang xsang.le@gmail.com
|
|
|
|
|
|
|
|
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
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
*/
|
2015-10-22 11:39:11 +02:00
|
|
|
#include "utils.h"
|
2016-12-17 12:28:05 +01:00
|
|
|
|
2020-08-25 16:40:24 +02:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <ctype.h>
|
2021-01-22 01:12:26 +01:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <netdb.h> //hostent
|
2020-08-25 16:40:24 +02:00
|
|
|
|
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
#include <openssl/sha.h>
|
|
|
|
#else
|
|
|
|
#include "sha1.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include "dictionary.h"
|
2021-01-01 13:21:26 +01:00
|
|
|
// #include <time.h>
|
2020-08-25 16:40:24 +02:00
|
|
|
|
|
|
|
|
2015-10-22 11:39:11 +02:00
|
|
|
/**
|
|
|
|
* Trim a string by a character on both ends
|
|
|
|
* @param str The target string
|
|
|
|
* @param delim the delim
|
|
|
|
*/
|
|
|
|
void trim(char* str, const char delim)
|
|
|
|
{
|
2018-03-14 11:55:15 +01:00
|
|
|
if(!str || strlen(str) == 0) return;
|
2015-10-22 11:39:11 +02:00
|
|
|
char * p = str;
|
|
|
|
int l = strlen(p);
|
2018-03-14 11:55:15 +01:00
|
|
|
while(l > 0 && p[l - 1] == delim)
|
|
|
|
p[--l] = 0;
|
2015-10-22 11:39:11 +02:00
|
|
|
while(* p && (* p) == delim ) ++p, --l;
|
|
|
|
memmove(str, p, l + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeAll(const char* path,int mode)
|
|
|
|
{
|
|
|
|
DIR *d;
|
|
|
|
struct dirent *dir;
|
|
|
|
char* file;
|
|
|
|
struct stat st;
|
|
|
|
if( stat(path, &st) == 0)
|
|
|
|
{
|
|
|
|
if(S_ISDIR(st.st_mode))
|
|
|
|
{
|
|
|
|
d = opendir(path);
|
|
|
|
if(d)
|
|
|
|
{
|
|
|
|
while ((dir = readdir(d)) != NULL)
|
|
|
|
{
|
|
|
|
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..")==0) continue;
|
|
|
|
file = __s("%s/%s",path,dir->d_name);
|
|
|
|
|
|
|
|
removeAll(file,1);
|
|
|
|
free(file);
|
|
|
|
}
|
|
|
|
closedir(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(mode)
|
|
|
|
remove(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-01-10 17:31:49 +01:00
|
|
|
// WARNING:
|
|
|
|
// TODO: remove it, this function is not thread-safe
|
|
|
|
|
|
|
|
void timestr(time_t time, char* buf,int len,char* format, int gmt)
|
2015-10-22 11:39:11 +02:00
|
|
|
{
|
2020-01-10 17:31:49 +01:00
|
|
|
struct tm t;
|
|
|
|
if(gmt)
|
|
|
|
{
|
|
|
|
gmtime_r(&time, &t);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
localtime_r(&time, &t);
|
|
|
|
}
|
|
|
|
strftime(buf, len, format, &t);
|
2015-10-22 11:39:11 +02:00
|
|
|
}
|
2020-01-10 17:31:49 +01:00
|
|
|
void server_time(char* buf, int len)
|
2015-10-22 11:39:11 +02:00
|
|
|
{
|
2020-01-10 17:31:49 +01:00
|
|
|
timestr(time(NULL), buf, len ,"%a, %d %b %Y %H:%M:%S", 0);
|
2015-10-22 11:39:11 +02:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Get extension of a file name
|
|
|
|
* @param file The file name
|
|
|
|
* @return the extension
|
|
|
|
*/
|
|
|
|
char* ext(const char* file)
|
|
|
|
{
|
|
|
|
char* token,*ltoken = "";
|
|
|
|
if(file == NULL) return NULL;
|
|
|
|
char* str_cpy = strdup(file);
|
2018-03-02 19:04:00 +01:00
|
|
|
char* str_org = str_cpy;
|
2018-10-09 10:35:37 +02:00
|
|
|
if(!strstr(str_cpy,"."))
|
2018-10-05 19:01:39 +02:00
|
|
|
{
|
|
|
|
free(str_org);
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-10-22 11:39:11 +02:00
|
|
|
if(*file == '.')
|
|
|
|
trim(str_cpy,'.');
|
|
|
|
|
|
|
|
while((token = strsep(&str_cpy,".")) && strlen(token)>0) {ltoken = token;}
|
2018-03-02 19:04:00 +01:00
|
|
|
char* ext = strdup(ltoken);
|
|
|
|
free(str_org);
|
|
|
|
return ext;
|
2015-10-22 11:39:11 +02:00
|
|
|
|
|
|
|
}
|
2016-12-17 12:28:05 +01:00
|
|
|
/*get mime file info from extension*/
|
|
|
|
mime_t mime_from_ext(const char* ex)
|
|
|
|
{
|
2019-12-15 12:10:06 +01:00
|
|
|
dictionary_t mime_list = mimes_list();
|
|
|
|
mime_t ret = (mime_t){"application/octet-stream",NULL};
|
|
|
|
if(!mime_list)
|
|
|
|
return ret;
|
|
|
|
chain_t it;
|
|
|
|
char * pattern = __s("(^\\s*%s\\s*,)|(\\s*,\\s*%s\\s*,\\s*)|(^\\s*%s\\s*$)|(,\\s*%s\\s*$)", ex, ex, ex, ex);
|
|
|
|
if(pattern)
|
|
|
|
{
|
|
|
|
for_each_assoc(it,mime_list)
|
|
|
|
{
|
|
|
|
|
|
|
|
if(regex_match(pattern,it->value,0, NULL))
|
|
|
|
{
|
|
|
|
ret.type = it->key;
|
|
|
|
ret.ext = it->value;
|
|
|
|
free(pattern);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(pattern);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2020-01-09 12:18:59 +01:00
|
|
|
|
|
|
|
void verify_header(char* k)
|
|
|
|
{
|
|
|
|
k[0] = toupper(k[0]);
|
|
|
|
int len = strlen(k);
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
if(k[i] == '-' && i < len-1)
|
|
|
|
{
|
|
|
|
k[i+1] = toupper(k[i+1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-12-15 12:10:06 +01:00
|
|
|
dictionary_t mimes_list()
|
|
|
|
{
|
|
|
|
return NULL;
|
2016-12-17 12:28:05 +01:00
|
|
|
}
|
|
|
|
/*get mime file info from type*/
|
|
|
|
mime_t mime_from_type(const char* type)
|
|
|
|
{
|
2019-12-15 12:10:06 +01:00
|
|
|
dictionary_t mime_list = mimes_list();
|
|
|
|
mime_t ret = (mime_t){NULL,NULL};
|
|
|
|
if(!mime_list)
|
|
|
|
return ret;
|
|
|
|
chain_t it = dlookup(mime_list, type);
|
|
|
|
if(it)
|
|
|
|
{
|
|
|
|
ret.type = it->key;
|
|
|
|
ret.ext = it->value;
|
|
|
|
}
|
|
|
|
return ret;
|
2016-12-17 12:28:05 +01:00
|
|
|
}
|
2015-10-22 11:39:11 +02:00
|
|
|
/**
|
|
|
|
* Get correct HTTP mime type of a file
|
|
|
|
* This is a minimalistic mime type list supported
|
|
|
|
* by the server
|
|
|
|
* @param file File name
|
|
|
|
* @return The HTTP Mime Type
|
|
|
|
*/
|
|
|
|
char* mime(const char* file)
|
|
|
|
{
|
|
|
|
char * ex = ext(file);
|
2018-10-05 19:01:39 +02:00
|
|
|
if(!ex) return "application/octet-stream";
|
2016-12-17 12:28:05 +01:00
|
|
|
mime_t m = mime_from_ext(ex);
|
2018-03-02 21:28:04 +01:00
|
|
|
if(ex)
|
2019-12-11 23:17:42 +01:00
|
|
|
{
|
2018-03-02 21:28:04 +01:00
|
|
|
free(ex);
|
2019-12-11 23:17:42 +01:00
|
|
|
}
|
2019-12-15 12:10:06 +01:00
|
|
|
return (char*)m.type;
|
2015-10-22 11:39:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int match_int(const char* search)
|
|
|
|
{
|
2018-02-04 19:46:47 +01:00
|
|
|
return regex_match("^[-+]?[0-9]+$",search,0, NULL);
|
2015-10-22 11:39:11 +02:00
|
|
|
}
|
|
|
|
int match_float(const char* search)
|
|
|
|
{
|
2018-02-04 19:46:47 +01:00
|
|
|
return regex_match("^[+-]?[0-9]*\\.[0-9]+$",search,0,NULL);
|
2015-10-22 11:39:11 +02:00
|
|
|
}
|
2018-02-04 10:58:02 +01:00
|
|
|
/*
|
|
|
|
regmatch_t matches[MAX_MATCHES];
|
|
|
|
if (regexec(&exp, sz, MAX_MATCHES, matches, 0) == 0) {
|
|
|
|
memcpy(buff, sz + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
|
|
|
|
printf("group1: %s\n", buff);
|
|
|
|
}
|
|
|
|
*/
|
2018-02-04 19:46:47 +01:00
|
|
|
int regex_match(const char* expr,const char* search, int msize, regmatch_t* matches)
|
2015-10-22 11:39:11 +02:00
|
|
|
{
|
|
|
|
regex_t regex;
|
|
|
|
int reti;
|
|
|
|
char msgbuf[100];
|
|
|
|
int ret;
|
|
|
|
/* Compile regular expression */
|
|
|
|
reti = regcomp(®ex, expr, REG_ICASE | REG_EXTENDED);
|
|
|
|
if( reti ){
|
2019-12-11 23:17:42 +01:00
|
|
|
//ERROR("Could not compile regex: %s",expr);
|
2018-02-05 11:42:01 +01:00
|
|
|
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
|
2019-12-20 16:49:41 +01:00
|
|
|
ERROR("Regex match failed: %s", msgbuf);
|
|
|
|
//return 0;
|
2015-10-22 11:39:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Execute regular expression */
|
2018-02-04 19:46:47 +01:00
|
|
|
reti = regexec(®ex, search, msize, matches, 0);
|
2015-10-22 11:39:11 +02:00
|
|
|
if( !reti ){
|
|
|
|
//LOG("Match");
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
else if( reti == REG_NOMATCH ){
|
|
|
|
//LOG("No match");
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
|
2019-12-11 23:17:42 +01:00
|
|
|
//ERROR("Regex match failed: %s\n", msgbuf);
|
2015-10-22 11:39:11 +02:00
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
regfree(®ex);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
char *url_decode(const char *str) {
|
2018-03-17 15:49:37 +01:00
|
|
|
if(!str)
|
2019-12-11 23:17:42 +01:00
|
|
|
{
|
2018-03-17 15:49:37 +01:00
|
|
|
return NULL;
|
2019-12-11 23:17:42 +01:00
|
|
|
}
|
2018-10-07 15:09:46 +02:00
|
|
|
char *pstr = (char*)str, *buf = malloc(strlen(str) + 1), *pbuf = buf;
|
2015-10-22 11:39:11 +02:00
|
|
|
|
|
|
|
while (*pstr) {
|
|
|
|
if (*pstr == '%') {
|
|
|
|
if (pstr[1] && pstr[2]) {
|
|
|
|
*pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
|
|
|
|
pstr += 2;
|
|
|
|
}
|
|
|
|
} else if (*pstr == '+') {
|
|
|
|
*pbuf++ = ' ';
|
|
|
|
} else {
|
|
|
|
*pbuf++ = *pstr;
|
|
|
|
}
|
|
|
|
pstr++;
|
|
|
|
}
|
|
|
|
*pbuf = '\0';
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *url_encode(const char *str) {
|
2018-10-07 15:09:46 +02:00
|
|
|
char *pstr = (char*)str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf;
|
2015-10-22 11:39:11 +02:00
|
|
|
while (*pstr) {
|
|
|
|
if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
|
|
|
|
*pbuf++ = *pstr;
|
|
|
|
else if (*pstr == ' ')
|
|
|
|
*pbuf++ = '+';
|
|
|
|
else
|
|
|
|
*pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
|
|
|
|
pstr++;
|
|
|
|
}
|
|
|
|
*pbuf = '\0';
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
char from_hex(char ch) {
|
|
|
|
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
char to_hex(char code) {
|
|
|
|
static char hex[] = "0123456789abcdef";
|
|
|
|
return hex[code & 15];
|
|
|
|
}
|
2015-11-24 17:58:32 +01:00
|
|
|
unsigned hash(const char* key, int hash_size)
|
2016-10-31 17:34:20 +01:00
|
|
|
{
|
|
|
|
unsigned hashval = simple_hash(key);
|
|
|
|
return hashval % hash_size;
|
|
|
|
}
|
|
|
|
unsigned simple_hash(const char* key)
|
2015-11-24 17:58:32 +01:00
|
|
|
{
|
|
|
|
unsigned hashval;
|
|
|
|
for (hashval = 0; *key != '\0'; key++)
|
|
|
|
hashval = *key + 31 * hashval;
|
2016-10-31 17:34:20 +01:00
|
|
|
return hashval;
|
2016-10-30 16:14:04 +01:00
|
|
|
}
|
2016-12-15 14:46:50 +01:00
|
|
|
int _exist(const char* f)
|
2016-10-30 16:14:04 +01:00
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
return !(stat(f, &st) == -1);
|
2016-10-31 22:18:24 +01:00
|
|
|
}
|
2016-12-15 14:46:50 +01:00
|
|
|
int is_file(const char* f)
|
|
|
|
{
|
|
|
|
int st = is_dir(f);
|
|
|
|
if(st == -1) return -1;
|
|
|
|
else return st==0;
|
|
|
|
}
|
|
|
|
int is_dir(const char* f)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
if(stat(f, &st) == -1)
|
|
|
|
return -1; // unknow
|
|
|
|
else if(st.st_mode & S_IFDIR)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
2016-10-31 22:18:24 +01:00
|
|
|
// These vars will contain the hash
|
|
|
|
|
|
|
|
void md5(uint8_t *initial_msg, size_t initial_len, char* buff) {
|
|
|
|
uint32_t h0, h1, h2, h3;
|
|
|
|
char tmp[80];
|
|
|
|
uint8_t *msg = NULL;
|
|
|
|
uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
|
|
|
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
|
|
|
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
|
|
|
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
|
|
|
// Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:
|
|
|
|
uint32_t k[] = {
|
|
|
|
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
|
|
|
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
|
|
|
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
|
|
|
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
|
|
|
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
|
|
|
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
|
|
|
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
|
|
|
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
|
|
|
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
|
|
|
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
|
|
|
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
|
|
|
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
|
|
|
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
|
|
|
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
|
|
|
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
|
|
|
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
|
|
|
|
|
|
|
h0 = 0x67452301;
|
|
|
|
h1 = 0xefcdab89;
|
|
|
|
h2 = 0x98badcfe;
|
|
|
|
h3 = 0x10325476;
|
|
|
|
|
|
|
|
// Pre-processing: adding a single 1 bit
|
|
|
|
//append "1" bit to message
|
|
|
|
/* Notice: the input bytes are considered as bits strings,
|
|
|
|
where the first bit is the most significant bit of the byte.[37] */
|
|
|
|
|
|
|
|
// Pre-processing: padding with zeros
|
|
|
|
//append "0" bit until message length in bit ≡ 448 (mod 512)
|
|
|
|
//append length mod (2 pow 64) to message
|
|
|
|
|
|
|
|
int new_len;
|
|
|
|
for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++);
|
|
|
|
new_len /= 8;
|
|
|
|
|
|
|
|
msg = calloc(new_len + 64, 1); // also appends "0" bits
|
|
|
|
// (we alloc also 64 extra bytes...)
|
|
|
|
memcpy(msg, initial_msg, initial_len);
|
|
|
|
msg[initial_len] = 128; // write the "1" bit
|
|
|
|
|
|
|
|
uint32_t bits_len = 8*initial_len; // note, we append the len
|
|
|
|
memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
|
|
|
|
|
|
|
|
// Process the message in successive 512-bit chunks:
|
|
|
|
//for each 512-bit chunk of message:
|
|
|
|
int offset;
|
|
|
|
for(offset=0; offset<new_len; offset += (512/8)) {
|
|
|
|
|
|
|
|
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
|
|
|
|
uint32_t *w = (uint32_t *) (msg + offset);
|
|
|
|
|
|
|
|
// Initialize hash value for this chunk:
|
|
|
|
uint32_t a = h0;
|
|
|
|
uint32_t b = h1;
|
|
|
|
uint32_t c = h2;
|
|
|
|
uint32_t d = h3;
|
|
|
|
|
|
|
|
// Main loop:
|
|
|
|
uint32_t i;
|
|
|
|
for(i = 0; i<64; i++) {
|
|
|
|
|
|
|
|
uint32_t f, g;
|
|
|
|
|
|
|
|
if (i < 16) {
|
|
|
|
f = (b & c) | ((~b) & d);
|
|
|
|
g = i;
|
|
|
|
} else if (i < 32) {
|
|
|
|
f = (d & b) | ((~d) & c);
|
|
|
|
g = (5*i + 1) % 16;
|
|
|
|
} else if (i < 48) {
|
|
|
|
f = b ^ c ^ d;
|
|
|
|
g = (3*i + 5) % 16;
|
|
|
|
} else {
|
|
|
|
f = c ^ (b | (~d));
|
|
|
|
g = (7*i) % 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t temp = d;
|
|
|
|
d = c;
|
|
|
|
c = b;
|
|
|
|
//printf("rotateLeft(%x + %x + %x + %x, %d)\n", a, f, k[i], w[g], r[i]);
|
|
|
|
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
|
|
|
|
a = temp;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add this chunk's hash to result so far:
|
|
|
|
|
|
|
|
h0 += a;
|
|
|
|
h1 += b;
|
|
|
|
h2 += c;
|
|
|
|
h3 += d;
|
|
|
|
|
|
|
|
}
|
|
|
|
uint8_t *p;
|
|
|
|
p=(uint8_t *)&h0;
|
2018-10-07 15:09:46 +02:00
|
|
|
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]);//, h0
|
2016-10-31 22:18:24 +01:00
|
|
|
strcpy(buff, tmp);
|
|
|
|
p=(uint8_t *)&h1;
|
2018-10-07 15:09:46 +02:00
|
|
|
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); //, h1)
|
2016-10-31 22:18:24 +01:00
|
|
|
strcat(buff,tmp);
|
|
|
|
p=(uint8_t *)&h2;
|
2018-10-07 15:09:46 +02:00
|
|
|
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); // , h2
|
2016-10-31 22:18:24 +01:00
|
|
|
strcat(buff,tmp);
|
|
|
|
p=(uint8_t *)&h3;
|
2018-10-07 15:09:46 +02:00
|
|
|
sprintf(tmp,"%02x%02x%02x%02x", p[0], p[1], p[2], p[3]); // , h3
|
2016-10-31 22:18:24 +01:00
|
|
|
strcat(buff,tmp);
|
|
|
|
// cleanup
|
|
|
|
free(msg);
|
|
|
|
|
2016-11-01 18:30:45 +01:00
|
|
|
}
|
|
|
|
void sha1(const char* text, char* out)
|
|
|
|
{
|
|
|
|
uint8_t d [20];
|
2018-02-10 11:22:41 +01:00
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
SHA_CTX context;
|
|
|
|
#else
|
|
|
|
SHA1_CTX context;
|
|
|
|
#endif
|
|
|
|
SHA1_Init(&context);
|
|
|
|
SHA1_Update(&context, text, strlen(text));
|
|
|
|
SHA1_Final(d, &context);
|
|
|
|
digest_to_hex(d,out);
|
2019-12-11 23:17:42 +01:00
|
|
|
}
|
2019-12-15 12:10:06 +01:00
|
|
|
|
|
|
|
|
|
|
|
char* __s(const char* fstring,...)
|
|
|
|
{
|
|
|
|
char* data;
|
|
|
|
va_list arguments;
|
|
|
|
int dlen;
|
|
|
|
va_start( arguments, fstring);
|
|
|
|
dlen = vsnprintf(0,0,fstring,arguments) + 1;
|
2020-08-19 12:26:17 +02:00
|
|
|
va_end(arguments);
|
2019-12-15 12:10:06 +01:00
|
|
|
if ((data = (char*)malloc(dlen*sizeof(char))) != 0)
|
|
|
|
{
|
|
|
|
va_start(arguments, fstring);
|
|
|
|
vsnprintf(data, dlen, fstring, arguments);
|
|
|
|
va_end(arguments);
|
|
|
|
return data;
|
|
|
|
} else
|
|
|
|
return "";
|
2019-12-20 16:49:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int mkdirp(const char* path, mode_t mode)
|
|
|
|
{
|
|
|
|
char tmp[BUFFLEN];
|
|
|
|
if(strlen(path) > BUFFLEN)
|
|
|
|
{
|
|
|
|
ERROR("mkdirp: Path is too long %s", path);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
char *p = NULL;
|
|
|
|
size_t len;
|
|
|
|
int stat;
|
|
|
|
snprintf(tmp, sizeof(tmp),"%s",path);
|
|
|
|
len = strlen(tmp);
|
|
|
|
if(tmp[len - 1] == '/')
|
|
|
|
tmp[len - 1] = 0;
|
|
|
|
for(p = tmp + 1; *p; p++)
|
|
|
|
{
|
|
|
|
if(*p == '/') {
|
|
|
|
*p = 0;
|
|
|
|
stat = mkdir(tmp, mode);
|
|
|
|
if(stat == -1 && errno != EEXIST)
|
|
|
|
return stat;
|
|
|
|
*p = '/';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mkdir(path, mode);
|
2021-01-03 11:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int guard_read(int fd, void* buffer, size_t size)
|
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
int read_len;
|
|
|
|
int st;
|
|
|
|
while(n != (int)size)
|
|
|
|
{
|
|
|
|
read_len = (int)size - n;
|
|
|
|
st = read(fd,buffer + n,read_len);
|
|
|
|
if(st == -1)
|
|
|
|
{
|
|
|
|
ERROR( "Unable to read from #%d: %s", fd, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if(st == 0)
|
|
|
|
{
|
|
|
|
ERROR("Endpoint %d is closed", fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
n += st;
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
int guard_write(int fd, void* buffer, size_t size)
|
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
int write_len;
|
|
|
|
int st;
|
|
|
|
while(n != (int)size)
|
|
|
|
{
|
|
|
|
write_len = (int)size - n;
|
|
|
|
st = write(fd,buffer + n,write_len);
|
|
|
|
if(st == -1)
|
|
|
|
{
|
|
|
|
ERROR("Unable to write to #%d: %s", fd, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if(st == 0)
|
|
|
|
{
|
|
|
|
ERROR("Endpoint %d is closed", fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
n += st;
|
|
|
|
}
|
|
|
|
return n;
|
2021-01-22 01:12:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
send a request
|
|
|
|
*/
|
|
|
|
int request_socket(const char *ip, int port)
|
|
|
|
{
|
|
|
|
int sockfd;
|
|
|
|
struct sockaddr_in dest;
|
2021-02-24 18:12:36 +01:00
|
|
|
if(!ip)
|
|
|
|
{
|
|
|
|
ERROR("Invalid IP address");
|
|
|
|
return -1;
|
|
|
|
}
|
2021-01-22 01:12:26 +01:00
|
|
|
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|
|
|
{
|
|
|
|
ERROR("Socket: %s", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/*struct linger lingerStruct;
|
|
|
|
lingerStruct.l_onoff = 0; // turn lingering off for sockets
|
|
|
|
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
|
|
|
|
|
|
|
|
bzero(&dest, sizeof(dest));
|
|
|
|
dest.sin_family = AF_INET;
|
|
|
|
dest.sin_port = htons(port);
|
|
|
|
if (inet_aton(ip, &dest.sin_addr) == 0)
|
|
|
|
{
|
|
|
|
perror(ip);
|
|
|
|
close(sockfd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0)
|
|
|
|
{
|
|
|
|
close(sockfd);
|
|
|
|
ERROR("Connect:%s", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return sockfd;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* ip_from_hostname(const char *hostname)
|
|
|
|
{
|
|
|
|
struct hostent *he;
|
|
|
|
struct in_addr **addr_list;
|
|
|
|
int i;
|
2021-02-24 18:12:36 +01:00
|
|
|
if(!hostname)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-01-22 01:12:26 +01:00
|
|
|
if ((he = gethostbyname(hostname)) == NULL)
|
|
|
|
{
|
|
|
|
// get the host info
|
|
|
|
ERROR("gethostbyname:%s", strerror(errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
addr_list = (struct in_addr **)he->h_addr_list;
|
|
|
|
|
|
|
|
for (i = 0; addr_list[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
//Return the first one;
|
|
|
|
return inet_ntoa(*addr_list[i]);
|
|
|
|
}
|
|
|
|
return NULL;
|
2019-12-15 12:10:06 +01:00
|
|
|
}
|