Index: src/common.c =================================================================== --- src/common.c +++ src/common.c 2009-07-26 04:00:42.000000000 +0200 @@ -26,6 +26,7 @@ #include <string.h> #include <ctype.h> #include <fcntl.h> +#include <errno.h> #ifdef WINDOWS32 #include <winsock2.h> @@ -165,6 +166,26 @@ } void +do_pidfile(char *pidfile) +{ +#ifndef WINDOWS32 + FILE *file; + + if ((file = fopen(pidfile, "w")) == NULL) { + fprintf(stderr, "Unable to open \"%s\" for writing: %s", pidfile, strerror(errno)); + err(1, "do_pidfile"); + } else { + fprintf(file, "%d\n", (int)getpid()); + fclose(file); + } + + +#else + fprintf(stderr, "Windows version does not support writing the process id to a file\n"); +#endif +} + +void do_detach() { #ifndef WINDOWS32 Index: src/common.h =================================================================== --- src/common.h +++ src/common.h 2009-07-26 03:47:24.000000000 +0200 @@ -83,6 +83,7 @@ void do_chroot(char *); void do_detach(); +void do_pidfile(char *); void read_password(char*, size_t); Index: src/iodine.c =================================================================== --- src/iodine.c +++ src/iodine.c 2009-07-26 03:47:02.000000000 +0200 @@ -958,7 +958,7 @@ extern char *__progname; fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] " - "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname); + "[-P password] [-m maxfragsize] [-p pidfile] [nameserver] topdomain\n", __progname); exit(2); } @@ -968,7 +968,7 @@ fprintf(stderr, "iodine IP over DNS tunneling client\n"); fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] " - "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname); + "[-P password] [-m maxfragsize] [-F pidfile] [nameserver] topdomain\n", __progname); fprintf(stderr, " -v to print version info and exit\n"); fprintf(stderr, " -h to print this help and exit\n"); fprintf(stderr, " -f to keep running in foreground\n"); @@ -977,6 +977,7 @@ fprintf(stderr, " -d device to set tunnel device name\n"); fprintf(stderr, " -P password used for authentication (max 32 chars will be used)\n"); fprintf(stderr, " -m maxfragsize, to limit size of downstream packets\n"); + fprintf(stderr, " -F pidfile to write pid to a file\n"); fprintf(stderr, "nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n"); fprintf(stderr, "topdomain is the FQDN that is delegated to the tunnel endpoint.\n"); @@ -1007,6 +1008,7 @@ int dns_fd; int max_downstream_frag_size; int autodetect_frag_size; + char *pidfile; memset(password, 0, 33); username = NULL; @@ -1014,6 +1016,7 @@ newroot = NULL; device = NULL; chunkid = 0; + pidfile = NULL; outpkt.seqno = 0; inpkt.len = 0; @@ -1036,7 +1039,7 @@ __progname++; #endif - while ((choice = getopt(argc, argv, "vfhu:t:d:P:m:")) != -1) { + while ((choice = getopt(argc, argv, "vfhu:t:d:P:m:F:")) != -1) { switch(choice) { case 'v': version(); @@ -1069,6 +1072,9 @@ autodetect_frag_size = 0; max_downstream_frag_size = atoi(optarg); break; + case 'F': + pidfile = optarg; + break; default: usage(); /* NOTREACHED */ @@ -1148,6 +1154,9 @@ if (foreground == 0) do_detach(); + if (pidfile != NULL) + do_pidfile(pidfile); + if (newroot != NULL) do_chroot(newroot); Index: src/iodined.c =================================================================== --- src/iodined.c +++ src/iodined.c 2009-07-26 14:24:32.000000000 +0200 @@ -892,7 +892,7 @@ fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] " "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]" - " tunnel_ip[/netmask] topdomain\n", __progname); + "[-F pidfile] tunnel_ip[/netmask] topdomain\n", __progname); exit(2); } @@ -904,7 +904,7 @@ fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] " "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]" - " tunnel_ip[/netmask] topdomain\n", __progname); + "[-F pidfile] tunnel_ip[/netmask] topdomain\n", __progname); fprintf(stderr, " -v to print version info and exit\n"); fprintf(stderr, " -h to print this help and exit\n"); fprintf(stderr, " -c to disable check of client IP/port on each request\n"); @@ -922,6 +922,7 @@ fprintf(stderr, " -n ip to respond with to NS queries\n"); fprintf(stderr, " -b port to forward normal DNS queries to (on localhost)\n"); fprintf(stderr, " -P password used for authentication (max 32 chars will be used)\n"); + fprintf(stderr, " -F pidfile to write pid to a file\n"); fprintf(stderr, "tunnel_ip is the IP number of the local tunnel interface.\n"); fprintf(stderr, " /netmask sets the size of the tunnel network.\n"); fprintf(stderr, "topdomain is the FQDN that is delegated to this server.\n"); @@ -960,6 +961,7 @@ int mtu; int skipipconfig; char *netsize; + char *pidfile; username = NULL; newroot = NULL; @@ -975,6 +977,7 @@ skipipconfig = 0; debug = 0; netmask = 27; + pidfile = NULL; b32 = get_base32_encoder(); @@ -994,7 +997,7 @@ srand(time(NULL)); fw_query_init(); - while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:")) != -1) { + while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:F:")) != -1) { switch(choice) { case 'v': version(); @@ -1039,6 +1042,9 @@ bind_enable = 1; bind_port = atoi(optarg); break; + case 'F': + pidfile = optarg; + break; case 'P': strncpy(password, optarg, sizeof(password)); password[sizeof(password)-1] = 0; @@ -1165,7 +1171,10 @@ if (foreground == 0) do_detach(); - + + if (pidfile != NULL) + do_pidfile(pidfile); + if (newroot != NULL) do_chroot(newroot);