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