# include # include # include # include # include # include # include # include # include # include # include struct fpv { uint32_t len; uint8_t type; uint32_t ms; uint8_t pad[8]; } __attribute__((packed)); static const char short_options[] = "s:e:"; static const struct option long_options[] = { { "start", required_argument, NULL, 's' }, { "end", required_argument, NULL, 'e' }, { 0, 0, NULL, 0 } }; static int opt_s = 0; static int opt_e = -1; size_t in(int fd, uint8_t *data, size_t len) { int res = 0; while (len > 0) { size_t n = read(fd, data, len); if (n > 0) { len -= n; data += n; res += n; } else { if (n < 0) { if (errno != EAGAIN) { printf("read: %s\n", strerror(errno)); } else { continue; } } break; } } return res; } int main(int argc, char *argv[]) { struct fpv fpv; static uint8_t data[8 * 1024 * 1024]; int i; for (;;) { int c; if ((c = getopt_long_only(argc, argv, short_options, long_options, &i)) == -1) { break; } switch (c) { case 's': opt_s = atoi(optarg); break; case 'e': opt_e = atoi(optarg); break; case 0: break; default: return 1; } } if ((argc - optind) < 1) { return 1; } for (i = 0; (optind + i) < argc; i++) { int fd = open(argv[optind + i], O_RDONLY); fprintf(stderr, "%s\n", argv[optind + i]); if (fd >= 0) { while (1) { if (in(fd, (uint8_t*)&fpv, sizeof(fpv)) < 0) { break; } if (in(fd, data, fpv.len) < 0) { break; } if (opt_e > 0 && fpv.ms >= opt_e) { break; } if (fpv.ms >= opt_s) { fpv.ms -= opt_s; write(fileno(stdout), &fpv, sizeof(fpv)); write(fileno(stdout), data, fpv.len); } } close(fd); } } return 0; }