#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" pid_t fork_proc() { /* Fork off the parent. */ pid_t pid = fork(); /* The process id is non zero, so it must be the parent process. */ if (pid) { /* Exit with EXIT_FAILURE if the parent's pid is * negative, otherwise exit with EXIT_SUCCESS. */ exit((pid < 0) ? EXIT_FAILURE : EXIT_SUCCESS); } return pid; } void child_handler(int sig_num) { signal(SIGCHLD, child_handler); } void hangup_handler(int sig_num) { signal(SIGHUP, hangup_handler); } void init_daemon(int change_dir, char *path) { /* Fork the parent. */ pid_t pid = fork_proc(); /* Exit if the child process isn't the session leader. */ if (setsid() < 0) { exit(EXIT_FAILURE); } /* Catch, ignore, and/or handle signals. */ signal(SIGCHLD, child_handler); signal(SIGHUP, hangup_handler); /* Fork again. */ pid = fork_proc(); /* Set new file permissions. */ umask(0); /* If change_dir is true, change the working directory to path, or * the root directory if path isn't set. */ if (change_dir) { chdir((!path) ? "/" : path); } /* Close any open file descriptors. */ for (int i = sysconf(_SC_OPEN_MAX); i >= 0; close(i--)); /* Open the logfile. */ openlog("pullreqd", LOG_PID, LOG_DAEMON); } int init_config(char *config_file, config **cfg) { syslog(LOG_INFO, "Reading config file %s.", config_file); *cfg = parse_config(config_file); /* Did the config file parser succeed? */ if (*cfg != NULL) { syslog(LOG_INFO, "Successfully read %s.", config_file); } else { syslog(LOG_ERR, "Error reading %s.", config_file); } return (*cfg != NULL); } int init_socket(config *cfg) { union sock_addr { struct sockaddr sa; struct sockaddr_un sa_un; struct sockaddr_in sa_in; } sock_addr; /* Set socket type to unix socket, if socket-type was set to unix, otherwise set it to network socket. */ const int sock_type = (!strcasecmp(cfg->sock_type, "unix")) ? AF_UNIX : AF_INET; /* Create a new listen socket. */ int fd = socket(sock_type, SOCK_SEQPACKET, 0); /* TODO: Add rest of init code. */ if (sock_type == AF_UNIX) { } return fd; } int main_loop(config *cfg, int listen_socket) { int done = 0; for (; !done;) { break; } return 0; } void cleanup(config *cfg, int listen_socket) { if (listen_socket > 0) { close(listen_socket); /* Is this a unix domain socket? */ if (!strcasecmp(cfg->sock_type, "unix")) { unlink(cfg->sock); } } if (cfg) { cleanup_config(cfg); } } int main(int argc, char **argv) { config *cfg; char *config_file = "test.conf"; int config_read = 0; int listen_socket = -1; int exit_status = EXIT_FAILURE; init_daemon(1, "/"); syslog(LOG_NOTICE, "pullreqd started."); /* Read the config file. */ config_read = init_config(config_file, &cfg); /* Did we successfully read the config file? */ if (config_read) { /* Create the Listen socket. */ listen_socket = init_socket(cfg); } /* Did we successfully read the config file, and create the listen socket? */ if (config_read && listen_socket >= 0) { exit_status = main_loop(cfg, listen_socket); } cleanup(cfg, listen_socket); syslog(LOG_NOTICE, "pullreqd stopped."); closelog(); return exit_status; }