static void on_download_read_filesize(int fd, input_id input, OpnDownload *dl) { uint8_t buf[128]; int recvd, i; uint32_t size = 0; if (fd == -1 || !input || net_sock_error(fd)) { opn_download_free(dl); return; } /* get the filesize */ if ((recvd = tcp_peek(dl->con, buf, sizeof(buf))) <= 0) { opn_download_free(dl); return; } buf[recvd] = 0; for (i = 0; isdigit(buf[i]) && size < dl->url->size; i++) size = (size * 10) + (buf[i] - '0'); tcp_recv(dl->con, buf, i); input_remove(input); input_add(fd, dl, INPUT_READ, (InputCallback) on_download_read_data, 5 * SECONDS); }
static void on_download_connect(int fd, input_id input, OpnDownload *dl) { char c; if (fd == -1 || !input || net_sock_error(fd) || tcp_recv(dl->con, (uint8_t *) &c, 1) <= 0 || c != '1') { opn_download_free(dl); return; } input_remove(input); input_add(fd, dl, INPUT_WRITE, (InputCallback) on_download_write, 5 * SECONDS); }
static void on_download_write(int fd, input_id input, OpnDownload *dl) { char buf[PATH_MAX + 256]; if (fd == -1 || !input || net_sock_error(fd)) { opn_download_free(dl); return; } tcp_writestr(dl->con, "GET"); snprintf(buf, sizeof(buf), "%s \"%s\" %lu", OPN_ALIAS, dl->url->file, dl->chunk->start + dl->chunk->transmit); tcp_writestr(dl->con, buf); input_remove(input); input_add(fd, dl, INPUT_READ, (InputCallback) on_download_read_filesize, 30 * SECONDS); }
static void hid_device_remove(struct btd_device *device) { input_remove(device, HID_UUID); }
static void headset_remove(struct btd_device *device) { input_remove(device, HSP_HS_UUID); }
static bool input_poll(bool (*handler) (struct input_event*, struct input_device*)) { // Block signals that are handled gracefully by the input polling code. This // is done at the last moment to allow Ctrl+C to work until everything // is ready to go. sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGHUP); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGQUIT); sigprocmask(SIG_BLOCK, &sigset, NULL); fds[sig_fdindex].fd = signalfd(-1, &sigset, 0); fds[sig_fdindex].events = POLLIN | POLLERR | POLLHUP; while (poll(fds, numFds, -1)) { if (fds[udev_fdindex].revents > 0) { struct udev_device *dev = udev_monitor_receive_device(udev_mon); const char *action = udev_device_get_action(dev); if (action != NULL) { if (autoadd && strcmp("add", action) == 0) { const char *devnode = udev_device_get_devnode(dev); int id; if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) { input_create(devnode, defaultMapfile); } } udev_device_unref(dev); } } else if (fds[sig_fdindex].revents > 0) { struct signalfd_siginfo info; read(fds[sig_fdindex].fd, &info, sizeof(info)); switch (info.ssi_signo) { case SIGINT: case SIGTERM: case SIGQUIT: case SIGHUP: return false; } } for (int i=0;i<numDevices;i++) { if (fds[devices[i].fdindex].revents > 0) { int rc; struct input_event ev; while ((rc = libevdev_next_event(devices[i].dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) >= 0) { if (rc == LIBEVDEV_READ_STATUS_SYNC) fprintf(stderr, "Error: cannot keep up\n"); else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) { if (!handler(&ev, &devices[i])) return true; } } if (rc == -ENODEV) { input_remove(i); } else if (rc != -EAGAIN && rc < 0) { fprintf(stderr, "Error: %s\n", strerror(-rc)); exit(EXIT_FAILURE); } } } } return false; }
int main (int argc, char *argv[]) { ASLogger *logger; int stdin_handle; input_id stdinput; #ifdef WIN32 HANDLE hThread; int fds[2]; #endif /* winsock init */ tcp_startup (); /* setup logging */ logger = as_logger_create (); as_logger_add_output (logger, "stderr"); as_logger_add_output (logger, "ares.log"); AS_DBG ("Logging subsystem started"); /* setup event system */ as_event_init (); /* init lib */ if (!as_init ()) { printf ("FATA: as_init() failed\n"); exit (1); } #ifdef WIN32 /* create console reading thread on windows */ if (socketpair (0, 0, 0, fds) < 0) { printf ("FATAL: socketpair() failed\n"); exit (1); } stdin_handle = fds[1]; hThread = (HANDLE) _beginthreadex (NULL, 0, console_input_func, (void *)fds[0], 0, NULL); if (hThread == (HANDLE) -1 || hThread == (HANDLE) 0) { printf ("FATAL: couldn't start input thread\n"); exit (1); } #else stdin_handle = 0; #endif /* add callback for command handling */ stdinput = input_add (stdin_handle, NULL, INPUT_READ, stdin_cb, 0); #if 0 /* print prompt */ printf ("> "); #endif /* run event loop */ AS_DBG ("Entering event loop"); as_event_loop (); AS_DBG ("Left event loop"); input_remove (stdinput); #if WIN32 /* terminate thread if it is still running and close thread handle */ TerminateThread (hThread, 0); CloseHandle (hThread); #endif /* cleanup lib */ as_cleanup (); /* shutdown */ as_event_shutdown (); as_logger_free (logger); /* winsock shutdown */ tcp_cleanup (); return 0; }