diff options
| author | 2009-08-16 19:08:56 +0200 | |
|---|---|---|
| committer | 2009-08-16 21:50:48 +0200 | |
| commit | a63578e2d71ae304f6f405b5bb491547f43b79ac (patch) | |
| tree | 9ff375d8c4557430606030a6facd6d93e3ff502e | |
| parent | a82a04f2c12b5ac5da8f9cb16c17ed4c4f6402a7 (diff) | |
| download | usbmuxd-a63578e2d71ae304f6f405b5bb491547f43b79ac.tar.gz usbmuxd-a63578e2d71ae304f6f405b5bb491547f43b79ac.tar.bz2 | |
Implemented option handling providing daemonization, verbosity, and logging to syslog
| -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 | |||
| 28 | #include <stdarg.h> | 28 | #include <stdarg.h> |
| 29 | #include <time.h> | 29 | #include <time.h> |
| 30 | #include <sys/time.h> | 30 | #include <sys/time.h> |
| 31 | #include <syslog.h> | ||
| 31 | 32 | ||
| 32 | #include "log.h" | 33 | #include "log.h" |
| 33 | 34 | ||
| 34 | int log_level = LL_INFO; | 35 | int log_level = LL_FATAL; |
| 36 | |||
| 37 | int log_syslog = 0; | ||
| 38 | |||
| 39 | void log_enable_syslog() | ||
| 40 | { | ||
| 41 | if (!log_syslog) { | ||
| 42 | openlog("usbmuxd", LOG_PID, 0); | ||
| 43 | log_syslog = 1; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void log_disable_syslog() | ||
| 48 | { | ||
| 49 | if (log_syslog) { | ||
| 50 | closelog(); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | static int level_to_syslog_level(int level) | ||
| 55 | { | ||
| 56 | int result = level + LOG_CRIT; | ||
| 57 | if (result > LOG_DEBUG) { | ||
| 58 | result = LOG_DEBUG; | ||
| 59 | } | ||
| 60 | return result; | ||
| 61 | } | ||
| 35 | 62 | ||
| 36 | void usbmuxd_log(enum loglevel level, const char *fmt, ...) | 63 | void usbmuxd_log(enum loglevel level, const char *fmt, ...) |
| 37 | { | 64 | { |
| @@ -51,7 +78,11 @@ void usbmuxd_log(enum loglevel level, const char *fmt, ...) | |||
| 51 | sprintf(fs+9, ".%03d][%d] %s\n", (int)(ts.tv_usec / 1000), level, fmt); | 78 | sprintf(fs+9, ".%03d][%d] %s\n", (int)(ts.tv_usec / 1000), level, fmt); |
| 52 | 79 | ||
| 53 | va_start(ap, fmt); | 80 | va_start(ap, fmt); |
| 54 | vfprintf(stderr, fs, ap); | 81 | if (log_syslog) { |
| 82 | vsyslog(level_to_syslog_level(level), fs, ap); | ||
| 83 | } else { | ||
| 84 | vfprintf(stderr, fs, ap); | ||
| 85 | } | ||
| 55 | va_end(ap); | 86 | va_end(ap); |
| 56 | 87 | ||
| 57 | free(fs); | 88 | 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 { | |||
| 34 | 34 | ||
| 35 | extern int log_level; | 35 | extern int log_level; |
| 36 | 36 | ||
| 37 | void log_enable_syslog(); | ||
| 38 | void log_disable_syslog(); | ||
| 39 | |||
| 37 | void usbmuxd_log(enum loglevel level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); | 40 | void usbmuxd_log(enum loglevel level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); |
| 38 | 41 | ||
| 39 | 42 | ||
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 | |||
| 33 | #include <sys/socket.h> | 33 | #include <sys/socket.h> |
| 34 | #include <sys/un.h> | 34 | #include <sys/un.h> |
| 35 | #include <sys/stat.h> | 35 | #include <sys/stat.h> |
| 36 | #include <getopt.h> | ||
| 36 | 37 | ||
| 37 | #include "log.h" | 38 | #include "log.h" |
| 38 | #include "usb.h" | 39 | #include "usb.h" |
| 39 | #include "device.h" | 40 | #include "device.h" |
| 40 | #include "client.h" | 41 | #include "client.h" |
| 41 | 42 | ||
| 42 | static const char *socket_path = "/var/run/usbmuxd"; //TODO: CHANGEME | 43 | static const char *socket_path = "/var/run/usbmuxd"; |
| 43 | int should_exit; | 44 | int should_exit; |
| 44 | 45 | ||
| 45 | struct sigaction sa_old; | 46 | struct sigaction sa_old; |
| 46 | 47 | ||
| 48 | static int verbose = 0; | ||
| 49 | static int foreground = 0; | ||
| 50 | |||
| 47 | int create_socket(void) { | 51 | int create_socket(void) { |
| 48 | struct sockaddr_un bind_addr; | 52 | struct sockaddr_un bind_addr; |
| 49 | int listenfd; | 53 | int listenfd; |
| @@ -163,11 +167,116 @@ int main_loop(int listenfd) | |||
| 163 | return 0; | 167 | return 0; |
| 164 | } | 168 | } |
| 165 | 169 | ||
| 170 | /** | ||
| 171 | * make this program run detached from the current console | ||
| 172 | */ | ||
| 173 | static int daemonize() | ||
| 174 | { | ||
| 175 | pid_t pid; | ||
| 176 | pid_t sid; | ||
| 177 | |||
| 178 | // already a daemon | ||
| 179 | if (getppid() == 1) | ||
| 180 | return 0; | ||
| 181 | |||
| 182 | pid = fork(); | ||
| 183 | if (pid < 0) { | ||
| 184 | exit(EXIT_FAILURE); | ||
| 185 | } | ||
| 186 | |||
| 187 | if (pid > 0) { | ||
| 188 | // exit parent process | ||
| 189 | exit(EXIT_SUCCESS); | ||
| 190 | } | ||
| 191 | // At this point we are executing as the child process | ||
| 192 | |||
| 193 | // Change the file mode mask | ||
| 194 | umask(0); | ||
| 195 | |||
| 196 | // Create a new SID for the child process | ||
| 197 | sid = setsid(); | ||
| 198 | if (sid < 0) { | ||
| 199 | return -1; | ||
| 200 | } | ||
| 201 | // Change the current working directory. | ||
| 202 | if ((chdir("/")) < 0) { | ||
| 203 | return -2; | ||
| 204 | } | ||
| 205 | // Redirect standard files to /dev/null | ||
| 206 | if (!freopen("/dev/null", "r", stdin)) { | ||
| 207 | usbmuxd_log(LL_ERROR, "ERROR: redirection of stdin failed."); | ||
| 208 | } | ||
| 209 | if (!freopen("/dev/null", "w", stdout)) { | ||
| 210 | usbmuxd_log(LL_ERROR, "ERROR: redirection of stdout failed."); | ||
| 211 | } | ||
| 212 | if (!freopen("/dev/null", "w", stderr)) { | ||
| 213 | usbmuxd_log(LL_ERROR, "ERROR: redirection of stderr failed."); | ||
| 214 | } | ||
| 215 | |||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static void usage() | ||
| 220 | { | ||
| 221 | printf("usage: usbmuxd [options]\n"); | ||
| 222 | printf("\t-h|--help Print this message.\n"); | ||
| 223 | printf("\t-v|--verbose Be verbose (use twice or more to increase).\n"); | ||
| 224 | printf("\t-f|--foreground Do not daemonize (implies a verbosity of 4).\n"); | ||
| 225 | printf("\n"); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void parse_opts(int argc, char **argv) | ||
| 229 | { | ||
| 230 | static struct option longopts[] = { | ||
| 231 | {"help", 0, NULL, 'h'}, | ||
| 232 | {"foreground", 0, NULL, 'f'}, | ||
| 233 | {"verbose", 0, NULL, 'v'}, | ||
| 234 | {NULL, 0, NULL, 0} | ||
| 235 | }; | ||
| 236 | int c; | ||
| 237 | |||
| 238 | while (1) { | ||
| 239 | c = getopt_long(argc, argv, "hfv", longopts, (int *) 0); | ||
| 240 | if (c == -1) { | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | |||
| 244 | switch (c) { | ||
| 245 | case 'h': | ||
| 246 | usage(); | ||
| 247 | exit(0); | ||
| 248 | case 'f': | ||
| 249 | foreground = 1; | ||
| 250 | break; | ||
| 251 | case 'v': | ||
| 252 | ++verbose; | ||
| 253 | break; | ||
| 254 | default: | ||
| 255 | usage(); | ||
| 256 | exit(2); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 166 | int main(int argc, char *argv[]) | 261 | int main(int argc, char *argv[]) |
| 167 | { | 262 | { |
| 168 | int listenfd; | 263 | int listenfd; |
| 169 | int res; | 264 | int res; |
| 170 | 265 | ||
| 266 | parse_opts(argc, argv); | ||
| 267 | |||
| 268 | argc -= optind; | ||
| 269 | argv += optind; | ||
| 270 | |||
| 271 | if (!foreground) { | ||
| 272 | log_enable_syslog(); | ||
| 273 | } else { | ||
| 274 | verbose += LL_INFO; | ||
| 275 | } | ||
| 276 | |||
| 277 | /* set log level to specified verbosity */ | ||
| 278 | log_level = verbose; | ||
| 279 | |||
| 171 | usbmuxd_log(LL_NOTICE, "usbmux v0.1 starting up"); | 280 | usbmuxd_log(LL_NOTICE, "usbmux v0.1 starting up"); |
| 172 | should_exit = 0; | 281 | should_exit = 0; |
| 173 | 282 | ||
| @@ -187,6 +296,15 @@ int main(int argc, char *argv[]) | |||
| 187 | 296 | ||
| 188 | usbmuxd_log(LL_NOTICE, "Initialization complete"); | 297 | usbmuxd_log(LL_NOTICE, "Initialization complete"); |
| 189 | 298 | ||
| 299 | if (!foreground) { | ||
| 300 | if (daemonize() < 0) { | ||
| 301 | fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n"); | ||
| 302 | usbmuxd_log(LL_ERROR, "FATAL: Could not daemonize!"); | ||
| 303 | log_disable_syslog(); | ||
| 304 | exit(EXIT_FAILURE); | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 190 | res = main_loop(listenfd); | 308 | res = main_loop(listenfd); |
| 191 | if(res < 0) | 309 | if(res < 0) |
| 192 | usbmuxd_log(LL_FATAL, "main_loop failed"); | 310 | usbmuxd_log(LL_FATAL, "main_loop failed"); |
| @@ -198,6 +316,8 @@ int main(int argc, char *argv[]) | |||
| 198 | client_shutdown(); | 316 | client_shutdown(); |
| 199 | usbmuxd_log(LL_NOTICE, "Shutdown complete"); | 317 | usbmuxd_log(LL_NOTICE, "Shutdown complete"); |
| 200 | 318 | ||
| 319 | log_disable_syslog(); | ||
| 320 | |||
| 201 | if(res < 0) | 321 | if(res < 0) |
| 202 | return -res; | 322 | return -res; |
| 203 | return 0; | 323 | return 0; |
