+
+ if (reboot_seconds && ((dev->opened_at + reboot_seconds) <= time(NULL))) {
+ if (verbose) {
+ printf("HM-CFG-USB running since %lu seconds, rebooting now...\n",
+ time(NULL) - dev->opened_at);
+ }
+ hmcfgusb_enter_bootloader(dev);
+ }
+ }
+
+ hmcfgusb_close(dev);
+ return 1;
+}
+
+void sigterm_handler(int sig)
+{
+ if (unlink(PID_FILE) == -1)
+ perror("Can't remove PID file");
+
+ exit(EXIT_SUCCESS);
+}
+
+#define FLAG_DAEMON (1 << 0)
+#define FLAG_PID_FILE (1 << 1)
+
+static int socket_server(char *iface, int port, int flags)
+{
+ struct sigaction sact;
+ struct sockaddr_in sin;
+ int sock;
+ int n;
+ pid_t pid;
+
+ if (flags & FLAG_DAEMON) {
+ FILE *pidfile = NULL;
+
+ if (flags & FLAG_PID_FILE) {
+ int fd;
+
+ fd = open(PID_FILE, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (fd == -1) {
+ if (errno == EEXIST) {
+ pid_t old_pid;
+ pidfile = fopen(PID_FILE, "r");
+ if (!pidfile) {
+ perror("PID file " PID_FILE " already exists, already running?");
+ exit(EXIT_FAILURE);
+ }
+
+ if (fscanf(pidfile, "%u", &old_pid) != 1) {
+ fclose(pidfile);
+ fprintf(stderr, "Can't read old PID from " PID_FILE ", already running?\n");
+ exit(EXIT_FAILURE);
+ }
+
+ fclose(pidfile);
+
+ fprintf(stderr, "Already running with PID %u according to " PID_FILE "!\n", old_pid);
+ exit(EXIT_FAILURE);
+ }
+ perror("Can't create PID file " PID_FILE);
+ exit(EXIT_FAILURE);
+ }
+
+ pidfile = fdopen(fd, "w");
+ if (!pidfile) {
+ perror("Can't reopen PID file fd");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&sact, 0, sizeof(sact));
+ sact.sa_handler = sigterm_handler;
+
+ if (sigaction(SIGTERM, &sact, NULL) == -1) {
+ perror("sigaction(SIGTERM)");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ pid = fork();
+ if (pid > 0) {
+ if (pidfile) {
+ fprintf(pidfile, "%u\n", pid);
+ fclose(pidfile);
+ }
+
+ printf("Daemon with PID %u started!\n", pid);
+ exit(EXIT_SUCCESS);
+ } else if (pid < 0) {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+
+ if (pidfile)
+ fclose(pidfile);
+ }
+
+ memset(&sact, 0, sizeof(sact));
+ sact.sa_handler = SIG_IGN;
+
+ if (sigaction(SIGPIPE, &sact, NULL) == -1) {
+ perror("sigaction(SIGPIPE)");
+ exit(EXIT_FAILURE);
+ }
+
+ impersonate_hmlanif = 1;
+
+ sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sock == -1) {
+ perror("Can't open socket");
+ return EXIT_FAILURE;
+ }
+
+ n = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) {
+ perror("Can't set socket options");
+ return EXIT_FAILURE;
+ }
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+ if (!iface) {
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ } else {
+ if (inet_pton(AF_INET, iface, &(sin.sin_addr.s_addr)) != 1) {
+ fprintf(stderr, "Can't convert IP %s, aborting!\n", iface);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (bind(sock, (struct sockaddr*)&sin, sizeof(sin)) == -1) {
+ perror("Can't bind socket");
+ return EXIT_FAILURE;
+ }
+
+ if (listen(sock, 1) == -1) {
+ perror("Can't listen on socket");
+ return EXIT_FAILURE;