1*333d2b36SAndroid Build Coastguard Worker// Copyright 2010 The Go Authors. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style 3*333d2b36SAndroid Build Coastguard Worker// license that can be found in the LICENSE file. 4*333d2b36SAndroid Build Coastguard Worker 5*333d2b36SAndroid Build Coastguard Worker/* 6*333d2b36SAndroid Build Coastguard WorkerPackage zip provides support for reading and writing ZIP archives. 7*333d2b36SAndroid Build Coastguard Worker 8*333d2b36SAndroid Build Coastguard WorkerSee: https://www.pkware.com/documents/casestudies/APPNOTE.TXT 9*333d2b36SAndroid Build Coastguard Worker 10*333d2b36SAndroid Build Coastguard WorkerThis package does not support disk spanning. 11*333d2b36SAndroid Build Coastguard Worker 12*333d2b36SAndroid Build Coastguard WorkerA note about ZIP64: 13*333d2b36SAndroid Build Coastguard Worker 14*333d2b36SAndroid Build Coastguard WorkerTo be backwards compatible the FileHeader has both 32 and 64 bit Size 15*333d2b36SAndroid Build Coastguard Workerfields. The 64 bit fields will always contain the correct value and 16*333d2b36SAndroid Build Coastguard Workerfor normal archives both fields will be the same. For files requiring 17*333d2b36SAndroid Build Coastguard Workerthe ZIP64 format the 32 bit fields will be 0xffffffff and the 64 bit 18*333d2b36SAndroid Build Coastguard Workerfields must be used instead. 19*333d2b36SAndroid Build Coastguard Worker*/ 20*333d2b36SAndroid Build Coastguard Workerpackage zip 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Workerimport ( 23*333d2b36SAndroid Build Coastguard Worker "os" 24*333d2b36SAndroid Build Coastguard Worker "path" 25*333d2b36SAndroid Build Coastguard Worker "time" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Worker// Compression methods. 29*333d2b36SAndroid Build Coastguard Workerconst ( 30*333d2b36SAndroid Build Coastguard Worker Store uint16 = 0 31*333d2b36SAndroid Build Coastguard Worker Deflate uint16 = 8 32*333d2b36SAndroid Build Coastguard Worker) 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Workerconst ( 35*333d2b36SAndroid Build Coastguard Worker fileHeaderSignature = 0x04034b50 36*333d2b36SAndroid Build Coastguard Worker directoryHeaderSignature = 0x02014b50 37*333d2b36SAndroid Build Coastguard Worker directoryEndSignature = 0x06054b50 38*333d2b36SAndroid Build Coastguard Worker directory64LocSignature = 0x07064b50 39*333d2b36SAndroid Build Coastguard Worker directory64EndSignature = 0x06064b50 40*333d2b36SAndroid Build Coastguard Worker dataDescriptorSignature = 0x08074b50 // de-facto standard; required by OS X Finder 41*333d2b36SAndroid Build Coastguard Worker fileHeaderLen = 30 // + filename + extra 42*333d2b36SAndroid Build Coastguard Worker directoryHeaderLen = 46 // + filename + extra + comment 43*333d2b36SAndroid Build Coastguard Worker directoryEndLen = 22 // + comment 44*333d2b36SAndroid Build Coastguard Worker dataDescriptorLen = 16 // four uint32: descriptor signature, crc32, compressed size, size 45*333d2b36SAndroid Build Coastguard Worker dataDescriptor64Len = 24 // descriptor with 8 byte sizes 46*333d2b36SAndroid Build Coastguard Worker directory64LocLen = 20 // 47*333d2b36SAndroid Build Coastguard Worker directory64EndLen = 56 // + extra 48*333d2b36SAndroid Build Coastguard Worker 49*333d2b36SAndroid Build Coastguard Worker // Constants for the first byte in CreatorVersion 50*333d2b36SAndroid Build Coastguard Worker creatorFAT = 0 51*333d2b36SAndroid Build Coastguard Worker creatorUnix = 3 52*333d2b36SAndroid Build Coastguard Worker creatorNTFS = 11 53*333d2b36SAndroid Build Coastguard Worker creatorVFAT = 14 54*333d2b36SAndroid Build Coastguard Worker creatorMacOSX = 19 55*333d2b36SAndroid Build Coastguard Worker 56*333d2b36SAndroid Build Coastguard Worker // version numbers 57*333d2b36SAndroid Build Coastguard Worker zipVersion20 = 20 // 2.0 58*333d2b36SAndroid Build Coastguard Worker zipVersion45 = 45 // 4.5 (reads and writes zip64 archives) 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker // limits for non zip64 files 61*333d2b36SAndroid Build Coastguard Worker uint16max = (1 << 16) - 1 62*333d2b36SAndroid Build Coastguard Worker uint32max = (1 << 32) - 1 63*333d2b36SAndroid Build Coastguard Worker 64*333d2b36SAndroid Build Coastguard Worker // extra header id's 65*333d2b36SAndroid Build Coastguard Worker zip64ExtraId = 0x0001 // zip64 Extended Information Extra Field 66*333d2b36SAndroid Build Coastguard Worker) 67*333d2b36SAndroid Build Coastguard Worker 68*333d2b36SAndroid Build Coastguard Worker// FileHeader describes a file within a zip file. 69*333d2b36SAndroid Build Coastguard Worker// See the zip spec for details. 70*333d2b36SAndroid Build Coastguard Workertype FileHeader struct { 71*333d2b36SAndroid Build Coastguard Worker // Name is the name of the file. 72*333d2b36SAndroid Build Coastguard Worker // It must be a relative path: it must not start with a drive 73*333d2b36SAndroid Build Coastguard Worker // letter (e.g. C:) or leading slash, and only forward slashes 74*333d2b36SAndroid Build Coastguard Worker // are allowed. 75*333d2b36SAndroid Build Coastguard Worker Name string 76*333d2b36SAndroid Build Coastguard Worker 77*333d2b36SAndroid Build Coastguard Worker CreatorVersion uint16 78*333d2b36SAndroid Build Coastguard Worker ReaderVersion uint16 79*333d2b36SAndroid Build Coastguard Worker Flags uint16 80*333d2b36SAndroid Build Coastguard Worker Method uint16 81*333d2b36SAndroid Build Coastguard Worker ModifiedTime uint16 // MS-DOS time 82*333d2b36SAndroid Build Coastguard Worker ModifiedDate uint16 // MS-DOS date 83*333d2b36SAndroid Build Coastguard Worker CRC32 uint32 84*333d2b36SAndroid Build Coastguard Worker CompressedSize uint32 // Deprecated: Use CompressedSize64 instead. 85*333d2b36SAndroid Build Coastguard Worker UncompressedSize uint32 // Deprecated: Use UncompressedSize64 instead. 86*333d2b36SAndroid Build Coastguard Worker CompressedSize64 uint64 87*333d2b36SAndroid Build Coastguard Worker UncompressedSize64 uint64 88*333d2b36SAndroid Build Coastguard Worker Extra []byte 89*333d2b36SAndroid Build Coastguard Worker ExternalAttrs uint32 // Meaning depends on CreatorVersion 90*333d2b36SAndroid Build Coastguard Worker Comment string 91*333d2b36SAndroid Build Coastguard Worker} 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Worker// FileInfo returns an os.FileInfo for the FileHeader. 94*333d2b36SAndroid Build Coastguard Workerfunc (h *FileHeader) FileInfo() os.FileInfo { 95*333d2b36SAndroid Build Coastguard Worker return headerFileInfo{h} 96*333d2b36SAndroid Build Coastguard Worker} 97*333d2b36SAndroid Build Coastguard Worker 98*333d2b36SAndroid Build Coastguard Worker// headerFileInfo implements os.FileInfo. 99*333d2b36SAndroid Build Coastguard Workertype headerFileInfo struct { 100*333d2b36SAndroid Build Coastguard Worker fh *FileHeader 101*333d2b36SAndroid Build Coastguard Worker} 102*333d2b36SAndroid Build Coastguard Worker 103*333d2b36SAndroid Build Coastguard Workerfunc (fi headerFileInfo) Name() string { return path.Base(fi.fh.Name) } 104*333d2b36SAndroid Build Coastguard Workerfunc (fi headerFileInfo) Size() int64 { 105*333d2b36SAndroid Build Coastguard Worker if fi.fh.UncompressedSize64 > 0 { 106*333d2b36SAndroid Build Coastguard Worker return int64(fi.fh.UncompressedSize64) 107*333d2b36SAndroid Build Coastguard Worker } 108*333d2b36SAndroid Build Coastguard Worker return int64(fi.fh.UncompressedSize) 109*333d2b36SAndroid Build Coastguard Worker} 110*333d2b36SAndroid Build Coastguard Workerfunc (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() } 111*333d2b36SAndroid Build Coastguard Workerfunc (fi headerFileInfo) ModTime() time.Time { return fi.fh.ModTime() } 112*333d2b36SAndroid Build Coastguard Workerfunc (fi headerFileInfo) Mode() os.FileMode { return fi.fh.Mode() } 113*333d2b36SAndroid Build Coastguard Workerfunc (fi headerFileInfo) Sys() interface{} { return fi.fh } 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Worker// FileInfoHeader creates a partially-populated FileHeader from an 116*333d2b36SAndroid Build Coastguard Worker// os.FileInfo. 117*333d2b36SAndroid Build Coastguard Worker// Because os.FileInfo's Name method returns only the base name of 118*333d2b36SAndroid Build Coastguard Worker// the file it describes, it may be necessary to modify the Name field 119*333d2b36SAndroid Build Coastguard Worker// of the returned header to provide the full path name of the file. 120*333d2b36SAndroid Build Coastguard Workerfunc FileInfoHeader(fi os.FileInfo) (*FileHeader, error) { 121*333d2b36SAndroid Build Coastguard Worker size := fi.Size() 122*333d2b36SAndroid Build Coastguard Worker fh := &FileHeader{ 123*333d2b36SAndroid Build Coastguard Worker Name: fi.Name(), 124*333d2b36SAndroid Build Coastguard Worker UncompressedSize64: uint64(size), 125*333d2b36SAndroid Build Coastguard Worker } 126*333d2b36SAndroid Build Coastguard Worker fh.SetModTime(fi.ModTime()) 127*333d2b36SAndroid Build Coastguard Worker fh.SetMode(fi.Mode()) 128*333d2b36SAndroid Build Coastguard Worker if fh.UncompressedSize64 > uint32max { 129*333d2b36SAndroid Build Coastguard Worker fh.UncompressedSize = uint32max 130*333d2b36SAndroid Build Coastguard Worker } else { 131*333d2b36SAndroid Build Coastguard Worker fh.UncompressedSize = uint32(fh.UncompressedSize64) 132*333d2b36SAndroid Build Coastguard Worker } 133*333d2b36SAndroid Build Coastguard Worker return fh, nil 134*333d2b36SAndroid Build Coastguard Worker} 135*333d2b36SAndroid Build Coastguard Worker 136*333d2b36SAndroid Build Coastguard Workertype directoryEnd struct { 137*333d2b36SAndroid Build Coastguard Worker diskNbr uint32 // unused 138*333d2b36SAndroid Build Coastguard Worker dirDiskNbr uint32 // unused 139*333d2b36SAndroid Build Coastguard Worker dirRecordsThisDisk uint64 // unused 140*333d2b36SAndroid Build Coastguard Worker directoryRecords uint64 141*333d2b36SAndroid Build Coastguard Worker directorySize uint64 142*333d2b36SAndroid Build Coastguard Worker directoryOffset uint64 // relative to file 143*333d2b36SAndroid Build Coastguard Worker commentLen uint16 144*333d2b36SAndroid Build Coastguard Worker comment string 145*333d2b36SAndroid Build Coastguard Worker} 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Worker// msDosTimeToTime converts an MS-DOS date and time into a time.Time. 148*333d2b36SAndroid Build Coastguard Worker// The resolution is 2s. 149*333d2b36SAndroid Build Coastguard Worker// See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx 150*333d2b36SAndroid Build Coastguard Workerfunc msDosTimeToTime(dosDate, dosTime uint16) time.Time { 151*333d2b36SAndroid Build Coastguard Worker return time.Date( 152*333d2b36SAndroid Build Coastguard Worker // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980 153*333d2b36SAndroid Build Coastguard Worker int(dosDate>>9+1980), 154*333d2b36SAndroid Build Coastguard Worker time.Month(dosDate>>5&0xf), 155*333d2b36SAndroid Build Coastguard Worker int(dosDate&0x1f), 156*333d2b36SAndroid Build Coastguard Worker 157*333d2b36SAndroid Build Coastguard Worker // time bits 0-4: second/2; 5-10: minute; 11-15: hour 158*333d2b36SAndroid Build Coastguard Worker int(dosTime>>11), 159*333d2b36SAndroid Build Coastguard Worker int(dosTime>>5&0x3f), 160*333d2b36SAndroid Build Coastguard Worker int(dosTime&0x1f*2), 161*333d2b36SAndroid Build Coastguard Worker 0, // nanoseconds 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker time.UTC, 164*333d2b36SAndroid Build Coastguard Worker ) 165*333d2b36SAndroid Build Coastguard Worker} 166*333d2b36SAndroid Build Coastguard Worker 167*333d2b36SAndroid Build Coastguard Worker// timeToMsDosTime converts a time.Time to an MS-DOS date and time. 168*333d2b36SAndroid Build Coastguard Worker// The resolution is 2s. 169*333d2b36SAndroid Build Coastguard Worker// See: http://msdn.microsoft.com/en-us/library/ms724274(v=VS.85).aspx 170*333d2b36SAndroid Build Coastguard Workerfunc timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) { 171*333d2b36SAndroid Build Coastguard Worker t = t.In(time.UTC) 172*333d2b36SAndroid Build Coastguard Worker fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9) 173*333d2b36SAndroid Build Coastguard Worker fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11) 174*333d2b36SAndroid Build Coastguard Worker return 175*333d2b36SAndroid Build Coastguard Worker} 176*333d2b36SAndroid Build Coastguard Worker 177*333d2b36SAndroid Build Coastguard Worker// ModTime returns the modification time in UTC. 178*333d2b36SAndroid Build Coastguard Worker// The resolution is 2s. 179*333d2b36SAndroid Build Coastguard Workerfunc (h *FileHeader) ModTime() time.Time { 180*333d2b36SAndroid Build Coastguard Worker return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime) 181*333d2b36SAndroid Build Coastguard Worker} 182*333d2b36SAndroid Build Coastguard Worker 183*333d2b36SAndroid Build Coastguard Worker// SetModTime sets the ModifiedTime and ModifiedDate fields to the given time in UTC. 184*333d2b36SAndroid Build Coastguard Worker// The resolution is 2s. 185*333d2b36SAndroid Build Coastguard Workerfunc (h *FileHeader) SetModTime(t time.Time) { 186*333d2b36SAndroid Build Coastguard Worker h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t) 187*333d2b36SAndroid Build Coastguard Worker} 188*333d2b36SAndroid Build Coastguard Worker 189*333d2b36SAndroid Build Coastguard Workerconst ( 190*333d2b36SAndroid Build Coastguard Worker // Unix constants. The specification doesn't mention them, 191*333d2b36SAndroid Build Coastguard Worker // but these seem to be the values agreed on by tools. 192*333d2b36SAndroid Build Coastguard Worker s_IFMT = 0xf000 193*333d2b36SAndroid Build Coastguard Worker s_IFSOCK = 0xc000 194*333d2b36SAndroid Build Coastguard Worker s_IFLNK = 0xa000 195*333d2b36SAndroid Build Coastguard Worker s_IFREG = 0x8000 196*333d2b36SAndroid Build Coastguard Worker s_IFBLK = 0x6000 197*333d2b36SAndroid Build Coastguard Worker s_IFDIR = 0x4000 198*333d2b36SAndroid Build Coastguard Worker s_IFCHR = 0x2000 199*333d2b36SAndroid Build Coastguard Worker s_IFIFO = 0x1000 200*333d2b36SAndroid Build Coastguard Worker s_ISUID = 0x800 201*333d2b36SAndroid Build Coastguard Worker s_ISGID = 0x400 202*333d2b36SAndroid Build Coastguard Worker s_ISVTX = 0x200 203*333d2b36SAndroid Build Coastguard Worker 204*333d2b36SAndroid Build Coastguard Worker msdosDir = 0x10 205*333d2b36SAndroid Build Coastguard Worker msdosReadOnly = 0x01 206*333d2b36SAndroid Build Coastguard Worker) 207*333d2b36SAndroid Build Coastguard Worker 208*333d2b36SAndroid Build Coastguard Worker// Mode returns the permission and mode bits for the FileHeader. 209*333d2b36SAndroid Build Coastguard Workerfunc (h *FileHeader) Mode() (mode os.FileMode) { 210*333d2b36SAndroid Build Coastguard Worker switch h.CreatorVersion >> 8 { 211*333d2b36SAndroid Build Coastguard Worker case creatorUnix, creatorMacOSX: 212*333d2b36SAndroid Build Coastguard Worker mode = unixModeToFileMode(h.ExternalAttrs >> 16) 213*333d2b36SAndroid Build Coastguard Worker case creatorNTFS, creatorVFAT, creatorFAT: 214*333d2b36SAndroid Build Coastguard Worker mode = msdosModeToFileMode(h.ExternalAttrs) 215*333d2b36SAndroid Build Coastguard Worker } 216*333d2b36SAndroid Build Coastguard Worker if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' { 217*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeDir 218*333d2b36SAndroid Build Coastguard Worker } 219*333d2b36SAndroid Build Coastguard Worker return mode 220*333d2b36SAndroid Build Coastguard Worker} 221*333d2b36SAndroid Build Coastguard Worker 222*333d2b36SAndroid Build Coastguard Worker// SetMode changes the permission and mode bits for the FileHeader. 223*333d2b36SAndroid Build Coastguard Workerfunc (h *FileHeader) SetMode(mode os.FileMode) { 224*333d2b36SAndroid Build Coastguard Worker h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8 225*333d2b36SAndroid Build Coastguard Worker h.ExternalAttrs = fileModeToUnixMode(mode) << 16 226*333d2b36SAndroid Build Coastguard Worker 227*333d2b36SAndroid Build Coastguard Worker // set MSDOS attributes too, as the original zip does. 228*333d2b36SAndroid Build Coastguard Worker if mode&os.ModeDir != 0 { 229*333d2b36SAndroid Build Coastguard Worker h.ExternalAttrs |= msdosDir 230*333d2b36SAndroid Build Coastguard Worker } 231*333d2b36SAndroid Build Coastguard Worker if mode&0200 == 0 { 232*333d2b36SAndroid Build Coastguard Worker h.ExternalAttrs |= msdosReadOnly 233*333d2b36SAndroid Build Coastguard Worker } 234*333d2b36SAndroid Build Coastguard Worker} 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker// isZip64 reports whether the file size exceeds the 32 bit limit 237*333d2b36SAndroid Build Coastguard Workerfunc (fh *FileHeader) isZip64() bool { 238*333d2b36SAndroid Build Coastguard Worker return fh.CompressedSize64 >= uint32max || fh.UncompressedSize64 >= uint32max 239*333d2b36SAndroid Build Coastguard Worker} 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Workerfunc msdosModeToFileMode(m uint32) (mode os.FileMode) { 242*333d2b36SAndroid Build Coastguard Worker if m&msdosDir != 0 { 243*333d2b36SAndroid Build Coastguard Worker mode = os.ModeDir | 0777 244*333d2b36SAndroid Build Coastguard Worker } else { 245*333d2b36SAndroid Build Coastguard Worker mode = 0666 246*333d2b36SAndroid Build Coastguard Worker } 247*333d2b36SAndroid Build Coastguard Worker if m&msdosReadOnly != 0 { 248*333d2b36SAndroid Build Coastguard Worker mode &^= 0222 249*333d2b36SAndroid Build Coastguard Worker } 250*333d2b36SAndroid Build Coastguard Worker return mode 251*333d2b36SAndroid Build Coastguard Worker} 252*333d2b36SAndroid Build Coastguard Worker 253*333d2b36SAndroid Build Coastguard Workerfunc fileModeToUnixMode(mode os.FileMode) uint32 { 254*333d2b36SAndroid Build Coastguard Worker var m uint32 255*333d2b36SAndroid Build Coastguard Worker switch mode & os.ModeType { 256*333d2b36SAndroid Build Coastguard Worker default: 257*333d2b36SAndroid Build Coastguard Worker m = s_IFREG 258*333d2b36SAndroid Build Coastguard Worker case os.ModeDir: 259*333d2b36SAndroid Build Coastguard Worker m = s_IFDIR 260*333d2b36SAndroid Build Coastguard Worker case os.ModeSymlink: 261*333d2b36SAndroid Build Coastguard Worker m = s_IFLNK 262*333d2b36SAndroid Build Coastguard Worker case os.ModeNamedPipe: 263*333d2b36SAndroid Build Coastguard Worker m = s_IFIFO 264*333d2b36SAndroid Build Coastguard Worker case os.ModeSocket: 265*333d2b36SAndroid Build Coastguard Worker m = s_IFSOCK 266*333d2b36SAndroid Build Coastguard Worker case os.ModeDevice: 267*333d2b36SAndroid Build Coastguard Worker if mode&os.ModeCharDevice != 0 { 268*333d2b36SAndroid Build Coastguard Worker m = s_IFCHR 269*333d2b36SAndroid Build Coastguard Worker } else { 270*333d2b36SAndroid Build Coastguard Worker m = s_IFBLK 271*333d2b36SAndroid Build Coastguard Worker } 272*333d2b36SAndroid Build Coastguard Worker } 273*333d2b36SAndroid Build Coastguard Worker if mode&os.ModeSetuid != 0 { 274*333d2b36SAndroid Build Coastguard Worker m |= s_ISUID 275*333d2b36SAndroid Build Coastguard Worker } 276*333d2b36SAndroid Build Coastguard Worker if mode&os.ModeSetgid != 0 { 277*333d2b36SAndroid Build Coastguard Worker m |= s_ISGID 278*333d2b36SAndroid Build Coastguard Worker } 279*333d2b36SAndroid Build Coastguard Worker if mode&os.ModeSticky != 0 { 280*333d2b36SAndroid Build Coastguard Worker m |= s_ISVTX 281*333d2b36SAndroid Build Coastguard Worker } 282*333d2b36SAndroid Build Coastguard Worker return m | uint32(mode&0777) 283*333d2b36SAndroid Build Coastguard Worker} 284*333d2b36SAndroid Build Coastguard Worker 285*333d2b36SAndroid Build Coastguard Workerfunc unixModeToFileMode(m uint32) os.FileMode { 286*333d2b36SAndroid Build Coastguard Worker mode := os.FileMode(m & 0777) 287*333d2b36SAndroid Build Coastguard Worker switch m & s_IFMT { 288*333d2b36SAndroid Build Coastguard Worker case s_IFBLK: 289*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeDevice 290*333d2b36SAndroid Build Coastguard Worker case s_IFCHR: 291*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeDevice | os.ModeCharDevice 292*333d2b36SAndroid Build Coastguard Worker case s_IFDIR: 293*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeDir 294*333d2b36SAndroid Build Coastguard Worker case s_IFIFO: 295*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeNamedPipe 296*333d2b36SAndroid Build Coastguard Worker case s_IFLNK: 297*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeSymlink 298*333d2b36SAndroid Build Coastguard Worker case s_IFREG: 299*333d2b36SAndroid Build Coastguard Worker // nothing to do 300*333d2b36SAndroid Build Coastguard Worker case s_IFSOCK: 301*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeSocket 302*333d2b36SAndroid Build Coastguard Worker } 303*333d2b36SAndroid Build Coastguard Worker if m&s_ISGID != 0 { 304*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeSetgid 305*333d2b36SAndroid Build Coastguard Worker } 306*333d2b36SAndroid Build Coastguard Worker if m&s_ISUID != 0 { 307*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeSetuid 308*333d2b36SAndroid Build Coastguard Worker } 309*333d2b36SAndroid Build Coastguard Worker if m&s_ISVTX != 0 { 310*333d2b36SAndroid Build Coastguard Worker mode |= os.ModeSticky 311*333d2b36SAndroid Build Coastguard Worker } 312*333d2b36SAndroid Build Coastguard Worker return mode 313*333d2b36SAndroid Build Coastguard Worker} 314