file db saving (not complete)
This commit is contained in:
@@ -7,12 +7,17 @@ BIN_DIR := bin
|
|||||||
SRCS := $(wildcard $(SRC_DIR)/*.c)
|
SRCS := $(wildcard $(SRC_DIR)/*.c)
|
||||||
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||||
|
|
||||||
|
OBJS += murmur3.o
|
||||||
|
|
||||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
|
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
bbs-server: $(OBJS)
|
bbs-server: $(OBJS)
|
||||||
$(CC) $(CFLAGS) $^ -o $(BIN_DIR)/$@
|
$(CC) $(CFLAGS) $^ -o $(BIN_DIR)/$@
|
||||||
|
|
||||||
|
murmur3.o: $(SRC_DIR)/libs/murmur3/murmur3.c $(SRC_DIR)/libs/murmur3/murmur3.h
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
ifneq (clean, $(MAKECMDGOALS))
|
ifneq (clean, $(MAKECMDGOALS))
|
||||||
-include deps.mk
|
-include deps.mk
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "main.h"
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
@@ -38,6 +43,16 @@ static int exit_query(int code) {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int exit_query_2(int code) {
|
||||||
|
if (code == 0)
|
||||||
|
fprintf(stderr, "%s\n", PQerrorMessage(conn));
|
||||||
|
|
||||||
|
if (res != NULL)
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static void processNotice(void *arg, const char *message) {
|
static void processNotice(void *arg, const char *message) {
|
||||||
UNUSED(arg);
|
UNUSED(arg);
|
||||||
UNUSED(message);
|
UNUSED(message);
|
||||||
@@ -56,6 +71,11 @@ int init_db_connection() {
|
|||||||
char *user = PQuser(conn);
|
char *user = PQuser(conn);
|
||||||
char *db_name = PQdb(conn);
|
char *db_name = PQdb(conn);
|
||||||
|
|
||||||
|
// res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '',
|
||||||
|
// false)"); if (PQresultStatus(res) != PGRES_TUPLES_OK) {
|
||||||
|
// return terminate(2);
|
||||||
|
// }
|
||||||
|
|
||||||
printf("Connection established! server version: %d, user: %s, db: %s\n",
|
printf("Connection established! server version: %d, user: %s, db: %s\n",
|
||||||
server_ver, user, db_name);
|
server_ver, user, db_name);
|
||||||
return exit_query(0);
|
return exit_query(0);
|
||||||
@@ -66,19 +86,144 @@ int db_user_auth(i_auth_t *credentials, o_auth_t *response) {
|
|||||||
paramValues[0] = credentials->name;
|
paramValues[0] = credentials->name;
|
||||||
|
|
||||||
res = PQexecParams(conn,
|
res = PQexecParams(conn,
|
||||||
"SELECT username, password, privileges "
|
"SELECT id, username, password, privileges "
|
||||||
"FROM users "
|
"FROM users "
|
||||||
"WHERE username= $1", 1,
|
"WHERE username= $1",
|
||||||
NULL, paramValues, NULL, NULL, 0);
|
1, NULL, paramValues, NULL, NULL, 0);
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
return exit_query(1);
|
return exit_query(1);
|
||||||
|
|
||||||
const char *pass = PQgetvalue(res, 0, 1);
|
const char *pass = PQgetvalue(res, 0, 2);
|
||||||
if (!strcmp(pass, credentials->pass)) {
|
if (!strcmp(pass, credentials->pass)) {
|
||||||
response->is_logged = 1;
|
response->privileges = PQgetvalue(res, 0, 3)[0];
|
||||||
response->privileges = PQgetvalue(res, 0, 2)[0];
|
response->uid = atoi(PQgetvalue(res, 0, 0));
|
||||||
return exit_query(0);
|
return exit_query(0);
|
||||||
}
|
}
|
||||||
return exit_query(2);
|
return exit_query(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int db_save_collision(uint32_t hash);
|
||||||
|
|
||||||
|
#define BIN 1
|
||||||
|
#define TEXT 0
|
||||||
|
|
||||||
|
int db_save_file(session *s) {
|
||||||
|
const char *paramValues[6];
|
||||||
|
int paramFormats[6];
|
||||||
|
int paramLengths[6];
|
||||||
|
int collision_id = 0;
|
||||||
|
session_file *sf = s->file;
|
||||||
|
|
||||||
|
if (sf->seed != FILE_HASH_SEED) {
|
||||||
|
// TODO: сиды обрабатываются неправильно
|
||||||
|
collision_id = db_save_collision(sf->hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t uid_n = htonl(s->uid);
|
||||||
|
int64_t size_n = htonl(sf->size);
|
||||||
|
int32_t coll_n = htonl(collision_id);
|
||||||
|
int32_t perm_n = htonl(sf->permissions);
|
||||||
|
|
||||||
|
paramValues[0] = (char *)&uid_n;
|
||||||
|
paramValues[1] = sf->name;
|
||||||
|
paramValues[2] = (char *)&size_n;
|
||||||
|
paramValues[3] = (char *)&coll_n;
|
||||||
|
paramValues[4] = sf->description;
|
||||||
|
paramValues[5] = (char *)&perm_n;
|
||||||
|
|
||||||
|
paramLengths[0] = sizeof(int32_t);
|
||||||
|
paramLengths[1] = strlen(sf->name);
|
||||||
|
paramLengths[2] = sizeof(int64_t);
|
||||||
|
paramLengths[3] = sizeof(int32_t);
|
||||||
|
paramLengths[4] = strlen(sf->description);
|
||||||
|
paramLengths[5] = sizeof(int32_t);
|
||||||
|
|
||||||
|
paramFormats[0] = BIN;
|
||||||
|
paramFormats[1] = TEXT;
|
||||||
|
paramFormats[2] = BIN;
|
||||||
|
paramFormats[3] = BIN;
|
||||||
|
paramFormats[4] = TEXT;
|
||||||
|
paramFormats[5] = BIN;
|
||||||
|
|
||||||
|
res = PQexecParams(conn,
|
||||||
|
"INSERT INTO files(user_id, name, size, created_at, "
|
||||||
|
"collision_id, description, permissions) "
|
||||||
|
"VALUES ($1, $2, $3, NOW(), NULLIF($4, 0), $5, $6) "
|
||||||
|
"RETURNING id",
|
||||||
|
6, NULL, paramValues, paramLengths, paramFormats, TEXT);
|
||||||
|
|
||||||
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
|
return exit_query_2(0);
|
||||||
|
|
||||||
|
int id = atoi(PQgetvalue(res, 0, 0));
|
||||||
|
clearRes();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_save_collision(uint32_t hash) {
|
||||||
|
const char *paramValues[1];
|
||||||
|
int paramLengths[1];
|
||||||
|
int paramFormats[1];
|
||||||
|
|
||||||
|
uint32_t hash_n = htonl(hash);
|
||||||
|
|
||||||
|
paramValues[0] = (char *)&hash_n;
|
||||||
|
paramLengths[0] = sizeof(uint32_t);
|
||||||
|
paramFormats[0] = BIN;
|
||||||
|
|
||||||
|
res = PQexecParams(conn,
|
||||||
|
"INSERT INTO file_collisions(hash) "
|
||||||
|
"VALUES ($1) "
|
||||||
|
"RETURNING id",
|
||||||
|
1, NULL, paramValues, paramLengths, paramFormats, TEXT);
|
||||||
|
|
||||||
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
|
return exit_query_2(0);
|
||||||
|
|
||||||
|
int id = atoi(PQgetvalue(res, 0, 0));
|
||||||
|
clearRes();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: get file
|
||||||
|
// int db_get_file(i_get_file_db *arg) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
int db_get_files(i_get_files_db *arg) {
|
||||||
|
const char *paramValues[3];
|
||||||
|
int paramLengths[3];
|
||||||
|
int paramFormats[3];
|
||||||
|
int i, j, nFields;
|
||||||
|
|
||||||
|
paramValues[0] = arg->sort_by;
|
||||||
|
paramValues[1] = (char *)&arg->limit;
|
||||||
|
paramValues[2] = (char *)&arg->offset;
|
||||||
|
|
||||||
|
paramLengths[0] = strlen(arg->sort_by);
|
||||||
|
paramLengths[1] = sizeof(arg->limit);
|
||||||
|
paramLengths[2] = sizeof(arg->offset);
|
||||||
|
|
||||||
|
paramFormats[0] = TEXT;
|
||||||
|
paramFormats[1] = BIN;
|
||||||
|
paramFormats[2] = BIN;
|
||||||
|
|
||||||
|
res = PQexecParams(conn, "SELECT * FROM files ORDER BY $1 LIMIT $2 OFFSET $3",
|
||||||
|
3, NULL, paramValues, paramLengths, paramFormats, TEXT);
|
||||||
|
|
||||||
|
nFields = PQnfields(res);
|
||||||
|
for (i = 0; i < nFields; i++)
|
||||||
|
printf("%-15s", PQfname(res, i));
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
for (i = 0; i < PQntuples(res); i++) {
|
||||||
|
for (j = 0; j < nFields; j++)
|
||||||
|
printf("%-15s", PQgetvalue(res, i, j));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
clearRes();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,12 +1,35 @@
|
|||||||
|
#include "main.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Auth */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
char *pass;
|
char *pass;
|
||||||
} i_auth_t;
|
} i_auth_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char privileges;
|
char privileges;
|
||||||
int is_logged;
|
uint32_t uid;
|
||||||
} o_auth_t;
|
} o_auth_t;
|
||||||
|
|
||||||
|
/* Get file */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int id;
|
||||||
|
char *name;
|
||||||
|
int user_id;
|
||||||
|
} i_get_file_db;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int user_id; // TODO: implement
|
||||||
|
char *name; // TODO: implement
|
||||||
|
int limit;
|
||||||
|
int offset;
|
||||||
|
char sort_by[12];
|
||||||
|
} i_get_files_db;
|
||||||
|
|
||||||
|
|
||||||
int init_db_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);
|
||||||
|
int db_save_file(session *s);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
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 src/main.h
|
||||||
|
file_p.o: src/file_p.c src/file_p.h src/main.h src/libs/murmur3/murmur3.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 src/db.h
|
||||||
|
user.o: src/user.c src/main.h src/session.h src/db.h
|
||||||
|
|||||||
+85
-75
@@ -1,7 +1,6 @@
|
|||||||
#include "file_p.h"
|
#include "file_p.h"
|
||||||
#include "libs/murmur3/murmur3.h"
|
#include "libs/murmur3/murmur3.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "session.h"
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -53,14 +52,14 @@ void file_list(session *sess, server_data_t *s_d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int file_send_prepare(session *sess, char *line, server_data_t *s_d) {
|
int file_send_prepare(session *sess, char *line, server_data_t *s_d) {
|
||||||
// TODO: рефактор в C++
|
sess->file = malloc(sizeof(session_file));
|
||||||
int sd = sess->sd;
|
int sd = sess->sd;
|
||||||
char fname[32];
|
char fname[50];
|
||||||
sscanf(line, "%*s %*s %s", fname);
|
sscanf(line, "%*s %*s %s", fname);
|
||||||
char filepath[256];
|
char filepath[256];
|
||||||
sprintf(filepath, "%s/%s", STORAGE_FOLDER, fname);
|
sprintf(filepath, "%s/%s", STORAGE_FOLDER, fname);
|
||||||
size_t fsize;
|
|
||||||
char st_message[256];
|
char st_message[256];
|
||||||
|
size_t fsize;
|
||||||
|
|
||||||
int file_d = open(filepath, O_RDONLY);
|
int file_d = open(filepath, O_RDONLY);
|
||||||
|
|
||||||
@@ -76,13 +75,13 @@ int file_send_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
fsize = lseek(file_d, 0, SEEK_END);
|
fsize = lseek(file_d, 0, SEEK_END);
|
||||||
lseek(file_d, 0, SEEK_SET);
|
lseek(file_d, 0, SEEK_SET);
|
||||||
|
|
||||||
sess->fd = file_d;
|
sess->file->fd = file_d;
|
||||||
sess->fsize = fsize;
|
sess->file->size = fsize;
|
||||||
sess->f_rest = fsize;
|
sess->file->rest = fsize;
|
||||||
sess->fname = malloc(strlen(fname));
|
sess->file->name = malloc(strlen(fname));
|
||||||
int fname_len = strlen(fname) - 1;
|
int fname_len = strlen(fname) - 1;
|
||||||
strncpy(sess->fname, fname, fname_len);
|
strncpy(sess->file->name, fname, fname_len);
|
||||||
sess->fname[fname_len] = 0;
|
sess->file->name[fname_len] = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,16 +110,19 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
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->fname = malloc(sizeof(char) * strlen(fname));
|
sess->file = malloc(sizeof(session_file));
|
||||||
sess->f_perm = (char)perm;
|
sess->file->name = malloc(sizeof(char) * strlen(fname));
|
||||||
strncpy(sess->fname, fname, strlen(fname) - 1); // remove the last \"
|
// TODO: в конце гуляет \n и \"
|
||||||
|
sess->file->permissions = (char)perm;
|
||||||
|
sess->file->description = NULL;
|
||||||
|
strncpy(sess->file->name, fname, strlen(fname) - 1); // remove the last \"
|
||||||
|
|
||||||
char mes[256];
|
char mes[256];
|
||||||
char mes_len = 0;
|
char mes_len = 0;
|
||||||
struct statvfs st_str;
|
struct statvfs st_str;
|
||||||
statvfs(".", &st_str);
|
statvfs(".", &st_str);
|
||||||
size_t available_space = st_str.f_bavail * st_str.f_bsize;
|
size_t available_space = st_str.f_bavail * st_str.f_bsize;
|
||||||
if (strlen(sess->fname) > st_str.f_namemax) {
|
if (strlen(sess->file->name) > st_str.f_namemax) {
|
||||||
mes_len = sprintf(mes, "file name is tool long\n");
|
mes_len = sprintf(mes, "file name is tool long\n");
|
||||||
write(sd, mes, mes_len);
|
write(sd, mes, mes_len);
|
||||||
sess->state = OP_WAIT;
|
sess->state = OP_WAIT;
|
||||||
@@ -136,81 +138,85 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
|
|||||||
|
|
||||||
char hashed_dir_name[3];
|
char hashed_dir_name[3];
|
||||||
char hashed_name[7];
|
char hashed_name[7];
|
||||||
int seed = FILE_HASH_SEED;
|
sess->file->seed = FILE_HASH_SEED;
|
||||||
int file_d;
|
int file_d;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
MurmurHash3_x86_32(sess->fname, strlen(sess->fname), FILE_HASH_SEED,
|
MurmurHash3_x86_32(sess->file->name, strlen(sess->file->name), sess->file->seed,
|
||||||
&(sess->hash));
|
&sess->file->hash);
|
||||||
|
|
||||||
extract_names_from_hash(sess->hash, hashed_dir_name, hashed_name);
|
extract_names_from_hash(sess->file->hash, hashed_dir_name, hashed_name);
|
||||||
|
|
||||||
sess->fpath = malloc(sizeof(STORAGE_FOLDER) + 2 + 9);
|
sess->file->path = malloc(sizeof(STORAGE_FOLDER) + 2 + 9);
|
||||||
sprintf(sess->fpath, "%s/%s/%s", STORAGE_FOLDER, hashed_dir_name,
|
sprintf(sess->file->path, "%s/%s/%s", STORAGE_FOLDER, hashed_dir_name,
|
||||||
hashed_name);
|
hashed_name);
|
||||||
|
|
||||||
|
chdir(STORAGE_FOLDER);
|
||||||
|
|
||||||
if (!directory_exists(hashed_dir_name)) {
|
if (!directory_exists(hashed_dir_name)) {
|
||||||
mkdir(hashed_dir_name, 0700);
|
mkdir(hashed_dir_name, 0700);
|
||||||
}
|
}
|
||||||
chdir(hashed_dir_name);
|
chdir("../");
|
||||||
|
|
||||||
file_d = open(sess->fpath, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
file_d = open(sess->file->path, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
||||||
if (file_d == -1) {
|
if (file_d == -1) {
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
seed++;
|
sess->file->seed++;
|
||||||
free(sess->fpath);
|
free(sess->file->path);
|
||||||
sess->fpath = NULL;
|
sess->file->path = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mes_len = sprintf(mes, "Can't create file with such name: \"%s\"\n",
|
mes_len = sprintf(mes, "Can't create file with such name: \"%s\"\n",
|
||||||
sess->fname);
|
sess->file->name);
|
||||||
write(sd, mes, mes_len);
|
write(sd, mes, mes_len);
|
||||||
clear_file_from_sess(sess);
|
clear_file_from_sess(sess);
|
||||||
|
sess->file = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mes_len = sprintf(mes, "accept");
|
mes_len = sprintf(mes, "accept");
|
||||||
sess->fd = file_d;
|
sess->file->fd = file_d;
|
||||||
sess->fsize = fsize;
|
sess->file->size = fsize;
|
||||||
sess->f_rest = fsize;
|
sess->file->rest = fsize;
|
||||||
write(sd, mes, mes_len);
|
write(sd, mes, mes_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_file_from_sess(session *sess) {
|
void clear_file_from_sess(session *s) {
|
||||||
if (sess->fname != NULL) {
|
session_file * sf = s->file;
|
||||||
free(sess->fname);
|
if (sf->name != NULL) {
|
||||||
sess->fname = NULL;
|
free(sf->name);
|
||||||
|
sf->name = NULL;
|
||||||
}
|
}
|
||||||
if (sess->fpath != NULL) {
|
if (sf->path != NULL) {
|
||||||
free(sess->fpath);
|
free(sf->path);
|
||||||
sess->fpath = NULL;
|
sf->path = NULL;
|
||||||
}
|
}
|
||||||
if (sess->fdesc != NULL) {
|
if (sf->description != NULL) {
|
||||||
free(sess->fdesc);
|
free(sf->description);
|
||||||
sess->fdesc = NULL;
|
sf->description = NULL;
|
||||||
}
|
}
|
||||||
if (sess->fd > -1) {
|
if (sf->fd > -1) {
|
||||||
close(sess->fd);
|
close(sf->fd);
|
||||||
}
|
}
|
||||||
sess->fd = -1;
|
free(sf);
|
||||||
sess->fsize = 0;
|
s->file = NULL;
|
||||||
sess->f_rest = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_download_upload(session *sess, enum f_actions f_action) {
|
void file_download_upload(session *sess, enum f_actions f_action) {
|
||||||
int source_d = f_action == F_DOWNLOAD ? sess->fd : sess->sd;
|
int source_d = f_action == F_DOWNLOAD ? sess->file->fd : sess->sd;
|
||||||
int dest_d = f_action == F_DOWNLOAD ? sess->sd : sess->fd;
|
int dest_d = f_action == F_DOWNLOAD ? sess->sd : sess->file->fd;
|
||||||
char buf[INBUFSIZE];
|
char buf[INBUFSIZE];
|
||||||
int rlen = read(source_d, buf, INBUFSIZE);
|
int rlen = read(source_d, buf, INBUFSIZE);
|
||||||
if (rlen == 0) {
|
if (rlen == 0) {
|
||||||
if (sess->f_rest) {
|
if (sess->file->rest) {
|
||||||
if (f_action == F_DOWNLOAD) {
|
if (f_action == F_DOWNLOAD) {
|
||||||
fprintf(stderr, "Error downloading file %s!\n", sess->fname);
|
fprintf(stderr, "Error downloading file %s!\n", sess->file->name);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Error uploading file %s!\n", sess->fname);
|
fprintf(stderr, "Error uploading file %s!\n", sess->file->name);
|
||||||
unlink(sess->fpath); /* remove file */
|
unlink(sess->file->path); /* remove file */
|
||||||
}
|
}
|
||||||
clear_file_from_sess(sess);
|
clear_file_from_sess(sess);
|
||||||
}
|
}
|
||||||
@@ -218,13 +224,13 @@ void file_download_upload(session *sess, enum f_actions f_action) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
write(dest_d, buf, rlen);
|
write(dest_d, buf, rlen);
|
||||||
sess->f_rest -= rlen;
|
sess->file->rest -= rlen;
|
||||||
if (!sess->f_rest) {
|
if (!sess->file->rest) {
|
||||||
if (f_action == F_DOWNLOAD) {
|
if (f_action == F_DOWNLOAD) {
|
||||||
printf("File %s is downloaded from the server\n", sess->fname);
|
printf("File %s is downloaded from the server\n", sess->file->name);
|
||||||
clear_file_from_sess(sess);
|
clear_file_from_sess(sess);
|
||||||
} else {
|
} else {
|
||||||
printf("File %s is uploaded to the server\n", sess->fname);
|
printf("File %s is uploaded to the server\n", sess->file->name);
|
||||||
}
|
}
|
||||||
if (f_action == F_UPLOAD) {
|
if (f_action == F_UPLOAD) {
|
||||||
sess->state = OP_UPLOAD_DESCRIPTION;
|
sess->state = OP_UPLOAD_DESCRIPTION;
|
||||||
@@ -256,27 +262,31 @@ size_t get_file_size(char *dir_n, char *file_n) {
|
|||||||
|
|
||||||
/* returns 1 if there is :END: ; 0 if opposite */
|
/* returns 1 if there is :END: ; 0 if opposite */
|
||||||
int file_upload_description(session *sess, char *line, server_data_t *s_d) {
|
int file_upload_description(session *sess, char *line, server_data_t *s_d) {
|
||||||
for (;;) {
|
// for (;;) {
|
||||||
if (line != NULL && sess->fdesc == NULL) { /* first query */
|
// if (line != NULL && sess->file->description == NULL) { /* first query */
|
||||||
sess->fdesc = malloc(strlen(line) + 1);
|
// sess->file->description = malloc(strlen(line) + 1);
|
||||||
strcpy(sess->fdesc, line);
|
// strcpy(sess->file->description, line);
|
||||||
} else { /* subsequent queries */
|
// } else { /* subsequent queries */
|
||||||
if (line == NULL) {
|
// if (line == NULL) {
|
||||||
if (sess->buf_used > 0) {
|
// if (sess->buf_used > 0) {
|
||||||
query_extract_from_buf(sess, &line);
|
// query_extract_from_buf(sess, &line);
|
||||||
} else {
|
// } else {
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
sess->fdesc =
|
// sess->file->description =
|
||||||
realloc(sess->fdesc, strlen(sess->fdesc) + strlen(line) + 1);
|
// realloc(sess->file->description, strlen(sess->file->description) + strlen(line) + 1);
|
||||||
strcat(sess->fdesc, line);
|
// strcat(sess->file->description, line);
|
||||||
}
|
// }
|
||||||
char *desc_end = strstr(line, ":END:");
|
// char *desc_end = strstr(line, ":END:");
|
||||||
if (desc_end != NULL) {
|
// if (desc_end != NULL) {
|
||||||
return 1;
|
// return 1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
char _msg[] = "This is a test \n Description!\n";
|
||||||
|
sess->file->description = malloc(sizeof(_msg) + 1);
|
||||||
|
strcpy(sess->file->description, _msg);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: синхронизовать c C++
|
// TODO: синхронизовать c C++
|
||||||
|
|||||||
+1
-1
@@ -12,5 +12,5 @@ void file_download_upload(session *sess, enum f_actions);
|
|||||||
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 file_upload_description(session *sess, char *line, server_data_t *s_d);
|
int file_upload_description(session *sess, char *line, server_data_t *s_d);
|
||||||
int file_save_db(session *sess, server_data_t *s_d);
|
int file_save_db(session *sess, server_data_t *s_d);
|
||||||
void clear_file_from_sess(session *sess);
|
void clear_file_from_sess(session *);
|
||||||
#endif
|
#endif
|
||||||
+14
-9
@@ -42,6 +42,18 @@ enum error_reason {
|
|||||||
EXIT,
|
EXIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
char *path;
|
||||||
|
char *description;
|
||||||
|
char permissions;
|
||||||
|
size_t size;
|
||||||
|
size_t rest;
|
||||||
|
uint32_t hash;
|
||||||
|
int seed;
|
||||||
|
int fd;
|
||||||
|
} session_file;
|
||||||
|
|
||||||
typedef struct session {
|
typedef struct session {
|
||||||
unsigned long from_ip;
|
unsigned long from_ip;
|
||||||
unsigned short from_port;
|
unsigned short from_port;
|
||||||
@@ -51,16 +63,9 @@ typedef struct session {
|
|||||||
enum error_reason reason;
|
enum error_reason reason;
|
||||||
char privileges;
|
char privileges;
|
||||||
char *uname;
|
char *uname;
|
||||||
|
uint32_t uid;
|
||||||
int sd; /* session descriptor */
|
int sd; /* session descriptor */
|
||||||
int fd; /* file descriptor */
|
session_file *file;
|
||||||
char *fname;
|
|
||||||
char *fpath;
|
|
||||||
char f_perm;
|
|
||||||
char *fdesc;
|
|
||||||
uint32_t hash;
|
|
||||||
size_t fsize;
|
|
||||||
size_t f_rest;
|
|
||||||
long int userpos; /* hint to the position in user list */
|
|
||||||
} session;
|
} session;
|
||||||
|
|
||||||
typedef struct fl_t {
|
typedef struct fl_t {
|
||||||
|
|||||||
+5
-5
@@ -4,11 +4,11 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@@ -35,8 +35,8 @@ void server_main_loop(server_data_t *s_d) {
|
|||||||
if (i > maxfd)
|
if (i > maxfd)
|
||||||
maxfd = i;
|
maxfd = i;
|
||||||
/* active uploads/downloads */
|
/* active uploads/downloads */
|
||||||
int fd = connections[i]->fd;
|
if (connections[i]->file && connections[i]->file->fd > -1) {
|
||||||
if (fd > -1) {
|
int fd = connections[i]->file->fd;
|
||||||
FD_SET(fd, &readfds);
|
FD_SET(fd, &readfds);
|
||||||
if (fd > maxfd)
|
if (fd > maxfd)
|
||||||
maxfd = fd;
|
maxfd = fd;
|
||||||
@@ -61,8 +61,8 @@ void server_main_loop(server_data_t *s_d) {
|
|||||||
/* download/upload file */
|
/* download/upload file */
|
||||||
if (connections[i] != NULL && (connections[i]->state == OP_UPLOAD ||
|
if (connections[i] != NULL && (connections[i]->state == OP_UPLOAD ||
|
||||||
connections[i]->state == OP_DOWNLOAD)) {
|
connections[i]->state == OP_DOWNLOAD)) {
|
||||||
if (connections[i] != NULL && connections[i]->fd > -1 &&
|
if (connections[i]->file && connections[i]->file->fd > -1 &&
|
||||||
FD_ISSET(connections[i]->fd, &readfds)) {
|
FD_ISSET(connections[i]->file->fd, &readfds)) {
|
||||||
perform_session_action(connections[i], NULL, s_d);
|
perform_session_action(connections[i], NULL, s_d);
|
||||||
}
|
}
|
||||||
} else if (connections[i] != NULL && FD_ISSET(i, &readfds)) {
|
} else if (connections[i] != NULL && FD_ISSET(i, &readfds)) {
|
||||||
|
|||||||
+11
-54
@@ -3,10 +3,12 @@
|
|||||||
#include "file_p.h"
|
#include "file_p.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
#include "db.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -39,14 +41,8 @@ session *make_new_session(int fd, struct sockaddr_in *from, char *wm) {
|
|||||||
sess->state = OP_LOGIN_USR;
|
sess->state = OP_LOGIN_USR;
|
||||||
sess->reason = NO_REASON;
|
sess->reason = NO_REASON;
|
||||||
sess->uname = NULL;
|
sess->uname = NULL;
|
||||||
sess->f_perm = 0;
|
|
||||||
sess->fdesc = NULL;
|
|
||||||
sess->sd = fd;
|
sess->sd = fd;
|
||||||
sess->fd = -1;
|
sess->file = NULL;
|
||||||
sess->fsize = 0;
|
|
||||||
sess->f_rest = 0;
|
|
||||||
sess->fname = NULL;
|
|
||||||
sess->fpath = NULL;
|
|
||||||
session_send_string(sess, wm);
|
session_send_string(sess, wm);
|
||||||
session_send_string(sess, "login> ");
|
session_send_string(sess, "login> ");
|
||||||
return sess;
|
return sess;
|
||||||
@@ -150,61 +146,22 @@ void perform_session_action(session *sess, char *line, server_data_t *s_d) {
|
|||||||
case OP_UPLOAD_DESCRIPTION:
|
case OP_UPLOAD_DESCRIPTION:
|
||||||
res = file_upload_description(sess, line, s_d);
|
res = file_upload_description(sess, line, s_d);
|
||||||
if (res) {
|
if (res) {
|
||||||
file_save_db(sess, s_d);
|
if (db_save_file(sess)) {
|
||||||
session_send_string(sess, "File is saved!\n");
|
clear_file_from_sess(sess);
|
||||||
sess->state = OP_WAIT;
|
session_send_string(sess, "File is saved!\n");
|
||||||
|
sess->state = OP_WAIT;
|
||||||
|
} else {
|
||||||
|
// TODO: error case
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* } */
|
/* } */
|
||||||
}
|
}
|
||||||
|
|
||||||
int file_save_db(session *sess, server_data_t *s_d) {
|
|
||||||
/* crate and fill the new item */
|
|
||||||
fl_t *nitem = malloc(sizeof(fl_t));
|
|
||||||
nitem->description = sess->fdesc;
|
|
||||||
nitem->name = sess->fname;
|
|
||||||
nitem->size = sess->fsize;
|
|
||||||
nitem->owner = malloc(strlen(sess->uname));
|
|
||||||
strcpy(nitem->owner, sess->uname);
|
|
||||||
nitem->permissions = sess->f_perm;
|
|
||||||
nitem->next = NULL;
|
|
||||||
|
|
||||||
/* set to NULL and clear */
|
|
||||||
sess->fname = NULL;
|
|
||||||
free(sess->fpath);
|
|
||||||
sess->fpath = NULL;
|
|
||||||
sess->fdesc = NULL;
|
|
||||||
if (sess->fd > -1) {
|
|
||||||
close(sess->fd);
|
|
||||||
}
|
|
||||||
sess->fd = -1;
|
|
||||||
sess->fsize = 0;
|
|
||||||
sess->f_rest = 0;
|
|
||||||
|
|
||||||
/* add new item to list */
|
|
||||||
s_d->fl_current->next = nitem;
|
|
||||||
s_d->fl_current = nitem;
|
|
||||||
|
|
||||||
/* save to the db file */
|
|
||||||
int fd = open(FILE_DESCRIPTIONS_NAME, O_WRONLY);
|
|
||||||
lseek(fd, 0, SEEK_END);
|
|
||||||
char permissions[4];
|
|
||||||
snprintf(permissions, 3, "%d", nitem->permissions);
|
|
||||||
unsigned int res_len = strlen(nitem->name) + 1 + strlen(nitem->owner) + 1 +
|
|
||||||
strlen(permissions) + 1 + strlen(nitem->description) +
|
|
||||||
1;
|
|
||||||
char *res_str = malloc(res_len);
|
|
||||||
res_len = sprintf(res_str, "%s\n%s\n%s\n%s", nitem->name, nitem->owner,
|
|
||||||
permissions, nitem->description);
|
|
||||||
nitem->description[strlen(nitem->description) - 6] = 0;
|
|
||||||
write(fd, res_str, res_len);
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void close_session(session *connections[], int sd) {
|
void close_session(session *connections[], int sd) {
|
||||||
if (connections[sd] != NULL) {
|
if (connections[sd] != NULL) {
|
||||||
|
if (connections[sd]->file) clear_file_from_sess(connections[sd]);
|
||||||
close(sd);
|
close(sd);
|
||||||
connections[sd]->sd = -1;
|
connections[sd]->sd = -1;
|
||||||
free(connections[sd]->uname);
|
free(connections[sd]->uname);
|
||||||
|
|||||||
+3
-1
@@ -40,10 +40,12 @@ int login(session *sess, char *pass) {
|
|||||||
o_auth_t response;
|
o_auth_t response;
|
||||||
cred.name = sess->uname;
|
cred.name = sess->uname;
|
||||||
cred.pass = pass;
|
cred.pass = pass;
|
||||||
|
response.uid = 0;
|
||||||
db_user_auth(&cred, &response);
|
db_user_auth(&cred, &response);
|
||||||
if (response.is_logged) {
|
if (response.uid) {
|
||||||
sess->state = OP_WAIT;
|
sess->state = OP_WAIT;
|
||||||
sess->privileges = (char)atoi(&response.privileges);
|
sess->privileges = (char)atoi(&response.privileges);
|
||||||
|
sess->uid = response.uid;
|
||||||
sprintf(tmp_string, "Welcome, %s\n", sess->uname);
|
sprintf(tmp_string, "Welcome, %s\n", sess->uname);
|
||||||
session_send_string(sess, tmp_string);
|
session_send_string(sess, tmp_string);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user