tar.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. typedef union Hblock Hblock;
  9. #define TBLOCK 512
  10. #define NAMSIZ 100
  11. union Hblock
  12. {
  13. char dummy[TBLOCK];
  14. struct header
  15. {
  16. char name[NAMSIZ];
  17. char mode[8];
  18. char uid[8];
  19. char gid[8];
  20. char size[12];
  21. char mtime[12];
  22. char chksum[8];
  23. char linkflag;
  24. char linkname[NAMSIZ];
  25. } dbuf;
  26. };
  27. static int getdir(Hblock *hb, Dir *sp);
  28. static int checksum(Hblock *hb);
  29. uchar*
  30. tarlookup(uchar *addr, char *file, int *dlen)
  31. {
  32. Hblock *hp;
  33. Dir dir;
  34. hp = (Hblock*)addr;
  35. while(getdir(hp, &dir) != 0) {
  36. if(strcmp(file, hp->dbuf.name) == 0) {
  37. *dlen = dir.length;
  38. return (uchar*)(hp+1);
  39. }
  40. hp += (dir.length+TBLOCK-1)/TBLOCK + 1;
  41. }
  42. return 0;
  43. }
  44. static int
  45. getdir(Hblock *hp, Dir *sp)
  46. {
  47. int chksum;
  48. if (hp->dbuf.name[0] == '\0')
  49. return 0;
  50. sp->length = strtol(hp->dbuf.size, 0, 8);
  51. sp->mtime = strtol(hp->dbuf.mtime, 0, 8);
  52. chksum = strtol(hp->dbuf.chksum, 0, 8);
  53. if (chksum != checksum(hp)) {
  54. print("directory checksum error\n");
  55. return 0;
  56. }
  57. return 1;
  58. }
  59. static int
  60. checksum(Hblock *hp)
  61. {
  62. int i;
  63. char *cp;
  64. i = 0;
  65. for (cp = hp->dummy; cp < &hp->dummy[TBLOCK]; cp++) {
  66. if(cp < hp->dbuf.chksum || cp >= &hp->dbuf.chksum[sizeof(hp->dbuf.chksum)])
  67. i += *cp & 0xff;
  68. else
  69. i += ' ' & 0xff;
  70. }
  71. return(i);
  72. }