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

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

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

CVSweb