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