Remove some debugging printfs and fix a bug where libc's fread() returns
[dragonfly.git] / sbin / jscan / jfile.c
CommitLineData
ce5e5ac4
MD
1/*
2 * Copyright (c) 2004,2005 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
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 *
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
16 * distribution.
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.
20 *
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
32 * SUCH DAMAGE.
33 *
a2158374 34 * $DragonFly: src/sbin/jscan/jfile.c,v 1.4 2005/07/05 04:08:07 dillon Exp $
ce5e5ac4
MD
35 */
36
37#include "jscan.h"
38
39/*
40 * Open a journal for directional scanning
41 */
42struct jfile *
43jopen_stream(const char *path, enum jdirection jdir)
9c118cb2
MD
44{
45 FILE *fp;
46 struct jfile *jf;
47
48 if ((fp = fopen(path, "r")) == NULL)
49 return (NULL);
50 if ((jf = jopen_fp(fp, jdir)) == NULL)
51 fclose (fp);
52 return(jf);
53}
54
55struct jfile *
56jopen_fp(FILE *fp, enum jdirection jdir)
ce5e5ac4
MD
57{
58 struct jfile *jf;
59
60 jf = malloc(sizeof(struct jfile));
61 bzero(jf, sizeof(struct jfile));
9c118cb2 62 jf->jf_fp = fp;
ce5e5ac4
MD
63 jf->jf_direction = jdir;
64 jf->jf_setpt = -1;
65 if (jdir == JF_BACKWARDS) {
66 fseeko(jf->jf_fp, 0L, SEEK_END);
67 jf->jf_pos = ftello(jf->jf_fp);
68 }
69 return(jf);
70}
71
72/*
73 * Close a previously opened journal, clean up any side allocations.
74 */
75void
76jclose_stream(struct jfile *jf)
77{
78 struct jdata *jd;
79
80 fclose(jf->jf_fp);
81 jf->jf_fp = NULL;
82 while ((jd = jf->jf_saved) != NULL) {
83 jf->jf_saved = jd->jd_next;
84 free(jd);
85 }
86 free(jf);
87}
88
89/*
90 * Align us to the next 16 byte boundary. If scanning forwards we align
91 * forwards if not already aligned. If scanning backwards we align
92 * backwards if not already aligned.
93 */
94void
95jalign(struct jfile *jf)
96{
97 if (jf->jf_direction == JF_FORWARDS) {
98 jf->jf_pos = (jf->jf_pos + 15) & ~15;
99 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
100 } else {
101 jf->jf_pos = jf->jf_pos & ~15;
102 }
103}
104
105/*
106 * Read data from a journal forwards or backwards. Note that the file
107 * pointer's actual seek position does not match jf_pos in the reverse
108 * scan case. Callers should never access jf_fp directly.
109 */
110int
111jread(struct jfile *jf, void *buf, int bytes)
112{
a2158374
MD
113 int n;
114
ce5e5ac4 115 if (jf->jf_direction == JF_FORWARDS) {
a2158374
MD
116 while (bytes) {
117 n = fread(buf, 1, bytes, jf->jf_fp);
118 if (n <= 0)
119 break;
120 assert(n <= bytes);
121 jf->jf_pos += n;
122 buf = (char *)buf + n;
123 bytes -= n;
124 }
125 if (bytes == 0) {
ce5e5ac4
MD
126 return (0);
127 } else {
128 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
712e03b0 129 return (errno ? errno : ENOENT);
ce5e5ac4
MD
130 }
131 } else {
132 if (bytes > jf->jf_pos)
133 return (ENOENT);
134 jf->jf_pos -= bytes;
135 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
136 if (fread(buf, bytes, 1, jf->jf_fp) == 1) {
137 return (0);
138 } else {
139 jf->jf_pos += bytes;
140 return (errno);
141 }
142 }
143}
144
145void
146jset(struct jfile *jf)
147{
148 jf->jf_setpt = jf->jf_pos;
149}
150
151void
152jreturn(struct jfile *jf)
153{
154 jf->jf_pos = jf->jf_setpt;
155 jf->jf_setpt = -1;
156 fseeko(jf->jf_fp, jf->jf_pos, SEEK_SET);
157}
158
159void
160jflush(struct jfile *jf)
161{
162 jf->jf_setpt = -1;
163}
164