Annotation of qemu/roms/openbios/fs/ext2/ext2_fs.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     /packages/ext2-files 
                      3:  *
                      4:  * (c) 2008-2009 Laurent Vivier <[email protected]>
                      5:  * (c) 2010 Mark Cave-Ayland <[email protected]>
                      6:  *
                      7:  * This file has been copied from EMILE, http://emile.sf.net
                      8:  *
                      9:  */
                     10: 
                     11: #include "config.h"
                     12: #include "libopenbios/bindings.h"
                     13: #include "libext2.h"
                     14: #include "ext2_utils.h"
                     15: #include "fs/fs.h"
                     16: #include "libc/vsprintf.h"
                     17: #include "libc/diskio.h"
                     18: 
                     19: extern void     ext2_init( void );
                     20: 
                     21: typedef struct {
                     22:        enum { FILE, DIR } type;
                     23:        union {
                     24:                ext2_FILE *file;
                     25:                ext2_DIR *dir;
                     26:        };
                     27: } ext2_COMMON;
                     28: 
                     29: typedef struct {
                     30:        ext2_VOLUME *volume;
                     31:        ext2_COMMON *common;
                     32: } ext2_info_t;
                     33: 
                     34: DECLARE_NODE( ext2, 0, sizeof(ext2_info_t), "+/packages/ext2-files" );
                     35: 
                     36: 
                     37: static const int days_month[12] =
                     38:        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                     39: static const int days_month_leap[12] =
                     40:        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                     41: 
                     42: static inline int is_leap(int year)
                     43: {
                     44:        return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
                     45: }
                     46: 
                     47: static void
                     48: print_date(time_t sec)
                     49: {
                     50:        unsigned int second, minute, hour, month, day, year;
                     51:        int current;
                     52:        const int *days;
                     53: 
                     54:        second = sec % 60;
                     55:        sec /= 60;
                     56: 
                     57:        minute = sec % 60;
                     58:        sec /= 60;
                     59: 
                     60:        hour = sec % 24;
                     61:        sec /= 24;
                     62: 
                     63:        year = sec * 100 / 36525;
                     64:        sec -= year * 36525 / 100;
                     65:        year += 1970;
                     66: 
                     67:        days = is_leap(year) ?  days_month_leap : days_month;
                     68: 
                     69:        current = 0;
                     70:        month = 0;
                     71:        while (month < 12) {
                     72:                if (sec <= current + days[month]) {
                     73:                        break;
                     74:                }
                     75:                current += days[month];
                     76:                month++;
                     77:        }
                     78:        month++;
                     79: 
                     80:        day = sec - current + 1;
                     81: 
                     82:        forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
                     83:                     year, month, day, hour, minute, second);
                     84: }
                     85: 
                     86: 
                     87: /************************************************************************/
                     88: /*     Standard package methods                                        */
                     89: /************************************************************************/
                     90: 
                     91: /* ( -- success? ) */
                     92: static void
                     93: ext2_files_open( ext2_info_t *mi )
                     94: {
                     95:        int fd;
                     96:        char *path = my_args_copy();
                     97: 
                     98:        fd = open_ih( my_parent() );
                     99:        if ( fd == -1 ) {
                    100:                free( path );
                    101:                RET( 0 );
                    102:        }
                    103: 
                    104:        mi->volume = ext2_mount(fd);
                    105:        if (!mi->volume) {
                    106:                RET( 0 );
                    107:        }
                    108: 
                    109:        mi->common = (ext2_COMMON*)malloc(sizeof(ext2_COMMON));
                    110:        if (mi->common == NULL)
                    111:                RET( 0 );
                    112: 
                    113:        mi->common->dir = ext2_opendir(mi->volume, path);
                    114:        if (mi->common->dir == NULL) {
                    115:                mi->common->file = ext2_open(mi->volume, path);
                    116:                if (mi->common->file == NULL) {
                    117:                        free(mi->common);
                    118:                        RET( 0 );
                    119:                }
                    120:                mi->common->type = FILE;
                    121:                RET( -1 );
                    122:        }
                    123:        mi->common->type = DIR;
                    124:        RET( -1 );
                    125: }
                    126: 
                    127: /* ( -- ) */
                    128: static void
                    129: ext2_files_close( ext2_info_t *mi )
                    130: {
                    131:        ext2_COMMON *common = mi->common;
                    132: 
                    133:        if (common->type == FILE)
                    134:                ext2_close(common->file);
                    135:        else if (common->type == DIR)
                    136:                ext2_closedir(common->dir);
                    137:        free(common);
                    138: 
                    139:        ext2_umount(mi->volume);
                    140: }
                    141: 
                    142: /* ( buf len -- actlen ) */
                    143: static void
                    144: ext2_files_read( ext2_info_t *mi )
                    145: {
                    146:        int count = POP();
                    147:        char *buf = (char *)cell2pointer(POP());
                    148: 
                    149:        ext2_COMMON *common = mi->common;
                    150:        if (common->type != FILE)
                    151:                RET( -1 );
                    152: 
                    153:        RET ( ext2_read( common->file, buf, count ) );
                    154: }
                    155: 
                    156: /* ( pos.d -- status ) */
                    157: static void
                    158: ext2_files_seek( ext2_info_t *mi )
                    159: {
                    160:        long long pos = DPOP();
                    161:        int offs = (int)pos;
                    162:        int whence = SEEK_SET;
                    163:        int ret;
                    164:        ext2_COMMON *common = mi->common;
                    165: 
                    166:        if (common->type != FILE)
                    167:                RET( -1 );
                    168: 
                    169:        ret = ext2_lseek(common->file, offs, whence);
                    170:        if (ret)
                    171:                RET( -1 );
                    172:        else
                    173:                RET( 0 );
                    174: }
                    175: 
                    176: /* ( addr -- size ) */
                    177: static void
                    178: ext2_files_load( ext2_info_t *mi )
                    179: {
                    180:        char *buf = (char *)cell2pointer(POP());
                    181:        int count;
                    182: 
                    183:        ext2_COMMON *common = mi->common;
                    184:        if (common->type != FILE)
                    185:                RET( -1 );
                    186: 
                    187:        /* Seek to the end in order to get the file size */
                    188:        ext2_lseek(common->file, 0, SEEK_END);
                    189:        count = common->file->offset;
                    190:        ext2_lseek(common->file, 0, SEEK_SET);
                    191: 
                    192:        RET ( ext2_read( common->file, buf, count ) );
                    193: }
                    194: 
                    195: /* ( -- cstr ) */
                    196: static void
                    197: ext2_files_get_path( ext2_info_t *mi )
                    198: {
                    199:        ext2_COMMON *common = mi->common;
                    200: 
                    201:        if (common->type != FILE)
                    202:                RET( 0 );
                    203: 
                    204:        RET( pointer2cell(strdup(common->file->path)) );
                    205: }
                    206: 
                    207: /* ( -- cstr ) */
                    208: static void
                    209: ext2_files_get_fstype( ext2_info_t *mi )
                    210: {
                    211:        PUSH( pointer2cell(strdup("ext2")) );
                    212: }
                    213: 
                    214: /* static method, ( pathstr len ihandle -- ) */
                    215: static void
                    216: ext2_files_dir( ext2_info_t *dummy )
                    217: {
                    218:        ext2_COMMON *common;
                    219:        ext2_VOLUME *volume;
                    220:        struct ext2_dir_entry_2 *entry;
                    221:        struct ext2_inode inode;
                    222:        int fd;
                    223: 
                    224:        ihandle_t ih = POP();
                    225:        char *path = pop_fstr_copy();
                    226: 
                    227:        fd = open_ih( ih );
                    228:        if ( fd == -1 ) {
                    229:                free( path );
                    230:                return;
                    231:        }
                    232: 
                    233:        volume = ext2_mount(fd);
                    234:        if (!volume) {
                    235:                return;
                    236:        }
                    237: 
                    238:        common = (ext2_COMMON*)malloc(sizeof(ext2_COMMON));
                    239:        common->dir = ext2_opendir(volume, path);
                    240: 
                    241:        forth_printf("\n");
                    242:        while ( (entry = ext2_readdir(common->dir)) ) {
                    243:                ext2_get_inode(common->dir->volume, entry->inode, &inode);
                    244:                forth_printf("% 10d ", inode.i_size);
                    245:                print_date(inode.i_mtime);
                    246:                if (S_ISDIR(inode.i_mode))
                    247:                        forth_printf("%s\\\n", entry->name);
                    248:                else
                    249:                        forth_printf("%s\n", entry->name);
                    250:        }
                    251: 
                    252:        ext2_closedir( common->dir );
                    253:        ext2_umount( volume );
                    254: 
                    255:        close_io( fd );
                    256: 
                    257:        free( common );
                    258:        free( path );
                    259: }
                    260: 
                    261: /* static method, ( pos.d ih -- flag? ) */
                    262: static void
                    263: ext2_files_probe( ext2_info_t *dummy )
                    264: {
                    265:        ihandle_t ih = POP_ih();
                    266:        long long offs = DPOP();
                    267:        int fd, ret = 0;
                    268: 
                    269:        fd = open_ih(ih);
                    270:         if (fd >= 0) {
                    271:                 if (ext2_probe(fd, offs)) {
                    272:                         ret = -1;
                    273:                 }
                    274:                 close_io(fd);
                    275:         } else {
                    276:                 ret = -1;
                    277:         }
                    278: 
                    279:        RET (ret);
                    280: }
                    281: 
                    282: 
                    283: static void
                    284: ext2_initializer( ext2_info_t *dummy )
                    285: {
                    286:        fword("register-fs-package");
                    287: }
                    288: 
                    289: NODE_METHODS( ext2 ) = {
                    290:        { "probe",      ext2_files_probe        },
                    291:        { "open",       ext2_files_open         },
                    292:        { "close",      ext2_files_close        },
                    293:        { "read",       ext2_files_read         },
                    294:        { "seek",       ext2_files_seek         },
                    295:        { "load",       ext2_files_load         },
                    296:        { "dir",        ext2_files_dir          },
                    297: 
                    298:        /* special */
                    299:        { "get-path",   ext2_files_get_path     },
                    300:        { "get-fstype", ext2_files_get_fstype   },
                    301: 
                    302:        { NULL,         ext2_initializer        },
                    303: };
                    304: 
                    305: void
                    306: ext2_init( void )
                    307: {
                    308:        REGISTER_NODE( ext2 );
                    309: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.