1/*
2 * Copyright 1999, Be Incorporated.   All Rights Reserved.
3 * This file may be used under the terms of the Be Sample Code License.
4 *
5 * Copyright 2001, pinc Software.  All Rights Reserved.
6 */
7#ifndef ISO_9660_H
8#define ISO_9660_H
9
10
11#if FS_SHELL
12#	include "fssh_api_wrapper.h"
13#else
14#	include <stdio.h>
15#	include <sys/types.h>
16#	include <time.h>
17#	include <endian.h>
18
19#	include <fs_interface.h>
20#	include <SupportDefs.h>
21
22#	include <lock.h>
23#endif
24
25
26// Size of primary volume descriptor for ISO9660
27#define ISO_PVD_SIZE 882
28
29// ISO structure has both msb and lsb first data. These let you do a
30// compile-time switch for different platforms.
31
32enum {
33	LSB_DATA = 0,
34	MSB_DATA
35};
36
37// This defines the data format for the platform we are compiling
38// for.
39#if BYTE_ORDER == __LITTLE_ENDIAN
40#	define FS_DATA_FORMAT LSB_DATA
41#else
42#	define FS_DATA_FORMAT MSB_DATA
43#endif
44
45// ISO pdf file spec I read appears to be WRONG about the date format. See
46// www.alumni.caltech.edu/~pje/iso9660.html, definition there seems
47// to match.
48typedef struct ISOVolDate {
49 	char	year[5];
50 	char	month[3];
51 	char	day[3];
52 	char	hour[3];
53 	char	minute[3];
54 	char	second[3];
55 	char	hunSec[3];
56 	int8	offsetGMT;
57} ISOVolDate;
58
59// Size of volume date and time data
60#define ISO_VOL_DATE_SIZE 17
61
62typedef struct ISORecDate {
63	uint8	year;			// Year - 1900
64	uint8	month;
65	uint8	date;
66	uint8	hour;
67	uint8	minute;
68	uint8	second;
69	int8	offsetGMT;
70} ISORecDate;
71
72// This next section is data structure to hold the data found in the
73// rock ridge extensions.
74struct rock_ridge_attributes {
75	char*			slName;
76	struct stat		stat[2];
77	uint8			nmVer;
78	uint8			pxVer;
79	uint8			slVer;
80};
81
82struct iso9660_volume;
83
84struct iso9660_inode {
85	/* Most drivers will probably want the first things defined here. */
86	ino_t		id;
87	ino_t	 	parID;		// parent vnode ID.
88	struct iso9660_volume* volume;
89	void		*cache;		// for file cache
90
91	// End of members other drivers will definitely want.
92
93	/* The rest of this struct is very ISO-specific. You should replace the rest of this
94		definition with the stuff your file system needs.
95	*/
96	uint8		extAttrRecLen;			// Length of extended attribute record.
97	uint32		startLBN[2];			// Logical block # of start of file/directory data
98	uint32		dataLen[2];				// Length of file section in bytes
99	ISORecDate	recordDate;				// Date file was recorded.
100
101										// BIT MEANING
102										// --- -----------------------------
103	uint8		flags;					// 0 - is hidden
104										// 1 - is directory
105										// 2 - is "Associated File"
106										// 3 - Info is structed according to extended attr record
107										// 4 - Owner, group, ppermisssions are specified in the
108										//		extended attr record
109										// 5 - Reserved
110										// 6 - Reserved
111										// 7 - File has more that one directory record
112
113	uint8		fileUnitSize;			// Interleave only
114	uint8		interleaveGapSize;		// Interleave only
115	uint32		volSeqNum;				// Volume sequence number of volume
116	char*		name;
117	uint32		name_length;
118
119	// The rest is Rock Ridge extensions. I suggest www.leo.org for spec info.
120	rock_ridge_attributes attr;
121};
122
123// These go with the flags member of the iso9660_volume struct.
124enum {
125	ISO_IS_HIDDEN				= 0x01,
126	ISO_IS_DIR					= 0x02,
127	ISO_IS_ASSOCIATED_FILE		= 0x04,
128	ISO_EXTENDED_ATTRIBUTE		= 0x08,
129	ISO_EXTENDED_PERMISSIONS	= 0x10,
130	ISO_MORE_DIRS				= 0x80
131};
132
133
134// Arbitrarily - selected root vnode id
135#define ISO_ROOTNODE_ID 1
136
137/* Structure used for directory "cookie". When you are asked
138 	to open a directory, you are asked to create a cookie for it
139 	and pass it back. The cookie should contain the information you
140 	need to determine where you are at in reading the directory
141 	entries, incremented every time readdir is called, until finally
142 	the end is reached, when readdir returns NULL. */
143typedef struct dircookie {
144	off_t startBlock;
145	off_t block;			// Current block
146	off_t pos;				// Position within block.
147	off_t totalSize;		// Size of directory file
148	off_t id;
149} dircookie;
150
151/* You may also need to define a cookie for files, which again is
152	allocated every time a file is opened and freed when the free
153	cookie function is called. For ISO, we didn't need one.
154*/
155
156typedef struct attrfilemap {
157	char  *name;
158	off_t offset;
159} attrfilemap;
160
161// This is the global volume iso9660_volume struct.
162struct iso9660_volume {
163	// Start of members other drivers will definitely want.
164	fs_volume		*volume;			// volume passed fo fs_mount
165	dev_t			id;
166	int				fd;				// File descriptor
167	int				fdOfSession;	// File descriptor of the (mounted) session
168	//unsigned int 	blockSize;  	// usually need this, but it's part of ISO
169	void                            *fBlockCache;
170
171	char			devicePath[127];
172	//off_t			numBlocks;		// May need this, but it's part of ISO
173
174	// End of members other drivers will definitely want.
175
176	// attribute extensions
177	int32			readAttributes;
178	attrfilemap 	*attrFileMap;
179	ino_t			attributesID;
180
181	// JOLIET extension: joliet_level for this volume
182	uint8			joliet_level;
183
184	// All this stuff comes straight from ISO primary volume
185	// descriptor structure.
186	uint8			volDescType;		// Volume Descriptor type								byte1
187	char			stdIDString[6];		// Standard ID, 1 extra for null						byte2-6
188	uint8			volDescVersion;		// Volume Descriptor version							byte7
189	uint8			unused1;			// Unused Field											byte8
190	char			systemIDString[33];	// System ID, 1 extra for null							byte9-40
191	char			volIDString[33];	// Volume ID, 1 extra for null							byte41-72
192	char			unused2[9];			// Unused Field											byte73-80
193	uint32			volSpaceSize[2];	// #logical blocks, lsb and msb							byte81-88
194	char			unused3[33];		// Unused Field											byte89-120
195	uint16			volSetSize[2];		// Assigned Volume Set Size of Vol						byte121-124
196	uint16			volSeqNum[2];		// Ordinal number of volume in Set						byte125-128
197	uint16			logicalBlkSize[2];	// Logical blocksize, usually 2048						byte129-132
198	uint32			pathTblSize[2];		// Path table size										byte133-149
199	uint16			lPathTblLoc[2];		// Loc (Logical block #) of "Type L" path table			byte141-144
200	uint16			optLPathTblLoc[2];	// Loc (Logical block #) of optional Type L path tbl	byte145-148
201	uint16			mPathTblLoc[2];		// Loc (Logical block #) of "Type M" path table			byte149-152
202	uint16			optMPathTblLoc[2];	// Loc (Logical block #) of optional Type M path tbl	byte153-156
203	iso9660_inode	rootDirRec;			// Directory record for root directory					byte157-190
204	char			volSetIDString[129]; // Name of multi-volume set where vol is member		byte191-318
205	char			pubIDString[129];	// Name of publisher									byte319-446
206	char			dataPreparer[129];	// Name of data preparer								byte447-574
207	char			appIDString[129];	// Identifies data fomrat								byte575-702
208	char			copyright[38];		// Copyright string										byte703-739
209	char			abstractFName[38];	// Name of file in root that has abstract				byte740-776
210	char			biblioFName[38];	// Name of file in root that has biblio					byte777-813
211
212	ISOVolDate		createDate;			// Creation date										byte
213	ISOVolDate		modDate;			// Modification date
214	ISOVolDate		expireDate;			// Data expiration date
215	ISOVolDate		effectiveDate;		// Data effective data
216
217	uint8			fileStructVers;		// File structure version								byte882
218};
219
220// Size of root directory record
221#define ISO_ROOT_DIR_REC_SIZE 34
222
223status_t ISOMount(const char *path, uint32 flags, iso9660_volume** _newVolume,
224	bool allowJoliet);
225status_t ISOReadDirEnt(iso9660_volume* ns, dircookie* cookie,
226	struct dirent* buffer, size_t bufferSize);
227status_t InitNode(iso9660_volume* volume, iso9660_inode* rec, char* buf,
228	size_t* bytesRead, bool relocated = false);
229status_t ConvertRecDate(ISORecDate* inDate, time_t* outDate);
230
231#endif	/* ISO_9660_H */
232