2 * /packages/iso9660-files filesystem handler
4 * (c) 2009 Laurent Vivier <Laurent@vivier.eu>
5 * (c) 2010 Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
9 #include "libopenbios/bindings.h"
10 #include "libiso9660.h"
12 #include "libc/vsprintf.h"
13 #include "libc/diskio.h"
15 extern void iso9660_init( void );
18 enum { FILE, DIR } type;
26 iso9660_VOLUME *volume;
27 iso9660_COMMON *common;
30 DECLARE_NODE( iso9660, 0, sizeof(iso9660_info_t), "+/packages/iso9660-files" );
34 iso9660_files_open( iso9660_info_t *mi )
37 char *path = my_args_copy();
42 fd = open_ih( my_parent() );
48 mi->volume = iso9660_mount( fd );
49 if ( mi->volume == NULL ) {
55 mi->common->dir = iso9660_opendir( mi->volume, path );
56 if ( mi->common->dir == NULL ) {
57 mi->common->file = iso9660_open( mi->volume, path );
58 if (mi->common->file == NULL) {
59 iso9660_umount( mi->volume );
64 mi->common->type = FILE;
68 mi->common->type = DIR;
76 iso9660_files_close( iso9660_info_t *mi )
78 int fd = mi->volume->fd;
80 if (mi->common->type == FILE )
81 iso9660_close( mi->common->file );
82 else if ( mi->common->type == DIR )
83 iso9660_closedir( mi->common->dir );
84 iso9660_umount( mi->volume );
88 /* ( buf len -- actlen ) */
90 iso9660_files_read( iso9660_info_t *mi )
93 char *buf = (char *)cell2pointer(POP());
96 if ( mi->common->type != FILE )
99 ret = iso9660_read( mi->common->file, buf, count );
104 /* ( pos.d -- status ) */
106 iso9660_files_seek( iso9660_info_t *mi )
108 long long pos = DPOP();
111 int whence = SEEK_SET;
113 if (mi->common->type != FILE)
121 ret = iso9660_lseek(mi->common->file, offs, whence);
123 PUSH( (ret < 0)? -1 : 0 );
126 /* ( -- filepos.d ) */
128 iso9660_files_offset( iso9660_info_t *mi )
130 if ( mi->common->type != FILE )
133 DPUSH( mi->common->file->offset );
136 /* ( addr -- size ) */
138 iso9660_files_load( iso9660_info_t *mi)
140 char *buf = (char*)cell2pointer(POP());
143 if ( mi->common->type != FILE )
148 ret = iso9660_read( mi->common->file, buf, 512 );
159 /* static method, ( pathstr len ihandle -- ) */
161 iso9660_files_dir( iso9660_info_t *dummy )
163 iso9660_VOLUME *volume;
164 iso9660_COMMON *common;
165 struct iso_directory_record *idr;
169 ihandle_t ih = POP();
170 char *path = pop_fstr_copy();
178 volume = iso9660_mount( fd );
179 if ( volume == NULL ) {
185 common = malloc(sizeof(iso9660_COMMON));
186 common->dir = iso9660_opendir( volume, path );
189 while ( (idr = iso9660_readdir(common->dir)) ) {
191 forth_printf("% 10d ", isonum_733(idr->size));
192 forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
193 idr->date[0] + 1900, /* year */
194 idr->date[1], /* month */
195 idr->date[2], /* day */
196 idr->date[3], idr->date[4], idr->date[5]);
197 iso9660_name(common->dir->volume, idr, name_buf);
198 if (idr->flags[0] & 2)
199 forth_printf("%s\\\n", name_buf);
201 forth_printf("%s\n", name_buf);
204 iso9660_closedir( common->dir );
205 iso9660_umount( volume );
213 /* static method, ( pos.d ih -- flag? ) */
215 iso9660_files_probe( iso9660_info_t *dummy )
217 ihandle_t ih = POP_ih();
218 long long offs = DPOP();
223 if (iso9660_probe(fd, offs)) {
235 iso9660_files_block_size( iso9660_info_t *dummy )
241 iso9660_initializer( iso9660_info_t *dummy )
243 fword("register-fs-package");
246 NODE_METHODS( iso9660 ) = {
247 { "probe", iso9660_files_probe },
248 { "open", iso9660_files_open },
249 { "close", iso9660_files_close },
250 { "read", iso9660_files_read },
251 { "seek", iso9660_files_seek },
252 { "offset", iso9660_files_offset },
253 { "load", iso9660_files_load },
254 { "dir", iso9660_files_dir },
255 { "block-size", iso9660_files_block_size },
256 { NULL, iso9660_initializer },
262 REGISTER_NODE( iso9660 );