You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
3.6 KiB
C

#include "process.h"
#include "model/server.h"
#include "controller/main.h"
#include "controller/inbox.h"
#include "controller/outbox.h"
#include "controller/test.h"
#include "controller/indexer.h"
#include "controller/fetch.h"
#include "tor.h"
#include "collections/array.h"
#include "http/server/server.h"
#include "http/server/request.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
struct process
{
pid_t pid;
int section;
};
struct {
struct process** items;
int count;
} process_list;
extern bool terminate;
static void handle_request( struct http_request* req, void* )
{
//printf( "Handling request from %s\n", http_request_get_remote_host_address( req ) );
if( !route_request( req ) ) {
FILE* f = http_request_get_response_body( req );
http_request_send_headers( req, 404, "text/html", true );
#include "view/404.html.inc"
}
fflush(stdout);
}
static bool run_webserver( struct app_args* args )
{
struct http_server* srv = http_server_new( args, handle_request, NULL );
if( !srv ) {
printf( "Error setting up server\n" );
return false;
}
http_server_set_debug( srv, args->debug );
while(!terminate) {
http_server_process( srv );
usleep(25000);
}
http_server_release( srv );
return true;
}
void develop();
int process_run_section( int id )
{
printf( "Starting section %d\n", id );
switch( id ) {
case 0:
return !run_webserver( g_server );
case 1:
process_inbox();
return EXIT_SUCCESS;
case 2:
process_outbox();
return EXIT_SUCCESS;
case 3:
built_in_test();
return EXIT_SUCCESS;
case 4:
reindex();
return EXIT_SUCCESS;
case 5:
process_fetch();
return EXIT_SUCCESS;
case 6:
start_tor();
return EXIT_SUCCESS;
case 100:
develop();
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
static void redirect_io( int section )
{
const char* filename = NULL;
switch( section ) {
case 0: filename = "data/logs/webserver.log"; break;
case 1: filename = "data/logs/inbox.log"; break;
case 2: filename = "data/logs/outbox.log"; break;
case 5: filename = "data/logs/fetch.log"; break;
case 6: filename = "data/logs/tor.log"; break;
}
if( !filename ) { return; }
int log = open( filename, O_CREAT | O_RDWR | O_APPEND, 0644 );
if( !log ) {
printf( "Unable to redirect I/O to log file %s: %s\n", filename, strerror(errno) );
return;
}
dup2( log, 1 );
dup2( log, 2 );
close( log );
}
void process_start_section( int id )
{
printf( "Starting section %d\n", id );
pid_t child_pid;
child_pid = fork();
if( child_pid ) {
// Parent
if( child_pid == -1 ) {
printf( "Failed to fork child process\n" );
return;
}
struct process* child;
child = malloc(sizeof(*child));
memset(child,0,sizeof(*child));
child->pid = child_pid;
child->section = id;
array_append( &process_list, sizeof(child), &child );
} else {
redirect_io( id );
// Child
exit( process_run_section(id) );
}
}
void process_stop()
{
}
void process_wait_for_finished()
{
while( !terminate ) {
usleep(100000); // sleep for 100ms
for( int i = 0; i < process_list.count; ++i ) {
struct process* child = process_list.items[i];
int status;
pid_t result = waitpid( child->pid, &status, WNOHANG );
if( result == child->pid ) {
int section = child->section;
printf( "Child process %d exited\n", child->pid );
array_delete( &process_list, sizeof(child), &child );
i -= 1;
if( !terminate ) {
// TODO: restart child process
printf( "Restarting...\n" );
process_start_section( section );
}
}
}
}
}