1 /* $NetBSD: lif.c,v 1.9 2009/10/26 19:16:55 cegger Exp $ */
3 /* $OpenBSD: lif.c,v 1.7 2001/06/09 03:54:41 mickey Exp $ */
6 * Copyright (c) 1998-2004 Michael Shalayeff
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/param.h>
32 #include <sys/disklabel.h>
38 char f_buf
[HP700_LIF_FILESTART
];/* buffer for lif volume header and dir */
39 struct hp700_lifvol
*f_lp
; /* lif volume header pointer */
40 struct hp700_lifdir
*f_ld
; /* lif dir pointer */
41 int f_nfiles
; /* gross number for lif dir entries */
43 off_t f_seek
; /* seek pointer for file read */
44 struct hp700_lifdir
*f_rd
; /* lif dir pointer for readdir */
46 int f_isdir
; /* special hacky flag for '.' dir */
47 int f_count
; /* this file length */
48 int f_off
; /* this file offset */
52 lif_open(const char *path
, struct open_file
*f
)
55 struct hp700_lifdir
*dp
;
57 struct hp700_lifload load
;
63 printf("lif_open(%s, %p)\n", path
, f
);
66 fp
= alloc(sizeof(*fp
));
67 /* XXX we're assuming here that sizeof(fp->f_buf) >= HP700_LIF_FILESTART */
69 err
= (*f
->f_dev
->dv_strategy
)(f
->f_devdata
, F_READ
, 0,
70 sizeof(fp
->f_buf
), &fp
->f_buf
, &buf_size
);
71 if (err
|| buf_size
!= sizeof(fp
->f_buf
)) {
74 printf("lif_open: unable to read LIF header (%d)\n", err
);
76 } else if ((fp
->f_lp
= (struct hp700_lifvol
*)fp
->f_buf
)->vol_id
==
79 fp
->f_ld
= (struct hp700_lifdir
*)(fp
->f_buf
+ HP700_LIF_DIRSTART
);
82 fp
->f_nfiles
= hp700_lifstob(fp
->f_lp
->vol_dirsize
) /
83 sizeof(struct hp700_lifdir
);
85 /* no dirs on the lif */
86 for (p
= path
+ (l
= strlen(path
)); p
>= path
; p
--)
96 if (!err
&& *path
!= '.') {
99 for (dp
= fp
->f_ld
; dp
< &fp
->f_ld
[fp
->f_nfiles
]; dp
++) {
103 "%s <--> '%c%c%c%c%c%c%c%c%c%c'\n",
104 path
, dp
->dir_name
[0], dp
->dir_name
[1],
105 dp
->dir_name
[2], dp
->dir_name
[3],
106 dp
->dir_name
[4], dp
->dir_name
[5],
107 dp
->dir_name
[6], dp
->dir_name
[7],
108 dp
->dir_name
[8], dp
->dir_name
[9]);
110 for (p
= path
, q
= dp
->dir_name
;
111 *q
&& *q
!= ' '; q
++, p
++)
112 if (tolower(*q
) != tolower(*p
))
114 if ((!*q
|| *q
== ' ') && !*p
) {
120 fp
->f_off
= hp700_lifstodb(dp
->dir_addr
);
121 if (!(err
=(f
->f_dev
->dv_strategy
)(f
->f_devdata
, F_READ
,
122 fp
->f_off
, sizeof(load
), &load
, &buf_size
)) &&
123 buf_size
== sizeof(load
)) {
125 fp
->f_count
= load
.count
- sizeof(int);
126 fp
->f_off
= dbtob(fp
->f_off
) + sizeof(load
);
129 printf("lif_open: %u @ %u [%x]\n",
130 fp
->f_count
, fp
->f_off
,
140 dealloc (fp
, sizeof(*fp
));
145 printf("ret(%d)\n", err
);
151 lif_close(struct open_file
*f
)
153 dealloc(f
->f_fsdata
, sizeof(struct file
));
159 lif_read(struct open_file
*f
, void *buf
, size_t size
, size_t *resid
)
161 struct file
*fp
= (struct file
*)f
->f_fsdata
;
163 char bbuf
[DEV_BSIZE
];
164 size_t bsize
, count
= sizeof(bbuf
);
170 printf("lif_read(%p, %p, %u, %p)\n", f
, buf
, size
, resid
);
173 for (p
= bbuf
; size
; fp
->f_seek
+= bsize
, p
+= bsize
) {
175 foff
= fp
->f_off
+ fp
->f_seek
;
176 if (fp
->f_seek
>= fp
->f_count
||
177 (err
= (f
->f_dev
->dv_strategy
)(f
->f_devdata
, F_READ
,
178 btodb(foff
), count
, p
, &bsize
)))
181 bsize
= sizeof(bbuf
) - (foff
& (sizeof(bbuf
) - 1));
182 bsize
= min(bsize
, size
);
183 memcpy(buf
, bbuf
+ (foff
& (sizeof(bbuf
) - 1)), bsize
);
186 count
= size
-= bsize
;
195 lif_write(struct open_file
*f
, void *buf
, size_t size
, size_t *resid
)
201 lif_seek(struct open_file
*f
, off_t offset
, int where
)
203 struct file
*fp
= (struct file
*)f
->f_fsdata
;
210 fp
->f_seek
+= offset
;
213 fp
->f_seek
= fp
->f_count
- offset
;
222 lif_stat(struct open_file
*f
, struct stat
*sb
)
224 struct file
*fp
= (struct file
*)f
->f_fsdata
;
226 sb
->st_mode
= 0755 | (fp
->f_isdir
? S_IFDIR
: 0); /* XXX */
229 sb
->st_size
= fp
->f_count
;
234 lif_readdir(struct open_file
*f
, char *name
)
236 struct file
*fp
= (struct file
*)f
->f_fsdata
;
240 while ((fp
->f_rd
->dir_name
[0] == ' ' ||
241 !fp
->f_rd
->dir_name
[0]) &&
242 (fp
->f_rd
- fp
->f_ld
) < fp
->f_nfiles
)
244 if ((fp
->f_rd
- fp
->f_ld
) >= fp
->f_nfiles
) {
248 strncpy(name
, fp
->f_rd
->dir_name
, sizeof(fp
->f_rd
->dir_name
));
249 if ((p
= strchr(name
, ' ')))