2 * Copyright (c) 2004,2005 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sbin/jscan/jfile.c,v 1.5 2005/07/06 06:06:44 dillon Exp $
40 * Open a journal for directional scanning
43 jopen_stream(const char *path, enum jdirection jdir, int flags)
48 if ((fp = fopen(path, "r")) == NULL)
50 if ((jf = jopen_fp(fp, jdir, flags)) == NULL)
56 jopen_fp(FILE *fp, enum jdirection jdir, int flags)
60 jf = malloc(sizeof(struct jfile));
61 bzero(jf, sizeof(struct jfile));
63 jf->jf_direction = jdir;
66 if (jdir == JF_BACKWARDS) {
67 fseeko(jf->jf_fp, 0L, SEEK_END);
68 jf->jf_pos = ftello(jf->jf_fp);
74 * Close a previously opened journal, clean up any side allocations.
77 jclose_stream(struct jfile *jf)
83 while ((jd = jf->jf_saved) != NULL) {
84 jf->jf_saved = jd->jd_next;
91 * Align us to the next 16 byte boundary. If scanning forwards we align
92 * forwards if not already aligned. If scanning backwards we align
93 * backwards if not already aligned.
96 jalign(struct jfile *jf)
98 if (jf->jf_direction == JF_FORWARDS) {
99 jf->jf_pos = (jf->jf_pos + 15) & ~15;
100 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
102 jf->jf_pos = jf->jf_pos & ~15;
107 * Read data from a journal forwards or backwards. Note that the file
108 * pointer's actual seek position does not match jf_pos in the reverse
109 * scan case. Callers should never access jf_fp directly.
112 jread(struct jfile *jf, void *buf, int bytes)
116 if (jf->jf_direction == JF_FORWARDS) {
118 n = fread(buf, 1, bytes, jf->jf_fp);
123 buf = (char *)buf + n;
129 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
130 return (errno ? errno : ENOENT);
133 if (bytes > jf->jf_pos)
136 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
137 if (fread(buf, bytes, 1, jf->jf_fp) == 1) {
147 jwrite(struct jfile *jf, void *buf, int bytes)
151 n = write(fileno(jf->jf_fp), buf, bytes);
156 jset(struct jfile *jf)
158 jf->jf_setpt = jf->jf_pos;
162 jreturn(struct jfile *jf)
164 jf->jf_pos = jf->jf_setpt;
166 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
170 jflush(struct jfile *jf)