bunzip2.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Modified for busybox by Glenn McGrath <bug1@iinet.net.au>
  4. * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
  5. *
  6. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  7. */
  8. #include "busybox.h"
  9. #include "unarchive.h"
  10. #define BUNZIP2_OPT_STDOUT 1
  11. #define BUNZIP2_OPT_FORCE 2
  12. int bunzip2_main(int argc, char **argv)
  13. {
  14. USE_DESKTOP(long long) int status;
  15. char *filename;
  16. unsigned opt;
  17. int src_fd, dst_fd;
  18. opt = getopt32(argc, argv, "cf");
  19. /* Set input filename and number */
  20. filename = argv[optind];
  21. if ((filename) && (filename[0] != '-') && (filename[1] != '\0')) {
  22. /* Open input file */
  23. src_fd = xopen(filename, O_RDONLY);
  24. } else {
  25. src_fd = STDIN_FILENO;
  26. filename = 0;
  27. }
  28. /* if called as bzcat force the stdout flag */
  29. if ((opt & BUNZIP2_OPT_STDOUT) || applet_name[2] == 'c')
  30. filename = 0;
  31. /* Check that the input is sane. */
  32. if (isatty(src_fd) && (opt & BUNZIP2_OPT_FORCE) == 0) {
  33. bb_error_msg_and_die("compressed data not read from terminal, "
  34. "use -f to force it");
  35. }
  36. if (filename) {
  37. struct stat stat_buf;
  38. /* extension = filename+strlen(filename)-4 is buggy:
  39. * strlen may be less than 4 */
  40. char *extension = strrchr(filename, '.');
  41. if (!extension || strcmp(extension, ".bz2") != 0) {
  42. bb_error_msg_and_die("invalid extension");
  43. }
  44. xstat(filename, &stat_buf);
  45. *extension = '\0';
  46. dst_fd = xopen3(filename, O_WRONLY | O_CREAT | O_TRUNC,
  47. stat_buf.st_mode);
  48. } else dst_fd = STDOUT_FILENO;
  49. status = uncompressStream(src_fd, dst_fd);
  50. if (filename) {
  51. if (status >= 0) filename[strlen(filename)] = '.';
  52. if (unlink(filename) < 0) {
  53. bb_error_msg_and_die("cannot remove %s", filename);
  54. }
  55. }
  56. return status;
  57. }