tar.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Attempt at emulation of Unix tar by calling Plan 9 tar.
  3. *
  4. * The differences from Plan 9 tar are:
  5. * In the absence of an "f" flag, the file /dev/tape is used.
  6. * An "f" flag with argument "-" causes use of stdin/stdout
  7. * by passing no "f" flag (nor argument) to Plan 9 tar.
  8. * By default, the "T" flag is passed to Plan 9 tar.
  9. * The "m" flag to this tar inhibits this behavior.
  10. */
  11. #include <u.h>
  12. #include <libc.h>
  13. void
  14. usage(void)
  15. {
  16. fprint(2, "usage: ape/tar [crtx][vfm] [args...] [file...]\n");
  17. exits("usage");
  18. }
  19. void
  20. main(int argc, char **argv)
  21. {
  22. int i, j, verb, vflag, fflag, Tflag, nargc;
  23. char *p, *file, **nargv, *cpu, flagbuf[10], execbuf[128];
  24. Waitmsg *w;
  25. argv++, argc--;
  26. if(argc < 1)
  27. usage();
  28. p = argv[0];
  29. argv++, argc--;
  30. if(*p == '-')
  31. p++;
  32. if(strchr("crtx", *p) == nil)
  33. usage();
  34. verb = *p++;
  35. /* unix defaults */
  36. fflag = 1;
  37. file = "/dev/tape";
  38. Tflag = 1;
  39. vflag = 0;
  40. for(; *p; p++) {
  41. switch(*p) {
  42. default:
  43. usage();
  44. case 'v':
  45. vflag = 1;
  46. break;
  47. case 'f':
  48. if(argc <= 0)
  49. usage();
  50. fflag = 1;
  51. file = argv[0];
  52. argv++, argc--;
  53. if(strcmp(file, "-") == 0) {
  54. /*
  55. * plan9 doesn't know about "-" meaning stdin/stdout,
  56. * but it's the default,
  57. * so rewrite to not use f flag at all.
  58. */
  59. file = nil;
  60. fflag = 0;
  61. }
  62. break;
  63. case 'm':
  64. Tflag = 0;
  65. break;
  66. case 'p': /* pretend nothing's wrong */
  67. break;
  68. }
  69. }
  70. nargc = 1 + 1 + fflag + argc + 1;
  71. nargv = malloc(sizeof(char*) * nargc);
  72. if(nargv == nil) {
  73. fprint(2, "ape/tar: out of memory\n");
  74. exits("memory");
  75. }
  76. cpu = getenv("cputype");
  77. if(cpu == nil) {
  78. fprint(2, "ape/tar: need cputype environment variable set\n");
  79. exits("cputype");
  80. }
  81. snprint(execbuf, sizeof execbuf, "/%s/bin/tar", cpu);
  82. nargv[0] = "tar";
  83. sprint(flagbuf, "%c%s%s%s", verb, vflag ? "v" : "", Tflag ? "T" : "", fflag ? "f" : "");
  84. nargv[1] = flagbuf;
  85. i = 2;
  86. if(fflag)
  87. nargv[i++] = file;
  88. for(j=0; j<argc; j++, i++)
  89. nargv[i] = argv[j];
  90. nargv[i++] = nil;
  91. assert(i == nargc);
  92. switch(fork()){
  93. case -1:
  94. fprint(2, "ape/tar: fork failed: %r\n");
  95. exits("fork");
  96. case 0:
  97. exec(execbuf, nargv);
  98. fprint(2, "exec %s fails: %r\n", execbuf);
  99. _exits("exec");
  100. default:
  101. w = wait();
  102. if(w == nil)
  103. exits("wait failed");
  104. if(w->msg[0] == '\0')
  105. exits(nil);
  106. else
  107. exits(w->msg);
  108. }
  109. assert(0);
  110. }