|
|
1.1 ! root 1: /* ! 2: * /packages/iso9660-files filesystem handler ! 3: * ! 4: * (c) 2009 Laurent Vivier <[email protected]> ! 5: * (c) 2010 Mark Cave-Ayland <[email protected]> ! 6: */ ! 7: ! 8: #include "config.h" ! 9: #include "libopenbios/bindings.h" ! 10: #include "libiso9660.h" ! 11: #include "fs/fs.h" ! 12: #include "libc/vsprintf.h" ! 13: #include "libc/diskio.h" ! 14: ! 15: extern void iso9660_init( void ); ! 16: ! 17: typedef struct { ! 18: enum { FILE, DIR } type; ! 19: union { ! 20: iso9660_FILE *file; ! 21: iso9660_DIR * dir; ! 22: }; ! 23: } iso9660_COMMON; ! 24: ! 25: typedef struct { ! 26: iso9660_VOLUME *volume; ! 27: iso9660_COMMON *common; ! 28: } iso9660_info_t; ! 29: ! 30: DECLARE_NODE( iso9660, 0, sizeof(iso9660_info_t), "+/packages/iso9660-files" ); ! 31: ! 32: /* ( -- success? ) */ ! 33: static void ! 34: iso9660_files_open( iso9660_info_t *mi ) ! 35: { ! 36: int fd; ! 37: char *path = my_args_copy(); ! 38: ! 39: if ( ! path ) ! 40: RET( 0 ); ! 41: ! 42: fd = open_ih( my_parent() ); ! 43: if ( fd == -1 ) { ! 44: free( path ); ! 45: RET( 0 ); ! 46: } ! 47: ! 48: mi->volume = iso9660_mount( fd ); ! 49: if ( mi->volume == NULL ) { ! 50: free( path ); ! 51: close_io( fd ); ! 52: RET( 0 ); ! 53: } ! 54: ! 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 ); ! 60: close_io( fd ); ! 61: free( path ); ! 62: RET( 0 ); ! 63: } ! 64: mi->common->type = FILE; ! 65: free( path ); ! 66: RET( -1 ); ! 67: } ! 68: mi->common->type = DIR; ! 69: free( path ); ! 70: ! 71: RET( -1 ); ! 72: } ! 73: ! 74: /* ( -- ) */ ! 75: static void ! 76: iso9660_files_close( iso9660_info_t *mi ) ! 77: { ! 78: int fd = mi->volume->fd; ! 79: ! 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 ); ! 85: close_io( fd ); ! 86: } ! 87: ! 88: /* ( buf len -- actlen ) */ ! 89: static void ! 90: iso9660_files_read( iso9660_info_t *mi ) ! 91: { ! 92: int count = POP(); ! 93: char *buf = (char *)cell2pointer(POP()); ! 94: int ret; ! 95: ! 96: if ( mi->common->type != FILE ) ! 97: PUSH( 0 ); ! 98: ! 99: ret = iso9660_read( mi->common->file, buf, count ); ! 100: ! 101: PUSH( ret ); ! 102: } ! 103: ! 104: /* ( pos.d -- status ) */ ! 105: static void ! 106: iso9660_files_seek( iso9660_info_t *mi ) ! 107: { ! 108: long long pos = DPOP(); ! 109: cell ret; ! 110: int offs = (int)pos; ! 111: int whence = SEEK_SET; ! 112: ! 113: if (mi->common->type != FILE) ! 114: PUSH( -1 ); ! 115: ! 116: if( offs == -1 ) { ! 117: offs = 0; ! 118: whence = SEEK_END; ! 119: } ! 120: ! 121: ret = iso9660_lseek(mi->common->file, offs, whence); ! 122: ! 123: PUSH( (ret < 0)? -1 : 0 ); ! 124: } ! 125: ! 126: /* ( -- filepos.d ) */ ! 127: static void ! 128: iso9660_files_offset( iso9660_info_t *mi ) ! 129: { ! 130: if ( mi->common->type != FILE ) ! 131: DPUSH( -1 ); ! 132: ! 133: DPUSH( mi->common->file->offset ); ! 134: } ! 135: ! 136: /* ( addr -- size ) */ ! 137: static void ! 138: iso9660_files_load( iso9660_info_t *mi) ! 139: { ! 140: char *buf = (char*)cell2pointer(POP()); ! 141: int ret, size; ! 142: ! 143: if ( mi->common->type != FILE ) ! 144: PUSH( 0 ); ! 145: ! 146: size = 0; ! 147: while(1) { ! 148: ret = iso9660_read( mi->common->file, buf, 512 ); ! 149: if (ret <= 0) ! 150: break; ! 151: buf += ret; ! 152: size += ret; ! 153: if (ret != 512) ! 154: break; ! 155: } ! 156: PUSH( size ); ! 157: } ! 158: ! 159: /* static method, ( pathstr len ihandle -- ) */ ! 160: static void ! 161: iso9660_files_dir( iso9660_info_t *dummy ) ! 162: { ! 163: iso9660_VOLUME *volume; ! 164: iso9660_COMMON *common; ! 165: struct iso_directory_record *idr; ! 166: char name_buf[256]; ! 167: int fd; ! 168: ! 169: ihandle_t ih = POP(); ! 170: char *path = pop_fstr_copy(); ! 171: ! 172: fd = open_ih( ih ); ! 173: if ( fd == -1 ) { ! 174: free( path ); ! 175: return; ! 176: } ! 177: ! 178: volume = iso9660_mount( fd ); ! 179: if ( volume == NULL ) { ! 180: free ( path ); ! 181: close_io( fd ); ! 182: return; ! 183: } ! 184: ! 185: common = malloc(sizeof(iso9660_COMMON)); ! 186: common->dir = iso9660_opendir( volume, path ); ! 187: ! 188: forth_printf("\n"); ! 189: while ( (idr = iso9660_readdir(common->dir)) ) { ! 190: ! 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); ! 200: else ! 201: forth_printf("%s\n", name_buf); ! 202: } ! 203: ! 204: iso9660_closedir( common->dir ); ! 205: iso9660_umount( volume ); ! 206: ! 207: close_io( fd ); ! 208: ! 209: free( common ); ! 210: free( path ); ! 211: } ! 212: ! 213: /* static method, ( pos.d ih -- flag? ) */ ! 214: static void ! 215: iso9660_files_probe( iso9660_info_t *dummy ) ! 216: { ! 217: ihandle_t ih = POP_ih(); ! 218: long long offs = DPOP(); ! 219: int fd, ret = 0; ! 220: ! 221: fd = open_ih(ih); ! 222: if (fd >= 0) { ! 223: if (iso9660_probe(fd, offs)) { ! 224: ret = -1; ! 225: } ! 226: close_io(fd); ! 227: } else { ! 228: ret = -1; ! 229: } ! 230: ! 231: RET (ret); ! 232: } ! 233: ! 234: static void ! 235: iso9660_files_block_size( iso9660_info_t *dummy ) ! 236: { ! 237: PUSH(2048); ! 238: } ! 239: ! 240: static void ! 241: iso9660_initializer( iso9660_info_t *dummy ) ! 242: { ! 243: fword("register-fs-package"); ! 244: } ! 245: ! 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 }, ! 257: }; ! 258: ! 259: void ! 260: iso9660_init( void ) ! 261: { ! 262: REGISTER_NODE( iso9660 ); ! 263: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.