diff --git a/fsipd.c b/fsipd.c index dc88018..a492368 100644 --- a/fsipd.c +++ b/fsipd.c @@ -30,10 +30,8 @@ #include #include #include -#include -#include -#include -#include +#include +#include #include #include @@ -46,15 +44,21 @@ #include #include #include +#include #include +#define PORT 5060 +#define BACKLOG 1024 + /* Globals */ struct pidfh *pfh; +struct sockaddr_in sa; +struct protoent *proto_tcp, *proto_udp; /* * Prepare for a clean shutdown */ -void +void daemon_shutdown() { pidfile_remove(pfh); @@ -63,12 +67,13 @@ daemon_shutdown() /* * Act upon receiving signals */ -void +void signal_handler(int sig) { switch (sig) { case SIGHUP: + break; case SIGINT: case SIGTERM: daemon_shutdown(); @@ -79,92 +84,130 @@ signal_handler(int sig) } } +void +process_request(char *str) +{ + /* check input str for SIP requests */ + syslog(LOG_ALERT, "incoming packet: %s\n", str); +} + /* * Daemonize and persist pid */ -int +int daemon_start() { struct sigaction sig_action; sigset_t sig_set; pid_t otherpid; + int curPID; + register int s, c; + unsigned int b; + FILE *client; + char inputstr[8192]; - char *no_fork = getenv("no_fork"); + /* Check if we can acquire the pid file */ + pfh = pidfile_open(NULL, 0600, &otherpid); - if (!no_fork || strcmp("1", no_fork)) { - - /* Check if parent process id is set */ - if (getppid() == 1) { - /* PPID exists, therefore we are already a daemon */ - return (EXIT_FAILURE); + if (pfh == NULL) { + if (errno == EEXIST) { + errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", (intmax_t)otherpid); } - /* Check if we can acquire the pid file */ - pfh = pidfile_open(NULL, 0600, &otherpid); - - if (pfh == NULL) { - if (errno == EEXIST) { - errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", (intmax_t)otherpid); - } - warn("Cannot open or create pidfile."); - } - /* fork ourselves if not asked otherwise */ - if (fork()) { - return (EXIT_SUCCESS); - } - /* we are the child, complete the daemonization */ - - /* Close standard IO */ - fclose(stdin); - fclose(stdout); - fclose(stderr); - - /* Block unnecessary signals */ - sigemptyset(&sig_set); - sigaddset(&sig_set, SIGCHLD); /* ignore child - i.e. we - * don't need to wait for it */ - sigaddset(&sig_set, SIGTSTP); /* ignore Tty stop signals */ - sigaddset(&sig_set, SIGTTOU); /* ignore Tty background - * writes */ - sigaddset(&sig_set, SIGTTIN); /* ignore Tty background reads */ - sigprocmask(SIG_BLOCK, &sig_set, NULL); /* Block the above - * specified signals */ - - /* Catch necessary signals */ - sig_action.sa_handler = signal_handler; - sigemptyset(&sig_action.sa_mask); - sig_action.sa_flags = 0; - - sigaction(SIGTERM, &sig_action, NULL); - sigaction(SIGHUP, &sig_action, NULL); - sigaction(SIGINT, &sig_action, NULL); - - /* create new session and process group */ - setsid(); - - /* persist pid */ - pidfile_write(pfh); - + warn("Cannot open or create pidfile."); } + /* setup socket */ + if ((proto_tcp = getprotobyname("tcp")) == NULL) + return -1; + + bzero(&sa, sizeof(sa)); + sa.sin_port = htons(PORT); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + + if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return EXIT_FAILURE; + } + + if (bind(s, (struct sockaddr *)&sa, sizeof sa) < 0) { + perror("bind"); + return EXIT_FAILURE; + } + + /* start daemonizing */ + curPID = fork(); + + switch (curPID) { + case 0: /* This process is the child */ + break; + case -1: /* fork() failed, should exit */ + perror("fork"); + return (EXIT_FAILURE); + default: /* fork() successful, should exit */ + return (EXIT_SUCCESS); + } + + /* we are the child, complete the daemonization */ + /* Close standard IO */ + fclose(stdin); + fclose(stdout); + fclose(stderr); + + /* Block unnecessary signals */ + sigemptyset(&sig_set); + sigaddset(&sig_set, SIGCHLD); /* ignore child - i.e. we don't need + * to wait for it */ + sigaddset(&sig_set, SIGTSTP); /* ignore Tty stop signals */ + sigaddset(&sig_set, SIGTTOU); /* ignore Tty background writes */ + sigaddset(&sig_set, SIGTTIN); /* ignore Tty background reads */ + sigprocmask(SIG_BLOCK, &sig_set, NULL); /* Block the above specified + * signals */ + + /* Catch necessary signals */ + sig_action.sa_handler = signal_handler; + sigemptyset(&sig_action.sa_mask); + sig_action.sa_flags = 0; + + sigaction(SIGTERM, &sig_action, NULL); + sigaction(SIGHUP, &sig_action, NULL); + sigaction(SIGINT, &sig_action, NULL); + + /* create new session and process group */ + setsid(); + + /* persist pid */ + pidfile_write(pfh); + /* TODO: Network Logic Here */ + + listen(s, BACKLOG); + while (1) { - sleep(5); - - } - - return (0); -} - -int -main(int argc, char *argv[]) -{ - if (argc > 1) { - char *first_arg = argv[1]; - - if (!strcmp(first_arg, "start")) { - return daemon_start(); + b = sizeof(sa); + if ((c = accept(s, (struct sockaddr *)&sa, &b)) < 0) { + perror("accept"); + return (EXIT_FAILURE); } + + if ((client = fdopen(c, "w")) == NULL) { + perror("fdopen"); + return (EXIT_FAILURE); + } + + fgets(inputstr, sizeof(inputstr), client); + + process_request(inputstr); + + fclose(client); } + return (EXIT_SUCCESS); } + +int +main(int argc, char *argv[]) +{ + return (daemon_start()); +}