tarfs.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. #include <fcall.h>
  5. #include "tapefs.h"
  6. /*
  7. * File system for tar tapes (read-only)
  8. */
  9. #define TBLOCK 512
  10. #define NBLOCK 40 /* maximum blocksize */
  11. #define DBLOCK 20 /* default blocksize */
  12. #define TNAMSIZ 100
  13. union hblock {
  14. char dummy[TBLOCK];
  15. char tbuf[Maxbuf];
  16. struct header {
  17. char name[TNAMSIZ];
  18. char mode[8];
  19. char uid[8];
  20. char gid[8];
  21. char size[12];
  22. char mtime[12];
  23. char chksum[8];
  24. char linkflag;
  25. char linkname[TNAMSIZ];
  26. } dbuf;
  27. } dblock;
  28. int tapefile;
  29. int checksum(void);
  30. void
  31. populate(char *name)
  32. {
  33. long blkno, isabs, chksum, linkflg;
  34. Fileinf f;
  35. tapefile = open(name, OREAD);
  36. if (tapefile<0)
  37. error("Can't open argument file");
  38. replete = 1;
  39. for (blkno = 0;;) {
  40. seek(tapefile, TBLOCK*blkno, 0);
  41. if (read(tapefile, dblock.dummy, sizeof(dblock.dummy))<sizeof(dblock.dummy))
  42. break;
  43. if (dblock.dbuf.name[0]=='\0')
  44. break;
  45. f.addr = (void*)(blkno+1);
  46. f.mode = strtoul(dblock.dbuf.mode, 0, 8);
  47. f.uid = strtoul(dblock.dbuf.uid, 0, 8);
  48. f.gid = strtoul(dblock.dbuf.gid, 0, 8);
  49. f.size = strtoul(dblock.dbuf.size, 0, 8);
  50. f.mdate = strtoul(dblock.dbuf.mtime, 0, 8);
  51. chksum = strtoul(dblock.dbuf.chksum, 0, 8);
  52. /* the mode test is ugly but sometimes necessary */
  53. if (dblock.dbuf.linkflag == '5' || (f.mode&0170000) == 040000)
  54. f.mode |= DMDIR;
  55. linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1';
  56. isabs = dblock.dbuf.name[0]=='/';
  57. if (chksum != checksum()){
  58. fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name);
  59. abort();
  60. }
  61. if (linkflg) {
  62. /*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name,
  63. dblock.dbuf.linkname);*/
  64. f.size = 0;
  65. blkno += 1;
  66. continue;
  67. }
  68. f.name = dblock.dbuf.name+isabs;
  69. if (f.name[0]=='\0')
  70. fprint(1, "null name skipped\n");
  71. else
  72. poppath(f, 1);
  73. blkno += 1 + (f.size+TBLOCK-1)/TBLOCK;
  74. }
  75. }
  76. void
  77. dotrunc(Ram *r)
  78. {
  79. USED(r);
  80. }
  81. void
  82. docreate(Ram *r)
  83. {
  84. USED(r);
  85. }
  86. char *
  87. doread(Ram *r, long off, long cnt)
  88. {
  89. seek(tapefile, (TBLOCK * (long)r->data)+off, 0);
  90. if (cnt>sizeof(dblock.tbuf))
  91. error("read too big");
  92. read(tapefile, dblock.tbuf, cnt);
  93. return dblock.tbuf;
  94. }
  95. void
  96. popdir(Ram *r)
  97. {
  98. USED(r);
  99. }
  100. void
  101. dowrite(Ram *r, char *buf, long off, long cnt)
  102. {
  103. USED(r); USED(buf); USED(off); USED(cnt);
  104. }
  105. int
  106. dopermw(Ram *r)
  107. {
  108. USED(r);
  109. return 0;
  110. }
  111. int
  112. checksum()
  113. {
  114. register i;
  115. register char *cp;
  116. for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
  117. *cp = ' ';
  118. i = 0;
  119. for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
  120. i += *cp&0xff;
  121. return(i);
  122. }