xref: /aosp_15_r20/build/soong/third_party/zip/struct.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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