summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2009-08-16 19:08:56 +0200
committerGravatar Hector Martin2009-08-16 21:50:48 +0200
commita63578e2d71ae304f6f405b5bb491547f43b79ac (patch)
tree9ff375d8c4557430606030a6facd6d93e3ff502e
parenta82a04f2c12b5ac5da8f9cb16c17ed4c4f6402a7 (diff)
downloadusbmuxd-a63578e2d71ae304f6f405b5bb491547f43b79ac.tar.gz
usbmuxd-a63578e2d71ae304f6f405b5bb491547f43b79ac.tar.bz2
Implemented option handling providing daemonization, verbosity, and logging to syslog
-rw-r--r--usbmuxd/log.c35
-rw-r--r--usbmuxd/log.h3
-rw-r--r--usbmuxd/main.c122
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;