tarfs.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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'
  54. || (f.mode&0170000) == 040000
  55. || strrchr(dblock.dbuf.name, '\0')[-1] == '/')
  56. f.mode |= DMDIR;
  57. f.mode &= DMDIR|0777;
  58. linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1';
  59. isabs = dblock.dbuf.name[0]=='/';
  60. if (chksum != checksum()){
  61. fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name);
  62. abort();
  63. }
  64. if (linkflg) {
  65. /*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name,
  66. dblock.dbuf.linkname);*/
  67. f.size = 0;
  68. blkno += 1;
  69. continue;
  70. }
  71. f.name = dblock.dbuf.name+isabs;
  72. if (f.name[0]=='\0')
  73. fprint(1, "null name skipped\n");
  74. else
  75. poppath(f, 1);
  76. blkno += 1 + (f.size+TBLOCK-1)/TBLOCK;
  77. }
  78. }
  79. void
  80. dotrunc(Ram *r)
  81. {
  82. USED(r);
  83. }
  84. void
  85. docreate(Ram *r)
  86. {
  87. USED(r);
  88. }
  89. char *
  90. doread(Ram *r, long off, long cnt)
  91. {
  92. seek(tapefile, (TBLOCK * (long)r->data)+off, 0);
  93. if (cnt>sizeof(dblock.tbuf))
  94. error("read too big");
  95. read(tapefile, dblock.tbuf, cnt);
  96. return dblock.tbuf;
  97. }
  98. void
  99. popdir(Ram *r)
  100. {
  101. USED(r);
  102. }
  103. void
  104. dowrite(Ram *r, char *buf, long off, long cnt)
  105. {
  106. USED(r); USED(buf); USED(off); USED(cnt);
  107. }
  108. int
  109. dopermw(Ram *r)
  110. {
  111. USED(r);
  112. return 0;
  113. }
  114. int
  115. checksum()
  116. {
  117. register i;
  118. register char *cp;
  119. for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
  120. *cp = ' ';
  121. i = 0;
  122. for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
  123. i += *cp&0xff;
  124. return(i);
  125. }