File hashing (not finished)
This commit is contained in:
@@ -5,10 +5,8 @@ mkdir wdir
|
|||||||
mkdir wdir/storage
|
mkdir wdir/storage
|
||||||
touch wdir/file_descriptions
|
touch wdir/file_descriptions
|
||||||
touch wdir/welcome
|
touch wdir/welcome
|
||||||
touch wdir/userlist
|
|
||||||
|
|
||||||
echo "Welcome to the BBS Setup!" >> wdir/welcome
|
echo "Welcome to the BBS Setup!" >> wdir/welcome
|
||||||
echo "user 1234 15" >> wdir/userlist
|
|
||||||
|
|
||||||
# Test file
|
# Test file
|
||||||
touch wdir/storage/testfile.txt
|
touch wdir/storage/testfile.txt
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static void processNotice(void *arg, const char *message) {
|
|||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_connection() {
|
int init_db_connection() {
|
||||||
// TODO: get from external configs
|
// TODO: get from external configs
|
||||||
conn = PQconnectdb("user=postgres password=dobro host=127.0.0.1 dbname=bbs");
|
conn = PQconnectdb("user=postgres password=dobro host=127.0.0.1 dbname=bbs");
|
||||||
|
|
||||||
@@ -56,20 +56,20 @@ int init_connection() {
|
|||||||
char *user = PQuser(conn);
|
char *user = PQuser(conn);
|
||||||
char *db_name = PQdb(conn);
|
char *db_name = PQdb(conn);
|
||||||
|
|
||||||
printf("Connection established! server version: %d, user: %s, db: %s\n", server_ver,
|
printf("Connection established! server version: %d, user: %s, db: %s\n",
|
||||||
user, db_name);
|
server_ver, user, db_name);
|
||||||
return exit_query(0);
|
return exit_query(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int db_user_auth(i_auth_t *credentials, o_auth_t *response) {
|
int db_user_auth(i_auth_t *credentials, o_auth_t *response) {
|
||||||
char query[Q_LEN];
|
const char *paramValues[1];
|
||||||
response->is_logged = 0;
|
paramValues[0] = credentials->name;
|
||||||
sprintf(query,
|
|
||||||
|
res = PQexecParams(conn,
|
||||||
"SELECT username, password, privileges "
|
"SELECT username, password, privileges "
|
||||||
"FROM users "
|
"FROM users "
|
||||||
"WHERE username= '%s'",
|
"WHERE username= $1", 1,
|
||||||
credentials->name);
|
NULL, paramValues, NULL, NULL, 0);
|
||||||
res = PQexec(conn, query);
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
return exit_query(1);
|
return exit_query(1);
|
||||||
@@ -82,48 +82,3 @@ int db_user_auth(i_auth_t *credentials, o_auth_t *response) {
|
|||||||
}
|
}
|
||||||
return exit_query(2);
|
return exit_query(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*s
|
|
||||||
|
|
||||||
int f_main() {
|
|
||||||
int libpq_ver = PQlibVersion();
|
|
||||||
printf("Version of libpq: %d\n", libpq_ver);
|
|
||||||
|
|
||||||
conn = PQconnectdb("user=postgres password=dobro host=127.0.0.1 dbname=bbs");
|
|
||||||
if (PQstatus(conn) != CONNECTION_OK)
|
|
||||||
terminate(1);
|
|
||||||
|
|
||||||
PQsetNoticeProcessor(conn, processNotice, NULL);
|
|
||||||
|
|
||||||
int server_ver = PQserverVersion(conn);
|
|
||||||
char *user = PQuser(conn);
|
|
||||||
char *db_name = PQdb(conn);
|
|
||||||
|
|
||||||
printf("Server version: %d\n", server_ver);
|
|
||||||
printf("User: %s\n", user);
|
|
||||||
printf("Database name: %s\n", db_name);
|
|
||||||
|
|
||||||
res = PQexec(conn, "SELECT id, username, privileges, email "
|
|
||||||
"FROM users");
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
terminate(1);
|
|
||||||
|
|
||||||
int nrows = PQntuples(res);
|
|
||||||
for (int i = 0; i < nrows; i++) {
|
|
||||||
char *id = PQgetvalue(res, i, 0);
|
|
||||||
char *name = PQgetvalue(res, i, 1);
|
|
||||||
char *privileges = PQgetvalue(res, i, 2);
|
|
||||||
char *email = PQgetvalue(res, i, 3);
|
|
||||||
printf("Id: %s, Name: %s, Privileges: %d, Email: %s, \n", id, name,
|
|
||||||
privileges[0], email);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Total: %d rows\n", nrows);
|
|
||||||
|
|
||||||
clearRes();
|
|
||||||
terminate(0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
@@ -8,5 +8,5 @@ typedef struct {
|
|||||||
int is_logged;
|
int is_logged;
|
||||||
} o_auth_t;
|
} o_auth_t;
|
||||||
|
|
||||||
int init_connection();
|
int init_db_connection();
|
||||||
int db_user_auth(i_auth_t *credentials, o_auth_t *response);
|
int db_user_auth(i_auth_t *credentials, o_auth_t *response);
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
client.o: src/client.c src/client.h src/main.h src/file_p.h src/session.h
|
|
||||||
db.o: src/db.c src/db.h
|
|
||||||
file_p.o: src/file_p.c src/file_p.h src/main.h src/session.h
|
|
||||||
main.o: src/main.c src/main.h src/file_p.h src/server.h src/db.h
|
|
||||||
server.o: src/server.c src/main.h src/session.h src/user.h
|
|
||||||
session.o: src/session.c src/session.h src/main.h src/client.h \
|
|
||||||
src/file_p.h src/user.h
|
|
||||||
user.o: src/user.c src/main.h src/session.h src/db.h
|
|
||||||
|
|||||||
+51
-8
@@ -1,4 +1,5 @@
|
|||||||
#include "file_p.h"
|
#include "file_p.h"
|
||||||
|
#include "libs/murmur3/murmur3.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -84,6 +86,25 @@ int file_send_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int directory_exists(const char *path) {
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
if (stat(path, &info) != 0) {
|
||||||
|
// stat() failed, probably doesn't exist
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return S_ISDIR(info.st_mode); // true if it's a directory
|
||||||
|
}
|
||||||
|
|
||||||
|
void extract_names_from_hash(uint32_t file_hash, char *dirname, char *fname) {
|
||||||
|
char hashed_full_name[9];
|
||||||
|
sprintf(hashed_full_name, "%08x", file_hash);
|
||||||
|
strncpy(dirname, hashed_full_name, 2);
|
||||||
|
strncpy(fname, hashed_full_name + 2, 6);
|
||||||
|
dirname[2] = 0;
|
||||||
|
fname[6] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
||||||
int sd = sess->sd;
|
int sd = sess->sd;
|
||||||
char fname[64];
|
char fname[64];
|
||||||
@@ -93,8 +114,6 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
sess->fname = malloc(sizeof(char) * strlen(fname));
|
sess->fname = malloc(sizeof(char) * strlen(fname));
|
||||||
sess->f_perm = (char)perm;
|
sess->f_perm = (char)perm;
|
||||||
strncpy(sess->fname, fname, strlen(fname) - 1); // remove the last \"
|
strncpy(sess->fname, fname, strlen(fname) - 1); // remove the last \"
|
||||||
sess->fpath = malloc(strlen(sess->fname) + sizeof(STORAGE_FOLDER) + 2);
|
|
||||||
sprintf(sess->fpath, "%s/%s", STORAGE_FOLDER, sess->fname);
|
|
||||||
|
|
||||||
char mes[256];
|
char mes[256];
|
||||||
char mes_len = 0;
|
char mes_len = 0;
|
||||||
@@ -114,19 +133,43 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
clear_file_from_sess(sess);
|
clear_file_from_sess(sess);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int file_d = open(sess->fpath, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
|
||||||
|
char hashed_dir_name[3];
|
||||||
|
char hashed_name[7];
|
||||||
|
int seed = FILE_HASH_SEED;
|
||||||
|
int file_d;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
MurmurHash3_x86_32(sess->fname, strlen(sess->fname), FILE_HASH_SEED,
|
||||||
|
&(sess->hash));
|
||||||
|
|
||||||
|
extract_names_from_hash(sess->hash, hashed_dir_name, hashed_name);
|
||||||
|
|
||||||
|
sess->fpath = malloc(sizeof(STORAGE_FOLDER) + 2 + 9);
|
||||||
|
sprintf(sess->fpath, "%s/%s/%s", STORAGE_FOLDER, hashed_dir_name,
|
||||||
|
hashed_name);
|
||||||
|
|
||||||
|
if (!directory_exists(hashed_dir_name)) {
|
||||||
|
mkdir(hashed_dir_name, 0700);
|
||||||
|
}
|
||||||
|
chdir(hashed_dir_name);
|
||||||
|
|
||||||
|
file_d = open(sess->fpath, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
||||||
if (file_d == -1) {
|
if (file_d == -1) {
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
mes_len =
|
seed++;
|
||||||
sprintf(mes, "File with name \"%s\" is already exist\n", sess->fname);
|
free(sess->fpath);
|
||||||
write(sd, mes, mes_len);
|
sess->fpath = NULL;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
mes_len =
|
mes_len = sprintf(mes, "Can't create file with such name: \"%s\"\n",
|
||||||
sprintf(mes, "Can't create file with such name: \"%s\"\n", sess->fname);
|
sess->fname);
|
||||||
write(sd, mes, mes_len);
|
write(sd, mes, mes_len);
|
||||||
clear_file_from_sess(sess);
|
clear_file_from_sess(sess);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mes_len = sprintf(mes, "accept");
|
mes_len = sprintf(mes, "accept");
|
||||||
sess->fd = file_d;
|
sess->fd = file_d;
|
||||||
sess->fsize = fsize;
|
sess->fsize = fsize;
|
||||||
|
|||||||
@@ -0,0 +1,314 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||||
|
// domain. The author hereby disclaims copyright to this source code.
|
||||||
|
|
||||||
|
// Note - The x86 and x64 versions do _not_ produce the same results, as the
|
||||||
|
// algorithms are optimized for their respective platforms. You can still
|
||||||
|
// compile and run any of them on any platform, but your performance with the
|
||||||
|
// non-native version will be less than optimal.
|
||||||
|
|
||||||
|
#include "murmur3.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Platform-specific functions and macros
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||||
|
#else
|
||||||
|
#define FORCE_INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r )
|
||||||
|
{
|
||||||
|
return (x << r) | (x >> (32 - r));
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r )
|
||||||
|
{
|
||||||
|
return (x << r) | (x >> (64 - r));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ROTL32(x,y) rotl32(x,y)
|
||||||
|
#define ROTL64(x,y) rotl64(x,y)
|
||||||
|
|
||||||
|
#define BIG_CONSTANT(x) (x##LLU)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Block read - if your platform needs to do endian-swapping or can only
|
||||||
|
// handle aligned reads, do the conversion here
|
||||||
|
|
||||||
|
#define getblock(p, i) (p[i])
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Finalization mix - force all bits of a hash block to avalanche
|
||||||
|
|
||||||
|
static FORCE_INLINE uint32_t fmix32 ( uint32_t h )
|
||||||
|
{
|
||||||
|
h ^= h >> 16;
|
||||||
|
h *= 0x85ebca6b;
|
||||||
|
h ^= h >> 13;
|
||||||
|
h *= 0xc2b2ae35;
|
||||||
|
h ^= h >> 16;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------
|
||||||
|
|
||||||
|
static FORCE_INLINE uint64_t fmix64 ( uint64_t k )
|
||||||
|
{
|
||||||
|
k ^= k >> 33;
|
||||||
|
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
|
||||||
|
k ^= k >> 33;
|
||||||
|
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
|
||||||
|
k ^= k >> 33;
|
||||||
|
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MurmurHash3_x86_32 ( const void * key, int len,
|
||||||
|
uint32_t seed, void * out )
|
||||||
|
{
|
||||||
|
const uint8_t * data = (const uint8_t*)key;
|
||||||
|
const int nblocks = len / 4;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
uint32_t h1 = seed;
|
||||||
|
|
||||||
|
uint32_t c1 = 0xcc9e2d51;
|
||||||
|
uint32_t c2 = 0x1b873593;
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// body
|
||||||
|
|
||||||
|
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
|
||||||
|
|
||||||
|
for(i = -nblocks; i; i++)
|
||||||
|
{
|
||||||
|
uint32_t k1 = getblock(blocks,i);
|
||||||
|
|
||||||
|
k1 *= c1;
|
||||||
|
k1 = ROTL32(k1,15);
|
||||||
|
k1 *= c2;
|
||||||
|
|
||||||
|
h1 ^= k1;
|
||||||
|
h1 = ROTL32(h1,13);
|
||||||
|
h1 = h1*5+0xe6546b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// tail
|
||||||
|
|
||||||
|
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
|
||||||
|
|
||||||
|
uint32_t k1 = 0;
|
||||||
|
|
||||||
|
switch(len & 3)
|
||||||
|
{
|
||||||
|
case 3: k1 ^= tail[2] << 16;
|
||||||
|
case 2: k1 ^= tail[1] << 8;
|
||||||
|
case 1: k1 ^= tail[0];
|
||||||
|
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// finalization
|
||||||
|
|
||||||
|
h1 ^= len;
|
||||||
|
|
||||||
|
h1 = fmix32(h1);
|
||||||
|
|
||||||
|
*(uint32_t*)out = h1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MurmurHash3_x86_128 ( const void * key, const int len,
|
||||||
|
uint32_t seed, void * out )
|
||||||
|
{
|
||||||
|
const uint8_t * data = (const uint8_t*)key;
|
||||||
|
const int nblocks = len / 16;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
uint32_t h1 = seed;
|
||||||
|
uint32_t h2 = seed;
|
||||||
|
uint32_t h3 = seed;
|
||||||
|
uint32_t h4 = seed;
|
||||||
|
|
||||||
|
uint32_t c1 = 0x239b961b;
|
||||||
|
uint32_t c2 = 0xab0e9789;
|
||||||
|
uint32_t c3 = 0x38b34ae5;
|
||||||
|
uint32_t c4 = 0xa1e38b93;
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// body
|
||||||
|
|
||||||
|
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
|
||||||
|
|
||||||
|
for(i = -nblocks; i; i++)
|
||||||
|
{
|
||||||
|
uint32_t k1 = getblock(blocks,i*4+0);
|
||||||
|
uint32_t k2 = getblock(blocks,i*4+1);
|
||||||
|
uint32_t k3 = getblock(blocks,i*4+2);
|
||||||
|
uint32_t k4 = getblock(blocks,i*4+3);
|
||||||
|
|
||||||
|
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||||
|
|
||||||
|
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
|
||||||
|
|
||||||
|
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
||||||
|
|
||||||
|
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
|
||||||
|
|
||||||
|
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
||||||
|
|
||||||
|
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
|
||||||
|
|
||||||
|
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
||||||
|
|
||||||
|
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// tail
|
||||||
|
|
||||||
|
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
|
||||||
|
|
||||||
|
uint32_t k1 = 0;
|
||||||
|
uint32_t k2 = 0;
|
||||||
|
uint32_t k3 = 0;
|
||||||
|
uint32_t k4 = 0;
|
||||||
|
|
||||||
|
switch(len & 15)
|
||||||
|
{
|
||||||
|
case 15: k4 ^= tail[14] << 16;
|
||||||
|
case 14: k4 ^= tail[13] << 8;
|
||||||
|
case 13: k4 ^= tail[12] << 0;
|
||||||
|
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
||||||
|
|
||||||
|
case 12: k3 ^= tail[11] << 24;
|
||||||
|
case 11: k3 ^= tail[10] << 16;
|
||||||
|
case 10: k3 ^= tail[ 9] << 8;
|
||||||
|
case 9: k3 ^= tail[ 8] << 0;
|
||||||
|
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
||||||
|
|
||||||
|
case 8: k2 ^= tail[ 7] << 24;
|
||||||
|
case 7: k2 ^= tail[ 6] << 16;
|
||||||
|
case 6: k2 ^= tail[ 5] << 8;
|
||||||
|
case 5: k2 ^= tail[ 4] << 0;
|
||||||
|
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
||||||
|
|
||||||
|
case 4: k1 ^= tail[ 3] << 24;
|
||||||
|
case 3: k1 ^= tail[ 2] << 16;
|
||||||
|
case 2: k1 ^= tail[ 1] << 8;
|
||||||
|
case 1: k1 ^= tail[ 0] << 0;
|
||||||
|
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// finalization
|
||||||
|
|
||||||
|
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
|
||||||
|
|
||||||
|
h1 += h2; h1 += h3; h1 += h4;
|
||||||
|
h2 += h1; h3 += h1; h4 += h1;
|
||||||
|
|
||||||
|
h1 = fmix32(h1);
|
||||||
|
h2 = fmix32(h2);
|
||||||
|
h3 = fmix32(h3);
|
||||||
|
h4 = fmix32(h4);
|
||||||
|
|
||||||
|
h1 += h2; h1 += h3; h1 += h4;
|
||||||
|
h2 += h1; h3 += h1; h4 += h1;
|
||||||
|
|
||||||
|
((uint32_t*)out)[0] = h1;
|
||||||
|
((uint32_t*)out)[1] = h2;
|
||||||
|
((uint32_t*)out)[2] = h3;
|
||||||
|
((uint32_t*)out)[3] = h4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MurmurHash3_x64_128 ( const void * key, const int len,
|
||||||
|
const uint32_t seed, void * out )
|
||||||
|
{
|
||||||
|
const uint8_t * data = (const uint8_t*)key;
|
||||||
|
const int nblocks = len / 16;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
uint64_t h1 = seed;
|
||||||
|
uint64_t h2 = seed;
|
||||||
|
|
||||||
|
uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
|
||||||
|
uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// body
|
||||||
|
|
||||||
|
const uint64_t * blocks = (const uint64_t *)(data);
|
||||||
|
|
||||||
|
for(i = 0; i < nblocks; i++)
|
||||||
|
{
|
||||||
|
uint64_t k1 = getblock(blocks,i*2+0);
|
||||||
|
uint64_t k2 = getblock(blocks,i*2+1);
|
||||||
|
|
||||||
|
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
|
||||||
|
|
||||||
|
h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
|
||||||
|
|
||||||
|
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
|
||||||
|
|
||||||
|
h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// tail
|
||||||
|
|
||||||
|
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
|
||||||
|
|
||||||
|
uint64_t k1 = 0;
|
||||||
|
uint64_t k2 = 0;
|
||||||
|
|
||||||
|
switch(len & 15)
|
||||||
|
{
|
||||||
|
case 15: k2 ^= (uint64_t)(tail[14]) << 48;
|
||||||
|
case 14: k2 ^= (uint64_t)(tail[13]) << 40;
|
||||||
|
case 13: k2 ^= (uint64_t)(tail[12]) << 32;
|
||||||
|
case 12: k2 ^= (uint64_t)(tail[11]) << 24;
|
||||||
|
case 11: k2 ^= (uint64_t)(tail[10]) << 16;
|
||||||
|
case 10: k2 ^= (uint64_t)(tail[ 9]) << 8;
|
||||||
|
case 9: k2 ^= (uint64_t)(tail[ 8]) << 0;
|
||||||
|
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
|
||||||
|
|
||||||
|
case 8: k1 ^= (uint64_t)(tail[ 7]) << 56;
|
||||||
|
case 7: k1 ^= (uint64_t)(tail[ 6]) << 48;
|
||||||
|
case 6: k1 ^= (uint64_t)(tail[ 5]) << 40;
|
||||||
|
case 5: k1 ^= (uint64_t)(tail[ 4]) << 32;
|
||||||
|
case 4: k1 ^= (uint64_t)(tail[ 3]) << 24;
|
||||||
|
case 3: k1 ^= (uint64_t)(tail[ 2]) << 16;
|
||||||
|
case 2: k1 ^= (uint64_t)(tail[ 1]) << 8;
|
||||||
|
case 1: k1 ^= (uint64_t)(tail[ 0]) << 0;
|
||||||
|
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------
|
||||||
|
// finalization
|
||||||
|
|
||||||
|
h1 ^= len; h2 ^= len;
|
||||||
|
|
||||||
|
h1 += h2;
|
||||||
|
h2 += h1;
|
||||||
|
|
||||||
|
h1 = fmix64(h1);
|
||||||
|
h2 = fmix64(h2);
|
||||||
|
|
||||||
|
h1 += h2;
|
||||||
|
h2 += h1;
|
||||||
|
|
||||||
|
((uint64_t*)out)[0] = h1;
|
||||||
|
((uint64_t*)out)[1] = h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// MurmurHash3 was written by Austin Appleby, and is placed in the
|
||||||
|
// public domain. The author hereby disclaims copyright to this source
|
||||||
|
// code.
|
||||||
|
|
||||||
|
#ifndef _MURMURHASH3_H_
|
||||||
|
#define _MURMURHASH3_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out);
|
||||||
|
|
||||||
|
void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out);
|
||||||
|
|
||||||
|
void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out);
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _MURMURHASH3_H_
|
||||||
+1
-1
@@ -10,7 +10,7 @@ int main(int argc, char *argv[]) {
|
|||||||
server_data.welcome_message = get_welcome_mes();
|
server_data.welcome_message = get_welcome_mes();
|
||||||
server_data.fl_start = NULL;
|
server_data.fl_start = NULL;
|
||||||
server_data.fl_current = NULL;
|
server_data.fl_current = NULL;
|
||||||
init_connection();
|
init_db_connection();
|
||||||
get_files_descriptions(&server_data);
|
get_files_descriptions(&server_data);
|
||||||
server_data.ls = start_server();
|
server_data.ls = start_server();
|
||||||
server_main_loop(&server_data);
|
server_main_loop(&server_data);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef MAIN_H
|
#ifndef MAIN_H
|
||||||
#define MAIN_H
|
#define MAIN_H
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#define PORT 2000
|
#define PORT 2000
|
||||||
#define MAX_CONNECTIONS 1024
|
#define MAX_CONNECTIONS 1024
|
||||||
#define INBUFSIZE 1024
|
#define INBUFSIZE 1024
|
||||||
@@ -56,6 +57,7 @@ typedef struct session {
|
|||||||
char *fpath;
|
char *fpath;
|
||||||
char f_perm;
|
char f_perm;
|
||||||
char *fdesc;
|
char *fdesc;
|
||||||
|
uint32_t hash;
|
||||||
size_t fsize;
|
size_t fsize;
|
||||||
size_t f_rest;
|
size_t f_rest;
|
||||||
long int userpos; /* hint to the position in user list */
|
long int userpos; /* hint to the position in user list */
|
||||||
@@ -77,4 +79,6 @@ typedef struct server_data_t {
|
|||||||
int ls;
|
int ls;
|
||||||
} server_data_t;
|
} server_data_t;
|
||||||
|
|
||||||
|
#define FILE_HASH_SEED 898
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user