API: + file search
This commit is contained in:
@@ -2,6 +2,8 @@ add_executable(zbbs-server)
|
|||||||
|
|
||||||
set_property(TARGET zbbs-server PROPERTY C_STANDARD 23)
|
set_property(TARGET zbbs-server PROPERTY C_STANDARD 23)
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
find_package(PostgreSQL REQUIRED)
|
find_package(PostgreSQL REQUIRED)
|
||||||
if(NOT PostgreSQL_FOUND)
|
if(NOT PostgreSQL_FOUND)
|
||||||
message(FATAL_ERROR "PostgreSQL not found. Please install libpq-dev or set PostgreSQL_ROOT.")
|
message(FATAL_ERROR "PostgreSQL not found. Please install libpq-dev or set PostgreSQL_ROOT.")
|
||||||
|
|||||||
+18
-3
@@ -12,15 +12,16 @@ void process_client_command(char *line, session *sess, server_data_t *s_d) {
|
|||||||
char arg_1[32];
|
char arg_1[32];
|
||||||
char arg_2[32];
|
char arg_2[32];
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
uint32_t limit, page;
|
i_file_list_t fl_args;
|
||||||
|
fl_args.name = NULL;
|
||||||
|
|
||||||
sscanf(line, "%s %s", arg_1, arg_2);
|
sscanf(line, "%s %s", arg_1, arg_2);
|
||||||
|
|
||||||
if (!strcmp(arg_1, "file")) {
|
if (!strcmp(arg_1, "file")) {
|
||||||
/* LIST */
|
/* LIST */
|
||||||
if (!strcmp(arg_2, "list")) {
|
if (!strcmp(arg_2, "list")) {
|
||||||
sscanf(line, "%*s %*s %u %u", &limit, &page);
|
sscanf(line, "%*s %*s %u %u", &(fl_args.limit), &(fl_args.page));
|
||||||
file_list(sess, s_d, limit, page);
|
file_list(sess, s_d, &fl_args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +40,20 @@ void process_client_command(char *line, session *sess, server_data_t *s_d) {
|
|||||||
sess->state = OP_DOWNLOAD;
|
sess->state = OP_DOWNLOAD;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SEARCH */
|
||||||
|
if (!strcmp(arg_2, "search")) {
|
||||||
|
char *s_type = arg_1; /* since we don't need the contents of arg_1 and arg_2 variables */
|
||||||
|
char *s_val = arg_2;
|
||||||
|
sscanf(line, "%*s %*s %s %s %u %u", s_type, s_val, &(fl_args.limit), &(fl_args.page));
|
||||||
|
|
||||||
|
/* by name */
|
||||||
|
if (!strcmp(s_type, "name")) {
|
||||||
|
fl_args.name = s_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_list(sess, s_d, &fl_args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncmp(line, "exit", sizeof "exit")) {
|
if (!strncmp(line, "exit", sizeof "exit")) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -126,7 +127,7 @@ int32_t db_user_auth(i_auth_t *c, o_auth_t *r) {
|
|||||||
return exit_query(1);
|
return exit_query(1);
|
||||||
|
|
||||||
const char *pass = PQgetvalue(res, 0, 2);
|
const char *pass = PQgetvalue(res, 0, 2);
|
||||||
string_to_SHA256( c->pass, passHashed);
|
string_to_SHA256(c->pass, passHashed);
|
||||||
if (pass == NULL) {
|
if (pass == NULL) {
|
||||||
/* TODO: return */
|
/* TODO: return */
|
||||||
}
|
}
|
||||||
@@ -276,13 +277,15 @@ uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
|||||||
char query[512];
|
char query[512];
|
||||||
char sort_by[16] = "id";
|
char sort_by[16] = "id";
|
||||||
char sort_dir[5] = "ASC";
|
char sort_dir[5] = "ASC";
|
||||||
const char *paramValues[2];
|
const char *paramValues[3];
|
||||||
int paramLengths[2];
|
int paramLengths[3];
|
||||||
int paramFormats[2];
|
int paramFormats[3];
|
||||||
int i;
|
int i;
|
||||||
uint64_t count;
|
uint64_t count;
|
||||||
uint64_t n_limit = htobe64(arg->limit);
|
uint64_t n_limit = htobe64(arg->limit);
|
||||||
uint64_t n_offset = htobe64(arg->offset);
|
uint64_t n_offset = htobe64(arg->offset);
|
||||||
|
bool by_name = strlen(arg->name) > 0;
|
||||||
|
uint32_t params_num = 3;
|
||||||
|
|
||||||
switch (arg->sort_by) {
|
switch (arg->sort_by) {
|
||||||
case NAME:
|
case NAME:
|
||||||
@@ -305,21 +308,35 @@ uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
|||||||
|
|
||||||
paramValues[0] = (char *)&n_limit;
|
paramValues[0] = (char *)&n_limit;
|
||||||
paramValues[1] = (char *)&n_offset;
|
paramValues[1] = (char *)&n_offset;
|
||||||
|
paramValues[2] = arg->name;
|
||||||
|
|
||||||
paramLengths[0] = sizeof(n_limit);
|
paramLengths[0] = sizeof(n_limit);
|
||||||
paramLengths[1] = sizeof(n_offset);
|
paramLengths[1] = sizeof(n_offset);
|
||||||
|
paramLengths[2] = strlen(arg->name);
|
||||||
|
|
||||||
paramFormats[0] = BIN;
|
paramFormats[0] = BIN;
|
||||||
paramFormats[1] = BIN;
|
paramFormats[1] = BIN;
|
||||||
|
paramFormats[2] = TEXT;
|
||||||
|
|
||||||
sprintf(query,
|
if (!by_name) {
|
||||||
"SELECT files.id, user_id, name, size, description, permissions, "
|
params_num = 2;
|
||||||
"hash, username "
|
sprintf(query,
|
||||||
"FROM files JOIN users ON user_id = users.id "
|
"SELECT files.id, user_id, name, size, description, permissions, "
|
||||||
"ORDER BY files.%s %s LIMIT $1 OFFSET $2",
|
"hash, username "
|
||||||
sort_by, sort_dir);
|
"FROM files JOIN users ON user_id = users.id "
|
||||||
|
"ORDER BY files.%s %s LIMIT $1 OFFSET $2",
|
||||||
|
sort_by, sort_dir);
|
||||||
|
} else {
|
||||||
|
sprintf(query,
|
||||||
|
"SELECT files.id, user_id, name, size, description, permissions, "
|
||||||
|
"hash, username "
|
||||||
|
"FROM files JOIN users ON user_id = users.id "
|
||||||
|
"WHERE name ILIKE '%%' || $3 || '%%'"
|
||||||
|
"ORDER BY files.%s %s LIMIT $1 OFFSET $2",
|
||||||
|
sort_by, sort_dir);
|
||||||
|
}
|
||||||
|
|
||||||
res = PQexecParams(conn, query, 2, NULL, paramValues, paramLengths,
|
res = PQexecParams(conn, query, params_num, NULL, paramValues, paramLengths,
|
||||||
paramFormats, TEXT);
|
paramFormats, TEXT);
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
@@ -355,8 +372,17 @@ uint64_t db_get_files_data(i_get_files_db *arg, fl_t **fl_start,
|
|||||||
|
|
||||||
clearRes();
|
clearRes();
|
||||||
|
|
||||||
res = PQexec(conn, "SELECT COUNT(id) "
|
if (by_name) {
|
||||||
"FROM files ");
|
res = PQexecParams(conn,
|
||||||
|
"SELECT COUNT(id) "
|
||||||
|
"FROM files "
|
||||||
|
"WHERE name ILIKE '%%' || $1 || '%%'",
|
||||||
|
1, NULL, paramValues + 2, paramLengths + 2,
|
||||||
|
paramFormats + 2, TEXT);
|
||||||
|
} else {
|
||||||
|
res = PQexec(conn, "SELECT COUNT(id) "
|
||||||
|
"FROM files ");
|
||||||
|
}
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
return exit_query_2(0);
|
return exit_query_2(0);
|
||||||
|
|||||||
+16
-9
@@ -1,11 +1,11 @@
|
|||||||
#include "file_p.h"
|
#include "file_p.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include <murmur3.h>
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <murmur3.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -39,7 +39,7 @@ void clear_list(fl_t *start) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_list(session *sess, server_data_t *s_d, uint32_t limit, uint32_t page) {
|
void file_list(session *sess, server_data_t *s_d, i_file_list_t *f_args) {
|
||||||
fl_t *fl_start, *fl_current;
|
fl_t *fl_start, *fl_current;
|
||||||
char item_h[256];
|
char item_h[256];
|
||||||
i_get_files_db args;
|
i_get_files_db args;
|
||||||
@@ -54,25 +54,32 @@ void file_list(session *sess, server_data_t *s_d, uint32_t limit, uint32_t page)
|
|||||||
sess->fl_current = NULL;
|
sess->fl_current = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.limit = limit;
|
args.limit = f_args->limit;
|
||||||
args.offset = limit * (page - 1);
|
args.offset = f_args->limit * (f_args->page - 1);
|
||||||
args.sort_by = ID;
|
args.sort_by = ID;
|
||||||
args.sort_direction = ASC;
|
args.sort_direction = ASC;
|
||||||
|
if (f_args->name != NULL) {
|
||||||
|
strcpy(args.name, f_args->name);
|
||||||
|
} else {
|
||||||
|
args.name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
count = db_get_files_data(&args, &fl_start, &full_count);
|
count = db_get_files_data(&args, &fl_start, &full_count);
|
||||||
char page_info[256];
|
char page_info[256];
|
||||||
|
|
||||||
pages_count = full_count / limit;
|
pages_count = full_count / f_args->limit;
|
||||||
if (!pages_count)
|
if (!pages_count)
|
||||||
pages_count = 1;
|
pages_count = 1;
|
||||||
if (pages_count % limit)
|
if (pages_count % f_args->limit)
|
||||||
pages_count++;
|
pages_count++;
|
||||||
|
|
||||||
sprintf(page_info, ":END: PAGE %u/%lu COUNT: %lu/%lu\n", page, pages_count,
|
sprintf(page_info, ":END: PAGE %u/%lu COUNT: %lu/%lu\n", f_args->page,
|
||||||
count, full_count - (page - 1) * limit);
|
pages_count, count, full_count - (f_args->page - 1) * f_args->limit);
|
||||||
|
|
||||||
if (!fl_start)
|
if (!fl_start) {
|
||||||
|
write(sess->sd, page_info, strlen(page_info));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fl_current = fl_start;
|
fl_current = fl_start;
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -1,8 +1,14 @@
|
|||||||
#ifndef FILEP_H
|
#ifndef FILEP_H
|
||||||
#define FILEP_H
|
#define FILEP_H
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include <stdint.h>
|
||||||
void clear_list(fl_t *start);
|
void clear_list(fl_t *start);
|
||||||
void file_list(session *, server_data_t *, uint32_t limit, uint32_t page);
|
typedef struct {
|
||||||
|
uint32_t page;
|
||||||
|
uint32_t limit;
|
||||||
|
char *name;
|
||||||
|
} i_file_list_t;
|
||||||
|
void file_list(session *, server_data_t *, i_file_list_t *l_args);
|
||||||
int file_send_prepare(session *, char *, server_data_t *);
|
int file_send_prepare(session *, char *, server_data_t *);
|
||||||
enum f_actions {
|
enum f_actions {
|
||||||
F_UPLOAD,
|
F_UPLOAD,
|
||||||
|
|||||||
Reference in New Issue
Block a user