- basic port listening functionality (prototyping)
This commit is contained in:
		
							
								
								
									
										113
									
								
								fsipd.c
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								fsipd.c
									
									
									
									
									
								
							| @ -30,10 +30,8 @@ | |||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| #include <sys/file.h> | #include <sys/file.h> | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| #include <net/if.h> | #include <netdb.h> | ||||||
| #include <net/if_var.h> | #include <netinet/in.h> | ||||||
| #include <net/if_types.h> |  | ||||||
| #include <ifaddrs.h> |  | ||||||
|  |  | ||||||
| #include <err.h> | #include <err.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| @ -46,10 +44,16 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <sysexits.h> | #include <sysexits.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | #include <syslog.h> | ||||||
| #include <libutil.h> | #include <libutil.h> | ||||||
|  |  | ||||||
|  | #define	PORT 5060 | ||||||
|  | #define BACKLOG 1024 | ||||||
|  |  | ||||||
| /* Globals */ | /* Globals */ | ||||||
| struct pidfh *pfh; | struct pidfh *pfh; | ||||||
|  | struct sockaddr_in sa; | ||||||
|  | struct protoent *proto_tcp, *proto_udp; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Prepare for a clean shutdown |  * Prepare for a clean shutdown | ||||||
| @ -69,6 +73,7 @@ signal_handler(int sig) | |||||||
| 	switch (sig) { | 	switch (sig) { | ||||||
|  |  | ||||||
| 	case SIGHUP: | 	case SIGHUP: | ||||||
|  | 		break; | ||||||
| 	case SIGINT: | 	case SIGINT: | ||||||
| 	case SIGTERM: | 	case SIGTERM: | ||||||
| 		daemon_shutdown(); | 		daemon_shutdown(); | ||||||
| @ -79,6 +84,13 @@ 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 |  * Daemonize and persist pid | ||||||
|  */ |  */ | ||||||
| @ -88,16 +100,12 @@ daemon_start() | |||||||
| 	struct sigaction sig_action; | 	struct sigaction sig_action; | ||||||
| 	sigset_t sig_set; | 	sigset_t sig_set; | ||||||
| 	pid_t otherpid; | 	pid_t otherpid; | ||||||
|  | 	int curPID; | ||||||
|  | 	register int s, c; | ||||||
|  | 	unsigned int b; | ||||||
|  | 	FILE *client; | ||||||
|  | 	char inputstr[8192]; | ||||||
|  |  | ||||||
| 	char *no_fork = getenv("no_fork"); |  | ||||||
|  |  | ||||||
| 	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); |  | ||||||
| 		} |  | ||||||
| 	/* Check if we can acquire the pid file */ | 	/* Check if we can acquire the pid file */ | ||||||
| 	pfh = pidfile_open(NULL, 0600, &otherpid); | 	pfh = pidfile_open(NULL, 0600, &otherpid); | ||||||
|  |  | ||||||
| @ -107,12 +115,40 @@ daemon_start() | |||||||
| 		} | 		} | ||||||
| 		warn("Cannot open or create pidfile."); | 		warn("Cannot open or create pidfile."); | ||||||
| 	} | 	} | ||||||
| 		/* fork ourselves if not asked otherwise */ |  | ||||||
| 		if (fork()) { | 	/* 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); | 		return (EXIT_SUCCESS); | ||||||
| 	} | 	} | ||||||
| 		/* we are the child, complete the daemonization */ |  | ||||||
|  |  | ||||||
|  | 	/* we are the child, complete the daemonization */ | ||||||
| 	/* Close standard IO */ | 	/* Close standard IO */ | ||||||
| 	fclose(stdin); | 	fclose(stdin); | ||||||
| 	fclose(stdout); | 	fclose(stdout); | ||||||
| @ -120,14 +156,13 @@ daemon_start() | |||||||
|  |  | ||||||
| 	/* Block unnecessary signals */ | 	/* Block unnecessary signals */ | ||||||
| 	sigemptyset(&sig_set); | 	sigemptyset(&sig_set); | ||||||
| 		sigaddset(&sig_set, SIGCHLD);	/* ignore child - i.e. we | 	sigaddset(&sig_set, SIGCHLD);	/* ignore child - i.e. we don't need | ||||||
| 						 * don't need to wait for it */ | 					 * to wait for it */ | ||||||
| 	sigaddset(&sig_set, SIGTSTP);	/* ignore Tty stop signals */ | 	sigaddset(&sig_set, SIGTSTP);	/* ignore Tty stop signals */ | ||||||
| 		sigaddset(&sig_set, SIGTTOU);	/* ignore Tty background | 	sigaddset(&sig_set, SIGTTOU);	/* ignore Tty background writes */ | ||||||
| 						 * writes */ |  | ||||||
| 	sigaddset(&sig_set, SIGTTIN);	/* ignore Tty background reads */ | 	sigaddset(&sig_set, SIGTTIN);	/* ignore Tty background reads */ | ||||||
| 		sigprocmask(SIG_BLOCK, &sig_set, NULL);	/* Block the above | 	sigprocmask(SIG_BLOCK, &sig_set, NULL);	/* Block the above specified | ||||||
| 							 * specified signals */ | 						 * signals */ | ||||||
|  |  | ||||||
| 	/* Catch necessary signals */ | 	/* Catch necessary signals */ | ||||||
| 	sig_action.sa_handler = signal_handler; | 	sig_action.sa_handler = signal_handler; | ||||||
| @ -144,27 +179,35 @@ daemon_start() | |||||||
| 	/* persist pid */ | 	/* persist pid */ | ||||||
| 	pidfile_write(pfh); | 	pidfile_write(pfh); | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* TODO: Network Logic Here */ | 	/* TODO: Network Logic Here */ | ||||||
|  |  | ||||||
|  | 	listen(s, BACKLOG); | ||||||
|  |  | ||||||
| 	while (1) { | 	while (1) { | ||||||
|  |  | ||||||
| 		sleep(5); | 		b = sizeof(sa); | ||||||
|  | 		if ((c = accept(s, (struct sockaddr *)&sa, &b)) < 0) { | ||||||
|  | 			perror("accept"); | ||||||
|  | 			return (EXIT_FAILURE); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	return (0); | 		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 | int | ||||||
| main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||||
| { | { | ||||||
| 	if (argc > 1) { | 	return (daemon_start()); | ||||||
| 		char *first_arg = argv[1]; |  | ||||||
|  |  | ||||||
| 		if (!strcmp(first_arg, "start")) { |  | ||||||
| 			return daemon_start(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return (EXIT_SUCCESS); |  | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user