Updated project structure and makefile. Started creating frontend. Created csv database interphase
This commit is contained in:
parent
457a52a585
commit
db9b46f041
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
bin/
|
||||
obj/
|
||||
tmp/
|
||||
build/
|
||||
.vscode/
|
39
Makefile
39
Makefile
@ -1,32 +1,29 @@
|
||||
CPPFLAGS := -Iinclude -MMD -MP
|
||||
CFLAGS := -Wall
|
||||
LDFLAGS := -Llib
|
||||
LDLIBS := -lm
|
||||
TARGET_EXEC ?= server
|
||||
|
||||
SRC_DIR := src
|
||||
OBJ_DIR := obj
|
||||
BIN_DIR := bin
|
||||
BUILD_DIR ?= ./build
|
||||
SRC_DIRS ?= ./src
|
||||
|
||||
EXE := $(BIN_DIR)/server
|
||||
SRCS := $(shell find $(SRC_DIRS) -name *.c)
|
||||
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
SRC := $(wildcard $(SRC_DIR)/*.c)
|
||||
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
|
||||
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
|
||||
|
||||
OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
|
||||
|
||||
all: $(EXE)
|
||||
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
|
||||
$(CC) $(OBJS) -o $@ $(LDFLAGS)
|
||||
|
||||
$(EXE): $(OBJ) | $(BIN_DIR)
|
||||
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
|
||||
$(BUILD_DIR)/%.c.o: %.c
|
||||
$(MKDIR_P) $(dir $@)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BIN_DIR) $(OBJ_DIR):
|
||||
mkdir -p $@
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
@$(RM) -rv $(BIN_DIR) $(OBJ_DIR)
|
||||
clean:
|
||||
$(RM) -r $(BUILD_DIR)
|
||||
|
||||
-include $(OBJ:.o=.d)
|
||||
-include $(DEPS)
|
||||
|
||||
.PHONY: all, clean
|
||||
MKDIR_P ?= mkdir -p
|
||||
|
11
include/db_op/blogpost.h
Normal file
11
include/db_op/blogpost.h
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *header;
|
||||
char *content;
|
||||
char **tags;
|
||||
char *author;
|
||||
unsigned int key;
|
||||
} blogpost_t;
|
17
include/db_op/db.h
Normal file
17
include/db_op/db.h
Normal file
@ -0,0 +1,17 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "./blogpost.h"
|
||||
|
||||
#define LINE_SIZE 512
|
||||
|
||||
int open_db(char *file_name, char *type, FILE **file, char ***head, int *head_length);
|
||||
int open_table(char *file_name, FILE **file);
|
||||
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 append_table(FILE *file, void *rec, int type, char *(*process_line)(void *, int));
|
||||
int remove_entry(FILE *file, int n);
|
@ -1,3 +1,10 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct file_s
|
||||
{
|
||||
char *path;
|
@ -1 +1,3 @@
|
||||
#include <string.h>
|
||||
|
||||
char *get_mime_type(char *file_path);
|
@ -1,2 +0,0 @@
|
||||
int get_listener_socket(char *port);
|
||||
void *get_in_addr(struct sockaddr *sa);
|
8
include/netw_op/netw.h
Normal file
8
include/netw_op/netw.h
Normal file
@ -0,0 +1,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
int get_listener_socket(char *port);
|
||||
void *get_in_addr(struct sockaddr *sa);
|
@ -1,3 +1,13 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct header_s {
|
||||
char * str;
|
||||
size_t size;
|
5
include/utils_op/arr.h
Normal file
5
include/utils_op/arr.h
Normal file
@ -0,0 +1,5 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void insert_to_arr(char ***arr, size_t length, char *value);
|
||||
void free_arr(char **arr, int length);
|
0
include/utils_op/llist.h
Normal file
0
include/utils_op/llist.h
Normal file
@ -1,3 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void err_msg(char *msg);
|
||||
char *add_to_front(char **str1, char *str2);
|
||||
char *get_status_message(int status_code);
|
1
src/db_op/blogpost.c
Normal file
1
src/db_op/blogpost.c
Normal file
@ -0,0 +1 @@
|
||||
#include "../../include/db_op/blogpost.h"
|
233
src/db_op/db.c
Normal file
233
src/db_op/db.c
Normal file
@ -0,0 +1,233 @@
|
||||
#include "../../include/db_op/db.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
#include "../../include/utils_op/arr.h"
|
||||
|
||||
/**
|
||||
* @brief Opens a table of specified type. If no such table, creates one and returns 1
|
||||
*
|
||||
* @param file_name
|
||||
* @param type
|
||||
* @param file
|
||||
* @param head
|
||||
* @param head_length
|
||||
* @return int
|
||||
*/
|
||||
int open_db(char *file_name, char *type, FILE **file, char ***head, int *head_length)
|
||||
{
|
||||
FILE *root_file;
|
||||
if ((root_file = fopen(file_name, "a+")) == NULL)
|
||||
{
|
||||
err_msg("can't open database file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buff = NULL;
|
||||
size_t size = LINE_SIZE;
|
||||
|
||||
while (getline(&buff, &size, root_file) >= 0)
|
||||
{
|
||||
if (strcmp(type, strtok(buff, " ")) == 0)
|
||||
{
|
||||
int ret = open_table(strtok(NULL, "\n"), file);
|
||||
|
||||
*head_length = read_head(*file, head);
|
||||
|
||||
fclose(root_file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
struct stat st = {0};
|
||||
if (stat("./db", &st) == -1)
|
||||
{
|
||||
mkdir("./db", 0700);
|
||||
}
|
||||
|
||||
int table_file_name_size = snprintf(NULL, 0, "./db/%s.csv", type) + 1;
|
||||
char *table_file_name = malloc(table_file_name_size);
|
||||
snprintf(table_file_name, table_file_name_size, "./db/%s.csv", type);
|
||||
|
||||
fseek(root_file, 0, SEEK_SET);
|
||||
fprintf(root_file, "%s %s\n", type, table_file_name);
|
||||
|
||||
fclose(root_file);
|
||||
|
||||
int ret = open_table(table_file_name, file);
|
||||
|
||||
free(table_file_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open table file
|
||||
*
|
||||
* @param file_name
|
||||
* @param file
|
||||
* @return int -1 if couldn't open file
|
||||
*/
|
||||
int open_table(char *file_name, FILE **file)
|
||||
{
|
||||
if ((*file = fopen(file_name, "a+")) == NULL)
|
||||
{
|
||||
err_msg("can't open table file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read table head
|
||||
*
|
||||
* @param file
|
||||
* @param head
|
||||
* @return int
|
||||
*/
|
||||
int read_head(FILE *file, char ***head)
|
||||
{
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
int length = 0;
|
||||
*head = malloc(length * sizeof(char *));
|
||||
|
||||
char buff[LINE_SIZE];
|
||||
fscanf(file, "%[^\n]", buff);
|
||||
|
||||
char *tok;
|
||||
int i = 0;
|
||||
for (tok = strtok(buff, ";"); tok && *tok; tok = strtok(NULL, ";"))
|
||||
{
|
||||
insert_to_arr(head, length++, tok);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the entry on line n
|
||||
*
|
||||
* @param file
|
||||
* @param rec
|
||||
* @param type
|
||||
* @param n
|
||||
* @param process_line
|
||||
* @return int
|
||||
*/
|
||||
int get_entry(FILE *file, void **rec, int type, int n, int (*process_line)(char *, void **, int))
|
||||
{
|
||||
char *buff = NULL;
|
||||
int i = 0;
|
||||
size_t size = LINE_SIZE;
|
||||
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
while (getline(&buff, &size, file) >= 0)
|
||||
{
|
||||
if (i == n)
|
||||
{
|
||||
int res = (*process_line)(buff, rec, type);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert entry to the end of table
|
||||
*
|
||||
* @param file
|
||||
* @param rec
|
||||
* @param type
|
||||
* @param process_line
|
||||
* @return int
|
||||
*/
|
||||
int append_table(FILE *file, void *rec, int type, char *(*process_line)(void *, int))
|
||||
{
|
||||
fseek(file, 0, SEEK_END);
|
||||
char *buff = (*process_line)(rec, type);
|
||||
|
||||
if (fprintf(file, "%s", buff) < 0)
|
||||
return -1;
|
||||
|
||||
free(buff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove entry located at line n
|
||||
*
|
||||
* @param file
|
||||
* @param n
|
||||
* @return int
|
||||
*/
|
||||
int remove_entry(FILE *file, int n)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
err_msg("you shouldn't remove table head. Aborting");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tmp_file_name_length = snprintf(NULL, 0, "./db/tmp%d.csv", n) + 1;
|
||||
char *tmp_file_name = malloc(tmp_file_name_length);
|
||||
snprintf(tmp_file_name, tmp_file_name_length, "./db/tmp%d.csv", n);
|
||||
|
||||
FILE *tmp_file = fopen(tmp_file_name, "w");
|
||||
|
||||
char *buff = NULL;
|
||||
size_t size = LINE_SIZE;
|
||||
|
||||
int i = 0;
|
||||
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
while (getline(&buff, &size, file) >= 0)
|
||||
{
|
||||
if (i != n)
|
||||
{
|
||||
fprintf(tmp_file, "%s", buff);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
fclose(tmp_file);
|
||||
free(buff);
|
||||
|
||||
int fd = fileno(file);
|
||||
char file_path[1024];
|
||||
|
||||
int path_length = snprintf(NULL, 0, "/proc/self/fd/%d", fd) + 1;
|
||||
char *path = malloc(path_length);
|
||||
snprintf(path, path_length, "/proc/self/fd/%d", fd);
|
||||
|
||||
memset(file_path, 0, sizeof(file_path));
|
||||
ssize_t l = readlink(path, file_path, sizeof(file_path) - 1);
|
||||
free(path);
|
||||
|
||||
if (l < 0)
|
||||
{
|
||||
err_msg("couldn't get table path");
|
||||
return -1;
|
||||
}
|
||||
file_path[l] = '\0';
|
||||
|
||||
if (remove(file_path) != 0)
|
||||
{
|
||||
err_msg("couldn't remove original file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rename(tmp_file_name, file_path) != 0)
|
||||
{
|
||||
err_msg("couldn't rename tmp file");
|
||||
return -1;
|
||||
}
|
||||
free(tmp_file_name);
|
||||
|
||||
return i;
|
||||
}
|
@ -1,12 +1,5 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../include/file.h"
|
||||
#include "../include/utils.h"
|
||||
#include "../../include/file_op/file.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
|
||||
/**
|
||||
* @brief Generate file path from request path provided
|
||||
@ -16,22 +9,22 @@
|
||||
*/
|
||||
char *gen_file_path(char *req_path)
|
||||
{
|
||||
char *path = (char *)malloc(sizeof req_path);
|
||||
char *path = (char *)malloc(strlen(req_path) + 1);
|
||||
strcpy(path, req_path);
|
||||
if (strchr(req_path, '.') == NULL)
|
||||
{
|
||||
if (req_path[strlen(req_path) - 1] != '/')
|
||||
{
|
||||
path = realloc(path, sizeof path + 1);
|
||||
path = realloc(path, strlen(path) + 1);
|
||||
path = strcat(path, "/");
|
||||
}
|
||||
path = realloc(path, sizeof path + sizeof "index.html");
|
||||
path = realloc(path, strlen(path) + strlen("index.html") + 1);
|
||||
path = strcat(path, "index.html");
|
||||
}
|
||||
|
||||
char *webroot = "static";
|
||||
|
||||
path = realloc(path, sizeof path + sizeof webroot);
|
||||
path = realloc(path, strlen(path) + strlen(webroot));
|
||||
path = add_to_front(&path, webroot);
|
||||
|
||||
return path;
|
||||
@ -47,7 +40,7 @@ char *gen_file_path(char *req_path)
|
||||
int send_file(int cli_fd, struct file_s *file)
|
||||
{
|
||||
off_t offset = 0;
|
||||
if (sendfile(cli_fd, file->fd, &offset, file->size+2) < 0)
|
||||
if (sendfile(cli_fd, file->fd, &offset, file->size + 2) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../include/mime.h"
|
||||
#include "../include/utils.h"
|
||||
#include "../../include/file_op/mime.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
|
||||
#define DEFAULT_mime_TYPE "application/octet-stream"
|
||||
|
||||
@ -62,4 +60,4 @@ char *get_mime_type(char *file_path)
|
||||
}
|
||||
|
||||
return DEFAULT_mime_TYPE;
|
||||
}
|
||||
}
|
@ -1,11 +1,5 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "../include/netw.h"
|
||||
#include "../include/utils.h"
|
||||
#include "../../include/netw_op/netw.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
|
||||
#define BACKLOG 10
|
||||
|
||||
@ -74,6 +68,7 @@ int get_listener_socket(char *port)
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get address from sockaddr structure
|
||||
*
|
@ -1,17 +1,33 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "../../include/netw_op/request.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
#include "../../include/file_op/file.h"
|
||||
#include "../../include/file_op/mime.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
/**
|
||||
* @brief Send 404 response
|
||||
*
|
||||
* @param fd
|
||||
* @param path
|
||||
*/
|
||||
void res_404(int fd, char *path)
|
||||
{
|
||||
FILE *fp = fopen("static/404.html", "r");
|
||||
const ssize_t fsize = 512;
|
||||
char buf[fsize], msg[fsize];
|
||||
|
||||
#include "../include/request.h"
|
||||
#include "../include/utils.h"
|
||||
#include "../include/file.h"
|
||||
#include "../include/mime.h"
|
||||
fread(buf, fsize, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
sprintf(msg, buf, path, path);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the path object
|
||||
@ -21,8 +37,7 @@
|
||||
*/
|
||||
char *get_path(char *request)
|
||||
{
|
||||
char *tmp = strtok(request, " ");
|
||||
char *path = strtok(NULL, " ");
|
||||
char *path = strtok(request, " ");
|
||||
|
||||
return path;
|
||||
}
|
||||
@ -67,6 +82,7 @@ int send_response(int fd, char *req_path)
|
||||
char *file_path = gen_file_path(req_path);
|
||||
|
||||
struct file_s *file = get_file_info(file_path);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
char *msg = "Server error";
|
||||
@ -79,15 +95,20 @@ int send_response(int fd, char *req_path)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file->fd < 0)
|
||||
{
|
||||
char *msg = "<html>\n<body>404, Not Found. Return to home? <a href=\"/\">Home</a></body><html/>";
|
||||
// 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);
|
||||
// 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);
|
||||
// send(fd, msg, strlen(msg), 0);
|
||||
// close(fd);
|
||||
|
||||
// printf("404 ERROR\n");
|
||||
|
||||
res_404(fd, req_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -96,8 +117,6 @@ int send_response(int fd, char *req_path)
|
||||
|
||||
struct header_s *header = gen_header(200, file->size, mime_type);
|
||||
|
||||
printf("\n---\n%s\n%ld\n---\n", header->str, header->size);
|
||||
|
||||
int rv = send(fd, header->str, header->size - 1, 0);
|
||||
|
||||
if (rv < 0)
|
||||
@ -141,6 +160,15 @@ void handle_get_request(int fd, char *request)
|
||||
char *path = get_path(request);
|
||||
printf("Client accessed path: %s\n", path);
|
||||
|
||||
if (strncmp(path, "/blog/", strlen("/blog/")) == 0)
|
||||
{
|
||||
char *id = (char *)malloc(strlen(path) - strlen("/blog/") + 1);
|
||||
memmove(id, path + strlen("/blog/"), strlen(path) - strlen("/blog/") + 1);
|
||||
|
||||
printf("Blog post id = %s\n", id);
|
||||
}
|
||||
|
||||
|
||||
if (send_response(fd, path) < 0)
|
||||
{
|
||||
err_msg("couldn't send response");
|
15
src/server.c
15
src/server.c
@ -8,9 +8,9 @@
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "../include/netw.h"
|
||||
#include "../include/utils.h"
|
||||
#include "../include/request.h"
|
||||
#include "../include/netw_op/netw.h"
|
||||
#include "../include/utils_op/utils.h"
|
||||
#include "../include/netw_op/request.h"
|
||||
|
||||
/**
|
||||
* @brief Handle client connection
|
||||
@ -19,7 +19,7 @@
|
||||
*/
|
||||
void handle_connection(int fd)
|
||||
{
|
||||
const size_t request_buffer_size = 512;
|
||||
const size_t request_buffer_size = 1024;
|
||||
char request[request_buffer_size];
|
||||
char *prt;
|
||||
|
||||
@ -31,7 +31,7 @@ void handle_connection(int fd)
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("Request:\n%s---\n", request);
|
||||
// printf("\nRequest:\n%s---\n", request);
|
||||
|
||||
prt = strstr(request, " HTTP/");
|
||||
if (prt == NULL)
|
||||
@ -42,10 +42,12 @@ void handle_connection(int fd)
|
||||
{
|
||||
if (strncmp(request, "GET ", 4) == 0)
|
||||
{
|
||||
memmove(request, request + 4, strlen(request) - 3);
|
||||
handle_get_request(fd, request);
|
||||
}
|
||||
else if (strncmp(request, "POST ", 5) == 0)
|
||||
{
|
||||
memmove(request, request + 5, strlen(request) - 4);
|
||||
handle_post_request(fd, request);
|
||||
}
|
||||
else
|
||||
@ -97,7 +99,10 @@ int main(int argc, char *argv[])
|
||||
int pid = fork();
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
err_msg("fork failed");
|
||||
close(client_fd);
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
close(listenfd);
|
||||
|
31
src/utils_op/arr.c
Normal file
31
src/utils_op/arr.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include "../../include/utils_op/arr.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @brief Insert string to the end of array of strings
|
||||
*
|
||||
* @param arr
|
||||
* @param length
|
||||
* @param value
|
||||
*/
|
||||
void insert_to_arr(char ***arr, size_t length, char *value)
|
||||
{
|
||||
*arr = realloc(*arr, (length + 1) * sizeof(char *));
|
||||
|
||||
(*arr)[length] = malloc(strlen(value) * sizeof(char));
|
||||
strcpy((*arr)[length], value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free memory allocated for array of strings
|
||||
*
|
||||
* @param arr
|
||||
* @param length
|
||||
*/
|
||||
void free_arr(char **arr, int length)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
free(arr[i]);
|
||||
|
||||
free(arr);
|
||||
}
|
126
src/utils_op/llist.c
Normal file
126
src/utils_op/llist.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NUMBER 5
|
||||
|
||||
typedef struct llist_s
|
||||
{
|
||||
char *value;
|
||||
struct llist_s *next;
|
||||
} llist_t;
|
||||
|
||||
/**
|
||||
* @brief Find item by number
|
||||
*
|
||||
* @param list
|
||||
* @param n
|
||||
* @return llist_t*
|
||||
*/
|
||||
llist_t *find_item(llist_t *list, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
list = list->next;
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fill llist with array
|
||||
*
|
||||
* @param list
|
||||
* @param arr
|
||||
* @param n
|
||||
*/
|
||||
void fill_with_arr(llist_t **list, char **arr, size_t n)
|
||||
{
|
||||
llist_t *current = *list;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
current->value = arr[i];
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Print hole list
|
||||
*
|
||||
* @param list
|
||||
*/
|
||||
void print_llist(llist_t *list)
|
||||
{
|
||||
llist_t *current = list;
|
||||
int i = 0;
|
||||
|
||||
while (current != NULL)
|
||||
{
|
||||
printf("%d - %s\n", i + 1, current->value);
|
||||
current = current->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add value to the specified pos of llist
|
||||
*
|
||||
* @param head
|
||||
* @param pos
|
||||
* @param value
|
||||
* @return llist_t*
|
||||
*/
|
||||
llist_t *add_to_list(llist_t **head, int pos, char *value)
|
||||
{
|
||||
if (pos == 1)
|
||||
{
|
||||
llist_t *new = malloc(sizeof(llist_t));
|
||||
new->value = value;
|
||||
new->next = *head;
|
||||
|
||||
*head = new;
|
||||
return new;
|
||||
}
|
||||
|
||||
llist_t *current = *head;
|
||||
|
||||
for (int i = 0; i < pos - 2; i++)
|
||||
current = current->next;
|
||||
|
||||
llist_t *next = current->next;
|
||||
|
||||
current->next = malloc(sizeof(llist_t));
|
||||
current->next->value = value;
|
||||
current->next->next = next;
|
||||
|
||||
return current->next;
|
||||
}
|
||||
|
||||
// int main()
|
||||
// {
|
||||
// llist_t *head = malloc(sizeof(llist_t));
|
||||
|
||||
// head->value = "first";
|
||||
|
||||
// head->next = malloc(sizeof(llist_t));
|
||||
// head->next->value = "second";
|
||||
|
||||
// head->next->next = malloc(sizeof(llist_t));
|
||||
// head->next->next->value = "third";
|
||||
|
||||
// head->next->next->next = malloc(sizeof(llist_t));
|
||||
// head->next->next->next->value = "forth";
|
||||
|
||||
// head->next->next->next->next = malloc(sizeof(llist_t));
|
||||
// head->next->next->next->next->value = "fifth";
|
||||
|
||||
// head->next->next->next->next->next = malloc(sizeof(llist_t));
|
||||
// head->next->next->next->next->next->value = "sixth";
|
||||
// head->next->next->next->next->next->next = NULL;
|
||||
|
||||
// print_llist(head);
|
||||
|
||||
// add_to_list(&head, 9, "Hola");
|
||||
|
||||
// print_llist(head);
|
||||
|
||||
// return 0;
|
||||
// }
|
@ -1,9 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../include/utils.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
|
||||
/**
|
||||
* @brief Prints error
|
||||
@ -29,7 +24,7 @@ char *add_to_front(char **str1, char *str2)
|
||||
strcpy(*str1, str2);
|
||||
strcat(*str1, tmp);
|
||||
|
||||
free(tmp);
|
||||
// free(tmp);
|
||||
|
||||
return *str1;
|
||||
}
|
@ -7,7 +7,8 @@
|
||||
|
||||
<body>
|
||||
<h1>Not Found</h1>
|
||||
<p>The requested URL was not found on this server.</p>
|
||||
<p>The requested URL: <a href="%s">%s</a> was not found on this server.</p>
|
||||
<p>Return <a href="/">home</a></p>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -5,10 +5,13 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>About</title>
|
||||
<link rel="stylesheet" href="../style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a href="../">Back</a>
|
||||
<header>
|
||||
<a href="/" id="logo"><img src="./logo.png" alt="logo" /></a>
|
||||
</header>
|
||||
<p>Me</p>
|
||||
<img src="/about/me.jpg" alt="the pig" style="max-height: 200px;" />
|
||||
</body>
|
||||
|
15
static/gallery/index.html
Normal file
15
static/gallery/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Gallery</title>
|
||||
<link rel="stylesheet" href="../style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/" id="logo"><img src="./logo.png" alt="logo" /></a>
|
||||
</header>
|
||||
%s
|
||||
</body>
|
||||
</html>
|
@ -1,12 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Test</title>
|
||||
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Testing paragraf</p>
|
||||
<a href="./about">About me</a>
|
||||
<header>
|
||||
<a href="/" id="logo"><img src="./logo.png" alt="logo" /></a>
|
||||
</header>
|
||||
<main>
|
||||
<h1>Home</h1>
|
||||
<ul>
|
||||
<li><a href="/about">About me</a></li>
|
||||
<li><a href="/gallery">Gallery</a></li>
|
||||
<li><a href="/projects">Projects</a></li>
|
||||
<li><a href="/philosophy">Philosophy</a></li>
|
||||
</ul>
|
||||
<h1>Blog</h1>
|
||||
<ul>
|
||||
%s
|
||||
</ul>
|
||||
<h1>Tech articles</h1>
|
||||
<ul>
|
||||
%s
|
||||
</ul>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
BIN
static/logo.png
Normal file
BIN
static/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 602 B |
48
static/style.css
Normal file
48
static/style.css
Normal file
@ -0,0 +1,48 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
font-family: "alte_haas_grotesk_bold", "Helvetica Neue", Helvetica, Arial;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
html {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
border-top: solid 5px #000000;
|
||||
padding: 45px;
|
||||
}
|
||||
|
||||
header {
|
||||
height: 65px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
header img {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
main h1 {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
main li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
li a {
|
||||
color: #000000;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
li:hover a {
|
||||
text-decoration: none;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user