[BACK]Return to lif.c CVS log [TXT][DIR] Up to [local] / sys / arch / hppa64 / stand / libsa

Annotation of sys/arch/hppa64/stand/libsa/lif.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: lif.c,v 1.1 2005/04/01 10:40:48 mickey Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Michael Shalayeff
                      5:  * All rights reserved.
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
                     16:  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: #include <sys/param.h>
                     21: #include <sys/disklabel.h>
                     22: #include "libsa.h"
                     23:
                     24: extern int debug;
                     25:
                     26: struct file {
                     27:        char f_buf[LIF_FILESTART];/* buffer for lif volume header and dir */
                     28:        struct lifvol *f_lp;    /* lif volume header pointer */
                     29:        struct lifdir *f_ld;    /* lif dir pointer */
                     30:        int     f_nfiles;       /* gross number for lif dir entries */
                     31:
                     32:        off_t   f_seek;         /* seek pointer for file read */
                     33:        struct lifdir *f_rd;    /* lif dir pointer for readdir */
                     34:
                     35:        int     f_isdir;        /* special hacky flag for '.' dir */
                     36:        int     f_count;        /* this file length */
                     37:        int     f_off;          /* this file offset */
                     38: };
                     39:
                     40: int
                     41: lif_open (path, f)
                     42:        char *path;
                     43:        struct open_file *f;
                     44: {
                     45:        struct file *fp;
                     46:        struct lifdir *dp;
                     47:        char *p, *q;
                     48:        struct lif_load load;
                     49:        size_t buf_size;
                     50:        int err, l;
                     51:
                     52: #ifdef LIFDEBUG
                     53:        if (debug)
                     54:                printf("lif_open(%s, %p)\n", path, f);
                     55: #endif
                     56:
                     57:        fp = alloc(sizeof(*fp));
                     58:        /* XXX we're assuming here that sizeof(fp->f_buf) >= LIF_FILESTART */
                     59:        if ((err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 0,
                     60:            sizeof(fp->f_buf), &fp->f_buf, &buf_size)) ||
                     61:            buf_size != sizeof(fp->f_buf)) {
                     62: #ifdef LIFDEBUG
                     63:                if (debug)
                     64:                        printf("lif_open: unable to read LIF header (%d)\n", err);
                     65: #endif
                     66:        } else if ((fp->f_lp = (struct lifvol *)fp->f_buf)->vol_id == LIF_VOL_ID) {
                     67:                f->f_fsdata = fp;
                     68:                fp->f_ld = (struct lifdir *)(fp->f_buf + LIF_DIRSTART);
                     69:                fp->f_seek = 0;
                     70:                fp->f_rd = fp->f_ld;
                     71:                fp->f_nfiles = lifstob(fp->f_lp->vol_dirsize) /
                     72:                        sizeof(struct lifdir);
                     73:
                     74:                /* no dirs on the lif */
                     75:                for (p = path + (l = strlen(path)); p >= path; p--)
                     76:                        if (*p == '/') {
                     77:                                p++;
                     78:                                break;
                     79:                        }
                     80:                if (p > path)
                     81:                        path = p;
                     82:        } else
                     83:                err = EINVAL;
                     84:
                     85:        if (!err && *path != '.') {
                     86:                fp->f_isdir = 0;
                     87:                err = ENOENT;
                     88:                for (dp = fp->f_ld; dp < &fp->f_ld[fp->f_nfiles]; dp++) {
                     89: #ifdef LIFDEBUG
                     90:                        if (debug)
                     91:                                printf("lif_open: "
                     92:                                       "%s <--> '%c%c%c%c%c%c%c%c%c%c'\n",
                     93:                                       path, dp->dir_name[0], dp->dir_name[1],
                     94:                                       dp->dir_name[2], dp->dir_name[3],
                     95:                                       dp->dir_name[4], dp->dir_name[5],
                     96:                                       dp->dir_name[6], dp->dir_name[7],
                     97:                                       dp->dir_name[8], dp->dir_name[9]);
                     98: #endif
                     99:                        for (p = path, q = dp->dir_name;
                    100:                             *q && *q != ' '; q++, p++)
                    101:                                if (tolower(*q) != tolower(*p))
                    102:                                        break;
                    103:                        if ((!*q || *q == ' ') && !*p) {
                    104:                                err = 0;
                    105:                                break;
                    106:                        }
                    107:                }
                    108:                if (!err) {
                    109:                        fp->f_off = lifstodb(dp->dir_addr);
                    110:                        if (!(err =(f->f_dev->dv_strategy)(f->f_devdata, F_READ,
                    111:                              fp->f_off, sizeof(load), &load, &buf_size)) &&
                    112:                            buf_size == sizeof(load)) {
                    113:                                /* no checksum */
                    114:                                fp->f_count = load.count - sizeof(int);
                    115:                                fp->f_off = dbtob(fp->f_off) + sizeof(load);
                    116: #ifdef LIFDEBUG
                    117:                                if (debug)
                    118:                                        printf("lif_open: %u @ %u [%x]\n",
                    119:                                               fp->f_count, fp->f_off,
                    120:                                               load.address);
                    121: #endif
                    122:                        } else if (!err)
                    123:                                err = EIO;
                    124:                }
                    125:        } else
                    126:                fp->f_isdir = 1;
                    127:
                    128:        if (err) {
                    129:                free (fp, sizeof(*fp));
                    130:                f->f_fsdata = NULL;
                    131:        }
                    132: #ifdef LIFDEBUG
                    133:        if (debug)
                    134:                printf("ret(%d)\n", err);
                    135: #endif
                    136:        return err;
                    137: }
                    138:
                    139: int
                    140: lif_close(f)
                    141:        struct open_file *f;
                    142: {
                    143:        free (f->f_fsdata, sizeof(struct file));
                    144:        f->f_fsdata = NULL;
                    145:        return 0;
                    146: }
                    147:
                    148: int
                    149: lif_read(f, buf, size, resid)
                    150:        struct open_file *f;
                    151:        void *buf;
                    152:        size_t size;
                    153:        size_t *resid;
                    154: {
                    155:        struct file *fp = (struct file *)f->f_fsdata;
                    156:        char *p;
                    157:        char bbuf[DEV_BSIZE];
                    158:        size_t bsize, count = sizeof(bbuf);
                    159:        int err = 0;
                    160:        int foff;
                    161:
                    162: #ifdef LIFDEBUG
                    163:        if (debug)
                    164:                printf("lif_read(%p, %p, %u, %p)\n", f, buf, size, resid);
                    165: #endif
                    166:
                    167:        for (p = bbuf; size; fp->f_seek += bsize, p += bsize) {
                    168:                twiddle();
                    169:                foff = fp->f_off + fp->f_seek;
                    170:                if (fp->f_seek >= fp->f_count ||
                    171:                    (err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
                    172:                     btodb(foff), count, p, &bsize)))
                    173:                        break;
                    174:                if (p == bbuf) {
                    175:                        bsize = sizeof(bbuf) - (foff & (sizeof(bbuf) - 1));
                    176:                        bsize = min(bsize, size);
                    177:                        bcopy(bbuf + (foff & (sizeof(bbuf) - 1)), buf, bsize);
                    178:                        p = buf;
                    179:                }
                    180:                count = size -= bsize;
                    181:        }
                    182:        if (resid)
                    183:                *resid = size;
                    184:
                    185:        return err;
                    186: }
                    187:
                    188: int
                    189: lif_write(f, buf, size, resid)
                    190:        struct open_file *f;
                    191:        void *buf;
                    192:        size_t size;
                    193:        size_t *resid;
                    194: {
                    195:        return EOPNOTSUPP;
                    196: }
                    197:
                    198: off_t
                    199: lif_seek(f, offset, where)
                    200:        struct open_file *f;
                    201:        off_t offset;
                    202:        int where;
                    203: {
                    204:        struct file *fp = (struct file *)f->f_fsdata;
                    205:
                    206:        switch (where) {
                    207:        case SEEK_SET:
                    208:                fp->f_seek = offset;
                    209:                break;
                    210:        case SEEK_CUR:
                    211:                fp->f_seek += offset;
                    212:                break;
                    213:        case SEEK_END:
                    214:                fp->f_seek = fp->f_count - offset;
                    215:                break;
                    216:        default:
                    217:                return (-1);
                    218:        }
                    219:        return (fp->f_seek);
                    220: }
                    221:
                    222: int
                    223: lif_stat(f, sb)
                    224:        struct open_file *f;
                    225:        struct stat *sb;
                    226: {
                    227:        struct file *fp = (struct file *)f->f_fsdata;
                    228:
                    229:        sb->st_mode = 0755 | (fp->f_isdir? S_IFDIR: 0); /* XXX */
                    230:        sb->st_uid = 0;
                    231:        sb->st_gid = 0;
                    232:        sb->st_size = fp->f_count;
                    233:        return 0;
                    234: }
                    235:
                    236: int
                    237: lif_readdir(f, name)
                    238:        struct open_file *f;
                    239:        char *name;
                    240: {
                    241:        struct file *fp = (struct file *)f->f_fsdata;
                    242:        char *p;
                    243:
                    244:        if (name) {
                    245:                while ((fp->f_rd->dir_name[0] == ' ' ||
                    246:                        !fp->f_rd->dir_name[0]) &&
                    247:                       (fp->f_rd - fp->f_ld) < fp->f_nfiles)
                    248:                        fp->f_rd++;
                    249:                if ((fp->f_rd - fp->f_ld) >= fp->f_nfiles) {
                    250:                        *name = '\0';
                    251:                        return -1;
                    252:                }
                    253:                strncpy(name, fp->f_rd->dir_name, sizeof(fp->f_rd->dir_name));
                    254:                if ((p = strchr(name, ' ')))
                    255:                        *p = '\0';
                    256:                fp->f_rd++;
                    257:        } else
                    258:                fp->f_rd = fp->f_ld;
                    259:
                    260:        return 0;
                    261: }

CVSweb