Annotation of sys/arch/hppa/stand/libsa/lif.c, Revision 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