diff options
| -rw-r--r-- | usbmuxd/log.c | 35 | ||||
| -rw-r--r-- | usbmuxd/log.h | 3 | ||||
| -rw-r--r-- | usbmuxd/main.c | 122 | 
3 files changed, 157 insertions, 3 deletions
| diff --git a/usbmuxd/log.c b/usbmuxd/log.c index a70120b..4f67e85 100644 --- a/usbmuxd/log.c +++ b/usbmuxd/log.c @@ -28,10 +28,37 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  #include <stdarg.h>  #include <time.h>  #include <sys/time.h> +#include <syslog.h>  #include "log.h" -int log_level = LL_INFO; +int log_level = LL_FATAL; + +int log_syslog = 0; + +void log_enable_syslog() +{ +	if (!log_syslog) { +		openlog("usbmuxd", LOG_PID, 0); +		log_syslog = 1; +	} +} + +void log_disable_syslog() +{ +	if (log_syslog) { +		closelog(); +	} +} + +static int level_to_syslog_level(int level) +{ +	int result = level + LOG_CRIT; +	if (result > LOG_DEBUG) { +		result = LOG_DEBUG; +	} +	return result; +}  void usbmuxd_log(enum loglevel level, const char *fmt, ...)  { @@ -51,7 +78,11 @@ void usbmuxd_log(enum loglevel level, const char *fmt, ...)  	sprintf(fs+9, ".%03d][%d] %s\n", (int)(ts.tv_usec / 1000), level, fmt);  	va_start(ap, fmt); -	vfprintf(stderr, fs, ap); +	if (log_syslog) { +		vsyslog(level_to_syslog_level(level), fs, ap); +	} else { +		vfprintf(stderr, fs, ap); +	}  	va_end(ap);  	free(fs); diff --git a/usbmuxd/log.h b/usbmuxd/log.h index f6eb5c1..4a2ac2e 100644 --- a/usbmuxd/log.h +++ b/usbmuxd/log.h @@ -34,6 +34,9 @@ enum loglevel {  extern int log_level; +void log_enable_syslog(); +void log_disable_syslog(); +  void usbmuxd_log(enum loglevel level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/usbmuxd/main.c b/usbmuxd/main.c index 90f7f22..3318ecd 100644 --- a/usbmuxd/main.c +++ b/usbmuxd/main.c @@ -33,17 +33,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  #include <sys/socket.h>  #include <sys/un.h>  #include <sys/stat.h> +#include <getopt.h>  #include "log.h"  #include "usb.h"  #include "device.h"  #include "client.h" -static const char *socket_path = "/var/run/usbmuxd"; //TODO: CHANGEME +static const char *socket_path = "/var/run/usbmuxd";  int should_exit;  struct sigaction sa_old; +static int verbose = 0; +static int foreground = 0; +  int create_socket(void) {  	struct sockaddr_un bind_addr;  	int listenfd; @@ -163,11 +167,116 @@ int main_loop(int listenfd)  	return 0;  } +/** + * make this program run detached from the current console + */ +static int daemonize() +{ +	pid_t pid; +	pid_t sid; + +	// already a daemon +	if (getppid() == 1) +		return 0; + +	pid = fork(); +	if (pid < 0) { +		exit(EXIT_FAILURE); +	} + +	if (pid > 0) { +		// exit parent process +		exit(EXIT_SUCCESS); +	} +	// At this point we are executing as the child process + +	// Change the file mode mask +	umask(0); + +	// Create a new SID for the child process +	sid = setsid(); +	if (sid < 0) { +		return -1; +	} +	// Change the current working directory. +	if ((chdir("/")) < 0) { +		return -2; +	} +	// Redirect standard files to /dev/null +	if (!freopen("/dev/null", "r", stdin)) { +		usbmuxd_log(LL_ERROR, "ERROR: redirection of stdin failed."); +	} +	if (!freopen("/dev/null", "w", stdout)) { +		usbmuxd_log(LL_ERROR, "ERROR: redirection of stdout failed."); +	} +	if (!freopen("/dev/null", "w", stderr)) { +		usbmuxd_log(LL_ERROR, "ERROR: redirection of stderr failed."); +	} + +	return 0; +} + +static void usage() +{ +	printf("usage: usbmuxd [options]\n"); +	printf("\t-h|--help                 Print this message.\n"); +	printf("\t-v|--verbose              Be verbose (use twice or more to increase).\n"); +	printf("\t-f|--foreground           Do not daemonize (implies a verbosity of 4).\n"); +	printf("\n"); +} + +static void parse_opts(int argc, char **argv) +{ +	static struct option longopts[] = { +		{"help", 0, NULL, 'h'}, +		{"foreground", 0, NULL, 'f'}, +		{"verbose", 0, NULL, 'v'}, +		{NULL, 0, NULL, 0} +	}; +	int c; + +	while (1) { +		c = getopt_long(argc, argv, "hfv", longopts, (int *) 0); +		if (c == -1) { +			break; +		} + +		switch (c) { +		case 'h': +			usage(); +			exit(0); +		case 'f': +			foreground = 1; +			break; +		case 'v': +			++verbose; +			break; +		default: +			usage(); +			exit(2); +		} +	} +} +  int main(int argc, char *argv[])  {  	int listenfd;  	int res; +	parse_opts(argc, argv); + +	argc -= optind; +	argv += optind; + +	if (!foreground) { +		log_enable_syslog(); +	} else { +		verbose += LL_INFO; +	} + +	/* set log level to specified verbosity */ +	log_level = verbose; +  	usbmuxd_log(LL_NOTICE, "usbmux v0.1 starting up");  	should_exit = 0; @@ -187,6 +296,15 @@ int main(int argc, char *argv[])  	usbmuxd_log(LL_NOTICE, "Initialization complete"); +	if (!foreground) { +		if (daemonize() < 0) { +			fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n"); +			usbmuxd_log(LL_ERROR, "FATAL: Could not daemonize!"); +			log_disable_syslog(); +			exit(EXIT_FAILURE); +		} +	} +	  	res = main_loop(listenfd);  	if(res < 0)  		usbmuxd_log(LL_FATAL, "main_loop failed"); @@ -198,6 +316,8 @@ int main(int argc, char *argv[])  	client_shutdown();  	usbmuxd_log(LL_NOTICE, "Shutdown complete"); +	log_disable_syslog(); +  	if(res < 0)  		return -res;  	return 0; | 
