aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2021-11-28 23:37:18 +0100
committerJeremias Stotter <jeremias@stotter.eu>2021-11-28 23:37:18 +0100
commit61e0a20a0506575fa8f0d459d8eec40a8c59bafa (patch)
treeb1acea0c9112bf0e6b3bec3601ae6dc6d1cd4e4a
parent1d3746b94db6864b833dfb9520328b5986385f36 (diff)
downloadJBlog-61e0a20a0506575fa8f0d459d8eec40a8c59bafa.tar.gz
JBlog-61e0a20a0506575fa8f0d459d8eec40a8c59bafa.tar.bz2
JBlog-61e0a20a0506575fa8f0d459d8eec40a8c59bafa.zip
Many things
- Log files - Can run as a proper daemon now - Cache was broken, works now
-rw-r--r--admin.c14
-rw-r--r--index.c10
-rw-r--r--jblog.c323
-rw-r--r--jblog.h6
-rw-r--r--md.c20
-rw-r--r--readme.html3
6 files changed, 306 insertions, 70 deletions
diff --git a/admin.c b/admin.c
index 2bd4b6b..d1bbb21 100644
--- a/admin.c
+++ b/admin.c
@@ -138,34 +138,34 @@ int create_admin(char* buffer, size_t buffer_size, char* adm_save_dir, char* pat
}
int edit_file = open(filepath, O_RDONLY);
if(edit_file < 0) {
- fprintf(stderr, "Could not open file %s: %s\n", filepath, strerror(errno));
+ jb_log(LL_WARN, true, "couldn't open file");
snprintf(buffer, buffer_size, "<p>ERROR: Could not open file for editing, please go back: %s</p>", strerror(errno));
return 0;
}
struct stat edit_file_stat = {0};
if(fstat(edit_file, &edit_file_stat) == -1) {
- fprintf(stderr, "Could not stat file %s: %s\n", filepath, strerror(errno));
+ jb_log(LL_WARN, true, "couldn't stat file");
snprintf(buffer, buffer_size, "<p>Could not stat file, please go back: %s</p>", strerror(errno));
close(edit_file);
return 0;
}
char* edit_file_content = calloc(edit_file_stat.st_size + 1, 1);
if(edit_file_content == NULL) {
- fprintf(stderr, "Could calloc for file %s of size %ld: %s\n", filepath, edit_file_stat.st_size, strerror(errno));
+ jb_log(LL_WARN, true, "calloc");
snprintf(buffer, buffer_size, "<p>Could not calloc buffer, please go back: %s</p>", strerror(errno));
close(edit_file);
return 0;
}
if(read(edit_file, edit_file_content, edit_file_stat.st_size) != edit_file_stat.st_size) {
- fprintf(stderr, "WARNING: only read fewer bytes than expected!\n");
+ jb_log(LL_WARN, false, "Fewer bytes read than expected");
}
close(edit_file);
struct jblog_file jblog_values = {0};
- if(split_jblog(&jblog_values, edit_file_content) != 0) {
- fprintf(stderr, "split_jblog failed for %s", filepath);
+ if(split_jblog(&jblog_values, edit_file_content) != 0) {
+ jb_log(LL_WARN, false, "split_jblog");
snprintf(buffer, buffer_size, "<p>Could not read file %s</p>", filepath);
close(edit_file);
return 0;
@@ -522,6 +522,6 @@ int post_admin(char* buffer, size_t buffer_size, char* req_content, size_t req_c
}
}
- fprintf(stderr, "Couldn't read all the values from the form successfully!\n");
+ jb_log(LL_WARN, false, "Couldn't read all the values from the form successfully");
return -1;
}
diff --git a/index.c b/index.c
index 81c328e..01caaed 100644
--- a/index.c
+++ b/index.c
@@ -44,7 +44,7 @@ int create_index(char* path_name, int search_depth,
int* timesort_count_ptr) {
DIR* index_dir = opendir(path_name);
if(index_dir == NULL) {
- perror("Error opening directory for indexing");
+ jb_log(LL_WARN, true, "couldn't open directory");
return -1;
}
@@ -68,7 +68,7 @@ int create_index(char* path_name, int search_depth,
char index_ent_fullname[PATH_MAX] = "";
sprintf(index_ent_fullname, "%s/%s", path_name, index_dirent->d_name);
if(stat(index_ent_fullname, &index_ent_stat) != 0) {
- fprintf(stderr, "stat error on file %s: %s\n", index_ent_fullname, strerror(errno));
+ jb_log(LL_WARN, true, "couldn't stat");
continue;
}
if(*(index_dirent->d_name) == '.') {
@@ -85,7 +85,7 @@ int create_index(char* path_name, int search_depth,
// We have a regular file that is also a jblog file
int jblog_file = open(index_ent_fullname, O_RDONLY);
if(jblog_file < 0) {
- fprintf(stderr, "error opening file %s: %s\n", index_ent_fullname, strerror(errno));
+ jb_log(LL_WARN, true, "couldn't open");
continue;
}
// read until, we don't need the content here
@@ -99,7 +99,7 @@ int create_index(char* path_name, int search_depth,
current_size ++;
header = realloc(header, current_size);
if(header == NULL) {
- perror("realloc error");
+ jb_log(LL_ERR, true, "realloc");
close(jblog_file);
closedir(index_dir);
return -1;
@@ -163,7 +163,7 @@ int create_index(char* path_name, int search_depth,
timesort_count++;
timesort_pointer = realloc(timesort_pointer, sizeof(struct timesort_entry) * timesort_count);
if(timesort_pointer == NULL) {
- perror("realloc error");
+ jb_log(LL_ERR, true, "realloc");
return -1;
}
timesort_pointer[timesort_count-1].time = entry_time;
diff --git a/jblog.c b/jblog.c
index 6e22ad1..20a14fa 100644
--- a/jblog.c
+++ b/jblog.c
@@ -34,14 +34,13 @@
#include <limits.h>
#include <pwd.h>
#include <grp.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <time.h>
#include "md.h"
#include "index.h"
#include "admin.h"
-
-// Call program like this
-// jblog <UNIX socket> <html pattern> <directory with blog files>
-
#include "cache.h"
#include "jblog.h"
@@ -59,6 +58,7 @@
#define HTML_ID 1
#define MAX_UPLOAD 134217700
+#define PIDFILE "/run/jblog.pid"
char* adm_save_dir;
char* base_path;
@@ -72,9 +72,39 @@ int pattern_type = 0;
// Root of the search tree used for caching
void* tree_root = NULL;
+int logfile = -1;
+
+#define LL_INFO 0
+#define LL_WARN 1
+#define LL_ERR 2
+void jb_log(int loglevel, bool include_errno, char* error_string) {
+ // @todo implement a minimum loglevel command line switch
+ int curr_errno = errno;
+ char error_full[4096] = {0};
+ char err_prefix[8] = {0};
+ FILE* nologfile_out = stdout;
+ switch(loglevel) {
+ case LL_INFO:
+ strcpy(err_prefix, "INFO");
+ break;
+ case LL_WARN:
+ strcpy(err_prefix, "WARNING");
+ break;
+ case LL_ERR:
+ strcpy(err_prefix, "ERROR");
+ nologfile_out = stderr;
+ break;
+ }
+ snprintf(error_full, 4095, "(%ld) %s: %s%s%s\n", time(NULL), err_prefix,error_string, include_errno ? " : " : "", include_errno ? strerror(curr_errno) : "" );
+ if(logfile >= 0) {
+ (void)!write(logfile, error_full, strlen(error_full));
+ }
+ fprintf(nologfile_out, error_full);
+}
+
void sigint_catch(int signo) {
if(shutdown(sockfd, SHUT_RDWR) != 0) {
- perror("Could not shutdown socket");
+ jb_log(LL_ERR, true, "Could not shutdown socket");
exit(-1);
}
exit(0);
@@ -134,19 +164,24 @@ int handle_request(int socket);
int create_html(char* content, size_t content_length, char request_uri[1024], char request_method[64], char** buffer, size_t* reply_size, bool ignore_cache, char* req_content, size_t req_content_size);
int main(int argc, char* argv[]) {
- // Signal handling
- signal(SIGINT, sigint_catch);
-
+ // Thingies needed if we are to daemonize
+ int parentpipe[2] = {0};
+ unsigned char closeparent_sig = 0xFF;
+ unsigned char errorparent_sig = 0xFE;
+
// Arguments
char* un_path = NULL;
char* pattern_path = NULL;
char* user = NULL;
char* group = NULL;
+ bool daemon = false;
+ char* logfile_path = NULL;
+ char* pidfile_path = NULL;
int cindex = 0;
// s: socket; p: pattern; b: blog base;
// a: admin base; u: process user;
- while((cindex = getopt(argc, argv, "hs:p:b:a:u:g:")) != -1) {
+ while((cindex = getopt(argc, argv, "hs:p:b:a:u:g:dl:r:")) != -1) {
switch(cindex) {
case 'h':
printf("Usage:\n"
@@ -158,6 +193,9 @@ int main(int argc, char* argv[]) {
" [-a <admin save directory>] directory which can be used on the admin page to save work without publishing\n"
" [-u <username>] user the process will setuid to\n"
" [-g <group>] group the process will setgid to\n"
+ " [-d] daemonize the process\n"
+ " [-l <logfile>] log file\n"
+ " [-r <pidfile>] the path of the PID file (defaults to "PIDFILE", only usefull with -d\n"
" [-h] display this dialog, then exit\n");
return 0;
break;
@@ -179,8 +217,17 @@ int main(int argc, char* argv[]) {
case 'g':
group = optarg;
break;
+ case 'd':
+ daemon = true;
+ break;
+ case 'l':
+ logfile_path = optarg;
+ break;
+ case 'r':
+ pidfile_path = optarg;
+ break;
default:
- fprintf(stderr, "ERROR: Invalid argument!\n");
+ jb_log(LL_ERR, false, "Invalid argument!");
return -1;
break;
}
@@ -194,16 +241,158 @@ int main(int argc, char* argv[]) {
return -1;
}
// END OF ARGUMENTS
+
+ // open logfile
+ if(logfile_path) {
+ logfile = open(logfile_path, O_RDWR | O_CREAT | O_APPEND, 0644);
+ if(logfile < 0) {
+ jb_log(LL_ERR, true, "couldn't open logfile");
+ }
+ }
+
+ // If we are supposed to daemonize the process do so now
+ if(daemon) {
+ // See daemon.7 man page for more details
+ // First see if there is already a pid file
+ int pidfile = open(pidfile_path ? pidfile_path : PIDFILE, O_RDONLY);
+ if(pidfile < 0) {
+ if(errno != ENOENT) {
+ jb_log(LL_ERR, true, "Can't open PID file");
+ return -1;
+ }
+ } else {
+ pid_t existing_daemon = 0;
+ if(read(pidfile, &existing_daemon, sizeof(pid_t)) != sizeof(pid_t)) {
+ jb_log(LL_ERR, true, "Can't reading PID file");
+ return -1;
+ }
+ if(kill(existing_daemon, 0) == 0 || errno != ESRCH) {
+ jb_log(LL_ERR, false, "JBlog is already running");
+ return -1;
+ }
+ }
+ // First close all the files
+ struct rlimit max_fd = {0};
+ if(getrlimit(RLIMIT_NOFILE, &max_fd) != 0) {
+ jb_log(LL_ERR, true, "getrlimit");
+ return -1;
+ }
+ for(int i = 3; i < max_fd.rlim_cur; i++) {
+ if(i == logfile) {
+ continue;
+ }
+ if(close(i) != 0 && errno != EBADF) {
+ jb_log(LL_ERR, true, "Couldn't close all open files");
+ return -1;
+ }
+ }
+ // Reset signal handlers
+ for(int i = 0; i < _NSIG; i++) {
+ signal(i, SIG_DFL);
+ }
+ // Reset signal mask
+ sigset_t full_signalset;
+ if(sigfillset(&full_signalset) != 0) {
+ jb_log(LL_ERR, true, "sigfillset");
+ return -1;
+ }
+ sigprocmask(SIG_UNBLOCK, &full_signalset, NULL);
+ // Open a pipe for communication between parent and child
+ if(pipe(parentpipe) == -1) {
+ jb_log(LL_ERR, true, "pipe");
+ return -1;
+ }
+ // 1. fork
+ pid_t fork_ret1 = fork();
+ if(fork_ret1 < 0) {
+ jb_log(LL_ERR, true, "1. fork");
+ return -1;
+ } else if(fork_ret1 > 0) {
+ close(parentpipe[1]);
+ unsigned char child_signal = 0;
+ while(child_signal != closeparent_sig) {
+ (void)!read(parentpipe[0], &child_signal, 1);
+ if(child_signal == errorparent_sig) {
+ jb_log(LL_ERR, false, "couldn't start child, look at the log file if it is set");
+ return -1;
+ }
+ }
+ exit(0);
+ } else {
+ close(parentpipe[0]);
+ if(setsid() == -1) {
+ jb_log(LL_ERR, true, "setsid");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ }
+ // 2. fork
+ pid_t fork_ret2 = fork();
+ if(fork_ret2 < 0) {
+ jb_log(LL_ERR, true, "2. fork");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ } else if(fork_ret2 > 0) {
+ exit(0);
+ }
+ // change stdin/out/err to /dev/null
+ int devnull = open("/dev/null", 0);
+ if(devnull < 0) {
+ jb_log(LL_ERR, true, "opening /dev/null");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ }
+ if(dup2(devnull, 0) < 0 || dup2(devnull, 1) < 0 || dup2(devnull, 2) < 0) {
+ jb_log(LL_ERR, true, "changing default file descriptors");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ }
+ // Umask to 0
+ umask(0);
+ // From here on it is useless to write to stderr!
+ // @todo LOGGING
+ if(chdir("/") != 0) {
+ jb_log(LL_ERR, true, "chdir");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ }
+ // Write PID to PIDFILE
+ int pidfile = open(pidfile_path ? pidfile_path : PIDFILE, O_RDWR | O_CREAT, 0644);
+ if(pidfile < 0) {
+ jb_log(LL_ERR, true, "opening pidfile");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ }
+ pid_t daemon_pid = getpid();
+ if(write(pidfile, &daemon_pid, sizeof(daemon_pid)) != sizeof(daemon_pid)) {
+ jb_log(LL_ERR, true, "writing pidfile");
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
+ }
+ close(pidfile);
+ // Signal the parent to stop
+ // @todo only do this once the main loop is actually started
+ (void)!write(parentpipe[1], &closeparent_sig, 1);
+ close(parentpipe[1]);
+ }
+ }
+ // Now we are a daemon
+ // Signal handling
+ signal(SIGINT, sigint_catch);
+
// change the user and group
if(user) {
struct passwd* upasswd = getpwnam(user);
if(upasswd == NULL) {
- perror("Error retrieving user information");
+ jb_log(LL_ERR, true, "getpwnam");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
if(setuid(upasswd->pw_uid) != 0) {
- perror("Error changing User ID");
+ jb_log(LL_ERR, true, "setuid");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
}
@@ -211,11 +400,15 @@ int main(int argc, char* argv[]) {
if(group) {
struct group* ggroup = getgrnam(group);
if(ggroup == NULL) {
- perror("Error retrieving group information");
+ jb_log(LL_ERR, true, "getgrnam");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
if(setgid(ggroup->gr_gid) != 0) {
- perror("Error changing Group ID");
+ jb_log(LL_ERR, true, "setgid");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
}
@@ -223,25 +416,33 @@ int main(int argc, char* argv[]) {
// read in the html pattern to memory
int patternfd = open(pattern_path, O_RDONLY);
if(patternfd < 0) {
- perror("Error opening the HTML pattern");
+ jb_log(LL_ERR, true, "opening pattern file");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
struct stat pattern_stat;
if(fstat(patternfd, &pattern_stat) != 0) {
- perror("Error executing stat on HTML pattern");
+ jb_log(LL_ERR, true, "stat pattern file");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
char* pattern = mmap(NULL, pattern_stat.st_size, PROT_WRITE, MAP_PRIVATE, patternfd, 0);
close(patternfd);
if(strnlen(pattern, MAX_REPLY + 1) > MAX_REPLY) {
- fprintf(stderr, "The Pattern is bigger than the buffer (%d)\n", MAX_REPLY);
+ jb_log(LL_ERR, false, "pattern to big");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return(-1);
}
// find out if the pattern is html or xhtml
{
char* fileext = strrchr(pattern_path, '.');
if(fileext == NULL) {
- fprintf(stderr, "ERROR: Pattern file doesn't have a file extension.\n");
+ jb_log(LL_ERR, false, "missing pattern file extension");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
if(strcmp(fileext+1, "xhtml") == 0) {
@@ -249,18 +450,26 @@ int main(int argc, char* argv[]) {
} else if(strcmp(fileext+1, "html") == 0) {
pattern_type = HTML_ID;
} else {
- fprintf(stderr, "ERROR: Pattern file doesn't have a valid file extension. (xhtml or html allowed)\n");
+ jb_log(LL_ERR, false, "invalid pattern file extension");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
}
// The pattern should contain a line starting with $BLOG$ at which the whole blog HTML code will be insertet
// Find the Title
- if(seperate_string(pattern, TITLEMARK, &blog_head_pretitle, &blog_head_postitle) != 0) {
- fprintf(stderr, "Missing title marker in pattern (%s)\n", TITLEMARK);
+ if(seperate_string(pattern, TITLEMARK, &blog_head_pretitle, &blog_head_postitle) != 0) {
+ jb_log(LL_ERR, false, "Missing "TITLEMARK" in pattern");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
}
- if(seperate_string(blog_head_postitle, BLOGMARK, &blog_head_postitle, &blog_foot) != 0) {
- fprintf(stderr, "Missing blog marker in pattern (%s)\n", BLOGMARK);
+ if(seperate_string(blog_head_postitle, BLOGMARK, &blog_head_postitle, &blog_foot) != 0) {
+ jb_log(LL_ERR, false, "Missing "BLOGMARK" in pattern");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
+ return -1;
}
@@ -268,9 +477,10 @@ int main(int argc, char* argv[]) {
// Set up the socket to listen to
sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
-
if(sockfd == -1) {
- perror("Socket error");
+ jb_log(LL_ERR, true, "socket");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
@@ -282,21 +492,28 @@ int main(int argc, char* argv[]) {
unlink(un_path);
if(bind(sockfd, (const struct sockaddr *)&socket_address, un_socklen) != 0) {
- perror("Bind Error");
+ jb_log(LL_ERR, true, "bind");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
return -1;
}
if(listen(sockfd, 256) != 0) {
- perror("Listen error");
+ jb_log(LL_ERR, true, "listen");
+ if(daemon)
+ (void)!write(parentpipe[1], &errorparent_sig, 1);
close(sockfd);
return -1;
}
+ // Tell the parent we are ready to start the main loop
+ if(daemon)
+ (void)!write(parentpipe[1], &closeparent_sig, 1);
// Start the main loop
for(;;) {
int connected_sock = accept(sockfd, (struct sockaddr *)&socket_address, &un_socklen);
if(connected_sock == -1) {
- perror("Accept Error");
+ jb_log(LL_ERR, true, "accept");
return -1;
}
handle_request(connected_sock);
@@ -354,17 +571,17 @@ int handle_request(int socket) {
int msg_len = get_next_netstr_len(socket);
char* msg = malloc(msg_len);
if(msg == NULL) {
- perror("malloc error");
+ jb_log(LL_ERR, true, "malloc");
}
if(read(socket, msg, msg_len) < msg_len) {
- fprintf(stderr, "WARNING: message read from socket was shortet than expected\n");
+ jb_log(LL_WARN, false, "message read from socket was shortet than expected");
}
// Check if the client is a valid SCGI client
{
char scgi_identifier[2] = "";
get_field_from_msg(msg, msg_len, "SCGI", scgi_identifier, 2);
if(strcmp(scgi_identifier, "1") != 0) {
- fprintf(stderr, "WARNING: The client does not seem to be a SCGI client!\n");
+ jb_log(LL_WARN, false, "The client does not seem to be a SCGI client!");
close(socket);
return -1;
}
@@ -385,7 +602,11 @@ int handle_request(int socket) {
strcpy(request_method, buffer);
}
free(msg);
- printf("Recieved a %s request at %s with content length %ld\n", request_method, request_uri, content_length);
+ {
+ char req_info[4096] = {0};
+ snprintf(req_info, 4096, "Recieved a %s request at %s with content length %ld", request_method, request_uri, content_length);
+ jb_log(LL_INFO, false, req_info);
+ }
// There is a ',' as the next character in the socket, just read it and ignore it
char last_msg;
(void)!read(socket, &last_msg, 1);
@@ -393,14 +614,13 @@ int handle_request(int socket) {
char* content = NULL;
if(content_length > 0) {
lseek(socket, 1, SEEK_CUR);
- printf("There is content of size %ld\n", content_length);
if(content_length > MAX_UPLOAD) {
- fprintf(stderr, "Error: Upload too big\n");
+ jb_log(LL_ERR, false, "Upload too big");
return -1;
}
content = calloc(content_length + 1, 1);
if(content == NULL) {
- perror("calloc error");
+ jb_log(LL_ERR, true, "calloc");
return -1;
}
size_t read_bytes = 0;
@@ -408,7 +628,7 @@ int handle_request(int socket) {
read_bytes_iter = read(socket, content + read_bytes, content_length - read_bytes);
}
if(read_bytes != content_length) {
- fprintf(stderr, "WARNING: message read from socket was shortet than expected (Got %ld ; expected %ld)\n", read_bytes, content_length);
+ jb_log(LL_WARN, true, "message read from socket was shortet than expected");
return -1;
}
}
@@ -441,7 +661,7 @@ int handle_request(int socket) {
}
if(write(socket, http_response, reply_len) < reply_len) {
- fprintf(stderr, "WARNING: message written to socket was shorter than expected\n");
+ jb_log(LL_WARN, true, "message written to socket was shortet than expected");
}
if(content_length > 0) {
@@ -470,7 +690,7 @@ int process_blog_text(char* buffer, size_t buffer_size, char* blog_text, char* t
int split_jblog(struct jblog_file* jblog_values, char* blog_content) {
jblog_values->blog_text = strstr(blog_content, "\n///");
if(jblog_values->blog_text == NULL) {
- fprintf(stderr, "File is empty\n");
+ jb_log(LL_ERR, false, "File is empty");
return 500;
}
memset(jblog_values->blog_text, (unsigned char)0, 4);
@@ -512,7 +732,7 @@ int read_jblog_file(char* buffer, int buffer_size, char* file_name, int* error_c
}
struct stat jblog_stat;
if(fstat(blog_fd, &jblog_stat) != 0) {
- perror("stat error");
+ jb_log(LL_ERR, true, "stat");
close(blog_fd);
*error_code = 500;
return 0;
@@ -523,13 +743,13 @@ int read_jblog_file(char* buffer, int buffer_size, char* file_name, int* error_c
}
char* blog_content = calloc(jblog_stat.st_size, 1);
if(blog_content == NULL) {
- perror("calloc error");
+ jb_log(LL_ERR, true, "calloc");
*error_code = 500;
return 0;
}
if(read(blog_fd, blog_content, jblog_stat.st_size) != jblog_stat.st_size) {
*error_code = 500;
- fprintf(stderr, "Could not read file\n");
+ jb_log(LL_ERR, false, "reading blog file");
return 0;
}
close(blog_fd);
@@ -551,7 +771,7 @@ int read_jblog_file(char* buffer, int buffer_size, char* file_name, int* error_c
bool wrap_html = true;
char* html = calloc(buffer_size, 1);
if(html == NULL) {
- perror("calloc error");
+ jb_log(LL_ERR, true, "calloc");
free(blog_content);
*error_code = 500;
return 0;
@@ -626,7 +846,7 @@ int read_jblog_file(char* buffer, int buffer_size, char* file_name, int* error_c
}
}
} else {
- fprintf(stderr, "Requested file has no valid type!\n");
+ jb_log(LL_ERR, false, "Invalid requested file type");
free(blog_content);
return 0;
}
@@ -661,7 +881,7 @@ int create_html(char* content, size_t content_length, char request_uri[1024], ch
}
*buffer = calloc(MAX_REPLY, 1);
if(buffer == NULL) {
- perror("malloc error");
+ jb_log(LL_ERR, false, "malloc");
return -1;
}
@@ -696,11 +916,11 @@ int create_html(char* content, size_t content_length, char request_uri[1024], ch
if(found_entry != NULL) {
if(ignore_cache) {
// If we ignore the cache we just free the old entry
- printf("Cache drop\n");
+ jb_log(LL_INFO, false, "Cache drop");
free((*found_entry)->content);
struct tree_entry* free_entry = *found_entry;
if(tdelete(in_entry, &tree_root, compare) == NULL) {
- fprintf(stderr, "error deleting entry from cache");
+ jb_log(LL_ERR, false, "could not delete cache entry");
}
free(free_entry);
} else {
@@ -708,13 +928,13 @@ int create_html(char* content, size_t content_length, char request_uri[1024], ch
*buffer = (*found_entry)->content;
return 200;
}
- }
+ }
}
int error_code = 0;
*reply_size = read_jblog_file(*buffer, MAX_REPLY, canonicalized_path, &error_code, request_uri, req_method, req_content, req_content_size, path_argument);
- bool no_create_cache = true;
+ bool no_create_cache = false;
if((signed)*reply_size < (signed)0) {
no_create_cache = true;
@@ -728,26 +948,25 @@ int create_html(char* content, size_t content_length, char request_uri[1024], ch
// The response was too big
if(*reply_size >= MAX_REPLY) {
strcpy(*buffer, HTML_ERROR(500));
- fprintf(stderr, "ERROR: Response to big, max is %ld got %ld\n", (long)MAX_REPLY, *reply_size);
+ jb_log(LL_ERR, false, "response too big");
return 500;
}
*buffer = realloc(*buffer, *reply_size + 1);
if(buffer == NULL) {
- perror("realloc error");
+ jb_log(LL_ERR, true, "realloc");
strcpy(*buffer, HTML_ERROR(500));
return 500;
}
if(req_method == REQ_GET && !no_create_cache){
in_entry->content = *buffer;
-
// Add the entry in
found_entry = tsearch(in_entry, &tree_root, compare);
if(found_entry == NULL) {
- perror("tsearch error");
+ jb_log(LL_ERR, true, "tsearch");
strcpy(*buffer, HTML_ERROR(500));
return 500;
}
diff --git a/jblog.h b/jblog.h
index 28cc6b3..9533b12 100644
--- a/jblog.h
+++ b/jblog.h
@@ -18,6 +18,7 @@
#ifndef JBLOG
#define JBLOG
+#include <stdbool.h>
// The maximum reply size
// Actually we are not gonna have quite as much usable
#define MAX_REPLY 131072
@@ -39,6 +40,11 @@ struct jblog_file {
char* blog_text;
};
+#define LL_INFO 0
+#define LL_WARN 1
+#define LL_ERR 2
+void jb_log(int loglevel, bool include_errno, char* error_string);
+
void retrieve_headvals(char* head, char retrieve_values[][32], char** returned_strings[], int retrieve_ammount);
char* trim_whitespace(char** str);
int process_blog_text(char* buffer, size_t buffer_size, char* blog_text, char* title, char* author, char* date, char* time);
diff --git a/md.c b/md.c
index 7aacc3b..7187575 100644
--- a/md.c
+++ b/md.c
@@ -22,6 +22,8 @@
#include <stdlib.h>
#include <stdbool.h>
+#include "jblog.h"
+
#define LINE_MAX 4096
// Some not so nice things about this:
@@ -86,12 +88,17 @@ char* get_link_components(char* start, char** out_text, char** out_loc, size_t*
size_t link_loc_len = closing_rnd_bracket - closing_sqr_bracket - 2;
char* link_text = calloc(link_text_len + 1, 1);
+ if(link_text == NULL) {
+ jb_log(LL_ERR, true, "calloc error");
+ return NULL;
+ }
char* link_loc = calloc(link_loc_len + 1, 1);
-
- if(link_text == NULL || link_loc == NULL) {
- perror("calloc error");
+ if(link_text == NULL) {
+ jb_log(LL_ERR, true, "calloc error");
+ free(link_text);
return NULL;
}
+
memcpy(link_text, start + 1, link_text_len);
memcpy(link_loc, closing_sqr_bracket + 2, link_loc_len);
@@ -296,8 +303,9 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
header_depth,
trimmed_title,
header_depth
- ) > LINE_MAX) {
- fprintf(stderr, "Title too long");
+ ) > LINE_MAX)
+ {
+ jb_log(LL_WARN, false, "Title too long");
return -1;
}
line_length = append(line_buffer, title);
@@ -506,7 +514,7 @@ int parse_markdown(char* input, char* buffer, size_t buffer_size) {
line_length = prepend(line_buffer, pre_line_buffer);
if(offset + line_length > buffer_size) {
- fprintf(stderr, "Too long!\n");
+ jb_log(LL_WARN, false, "too long");
return -1;
}
diff --git a/readme.html b/readme.html
index 4d4d0ca..2547dc1 100644
--- a/readme.html
+++ b/readme.html
@@ -15,6 +15,9 @@
<li><b>-a</b> admin save directory (optional)</li>
<li><b>-u</b> user the process will use (optional)</li>
<li><b>-g</b> group the pocess will use (optional)</li>
+ <li><b>-d</b> run as a daemon (optional)</li>
+ <li><b>-l</b> log file (optional)</li>
+ <li><b>-r</b> pid file (defaults to /run/jblog.pid)(optional)</li>
</ol>
<p>After you did that, start the webserver, make sure the config file of the webserver has a valid user and points to the right socket!</p>
<h3>The pattern file</h3>
Jeremias Stotters git repositories generated by CGIT