/* * compress the given file: create a corresponding .gz file and remove the * original. */ static off_t file_compress(char *file, char *outfile, size_t outsize) { int in; int out; off_t size, insize; #ifndef SMALL struct stat isb, osb; const suffixes_t *suff; #endif in = open(file, O_RDONLY); if (in == -1) { maybe_warn("can't open %s", file); return -1; } if (cflag == 0) { #ifndef SMALL if (fstat(in, &isb) == 0) { if (isb.st_nlink > 1 && fflag == 0) { maybe_warnx("%s has %d other link%s -- " "skipping", file, isb.st_nlink - 1, isb.st_nlink == 1 ? "" : "s"); close(in); return -1; } } if (fflag == 0 && (suff = check_suffix(file, 0)) && suff->zipped[0] != 0) { maybe_warnx("%s already has %s suffix -- unchanged", file, suff->zipped); close(in); return -1; } #endif /* Add (usually) .gz to filename */ if ((size_t)snprintf(outfile, outsize, "%s%s", file, suffixes[0].zipped) >= outsize) memcpy(outfile + outsize - suffixes[0].ziplen - 1, suffixes[0].zipped, suffixes[0].ziplen + 1); #ifndef SMALL if (check_outfile(outfile) == 0) { close(in); return -1; } #endif } if (cflag == 0) { out = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600); if (out == -1) { maybe_warn("could not create output: %s", outfile); fclose(stdin); return -1; } } else out = STDOUT_FILENO; insize = gz_compress(in, out, &size, basename(file), (uint32_t)isb.st_mtime); (void)close(in); /* * If there was an error, insize will be -1. * If we compressed to stdout, just return the size. * Otherwise stat the file and check it is the correct size. * We only blow away the file if we can stat the output and it * has the expected size. */ if (cflag != 0) return insize == -1 ? -1 : size; #ifndef SMALL if (fstat(out, &osb) != 0) { maybe_warn("couldn't stat: %s", outfile); goto bad_outfile; } if (osb.st_size != size) { maybe_warnx("output file: %s wrong size (%" PRIdOFF " != %" PRIdOFF "), deleting", outfile, osb.st_size, size); goto bad_outfile; } copymodes(out, &isb, outfile); #endif if (close(out) == -1) maybe_warn("couldn't close output"); /* output is good, ok to delete input */ unlink_input(file, &isb); return size; #ifndef SMALL bad_outfile: if (close(out) == -1) maybe_warn("couldn't close output"); maybe_warnx("leaving original %s", file); unlink(outfile); return size; #endif }
/* uncompress the given file and remove the original */ static off_t file_uncompress(char *file, char *outfile, size_t outsize) { struct stat isb, osb; off_t size; ssize_t rbytes; unsigned char header1[4]; enum filetype method; int fd, ofd, zfd = -1; #ifndef SMALL ssize_t rv; time_t timestamp = 0; char name[PATH_MAX + 1]; #endif /* gather the old name info */ fd = open(file, O_RDONLY); if (fd < 0) { maybe_warn("can't open %s", file); goto lose; } strlcpy(outfile, file, outsize); if (check_suffix(outfile, 1) == NULL && !(cflag || lflag)) { maybe_warnx("%s: unknown suffix -- ignored", file); goto lose; } rbytes = read(fd, header1, sizeof header1); if (rbytes != sizeof header1) { /* we don't want to fail here. */ #ifndef SMALL if (fflag) goto lose; #endif if (rbytes == -1) maybe_warn("can't read %s", file); else goto unexpected_EOF; goto lose; } method = file_gettype(header1); #ifndef SMALL if (fflag == 0 && method == FT_UNKNOWN) { maybe_warnx("%s: not in gzip format", file); goto lose; } #endif #ifndef SMALL if (method == FT_GZIP && Nflag) { unsigned char ts[4]; /* timestamp */ rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP); if (rv >= 0 && rv < (ssize_t)(sizeof ts)) goto unexpected_EOF; if (rv == -1) { if (!fflag) maybe_warn("can't read %s", file); goto lose; } timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0]; if (header1[3] & ORIG_NAME) { rbytes = pread(fd, name, sizeof(name) - 1, GZIP_ORIGNAME); if (rbytes < 0) { maybe_warn("can't read %s", file); goto lose; } if (name[0] != '\0') { char *dp, *nf; /* Make sure that name is NUL-terminated */ name[rbytes] = '\0'; /* strip saved directory name */ nf = strrchr(name, '/'); if (nf == NULL) nf = name; else nf++; /* preserve original directory name */ dp = strrchr(file, '/'); if (dp == NULL) dp = file; else dp++; snprintf(outfile, outsize, "%.*s%.*s", (int) (dp - file), file, (int) rbytes, nf); } } } #endif lseek(fd, 0, SEEK_SET); if (cflag == 0 || lflag) { if (fstat(fd, &isb) != 0) goto lose; #ifndef SMALL if (isb.st_nlink > 1 && lflag == 0 && fflag == 0) { maybe_warnx("%s has %d other links -- skipping", file, isb.st_nlink - 1); goto lose; } if (nflag == 0 && timestamp) isb.st_mtime = timestamp; if (check_outfile(outfile) == 0) goto lose; #endif } if (cflag == 0 && lflag == 0) { zfd = open(outfile, O_WRONLY|O_CREAT|O_EXCL, 0600); if (zfd == STDOUT_FILENO) { /* We won't close STDOUT_FILENO later... */ zfd = dup(zfd); close(STDOUT_FILENO); } if (zfd == -1) { maybe_warn("can't open %s", outfile); goto lose; } } else zfd = STDOUT_FILENO; switch (method) { #ifndef NO_BZIP2_SUPPORT case FT_BZIP2: /* XXX */ if (lflag) { maybe_warnx("no -l with bzip2 files"); goto lose; } size = unbzip2(fd, zfd, NULL, 0, NULL); break; #endif #ifndef NO_COMPRESS_SUPPORT case FT_Z: { FILE *in, *out; /* XXX */ if (lflag) { maybe_warnx("no -l with Lempel-Ziv files"); goto lose; } if ((in = zdopen(fd)) == NULL) { maybe_warn("zdopen for read: %s", file); goto lose; } out = fdopen(dup(zfd), "w"); if (out == NULL) { maybe_warn("fdopen for write: %s", outfile); fclose(in); goto lose; } size = zuncompress(in, out, NULL, 0, NULL); /* need to fclose() if ferror() is true... */ if (ferror(in) | fclose(in)) { maybe_warn("failed infile fclose"); unlink(outfile); (void)fclose(out); } if (fclose(out) != 0) { maybe_warn("failed outfile fclose"); unlink(outfile); goto lose; } break; } #endif #ifndef NO_PACK_SUPPORT case FT_PACK: if (lflag) { maybe_warnx("no -l with packed files"); goto lose; } size = unpack(fd, zfd, NULL, 0, NULL); break; #endif #ifndef NO_XZ_SUPPORT case FT_XZ: if (lflag) { maybe_warnx("no -l with xz files"); goto lose; } size = unxz(fd, zfd, NULL, 0, NULL); break; #endif #ifndef SMALL case FT_UNKNOWN: if (lflag) { maybe_warnx("no -l for unknown filetypes"); goto lose; } size = cat_fd(NULL, 0, NULL, fd); break; #endif default: if (lflag) { print_list(fd, isb.st_size, outfile, isb.st_mtime); close(fd); return -1; /* XXX */ } size = gz_uncompress(fd, zfd, NULL, 0, NULL, file); break; } if (close(fd) != 0) maybe_warn("couldn't close input"); if (zfd != STDOUT_FILENO && close(zfd) != 0) maybe_warn("couldn't close output"); if (size == -1) { if (cflag == 0) unlink(outfile); maybe_warnx("%s: uncompress failed", file); return -1; } /* if testing, or we uncompressed to stdout, this is all we need */ #ifndef SMALL if (tflag) return size; #endif /* if we are uncompressing to stdin, don't remove the file. */ if (cflag) return size; /* * if we create a file... */ /* * if we can't stat the file don't remove the file. */ ofd = open(outfile, O_RDWR, 0); if (ofd == -1) { maybe_warn("couldn't open (leaving original): %s", outfile); return -1; } if (fstat(ofd, &osb) != 0) { maybe_warn("couldn't stat (leaving original): %s", outfile); close(ofd); return -1; } if (osb.st_size != size) { maybe_warnx("stat gave different size: %" PRIdOFF " != %" PRIdOFF " (leaving original)", size, osb.st_size); close(ofd); unlink(outfile); return -1; } unlink_input(file, &isb); #ifndef SMALL copymodes(ofd, &isb, outfile); #endif close(ofd); return size; unexpected_EOF: maybe_warnx("%s: unexpected end of file", file); lose: if (fd != -1) close(fd); if (zfd != -1 && zfd != STDOUT_FILENO) close(fd); return -1; }
int main(int argc, char **argv) { struct ftdi_context *ftdi; int err, c; FILE *of = NULL; char const *outfile = 0; outputFile =0; exitRequested = 0; char *descstring = NULL; int option_index; static struct option long_options[] = {{NULL},}; while ((c = getopt_long(argc, argv, "P:n", long_options, &option_index)) !=- 1) switch (c) { case -1: break; case 'P': descstring = optarg; break; case 'n': check = 0; break; default: usage(argv[0]); } if (optind == argc - 1) { // Exactly one extra argument- a dump file outfile = argv[optind]; } else if (optind < argc) { // Too many extra args usage(argv[0]); } if ((ftdi = ftdi_new()) == 0) { fprintf(stderr, "ftdi_new failed\n"); return EXIT_FAILURE; } if (ftdi_set_interface(ftdi, INTERFACE_A) < 0) { fprintf(stderr, "ftdi_set_interface failed\n"); ftdi_free(ftdi); return EXIT_FAILURE; } if (ftdi_usb_open_desc(ftdi, 0x0403, 0x6014, descstring, NULL) < 0) { fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(ftdi)); ftdi_free(ftdi); return EXIT_FAILURE; } /* A timeout value of 1 results in may skipped blocks */ if(ftdi_set_latency_timer(ftdi, 2)) { fprintf(stderr,"Can't set latency, Error %s\n",ftdi_get_error_string(ftdi)); ftdi_usb_close(ftdi); ftdi_free(ftdi); return EXIT_FAILURE; } /* if(ftdi_usb_purge_rx_buffer(ftdi) < 0) { fprintf(stderr,"Can't rx purge\n",ftdi_get_error_string(ftdi)); return EXIT_FAILURE; }*/ if (outfile) if ((of = fopen(outfile,"w+")) == 0) fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno)); if (of) if (setvbuf(of, NULL, _IOFBF , 1<<16) == 0) outputFile = of; signal(SIGINT, sigintHandler); err = ftdi_readstream(ftdi, readCallback, NULL, 8, 256); if (err < 0 && !exitRequested) exit(1); if (outputFile) { fclose(outputFile); outputFile = NULL; } fprintf(stderr, "Capture ended.\n"); if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET) < 0) { fprintf(stderr,"Can't set synchronous fifo mode, Error %s\n",ftdi_get_error_string(ftdi)); ftdi_usb_close(ftdi); ftdi_free(ftdi); return EXIT_FAILURE; } ftdi_usb_close(ftdi); ftdi_free(ftdi); signal(SIGINT, SIG_DFL); if (check && outfile) { if ((outputFile = fopen(outfile,"r")) == 0) { fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno)); ftdi_usb_close(ftdi); ftdi_free(ftdi); return EXIT_FAILURE; } check_outfile(descstring); fclose(outputFile); } else if (check) fprintf(stderr,"%d errors of %llu blocks (%Le), %d (%Le) blocks skipped\n", n_err, (unsigned long long) blocks, (long double)n_err/(long double) blocks, skips, (long double)skips/(long double) blocks); exit (0); }