1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180 |
- using System;
- using System.Text;
- namespace CommonMPQ.SharpZipLib.Tar
- {
-
-
-
-
-
-
- public class TarHeader : ICloneable
- {
- #region Constants
-
-
-
- public const int NAMELEN = 100;
-
-
-
-
- public const int MODELEN = 8;
-
-
-
-
- public const int UIDLEN = 8;
-
-
-
-
- public const int GIDLEN = 8;
-
-
-
-
- public const int CHKSUMLEN = 8;
-
-
-
- public const int CHKSUMOFS = 148;
-
-
-
-
- public const int SIZELEN = 12;
-
-
-
-
- public const int MAGICLEN = 6;
-
-
-
-
- public const int VERSIONLEN = 2;
-
-
-
- public const int MODTIMELEN = 12;
-
-
-
-
- public const int UNAMELEN = 32;
-
-
-
-
- public const int GNAMELEN = 32;
-
-
-
-
- public const int DEVLEN = 8;
-
-
-
-
-
-
-
- public const byte LF_OLDNORM = 0;
-
-
-
-
- public const byte LF_NORMAL = (byte) '0';
-
-
-
-
- public const byte LF_LINK = (byte) '1';
-
-
-
-
- public const byte LF_SYMLINK = (byte) '2';
-
-
-
-
- public const byte LF_CHR = (byte) '3';
-
-
-
-
- public const byte LF_BLK = (byte) '4';
-
-
-
-
- public const byte LF_DIR = (byte) '5';
-
-
-
-
- public const byte LF_FIFO = (byte) '6';
-
-
-
-
- public const byte LF_CONTIG = (byte) '7';
-
-
-
-
- public const byte LF_GHDR = (byte) 'g';
-
-
-
-
- public const byte LF_XHDR = (byte) 'x';
-
-
-
-
-
-
- public const byte LF_ACL = (byte) 'A';
-
-
-
-
-
-
- public const byte LF_GNU_DUMPDIR = (byte) 'D';
-
-
-
-
- public const byte LF_EXTATTR = (byte) 'E' ;
-
-
-
-
- public const byte LF_META = (byte) 'I';
-
-
-
-
- public const byte LF_GNU_LONGLINK = (byte) 'K';
-
-
-
-
- public const byte LF_GNU_LONGNAME = (byte) 'L';
-
-
-
-
- public const byte LF_GNU_MULTIVOL = (byte) 'M';
-
-
-
-
- public const byte LF_GNU_NAMES = (byte) 'N';
-
-
-
-
- public const byte LF_GNU_SPARSE = (byte) 'S';
-
-
-
-
- public const byte LF_GNU_VOLHDR = (byte) 'V';
-
-
-
-
- public const string TMAGIC = "ustar ";
-
-
-
-
- public const string GNU_TMAGIC = "ustar ";
- const long timeConversionFactor = 10000000L;
- readonly static DateTime dateTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
- #endregion
- #region Constructors
-
-
-
- public TarHeader()
- {
- Magic = TMAGIC;
- Version = " ";
-
- Name = "";
- LinkName = "";
-
- UserId = defaultUserId;
- GroupId = defaultGroupId;
- UserName = defaultUser;
- GroupName = defaultGroupName;
- Size = 0;
- }
- #endregion
- #region Properties
-
-
-
-
- public string Name
- {
- get { return name; }
- set {
- if ( value == null ) {
- throw new ArgumentNullException("value");
- }
- name = value;
- }
- }
-
-
-
-
- [Obsolete("Use the Name property instead", true)]
- public string GetName()
- {
- return name;
- }
-
-
-
-
- public int Mode
- {
- get { return mode; }
- set { mode = value; }
- }
-
-
-
-
-
-
-
-
-
- public int UserId
- {
- get { return userId; }
- set { userId = value; }
- }
-
-
-
-
-
-
-
-
-
- public int GroupId
- {
- get { return groupId; }
- set { groupId = value; }
- }
-
-
-
-
-
- public long Size
- {
- get { return size; }
- set {
- if ( value < 0 ) {
- #if NETCF_1_0
- throw new ArgumentOutOfRangeException("value");
- #else
- throw new ArgumentOutOfRangeException("value", "Cannot be less than zero");
- #endif
- }
- size = value;
- }
- }
-
-
-
-
-
-
-
-
-
- public DateTime ModTime
- {
- get { return modTime; }
- set {
- if ( value < dateTime1970 )
- {
- #if NETCF_1_0
- throw new ArgumentOutOfRangeException("value");
- #else
- throw new ArgumentOutOfRangeException("value", "ModTime cannot be before Jan 1st 1970");
- #endif
- }
- modTime = new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second);
- }
- }
-
-
-
-
-
- public int Checksum
- {
- get { return checksum; }
- }
-
-
-
-
-
- public bool IsChecksumValid
- {
- get { return isChecksumValid; }
- }
-
-
-
-
-
- public byte TypeFlag
- {
- get { return typeFlag; }
- set { typeFlag = value; }
- }
-
-
-
-
-
- public string LinkName
- {
- get { return linkName; }
- set {
- if ( value == null ) {
- throw new ArgumentNullException("value");
- }
- linkName = value;
- }
- }
-
-
-
-
-
-
- public string Magic
- {
- get { return magic; }
- set {
- if ( value == null ) {
- throw new ArgumentNullException("value");
- }
- magic = value;
- }
- }
-
-
-
-
-
-
- public string Version
- {
- get {
- return version;
- }
- set {
- if ( value == null ) {
- throw new ArgumentNullException("value");
- }
- version = value;
- }
- }
-
-
-
-
-
- public string UserName
- {
- get { return userName; }
- set {
- if (value != null) {
- userName = value.Substring(0, Math.Min(UNAMELEN, value.Length));
- }
- else {
- #if NETCF_1_0 || NETCF_2_0
- string currentUser = "PocketPC";
- #else
- string currentUser = Environment.UserName;
- #endif
- if (currentUser.Length > UNAMELEN) {
- currentUser = currentUser.Substring(0, UNAMELEN);
- }
- userName = currentUser;
- }
- }
- }
-
-
-
-
-
-
-
-
- public string GroupName
- {
- get { return groupName; }
- set {
- if ( value == null ) {
- groupName = "None";
- }
- else {
- groupName = value;
- }
- }
- }
-
-
-
-
-
- public int DevMajor
- {
- get { return devMajor; }
- set { devMajor = value; }
- }
-
-
-
-
-
- public int DevMinor
- {
- get { return devMinor; }
- set { devMinor = value; }
- }
-
- #endregion
- #region ICloneable Members
-
-
-
-
- public object Clone()
- {
- return MemberwiseClone();
- }
- #endregion
-
-
-
-
-
-
- public void ParseBuffer(byte[] header)
- {
- if ( header == null )
- {
- throw new ArgumentNullException("header");
- }
- int offset = 0;
-
- name = ParseName(header, offset, NAMELEN).ToString();
- offset += NAMELEN;
-
- mode = (int)ParseOctal(header, offset, MODELEN);
- offset += MODELEN;
-
- UserId = (int)ParseOctal(header, offset, UIDLEN);
- offset += UIDLEN;
-
- GroupId = (int)ParseOctal(header, offset, GIDLEN);
- offset += GIDLEN;
- Size = ParseBinaryOrOctal(header, offset, SIZELEN);
- offset += SIZELEN;
-
- ModTime = GetDateTimeFromCTime(ParseOctal(header, offset, MODTIMELEN));
- offset += MODTIMELEN;
-
- checksum = (int)ParseOctal(header, offset, CHKSUMLEN);
- offset += CHKSUMLEN;
-
- TypeFlag = header[ offset++ ];
- LinkName = ParseName(header, offset, NAMELEN).ToString();
- offset += NAMELEN;
-
- Magic = ParseName(header, offset, MAGICLEN).ToString();
- offset += MAGICLEN;
-
- Version = ParseName(header, offset, VERSIONLEN).ToString();
- offset += VERSIONLEN;
-
- UserName = ParseName(header, offset, UNAMELEN).ToString();
- offset += UNAMELEN;
-
- GroupName = ParseName(header, offset, GNAMELEN).ToString();
- offset += GNAMELEN;
-
- DevMajor = (int)ParseOctal(header, offset, DEVLEN);
- offset += DEVLEN;
-
- DevMinor = (int)ParseOctal(header, offset, DEVLEN);
-
-
-
- isChecksumValid = Checksum == TarHeader.MakeCheckSum(header);
- }
-
-
-
-
- public void WriteHeader(byte[] outBuffer)
- {
- if ( outBuffer == null )
- {
- throw new ArgumentNullException("outBuffer");
- }
- int offset = 0;
-
- offset = GetNameBytes(Name, outBuffer, offset, NAMELEN);
- offset = GetOctalBytes(mode, outBuffer, offset, MODELEN);
- offset = GetOctalBytes(UserId, outBuffer, offset, UIDLEN);
- offset = GetOctalBytes(GroupId, outBuffer, offset, GIDLEN);
- offset = GetBinaryOrOctalBytes(Size, outBuffer, offset, SIZELEN);
- offset = GetOctalBytes(GetCTime(ModTime), outBuffer, offset, MODTIMELEN);
- int csOffset = offset;
- for (int c = 0; c < CHKSUMLEN; ++c)
- {
- outBuffer[offset++] = (byte)' ';
- }
-
- outBuffer[offset++] = TypeFlag;
-
- offset = GetNameBytes(LinkName, outBuffer, offset, NAMELEN);
- offset = GetAsciiBytes(Magic, 0, outBuffer, offset, MAGICLEN);
- offset = GetNameBytes(Version, outBuffer, offset, VERSIONLEN);
- offset = GetNameBytes(UserName, outBuffer, offset, UNAMELEN);
- offset = GetNameBytes(GroupName, outBuffer, offset, GNAMELEN);
-
- if ((TypeFlag == LF_CHR) || (TypeFlag == LF_BLK))
- {
- offset = GetOctalBytes(DevMajor, outBuffer, offset, DEVLEN);
- offset = GetOctalBytes(DevMinor, outBuffer, offset, DEVLEN);
- }
-
- for ( ; offset < outBuffer.Length; )
- {
- outBuffer[offset++] = 0;
- }
-
- checksum = ComputeCheckSum(outBuffer);
-
- GetCheckSumOctalBytes(checksum, outBuffer, csOffset, CHKSUMLEN);
- isChecksumValid = true;
- }
-
-
-
-
- public override int GetHashCode()
- {
- return Name.GetHashCode();
- }
-
-
-
-
-
-
- public override bool Equals(object obj)
- {
- TarHeader localHeader = obj as TarHeader;
- bool result;
- if ( localHeader != null )
- {
- result = (name == localHeader.name)
- && (mode == localHeader.mode)
- && (UserId == localHeader.UserId)
- && (GroupId == localHeader.GroupId)
- && (Size == localHeader.Size)
- && (ModTime == localHeader.ModTime)
- && (Checksum == localHeader.Checksum)
- && (TypeFlag == localHeader.TypeFlag)
- && (LinkName == localHeader.LinkName)
- && (Magic == localHeader.Magic)
- && (Version == localHeader.Version)
- && (UserName == localHeader.UserName)
- && (GroupName == localHeader.GroupName)
- && (DevMajor == localHeader.DevMajor)
- && (DevMinor == localHeader.DevMinor);
- }
- else
- {
- result = false;
- }
- return result;
- }
-
-
-
-
-
-
-
-
- static internal void SetValueDefaults(int userId, string userName, int groupId, string groupName)
- {
- defaultUserId = userIdAsSet = userId;
- defaultUser = userNameAsSet = userName;
- defaultGroupId = groupIdAsSet = groupId;
- defaultGroupName = groupNameAsSet = groupName;
- }
- static internal void RestoreSetValues()
- {
- defaultUserId = userIdAsSet;
- defaultUser = userNameAsSet;
- defaultGroupId = groupIdAsSet;
- defaultGroupName = groupNameAsSet;
- }
-
-
- static private long ParseBinaryOrOctal(byte[] header, int offset, int length) {
- if (header[offset] >= 0x80) {
-
- long result = 0;
- for (int pos = length - 8; pos < length; pos++) {
- result = result << 8 | header[offset + pos];
- }
- return result;
- }
- return ParseOctal(header, offset, length);
- }
-
-
-
-
-
-
-
- static public long ParseOctal(byte[] header, int offset, int length)
- {
- if ( header == null ) {
- throw new ArgumentNullException("header");
- }
- long result = 0;
- bool stillPadding = true;
-
- int end = offset + length;
- for (int i = offset; i < end ; ++i) {
- if (header[i] == 0) {
- break;
- }
-
- if (header[i] == (byte)' ' || header[i] == '0') {
- if (stillPadding) {
- continue;
- }
-
- if (header[i] == (byte)' ') {
- break;
- }
- }
-
- stillPadding = false;
-
- result = (result << 3) + (header[i] - '0');
- }
-
- return result;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- static public StringBuilder ParseName(byte[] header, int offset, int length)
- {
- if ( header == null ) {
- throw new ArgumentNullException("header");
- }
- if ( offset < 0 ) {
- #if NETCF_1_0
- throw new ArgumentOutOfRangeException("offset");
- #else
- throw new ArgumentOutOfRangeException("offset", "Cannot be less than zero");
- #endif
- }
- if ( length < 0 )
- {
- #if NETCF_1_0
- throw new ArgumentOutOfRangeException("length");
- #else
- throw new ArgumentOutOfRangeException("length", "Cannot be less than zero");
- #endif
- }
- if ( offset + length > header.Length )
- {
- throw new ArgumentException("Exceeds header size", "length");
- }
- StringBuilder result = new StringBuilder(length);
-
- for (int i = offset; i < offset + length; ++i) {
- if (header[i] == 0) {
- break;
- }
- result.Append((char)header[i]);
- }
-
- return result;
- }
-
-
-
-
-
-
-
-
-
-
- public static int GetNameBytes(StringBuilder name, int nameOffset, byte[] buffer, int bufferOffset, int length)
- {
- if ( name == null ) {
- throw new ArgumentNullException("name");
- }
- if ( buffer == null ) {
- throw new ArgumentNullException("buffer");
- }
- return GetNameBytes(name.ToString(), nameOffset, buffer, bufferOffset, length);
- }
-
-
-
-
-
-
-
-
-
-
- public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int bufferOffset, int length)
- {
- if ( name == null )
- {
- throw new ArgumentNullException("name");
- }
- if ( buffer == null )
- {
- throw new ArgumentNullException("buffer");
- }
- int i;
-
- for (i = 0 ; i < length - 1 && nameOffset + i < name.Length; ++i) {
- buffer[bufferOffset + i] = (byte)name[nameOffset + i];
- }
-
- for (; i < length ; ++i) {
- buffer[bufferOffset + i] = 0;
- }
-
- return bufferOffset + length;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, int length)
- {
- if ( name == null ) {
- throw new ArgumentNullException("name");
- }
- if ( buffer == null ) {
- throw new ArgumentNullException("buffer");
- }
- return GetNameBytes(name.ToString(), 0, buffer, offset, length);
- }
-
-
-
-
-
-
-
-
-
- public static int GetNameBytes(string name, byte[] buffer, int offset, int length)
- {
- if ( name == null ) {
- throw new ArgumentNullException("name");
- }
- if ( buffer == null )
- {
- throw new ArgumentNullException("buffer");
- }
- return GetNameBytes(name, 0, buffer, offset, length);
- }
-
-
-
-
-
-
-
-
-
-
- public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int bufferOffset, int length )
- {
- if ( toAdd == null ) {
- throw new ArgumentNullException("toAdd");
- }
- if ( buffer == null ) {
- throw new ArgumentNullException("buffer");
- }
- for (int i = 0 ; i < length && nameOffset + i < toAdd.Length; ++i)
- {
- buffer[bufferOffset + i] = (byte)toAdd[nameOffset + i];
- }
- return bufferOffset + length;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public static int GetOctalBytes(long value, byte[] buffer, int offset, int length)
- {
- if ( buffer == null ) {
- throw new ArgumentNullException("buffer");
- }
- int localIndex = length - 1;
-
- buffer[offset + localIndex] = 0;
- --localIndex;
- if (value > 0) {
- for ( long v = value; (localIndex >= 0) && (v > 0); --localIndex ) {
- buffer[offset + localIndex] = (byte)((byte)'0' + (byte)(v & 7));
- v >>= 3;
- }
- }
-
- for ( ; localIndex >= 0; --localIndex ) {
- buffer[offset + localIndex] = (byte)'0';
- }
-
- return offset + length;
- }
-
-
-
-
-
-
-
-
-
- private static int GetBinaryOrOctalBytes(long value, byte[] buffer, int offset, int length)
- {
- if (value > 0x1FFFFFFFF) {
-
- for (int pos = length - 1; pos > 0; pos--) {
- buffer[offset + pos] = (byte)value;
- value = value >> 8;
- }
- buffer[offset] = 0x80;
- return offset + length;
- }
- return GetOctalBytes(value, buffer, offset, length);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- static void GetCheckSumOctalBytes(long value, byte[] buffer, int offset, int length)
- {
- GetOctalBytes(value, buffer, offset, length - 1);
- }
-
-
-
-
-
-
-
- static int ComputeCheckSum(byte[] buffer)
- {
- int sum = 0;
- for (int i = 0; i < buffer.Length; ++i) {
- sum += buffer[i];
- }
- return sum;
- }
-
-
-
-
-
-
- static int MakeCheckSum(byte[] buffer)
- {
- int sum = 0;
- for ( int i = 0; i < CHKSUMOFS; ++i )
- {
- sum += buffer[i];
- }
-
- for ( int i = 0; i < CHKSUMLEN; ++i)
- {
- sum += (byte)' ';
- }
-
- for (int i = CHKSUMOFS + CHKSUMLEN; i < buffer.Length; ++i)
- {
- sum += buffer[i];
- }
- return sum;
- }
-
- static int GetCTime(DateTime dateTime)
- {
- return unchecked((int)((dateTime.Ticks - dateTime1970.Ticks) / timeConversionFactor));
- }
-
- static DateTime GetDateTimeFromCTime(long ticks)
- {
- DateTime result;
-
- try {
- result = new DateTime(dateTime1970.Ticks + ticks * timeConversionFactor);
- }
- catch(ArgumentOutOfRangeException) {
- result = dateTime1970;
- }
- return result;
- }
- #region Instance Fields
- string name;
- int mode;
- int userId;
- int groupId;
- long size;
- DateTime modTime;
- int checksum;
- bool isChecksumValid;
- byte typeFlag;
- string linkName;
- string magic;
- string version;
- string userName;
- string groupName;
- int devMajor;
- int devMinor;
- #endregion
- #region Class Fields
-
- static internal int userIdAsSet;
- static internal int groupIdAsSet;
- static internal string userNameAsSet;
- static internal string groupNameAsSet = "None";
-
- static internal int defaultUserId;
- static internal int defaultGroupId;
- static internal string defaultGroupName = "None";
- static internal string defaultUser;
- #endregion
- }
- }
|