Last commit with db. Switching to makdown articles representation
This commit is contained in:
parent
db9b46f041
commit
68d1c8211c
4
Makefile
4
Makefile
@ -13,11 +13,11 @@ INC_FLAGS := $(addprefix -I,$(INC_DIRS))
|
|||||||
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
|
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
|
||||||
|
|
||||||
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
|
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
|
||||||
$(CC) $(OBJS) -o $@ $(LDFLAGS)
|
$(CC) -ggdb3 $(OBJS) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/%.c.o: %.c
|
$(BUILD_DIR)/%.c.o: %.c
|
||||||
$(MKDIR_P) $(dir $@)
|
$(MKDIR_P) $(dir $@)
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
$(CC) -ggdb3 $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
|
26
include/db_op/article.h
Normal file
26
include/db_op/article.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _ARTICLE_H
|
||||||
|
#define _ARTICLE_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../../include/db_op/db.h"
|
||||||
|
|
||||||
|
#ifndef ARTICLE_T_TYPE
|
||||||
|
#define ARTICLE_T_TYPE
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int id;
|
||||||
|
char *header;
|
||||||
|
char *content;
|
||||||
|
char *author;
|
||||||
|
char *topic;
|
||||||
|
} article_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int expand_line_article(int n, char *buff, entry_s *rec);
|
||||||
|
char *serialize_article(entry_s *rec);
|
||||||
|
|
||||||
|
#endif
|
@ -1,11 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char *header;
|
|
||||||
char *content;
|
|
||||||
char **tags;
|
|
||||||
char *author;
|
|
||||||
unsigned int key;
|
|
||||||
} blogpost_t;
|
|
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef _DB_H
|
||||||
|
#define _DB_H
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -5,13 +8,44 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "./blogpost.h"
|
#ifndef ARTICLE_T_TYPE
|
||||||
|
#define ARTICLE_T_TYPE
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int id;
|
||||||
|
char *header;
|
||||||
|
char *content;
|
||||||
|
char *author;
|
||||||
|
char *topic;
|
||||||
|
} article_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BLOGPOST_T,
|
||||||
|
ARTICLE_T
|
||||||
|
} types;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
types type;
|
||||||
|
union {
|
||||||
|
article_t a;
|
||||||
|
} data;
|
||||||
|
} entry_s;
|
||||||
|
|
||||||
|
#include "./article.h"
|
||||||
|
|
||||||
#define LINE_SIZE 512
|
#define LINE_SIZE 512
|
||||||
|
|
||||||
int open_db(char *file_name, char *type, FILE **file, char ***head, int *head_length);
|
int open_db(char *file_name, types type, FILE **file, char ***head, int *head_length);
|
||||||
int open_table(char *file_name, FILE **file);
|
int open_table(char *file_name, FILE **file);
|
||||||
int read_head(FILE *file, char ***head);
|
int read_head(FILE *file, char ***head);
|
||||||
int get_entry(FILE *file, void **rec, int type, int n, int (*process_line)(char *, void **, int));
|
int get_entry(FILE *file, entry_s *rec, int n, int (*process_line)(int, char *, entry_s *));
|
||||||
int append_table(FILE *file, void *rec, int type, char *(*process_line)(void *, int));
|
int append_table(FILE *file, entry_s *rec, char *(*process_line)(entry_s *));
|
||||||
int remove_entry(FILE *file, int n);
|
int remove_entry(FILE *file, int n);
|
||||||
|
int read_whole_table(FILE *file, entry_s **rec, int (*process_line)(int, char *, entry_s *));
|
||||||
|
int find_by(FILE *file, entry_s **entries, int (*check_line)(int, char *, entry_s), int (*process_line)(int, char *, entry_s));
|
||||||
|
|
||||||
|
#endif
|
8
include/db_op/db_cli.h
Normal file
8
include/db_op/db_cli.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _DB_CLI_H
|
||||||
|
#define _DB_CLI_H
|
||||||
|
|
||||||
|
#include "../../include/db_op/db.h"
|
||||||
|
|
||||||
|
char *get_all_articles_list();
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef _FILE_H
|
||||||
|
#define _FILE_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/sendfile.h>
|
#include <sys/sendfile.h>
|
||||||
@ -15,3 +18,5 @@ struct file_s
|
|||||||
char *gen_file_path(char *path);
|
char *gen_file_path(char *path);
|
||||||
int send_file(int cli_fd, struct file_s *file);
|
int send_file(int cli_fd, struct file_s *file);
|
||||||
struct file_s *get_file_info(char *file_path);
|
struct file_s *get_file_info(char *file_path);
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,10 @@
|
|||||||
|
#ifndef _MIME_H
|
||||||
|
#define _MIME_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DEFAULT_MIME_TYPE "application/octet-stream"
|
||||||
|
|
||||||
char *get_mime_type(char *file_path);
|
char *get_mime_type(char *file_path);
|
||||||
|
|
||||||
|
#endif
|
@ -1,8 +1,15 @@
|
|||||||
|
#ifndef _NETW_H
|
||||||
|
#define _NETW_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#define BACKLOG 10
|
||||||
|
|
||||||
int get_listener_socket(char *port);
|
int get_listener_socket(char *port);
|
||||||
void *get_in_addr(struct sockaddr *sa);
|
void *get_in_addr(struct sockaddr *sa);
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef _REQUEST_H
|
||||||
|
#define _REQUEST_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -8,13 +11,19 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#define FILE_SIZE 1024
|
||||||
|
|
||||||
struct header_s {
|
struct header_s {
|
||||||
char * str;
|
char * str;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void res_404(int fd, char *path);
|
||||||
|
void res_500(int fd);
|
||||||
char *get_path(char *request);
|
char *get_path(char *request);
|
||||||
struct header_s *gen_header(int status_code, size_t file_size, char *mime_type);
|
struct header_s *gen_header(int status_code, size_t file_size, char *mime_type);
|
||||||
int send_response(int fd, char *req_path);
|
int send_response(int fd, char *req_path);
|
||||||
void handle_post_request(int fd, char *request);
|
void handle_post_request(int fd, char *request);
|
||||||
void handle_get_request(int fd, char *request);
|
void handle_get_request(int fd, char *request);
|
||||||
|
|
||||||
|
#endif
|
@ -1,5 +1,11 @@
|
|||||||
|
#ifndef _ARR_H
|
||||||
|
#define _ARR_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void insert_to_arr(char ***arr, size_t length, char *value);
|
void insert_to_arr(char ***arr, size_t length, char *value);
|
||||||
void free_arr(char **arr, int length);
|
void free_arr(char **arr, int length);
|
||||||
|
int check_if_contains(char **arr, size_t length, char *str);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _LLIST_H
|
||||||
|
#define _LLIST_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define NUMBER 5
|
||||||
|
|
||||||
|
typedef struct llist_s
|
||||||
|
{
|
||||||
|
char *value;
|
||||||
|
struct llist_s *next;
|
||||||
|
} llist_t;
|
||||||
|
|
||||||
|
llist_t *find_item(llist_t *list, int n);
|
||||||
|
void fill_with_arr(llist_t **list, char **arr, size_t n);
|
||||||
|
void print_llist(llist_t *list);
|
||||||
|
llist_t *add_to_list(llist_t **head, int pos, char *value);
|
||||||
|
|
||||||
|
#endif
|
@ -1,9 +1,14 @@
|
|||||||
|
#ifndef _UTILS_H
|
||||||
|
#define _UTILS_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void err_msg(char *msg);
|
void err_msg(char *msg);
|
||||||
char *add_to_front(char **str1, char *str2);
|
char *concat_to_front(char **str1, char *str2);
|
||||||
char *get_status_message(int status_code);
|
char *get_status_message(int status_code);
|
||||||
char *to_lower(char *str);
|
char *to_lower(char *str);
|
||||||
|
|
||||||
|
#endif
|
49
src/db_op/article.c
Normal file
49
src/db_op/article.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#include "../../include/db_op/db.h"
|
||||||
|
|
||||||
|
int expand_line_article(int n, char *buff, entry_s *rec)
|
||||||
|
{
|
||||||
|
#define entry rec->data.a
|
||||||
|
|
||||||
|
entry.id = n;
|
||||||
|
|
||||||
|
char *tmp = strtok(buff, ";");
|
||||||
|
if (tmp == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
entry.header = malloc(strlen(tmp) + 1);
|
||||||
|
entry.header = tmp;
|
||||||
|
|
||||||
|
tmp = strtok(NULL, ";");
|
||||||
|
if (tmp == NULL)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
entry.content = malloc(strlen(tmp) + 1);
|
||||||
|
entry.content = tmp;
|
||||||
|
|
||||||
|
tmp = strtok(NULL, ";");
|
||||||
|
if (tmp == NULL)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
entry.author = malloc(strlen(tmp) + 1);
|
||||||
|
entry.author = tmp;
|
||||||
|
|
||||||
|
tmp = strtok(NULL, "\n");
|
||||||
|
if (tmp == NULL)
|
||||||
|
return -4;
|
||||||
|
|
||||||
|
entry.topic = malloc(strlen(tmp) + 1);
|
||||||
|
entry.topic = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *serialize_article(entry_s *rec)
|
||||||
|
{
|
||||||
|
int line_length = snprintf(NULL, 0, "%s;%s;%s;%s\n", entry.header, entry.content, entry.author, entry.topic) + 1;
|
||||||
|
char *line = malloc(line_length);
|
||||||
|
if (line == NULL)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
snprintf(line, line_length, "%s;%s;%s;%s\n", entry.header, entry.content, entry.author, entry.topic);
|
||||||
|
return line;
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
#include "../../include/db_op/blogpost.h"
|
|
@ -12,8 +12,24 @@
|
|||||||
* @param head_length
|
* @param head_length
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int open_db(char *file_name, char *type, FILE **file, char ***head, int *head_length)
|
int open_db(char *file_name, types type, FILE **file, char ***head, int *head_length)
|
||||||
{
|
{
|
||||||
|
char *type_string;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case BLOGPOST_T:
|
||||||
|
type_string = "blogpost";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARTICLE_T:
|
||||||
|
type_string = "article";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
err_msg("This type is not supported");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
FILE *root_file;
|
FILE *root_file;
|
||||||
if ((root_file = fopen(file_name, "a+")) == NULL)
|
if ((root_file = fopen(file_name, "a+")) == NULL)
|
||||||
{
|
{
|
||||||
@ -25,8 +41,7 @@ int open_db(char *file_name, char *type, FILE **file, char ***head, int *head_le
|
|||||||
size_t size = LINE_SIZE;
|
size_t size = LINE_SIZE;
|
||||||
|
|
||||||
while (getline(&buff, &size, root_file) >= 0)
|
while (getline(&buff, &size, root_file) >= 0)
|
||||||
{
|
if (strcmp(type_string, strtok(buff, " ")) == 0)
|
||||||
if (strcmp(type, strtok(buff, " ")) == 0)
|
|
||||||
{
|
{
|
||||||
int ret = open_table(strtok(NULL, "\n"), file);
|
int ret = open_table(strtok(NULL, "\n"), file);
|
||||||
|
|
||||||
@ -36,20 +51,19 @@ int open_db(char *file_name, char *type, FILE **file, char ***head, int *head_le
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
free(buff);
|
||||||
|
|
||||||
struct stat st = {0};
|
struct stat st = {0};
|
||||||
if (stat("./db", &st) == -1)
|
if (stat("./db", &st) == -1)
|
||||||
{
|
|
||||||
mkdir("./db", 0700);
|
mkdir("./db", 0700);
|
||||||
}
|
|
||||||
|
|
||||||
int table_file_name_size = snprintf(NULL, 0, "./db/%s.csv", type) + 1;
|
int table_file_name_size = snprintf(NULL, 0, "./db/%s.csv", type_string) + 1;
|
||||||
char *table_file_name = malloc(table_file_name_size);
|
char *table_file_name = malloc(table_file_name_size);
|
||||||
snprintf(table_file_name, table_file_name_size, "./db/%s.csv", type);
|
snprintf(table_file_name, table_file_name_size, "./db/%s.csv", type_string);
|
||||||
|
|
||||||
fseek(root_file, 0, SEEK_SET);
|
fseek(root_file, 0, SEEK_SET);
|
||||||
fprintf(root_file, "%s %s\n", type, table_file_name);
|
fprintf(root_file, "%s %s\n", type_string, table_file_name);
|
||||||
|
|
||||||
fclose(root_file);
|
fclose(root_file);
|
||||||
|
|
||||||
@ -98,9 +112,7 @@ int read_head(FILE *file, char ***head)
|
|||||||
char *tok;
|
char *tok;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (tok = strtok(buff, ";"); tok && *tok; tok = strtok(NULL, ";"))
|
for (tok = strtok(buff, ";"); tok && *tok; tok = strtok(NULL, ";"))
|
||||||
{
|
|
||||||
insert_to_arr(head, length++, tok);
|
insert_to_arr(head, length++, tok);
|
||||||
}
|
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -110,12 +122,11 @@ int read_head(FILE *file, char ***head)
|
|||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* @param rec
|
* @param rec
|
||||||
* @param type
|
|
||||||
* @param n
|
* @param n
|
||||||
* @param process_line
|
* @param process_line
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int get_entry(FILE *file, void **rec, int type, int n, int (*process_line)(char *, void **, int))
|
int get_entry(FILE *file, entry_s *rec, int n, int (*process_line)(int, char *, entry_s *))
|
||||||
{
|
{
|
||||||
char *buff = NULL;
|
char *buff = NULL;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -127,13 +138,15 @@ int get_entry(FILE *file, void **rec, int type, int n, int (*process_line)(char
|
|||||||
{
|
{
|
||||||
if (i == n)
|
if (i == n)
|
||||||
{
|
{
|
||||||
int res = (*process_line)(buff, rec, type);
|
int res = (*process_line)(n, buff, rec);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(buff);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,14 +155,13 @@ int get_entry(FILE *file, void **rec, int type, int n, int (*process_line)(char
|
|||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* @param rec
|
* @param rec
|
||||||
* @param type
|
|
||||||
* @param process_line
|
* @param process_line
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int append_table(FILE *file, void *rec, int type, char *(*process_line)(void *, int))
|
int append_table(FILE *file, entry_s *rec, char *(*process_line)(entry_s *))
|
||||||
{
|
{
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
char *buff = (*process_line)(rec, type);
|
char *buff = (*process_line)(rec);
|
||||||
|
|
||||||
if (fprintf(file, "%s", buff) < 0)
|
if (fprintf(file, "%s", buff) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -189,9 +201,8 @@ int remove_entry(FILE *file, int n)
|
|||||||
while (getline(&buff, &size, file) >= 0)
|
while (getline(&buff, &size, file) >= 0)
|
||||||
{
|
{
|
||||||
if (i != n)
|
if (i != n)
|
||||||
{
|
|
||||||
fprintf(tmp_file, "%s", buff);
|
fprintf(tmp_file, "%s", buff);
|
||||||
}
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,3 +242,41 @@ int remove_entry(FILE *file, int n)
|
|||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int read_whole_table(FILE *file, entry_s **entries, int (*process_line)(int ,char *, entry_s *))
|
||||||
|
{
|
||||||
|
char *buff;
|
||||||
|
int i = 0;
|
||||||
|
size_t size = LINE_SIZE;
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
printf("Begining line-by-line reading\n");
|
||||||
|
|
||||||
|
while (getline(&buff, &size, file) >= 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Read line [%d]: %s\n", i, buff);
|
||||||
|
|
||||||
|
int res = (*process_line)(i, buff, &((*entries)[i]));
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
printf("---%lu---\n", sizeof(entry_s));
|
||||||
|
*entries = (entry_s *)realloc(*entries, sizeof(entry_s) * i);
|
||||||
|
}
|
||||||
|
if (i == 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
free(buff);
|
||||||
|
|
||||||
|
return ++i;
|
||||||
|
}
|
103
src/db_op/db_cli.c
Normal file
103
src/db_op/db_cli.c
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include "../../include/db_op/db_cli.h"
|
||||||
|
#include "../../include/utils_op/arr.h"
|
||||||
|
|
||||||
|
char *get_all_articles_list()
|
||||||
|
{
|
||||||
|
FILE *db_file;
|
||||||
|
char **db_head;
|
||||||
|
int length = -1;
|
||||||
|
|
||||||
|
int ret = open_db("root.db", ARTICLE_T, &db_file, &db_head, &length);
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
perror("No such database\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_s *articles_table = (entry_s *)malloc(sizeof(entry_s));
|
||||||
|
if (articles_table == NULL)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
size_t entries_amount = read_whole_table(db_file, &articles_table, expand_line_article);
|
||||||
|
|
||||||
|
printf("\nStarting processing table\n");
|
||||||
|
|
||||||
|
size_t topics_amount = 0;
|
||||||
|
char **articles_by_topics_lists = malloc(topics_amount * sizeof(char *));
|
||||||
|
char **topics_list = malloc(topics_amount * sizeof(char));
|
||||||
|
if (articles_by_topics_lists == NULL || topics_list == NULL)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
printf("Initialized lists arrays\n");
|
||||||
|
|
||||||
|
size_t topics_list_size = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < entries_amount; i++)
|
||||||
|
{
|
||||||
|
printf("Processing entry [%d]\n", i);
|
||||||
|
|
||||||
|
article_t rec = articles_table[i].data.a;
|
||||||
|
|
||||||
|
int pos = check_if_contains(topics_list, topics_amount, rec.topic);
|
||||||
|
if (pos == 0)
|
||||||
|
{
|
||||||
|
topics_amount++;
|
||||||
|
|
||||||
|
char **tmp_topics_list = realloc(topics_list, topics_list_size + strlen(rec.topic));
|
||||||
|
if (tmp_topics_list == NULL)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
topics_list = tmp_topics_list;
|
||||||
|
|
||||||
|
topics_list_size += strlen(rec.topic);
|
||||||
|
|
||||||
|
pos = topics_amount - 1;
|
||||||
|
|
||||||
|
topics_list[pos] = rec.topic;
|
||||||
|
|
||||||
|
char **tmp_articles_by_topics_lists = realloc(articles_by_topics_lists, topics_amount * sizeof(char *));
|
||||||
|
if (tmp_articles_by_topics_lists == NULL)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
articles_by_topics_lists = tmp_articles_by_topics_lists;
|
||||||
|
}
|
||||||
|
|
||||||
|
int line_length = snprintf(NULL, 0, "<li>%s</li>\n", rec.header) + 1;
|
||||||
|
char *tmp_line = malloc(line_length);
|
||||||
|
if (tmp_line == NULL)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
snprintf(tmp_line, line_length, "<li>%s</li>\n", rec.header);
|
||||||
|
|
||||||
|
char *tmp_articles_by_topics_lists_line = realloc(articles_by_topics_lists[pos], strlen(articles_by_topics_lists[pos]) + line_length + 1);
|
||||||
|
if (tmp_articles_by_topics_lists_line == NULL)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
articles_by_topics_lists[pos] = tmp_articles_by_topics_lists_line;
|
||||||
|
|
||||||
|
strncat(articles_by_topics_lists[pos], tmp_line, line_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *articles_table_list_str = malloc(topics_amount * strlen("<h1></h1>\n<ul></ul>\n"));
|
||||||
|
if (articles_table_list_str == NULL)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
for (int i = 0; i < topics_amount; i++)
|
||||||
|
{
|
||||||
|
int add_len = snprintf(NULL, 0, "<h1>%s</h1>\n<ul>%s</ul>\n", topics_list[i], articles_by_topics_lists[i]);
|
||||||
|
char *tmp_line = malloc(add_len);
|
||||||
|
if (tmp_line == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(tmp_line, add_len, "<h1>%s</h1>\n<ul>%s</ul>\n", topics_list[i], articles_by_topics_lists[i]);
|
||||||
|
|
||||||
|
char *tmp_articles_table_list_str = realloc(articles_table_list_str, strlen(articles_table_list_str) + add_len + 1);
|
||||||
|
if (tmp_articles_table_list_str == NULL)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
articles_table_list_str = tmp_articles_table_list_str;
|
||||||
|
|
||||||
|
strcat(articles_table_list_str, tmp_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return articles_table_list_str;
|
||||||
|
}
|
@ -25,7 +25,7 @@ char *gen_file_path(char *req_path)
|
|||||||
char *webroot = "static";
|
char *webroot = "static";
|
||||||
|
|
||||||
path = realloc(path, strlen(path) + strlen(webroot));
|
path = realloc(path, strlen(path) + strlen(webroot));
|
||||||
path = add_to_front(&path, webroot);
|
path = concat_to_front(&path, webroot);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#include "../../include/file_op/mime.h"
|
#include "../../include/file_op/mime.h"
|
||||||
#include "../../include/utils_op/utils.h"
|
#include "../../include/utils_op/utils.h"
|
||||||
|
|
||||||
#define DEFAULT_mime_TYPE "application/octet-stream"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the mime type of file
|
* @brief Get the mime type of file
|
||||||
*
|
*
|
||||||
@ -15,11 +13,10 @@ char *get_mime_type(char *file_path)
|
|||||||
|
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
{
|
{
|
||||||
return DEFAULT_mime_TYPE;
|
return DEFAULT_MIME_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext++;
|
ext++;
|
||||||
|
|
||||||
ext = to_lower(ext);
|
ext = to_lower(ext);
|
||||||
|
|
||||||
if (strcmp(ext, "html") == 0 || strcmp(ext, "htm") == 0)
|
if (strcmp(ext, "html") == 0 || strcmp(ext, "htm") == 0)
|
||||||
@ -59,5 +56,5 @@ char *get_mime_type(char *file_path)
|
|||||||
return "image/x-icon";
|
return "image/x-icon";
|
||||||
}
|
}
|
||||||
|
|
||||||
return DEFAULT_mime_TYPE;
|
return DEFAULT_MIME_TYPE;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#include "../../include/netw_op/netw.h"
|
#include "../../include/netw_op/netw.h"
|
||||||
#include "../../include/utils_op/utils.h"
|
#include "../../include/utils_op/utils.h"
|
||||||
|
|
||||||
#define BACKLOG 10
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the listener socket object
|
* @brief Get the listener socket object
|
||||||
*
|
*
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "../../include/utils_op/utils.h"
|
#include "../../include/utils_op/utils.h"
|
||||||
#include "../../include/file_op/file.h"
|
#include "../../include/file_op/file.h"
|
||||||
#include "../../include/file_op/mime.h"
|
#include "../../include/file_op/mime.h"
|
||||||
|
#include "../../include/db_op/db_cli.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send 404 response
|
* @brief Send 404 response
|
||||||
@ -13,12 +14,12 @@ void res_404(int fd, char *path)
|
|||||||
{
|
{
|
||||||
FILE *fp = fopen("static/404.html", "r");
|
FILE *fp = fopen("static/404.html", "r");
|
||||||
const ssize_t fsize = 512;
|
const ssize_t fsize = 512;
|
||||||
char buf[fsize], msg[fsize];
|
char buff[fsize], msg[fsize];
|
||||||
|
|
||||||
fread(buf, fsize, 1, fp);
|
fread(buff, fsize, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
sprintf(msg, buf, path, path);
|
sprintf(msg, buff, path, path);
|
||||||
|
|
||||||
struct header_s *header = gen_header(404, strlen(msg), "text/html");
|
struct header_s *header = gen_header(404, strlen(msg), "text/html");
|
||||||
send(fd, header->str, header->size - 1, 0);
|
send(fd, header->str, header->size - 1, 0);
|
||||||
@ -29,8 +30,21 @@ void res_404(int fd, char *path)
|
|||||||
printf("404 ERROR\n");
|
printf("404 ERROR\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void res_500(int fd)
|
||||||
|
{
|
||||||
|
char *msg = "Server error";
|
||||||
|
|
||||||
|
struct header_s *header = gen_header(500, sizeof(msg), "text/plain");
|
||||||
|
send(fd, header->str, header->size - 1, 0);
|
||||||
|
|
||||||
|
send(fd, msg, sizeof(msg), 0);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
printf("500 ERROR\n");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the path object
|
* @brief Get the path string
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* @return char*
|
* @return char*
|
||||||
@ -85,29 +99,13 @@ int send_response(int fd, char *req_path)
|
|||||||
|
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
char *msg = "Server error";
|
res_500(fd);
|
||||||
|
|
||||||
struct header_s *header = gen_header(500, sizeof(msg), "text/plain");
|
|
||||||
send(fd, header->str, header->size - 1, 0);
|
|
||||||
|
|
||||||
send(fd, msg, sizeof(msg), 0);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->fd < 0)
|
if (file->fd < 0)
|
||||||
{
|
{
|
||||||
// char *msg = "<html>\n<body>404, Not Found. Return to home? <a href=\"/\">Home</a></body><html/>";
|
|
||||||
|
|
||||||
// struct header_s *header = gen_header(404, strlen(msg), "text/html");
|
|
||||||
// send(fd, header->str, header->size - 1, 0);
|
|
||||||
|
|
||||||
// send(fd, msg, strlen(msg), 0);
|
|
||||||
// close(fd);
|
|
||||||
|
|
||||||
// printf("404 ERROR\n");
|
|
||||||
|
|
||||||
res_404(fd, req_path);
|
res_404(fd, req_path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -160,6 +158,29 @@ void handle_get_request(int fd, char *request)
|
|||||||
char *path = get_path(request);
|
char *path = get_path(request);
|
||||||
printf("Client accessed path: %s\n", path);
|
printf("Client accessed path: %s\n", path);
|
||||||
|
|
||||||
|
if (strcmp(path, "/") == 0)
|
||||||
|
{
|
||||||
|
FILE *fp = fopen("static/index.html", "r");
|
||||||
|
char buff[FILE_SIZE], msg[FILE_SIZE * 2], articles_list_str[FILE_SIZE / 2] = {0}, blogposts_list_str[FILE_SIZE / 2] = {0};
|
||||||
|
|
||||||
|
fread(buff, FILE_SIZE, 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sprintf(msg, buff, articles_list_str, blogposts_list_str);
|
||||||
|
|
||||||
|
struct header_s *header = gen_header(200, strlen(msg), "text/html");
|
||||||
|
send(fd, header->str, header->size - 1, 0);
|
||||||
|
|
||||||
|
send(fd, msg, strlen(msg), 0);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
printf("Sent home page\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp(path, "/blog/", strlen("/blog/")) == 0)
|
if (strncmp(path, "/blog/", strlen("/blog/")) == 0)
|
||||||
{
|
{
|
||||||
char *id = (char *)malloc(strlen(path) - strlen("/blog/") + 1);
|
char *id = (char *)malloc(strlen(path) - strlen("/blog/") + 1);
|
||||||
@ -168,7 +189,6 @@ void handle_get_request(int fd, char *request)
|
|||||||
printf("Blog post id = %s\n", id);
|
printf("Blog post id = %s\n", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (send_response(fd, path) < 0)
|
if (send_response(fd, path) < 0)
|
||||||
{
|
{
|
||||||
err_msg("couldn't send response");
|
err_msg("couldn't send response");
|
||||||
|
@ -29,3 +29,20 @@ void free_arr(char **arr, int length)
|
|||||||
|
|
||||||
free(arr);
|
free(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if array contains string
|
||||||
|
*
|
||||||
|
* @param arr
|
||||||
|
* @param length
|
||||||
|
* @param str
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int check_if_contains(char **arr, size_t length, char *str)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
if (strcmp(arr[i], str) == 0)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,13 +1,4 @@
|
|||||||
#include <stdio.h>
|
#include "../../include/utils_op/llist.h"
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define NUMBER 5
|
|
||||||
|
|
||||||
typedef struct llist_s
|
|
||||||
{
|
|
||||||
char *value;
|
|
||||||
struct llist_s *next;
|
|
||||||
} llist_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Find item by number
|
* @brief Find item by number
|
||||||
@ -41,7 +32,7 @@ void fill_with_arr(llist_t **list, char **arr, size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print hole list
|
* @brief Print whole list
|
||||||
*
|
*
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
@ -94,6 +85,7 @@ llist_t *add_to_list(llist_t **head, int pos, char *value)
|
|||||||
return current->next;
|
return current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Example of usage
|
||||||
// int main()
|
// int main()
|
||||||
// {
|
// {
|
||||||
// llist_t *head = malloc(sizeof(llist_t));
|
// llist_t *head = malloc(sizeof(llist_t));
|
||||||
|
@ -17,15 +17,13 @@ void err_msg(char *msg)
|
|||||||
* @param str2
|
* @param str2
|
||||||
* @return char*
|
* @return char*
|
||||||
*/
|
*/
|
||||||
char *add_to_front(char **str1, char *str2)
|
char *concat_to_front(char **str1, char *str2)
|
||||||
{
|
{
|
||||||
char *tmp = strdup(*str1);
|
char *tmp = strdup(*str1);
|
||||||
|
|
||||||
strcpy(*str1, str2);
|
strcpy(*str1, str2);
|
||||||
strcat(*str1, tmp);
|
strcat(*str1, tmp);
|
||||||
|
|
||||||
// free(tmp);
|
|
||||||
|
|
||||||
return *str1;
|
return *str1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,14 +21,7 @@
|
|||||||
<li><a href="/projects">Projects</a></li>
|
<li><a href="/projects">Projects</a></li>
|
||||||
<li><a href="/philosophy">Philosophy</a></li>
|
<li><a href="/philosophy">Philosophy</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<h1>Blog</h1>
|
%s
|
||||||
<ul>
|
|
||||||
%s
|
|
||||||
</ul>
|
|
||||||
<h1>Tech articles</h1>
|
|
||||||
<ul>
|
|
||||||
%s
|
|
||||||
</ul>
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user