tar.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // field paths that every tar file must have.
  2. // header is padded to 512 bytes.
  3. var f = 0
  4. , fields = {}
  5. , path = fields.path = f++
  6. , mode = fields.mode = f++
  7. , uid = fields.uid = f++
  8. , gid = fields.gid = f++
  9. , size = fields.size = f++
  10. , mtime = fields.mtime = f++
  11. , cksum = fields.cksum = f++
  12. , type = fields.type = f++
  13. , linkpath = fields.linkpath = f++
  14. , headerSize = 512
  15. , blockSize = 512
  16. , fieldSize = []
  17. fieldSize[path] = 100
  18. fieldSize[mode] = 8
  19. fieldSize[uid] = 8
  20. fieldSize[gid] = 8
  21. fieldSize[size] = 12
  22. fieldSize[mtime] = 12
  23. fieldSize[cksum] = 8
  24. fieldSize[type] = 1
  25. fieldSize[linkpath] = 100
  26. // "ustar\0" may introduce another bunch of headers.
  27. // these are optional, and will be nulled out if not present.
  28. var ustar = fields.ustar = f++
  29. , ustarver = fields.ustarver = f++
  30. , uname = fields.uname = f++
  31. , gname = fields.gname = f++
  32. , devmaj = fields.devmaj = f++
  33. , devmin = fields.devmin = f++
  34. , prefix = fields.prefix = f++
  35. , fill = fields.fill = f++
  36. // terminate fields.
  37. fields[f] = null
  38. fieldSize[ustar] = 6
  39. fieldSize[ustarver] = 2
  40. fieldSize[uname] = 32
  41. fieldSize[gname] = 32
  42. fieldSize[devmaj] = 8
  43. fieldSize[devmin] = 8
  44. fieldSize[prefix] = 155
  45. fieldSize[fill] = 12
  46. // nb: prefix field may in fact be 130 bytes of prefix,
  47. // a null char, 12 bytes for atime, 12 bytes for ctime.
  48. //
  49. // To recognize this format:
  50. // 1. prefix[130] === ' ' or '\0'
  51. // 2. atime and ctime are octal numeric values
  52. // 3. atime and ctime have ' ' in their last byte
  53. var fieldEnds = {}
  54. , fieldOffs = {}
  55. , fe = 0
  56. for (var i = 0; i < f; i ++) {
  57. fieldOffs[i] = fe
  58. fieldEnds[i] = (fe += fieldSize[i])
  59. }
  60. // build a translation table of field paths.
  61. Object.keys(fields).forEach(function (f) {
  62. if (fields[f] !== null) fields[fields[f]] = f
  63. })
  64. // different values of the 'type' field
  65. // paths match the values of Stats.isX() functions, where appropriate
  66. var types =
  67. { 0: "File"
  68. , "\0": "OldFile" // like 0
  69. , "": "OldFile"
  70. , 1: "Link"
  71. , 2: "SymbolicLink"
  72. , 3: "CharacterDevice"
  73. , 4: "BlockDevice"
  74. , 5: "Directory"
  75. , 6: "FIFO"
  76. , 7: "ContiguousFile" // like 0
  77. // posix headers
  78. , g: "GlobalExtendedHeader" // k=v for the rest of the archive
  79. , x: "ExtendedHeader" // k=v for the next file
  80. // vendor-specific stuff
  81. , A: "SolarisACL" // skip
  82. , D: "GNUDumpDir" // like 5, but with data, which should be skipped
  83. , I: "Inode" // metadata only, skip
  84. , K: "NextFileHasLongLinkpath" // data = link path of next file
  85. , L: "NextFileHasLongPath" // data = path of next file
  86. , M: "ContinuationFile" // skip
  87. , N: "OldGnuLongPath" // like L
  88. , S: "SparseFile" // skip
  89. , V: "TapeVolumeHeader" // skip
  90. , X: "OldExtendedHeader" // like x
  91. }
  92. Object.keys(types).forEach(function (t) {
  93. types[types[t]] = types[types[t]] || t
  94. })
  95. // values for the mode field
  96. var modes =
  97. { suid: 04000 // set uid on extraction
  98. , sgid: 02000 // set gid on extraction
  99. , svtx: 01000 // set restricted deletion flag on dirs on extraction
  100. , uread: 0400
  101. , uwrite: 0200
  102. , uexec: 0100
  103. , gread: 040
  104. , gwrite: 020
  105. , gexec: 010
  106. , oread: 4
  107. , owrite: 2
  108. , oexec: 1
  109. , all: 07777
  110. }
  111. var numeric =
  112. { mode: true
  113. , uid: true
  114. , gid: true
  115. , size: true
  116. , mtime: true
  117. , devmaj: true
  118. , devmin: true
  119. , cksum: true
  120. , atime: true
  121. , ctime: true
  122. , dev: true
  123. , ino: true
  124. , nlink: true
  125. }
  126. Object.keys(modes).forEach(function (t) {
  127. modes[modes[t]] = modes[modes[t]] || t
  128. })
  129. var knownExtended =
  130. { atime: true
  131. , charset: true
  132. , comment: true
  133. , ctime: true
  134. , gid: true
  135. , gname: true
  136. , linkpath: true
  137. , mtime: true
  138. , path: true
  139. , realtime: true
  140. , security: true
  141. , size: true
  142. , uid: true
  143. , uname: true }
  144. exports.fields = fields
  145. exports.fieldSize = fieldSize
  146. exports.fieldOffs = fieldOffs
  147. exports.fieldEnds = fieldEnds
  148. exports.types = types
  149. exports.modes = modes
  150. exports.numeric = numeric
  151. exports.headerSize = headerSize
  152. exports.blockSize = blockSize
  153. exports.knownExtended = knownExtended
  154. exports.Pack = require("./lib/pack.js")
  155. exports.Parse = require("./lib/parse.js")
  156. exports.Extract = require("./lib/extract.js")