get files in FS by their hash number
This commit is contained in:
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [ ] Database integration
|
- [x] Database integration
|
||||||
- [ ] Paging in the file list
|
- [ ] Paging in the file list
|
||||||
- [ ] Get files in FS by their hash
|
- [x] Get files in FS by their hash
|
||||||
- [ ] Registration
|
- [ ] Registration
|
||||||
- [ ] Message to admin
|
- [ ] Message to admin
|
||||||
- [ ] Advanced folder structure for the storage
|
- [x] Advanced folder structure in the storage
|
||||||
- [ ] File encryption
|
- [ ] File encryption
|
||||||
- [ ] Connection encryption
|
- [ ] Connection encryption
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,15 @@ static int exit_query_2(int code) {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *exit_query_3(void *ptr) {
|
||||||
|
fprintf(stderr, "%s\n", PQerrorMessage(conn));
|
||||||
|
|
||||||
|
if (res != NULL)
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static void processNotice(void *arg, const char *message) {
|
static void processNotice(void *arg, const char *message) {
|
||||||
UNUSED(arg);
|
UNUSED(arg);
|
||||||
UNUSED(message);
|
UNUSED(message);
|
||||||
@@ -104,20 +113,18 @@ int db_user_auth(i_auth_t *credentials, o_auth_t *response) {
|
|||||||
return exit_query(2);
|
return exit_query(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int db_save_collision(uint32_t hash);
|
|
||||||
|
|
||||||
#define BIN 1
|
#define BIN 1
|
||||||
#define TEXT 0
|
#define TEXT 0
|
||||||
|
|
||||||
int db_save_file(session *s) {
|
int32_t db_save_file(session *s) {
|
||||||
const char *paramValues[6];
|
const char *paramValues[6];
|
||||||
int paramFormats[6];
|
int paramFormats[6];
|
||||||
int paramLengths[6];
|
int paramLengths[6];
|
||||||
int collision_id = 0;
|
int collision_id = 0;
|
||||||
session_file *sf = s->file;
|
s_file_t *sf = s->file;
|
||||||
|
|
||||||
int32_t uid_n = htonl(s->uid);
|
int32_t uid_n = htonl(s->uid);
|
||||||
int64_t size_n = htonl(sf->size);
|
uint64_t size_n = htobe64(sf->size);
|
||||||
int32_t hash_n = htonl(sf->hash);
|
int32_t hash_n = htonl(sf->hash);
|
||||||
int32_t perm_n = htonl(sf->permissions);
|
int32_t perm_n = htonl(sf->permissions);
|
||||||
|
|
||||||
@@ -130,7 +137,7 @@ int db_save_file(session *s) {
|
|||||||
|
|
||||||
paramLengths[0] = sizeof(int32_t);
|
paramLengths[0] = sizeof(int32_t);
|
||||||
paramLengths[1] = strlen(sf->name);
|
paramLengths[1] = strlen(sf->name);
|
||||||
paramLengths[2] = sizeof(int64_t);
|
paramLengths[2] = sizeof(uint64_t);
|
||||||
paramLengths[3] = sizeof(int32_t);
|
paramLengths[3] = sizeof(int32_t);
|
||||||
paramLengths[4] = strlen(sf->description);
|
paramLengths[4] = strlen(sf->description);
|
||||||
paramLengths[5] = sizeof(int32_t);
|
paramLengths[5] = sizeof(int32_t);
|
||||||
@@ -158,9 +165,57 @@ int db_save_file(session *s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get file
|
// TODO: get file
|
||||||
// int db_get_file(i_get_file_db *arg) {
|
s_file_t *db_get_file(i_get_file_db *arg) {
|
||||||
|
s_file_t *sf;
|
||||||
|
char s_field[24];
|
||||||
|
char value[64] = "";
|
||||||
|
const char *paramValues[1];
|
||||||
|
char query[512];
|
||||||
|
uint32_t q_len = 0;
|
||||||
|
|
||||||
// }
|
if (arg->id) {
|
||||||
|
strcpy(s_field, "id");
|
||||||
|
sprintf(value, "%u", arg->id);
|
||||||
|
} else if (strlen(arg->name)) {
|
||||||
|
strcpy(s_field, "name");
|
||||||
|
strcpy(value, arg->name);
|
||||||
|
} else if (arg->user_id) {
|
||||||
|
strcpy(s_field, "user_id");
|
||||||
|
sprintf(value, "%u", arg->user_id);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "db_get_file: none of the args is specified!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
paramValues[0] = value;
|
||||||
|
|
||||||
|
sprintf(query,
|
||||||
|
"SELECT files.id, user_id, name, size, description, permissions, hash "
|
||||||
|
"FROM files JOIN users ON user_id = users.id WHERE files.%s = $1%n",
|
||||||
|
s_field, &q_len);
|
||||||
|
|
||||||
|
res = PQexecParams(conn, query, 1, NULL, paramValues, NULL, NULL, TEXT);
|
||||||
|
|
||||||
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
|
return exit_query_3(NULL);
|
||||||
|
|
||||||
|
sf = malloc(sizeof(s_file_t));
|
||||||
|
sf->id = atoi(PQgetvalue(res, 0, 0));
|
||||||
|
sf->owner_id = atoi(PQgetvalue(res, 0, 1));
|
||||||
|
char *name = PQgetvalue(res, 0, 2);
|
||||||
|
sf->name = malloc(strlen(name) + 1);
|
||||||
|
strcpy(sf->name, name);
|
||||||
|
sf->size = atoll(PQgetvalue(res, 0, 3));
|
||||||
|
char *description = PQgetvalue(res, 0, 4);
|
||||||
|
sf->description = malloc(strlen(description) + 1);
|
||||||
|
strcpy(sf->description, description);
|
||||||
|
sf->permissions = atoi(PQgetvalue(res, 0, 5));
|
||||||
|
sf->hash = atoi(PQgetvalue(res, 0, 6));
|
||||||
|
|
||||||
|
clearRes();
|
||||||
|
|
||||||
|
return sf;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
||||||
uint64_t *full_count) {
|
uint64_t *full_count) {
|
||||||
@@ -204,9 +259,9 @@ uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
|||||||
paramFormats[0] = BIN;
|
paramFormats[0] = BIN;
|
||||||
paramFormats[1] = BIN;
|
paramFormats[1] = BIN;
|
||||||
|
|
||||||
sprintf(
|
sprintf(query,
|
||||||
query,
|
"SELECT files.id, user_id, name, size, description, permissions, "
|
||||||
"SELECT user_id, name, size, description, permissions, hash, username "
|
"hash, username "
|
||||||
"FROM files JOIN users ON user_id = users.id "
|
"FROM files JOIN users ON user_id = users.id "
|
||||||
"ORDER BY files.%s %s LIMIT $1 OFFSET $2",
|
"ORDER BY files.%s %s LIMIT $1 OFFSET $2",
|
||||||
sort_by, sort_dir);
|
sort_by, sort_dir);
|
||||||
@@ -220,17 +275,18 @@ uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
|||||||
for (i = 0; i < PQntuples(res); i++) {
|
for (i = 0; i < PQntuples(res); i++) {
|
||||||
fl_t *l_item = malloc(sizeof(fl_t));
|
fl_t *l_item = malloc(sizeof(fl_t));
|
||||||
l_item->next = NULL;
|
l_item->next = NULL;
|
||||||
l_item->owner_id = atoi(PQgetvalue(res, i, 0));
|
l_item->id = atoi(PQgetvalue(res, i, 0));
|
||||||
char *name = PQgetvalue(res, i, 1);
|
l_item->owner_id = atoi(PQgetvalue(res, i, 1));
|
||||||
|
char *name = PQgetvalue(res, i, 2);
|
||||||
l_item->name = malloc(strlen(name) + 1);
|
l_item->name = malloc(strlen(name) + 1);
|
||||||
strcpy(l_item->name, name);
|
strcpy(l_item->name, name);
|
||||||
l_item->size = atoll(PQgetvalue(res, i, 2));
|
l_item->size = atoll(PQgetvalue(res, i, 3));
|
||||||
char *description = PQgetvalue(res, i, 3);
|
char *description = PQgetvalue(res, i, 4);
|
||||||
l_item->description = malloc(strlen(description) + 1);
|
l_item->description = malloc(strlen(description) + 1);
|
||||||
strcpy(l_item->description, description);
|
strcpy(l_item->description, description);
|
||||||
l_item->permissions = atoi(PQgetvalue(res, i, 4));
|
l_item->permissions = atoi(PQgetvalue(res, i, 5));
|
||||||
l_item->hash = atoi(PQgetvalue(res, i, 5));
|
l_item->hash = atoi(PQgetvalue(res, i, 6));
|
||||||
char *owner = PQgetvalue(res, i, 6);
|
char *owner = PQgetvalue(res, i, 7);
|
||||||
l_item->owner = malloc(strlen(owner) + 1);
|
l_item->owner = malloc(strlen(owner) + 1);
|
||||||
strcpy(l_item->owner, owner);
|
strcpy(l_item->owner, owner);
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ typedef struct {
|
|||||||
/* Get file */
|
/* Get file */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int id;
|
uint32_t id;
|
||||||
char *name;
|
uint32_t user_id;
|
||||||
int user_id;
|
char name[64];
|
||||||
} i_get_file_db;
|
} i_get_file_db;
|
||||||
|
|
||||||
enum sort_direction { ASC, DESC };
|
enum sort_direction { ASC, DESC };
|
||||||
@@ -35,9 +35,10 @@ typedef struct {
|
|||||||
enum sort_direction sort_direction;
|
enum sort_direction sort_direction;
|
||||||
} i_get_files_db;
|
} i_get_files_db;
|
||||||
|
|
||||||
int init_db_connection();
|
int32_t init_db_connection();
|
||||||
int db_user_auth(i_auth_t *credentials, o_auth_t *response);
|
int32_t db_save_file(session *s);
|
||||||
int db_save_file(session *s);
|
int32_t db_user_auth(i_auth_t *credentials, o_auth_t *response);
|
||||||
|
s_file_t *db_get_file(i_get_file_db *arg);
|
||||||
uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
||||||
uint64_t *full_count);
|
uint64_t *full_count);
|
||||||
#endif
|
#endif
|
||||||
+48
-36
@@ -100,43 +100,10 @@ void file_list(session *sess, server_data_t *s_d) {
|
|||||||
} while ((fl_current = fl_current->next) != NULL);
|
} while ((fl_current = fl_current->next) != NULL);
|
||||||
|
|
||||||
sess->fl_start = fl_start;
|
sess->fl_start = fl_start;
|
||||||
write(sess->sd, list_end, sizeof(list_end));
|
write(sess->sd, list_end, sizeof(list_end)-1);
|
||||||
write(sess->sd, page_info, strlen(page_info));
|
write(sess->sd, page_info, strlen(page_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
int file_send_prepare(session *sess, char *line, server_data_t *s_d) {
|
|
||||||
sess->file = malloc(sizeof(session_file));
|
|
||||||
int sd = sess->sd;
|
|
||||||
char fname[50];
|
|
||||||
sscanf(line, "%*s %*s %s", fname);
|
|
||||||
char filepath[256];
|
|
||||||
sprintf(filepath, "%s/%s", STORAGE_FOLDER, fname);
|
|
||||||
char st_message[256];
|
|
||||||
size_t fsize;
|
|
||||||
|
|
||||||
int file_d = open(filepath, O_RDONLY);
|
|
||||||
|
|
||||||
if (file_d == -1) {
|
|
||||||
fprintf(stdout, "ERROR: %d\n", errno);
|
|
||||||
char err_mes[256];
|
|
||||||
int mlen;
|
|
||||||
mlen = sprintf(err_mes, "Can't open file named \"%s\"\n", fname);
|
|
||||||
write(sd, err_mes, mlen);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fsize = lseek(file_d, 0, SEEK_END);
|
|
||||||
lseek(file_d, 0, SEEK_SET);
|
|
||||||
|
|
||||||
sess->file->size = fsize;
|
|
||||||
sess->file->rest = fsize;
|
|
||||||
sess->file->name = malloc(strlen(fname));
|
|
||||||
int fname_len = strlen(fname) - 1;
|
|
||||||
strncpy(sess->file->name, fname, fname_len);
|
|
||||||
sess->file->name[fname_len] = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int directory_exists(const char *path) {
|
int directory_exists(const char *path) {
|
||||||
struct stat info;
|
struct stat info;
|
||||||
|
|
||||||
@@ -156,13 +123,58 @@ void extract_names_from_hash(uint32_t file_hash, char *dirname, char *fname) {
|
|||||||
fname[6] = 0;
|
fname[6] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t file_send_prepare(session *sess, char *line, server_data_t *s_d) {
|
||||||
|
int32_t sd = sess->sd;
|
||||||
|
i_get_file_db args = {.id = 0, .user_id = 0, .name = ""};
|
||||||
|
char st_message[256];
|
||||||
|
int32_t file_d;
|
||||||
|
size_t fsize;
|
||||||
|
char hashed_dir_name[3];
|
||||||
|
char hashed_name[7];
|
||||||
|
char err_mes[256];
|
||||||
|
uint32_t mlen;
|
||||||
|
|
||||||
|
sscanf(line, "%*s %*s %s", args.name);
|
||||||
|
sess->file = db_get_file(&args);
|
||||||
|
|
||||||
|
if (sess->file == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
extract_names_from_hash(sess->file->hash, hashed_dir_name, hashed_name);
|
||||||
|
sess->file->path = malloc(sizeof(STORAGE_FOLDER) + 2 + 9);
|
||||||
|
sprintf(sess->file->path, "%s/%s/%s", STORAGE_FOLDER, hashed_dir_name,
|
||||||
|
hashed_name);
|
||||||
|
|
||||||
|
file_d = open(sess->file->path, O_RDONLY);
|
||||||
|
|
||||||
|
if (file_d == -1) {
|
||||||
|
fprintf(stdout, "ERROR: %d\n", errno);
|
||||||
|
mlen = sprintf(err_mes, "Can't open file with id = %u\n", sess->file->id);
|
||||||
|
write(sd, err_mes, mlen);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsize = lseek(file_d, 0, SEEK_END);
|
||||||
|
lseek(file_d, 0, SEEK_SET);
|
||||||
|
|
||||||
|
if (sess->file->size != fsize) {
|
||||||
|
mlen = sprintf(err_mes, "File with id = %u exists, but seems to be damaged\n", sess->file->id);
|
||||||
|
write(sd, err_mes, mlen);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
sess->file->rest = fsize;
|
||||||
|
sess->fd = file_d;
|
||||||
|
return 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];
|
||||||
size_t fsize;
|
size_t fsize;
|
||||||
int perm;
|
int perm;
|
||||||
sscanf(line, "file upload \"%s %zd %d", fname, &fsize, &perm);
|
sscanf(line, "file upload \"%s %zd %d", fname, &fsize, &perm);
|
||||||
sess->file = malloc(sizeof(session_file));
|
sess->file = malloc(sizeof(s_file_t));
|
||||||
sess->file->name = malloc(sizeof(char) * strlen(fname));
|
sess->file->name = malloc(sizeof(char) * strlen(fname));
|
||||||
sess->file->path = malloc(sizeof(STORAGE_FOLDER) + 2 + 9);
|
sess->file->path = malloc(sizeof(STORAGE_FOLDER) + 2 + 9);
|
||||||
sess->file->permissions = (char)perm;
|
sess->file->permissions = (char)perm;
|
||||||
@@ -235,7 +247,7 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear_file_from_sess(session *s) {
|
void clear_file_from_sess(session *s) {
|
||||||
session_file *sf = s->file;
|
s_file_t *sf = s->file;
|
||||||
if (sf->name != NULL) {
|
if (sf->name != NULL) {
|
||||||
free(sf->name);
|
free(sf->name);
|
||||||
sf->name = NULL;
|
sf->name = NULL;
|
||||||
|
|||||||
+5
-2
@@ -49,7 +49,9 @@ typedef struct {
|
|||||||
size_t size;
|
size_t size;
|
||||||
size_t rest;
|
size_t rest;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
} session_file;
|
uint32_t id;
|
||||||
|
uint32_t owner_id;
|
||||||
|
} s_file_t;
|
||||||
|
|
||||||
typedef struct fl_t {
|
typedef struct fl_t {
|
||||||
char *name;
|
char *name;
|
||||||
@@ -59,6 +61,7 @@ typedef struct fl_t {
|
|||||||
uint32_t owner_id;
|
uint32_t owner_id;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
uint32_t id;
|
||||||
struct fl_t *next;
|
struct fl_t *next;
|
||||||
} fl_t;
|
} fl_t;
|
||||||
|
|
||||||
@@ -74,7 +77,7 @@ typedef struct session {
|
|||||||
uint32_t uid;
|
uint32_t uid;
|
||||||
int fd;
|
int fd;
|
||||||
int sd; /* session descriptor */
|
int sd; /* session descriptor */
|
||||||
session_file *file;
|
s_file_t *file;
|
||||||
fl_t *fl_start;
|
fl_t *fl_start;
|
||||||
fl_t *fl_current;
|
fl_t *fl_current;
|
||||||
} session;
|
} session;
|
||||||
|
|||||||
Reference in New Issue
Block a user