Annotation of qemu/roms/openbios/fs/ext2/ext2_fs.c, revision 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.