Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tools / dumpscan / xf_files.c
CommitLineData
805e021f
CE
1/*
2 * CMUCS AFStools
3 * dumpscan - routines for scanning and manipulating AFS volume dumps
4 *
5 * Copyright (c) 1998 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29/* xf_files.c - XFILE routines for accessing UNIX files */
30
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <errno.h>
35#include <stdlib.h>
36#include <string.h>
37#include <stdio.h>
38#include <unistd.h>
39
40#include "xfiles.h"
41#include "xf_errs.h"
42
43#define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
44
45
46/* do_read for stdio xfiles */
47static afs_uint32
48xf_FILE_do_read(XFILE * X, void *buf, afs_uint32 count)
49{
50 FILE *F = X->refcon;
51
52 /* XXX: handle short and interrupted reads */
53 if (fread(buf, count, 1, F) != 1)
54 return ferror(F) ? errno : ERROR_XFILE_EOF;
55 return 0;
56}
57
58
59/* do_write for stdio xfiles */
60static afs_uint32
61xf_FILE_do_write(XFILE * X, void *buf, afs_uint32 count)
62{
63 FILE *F = X->refcon;
64
65 /* XXX: handle interrupted writes */
66 if (fwrite(buf, count, 1, F) != 1)
67 return errno;
68 return 0;
69}
70
71
72/* do_tell for stdio xfiles */
73static afs_uint32
74xf_FILE_do_tell(XFILE * X, dt_uint64 * offset)
75{
76 FILE *F = X->refcon;
77 off_t where;
78
79 where = ftell(F);
80 if (where == -1)
81 return errno;
82 set64(*offset, where);
83 return 0;
84}
85
86
87/* do_seek for stdio xfiles */
88static afs_uint32
89xf_FILE_do_seek(XFILE * X, dt_uint64 * offset)
90{
91 FILE *F = X->refcon;
92 off_t where = get64(*offset);
93
94 if (fseek(F, where, SEEK_SET) == -1)
95 return errno;
96 return 0;
97}
98
99
100/* do_skip for stdio xfiles */
101static afs_uint32
102xf_FILE_do_skip(XFILE * X, afs_uint32 count)
103{
104 FILE *F = X->refcon;
105
106 if (fseek(F, count, SEEK_CUR) == -1)
107 return errno;
108 return 0;
109}
110
111
112/* do_close for stdio xfiles */
113static afs_uint32
114xf_FILE_do_close(XFILE * X)
115{
116 FILE *F = X->refcon;
117
118 X->refcon = 0;
119 if (fclose(F))
120 return errno;
121 return 0;
122}
123
124
125/* Prepare a stdio XFILE */
126static void
127prepare(XFILE * X, FILE * F, int xflag)
128{
129 struct stat st;
130
131 memset(X, 0, sizeof(*X));
132 X->do_read = xf_FILE_do_read;
133 X->do_write = xf_FILE_do_write;
134 X->do_tell = xf_FILE_do_tell;
135 X->do_close = xf_FILE_do_close;
136 X->refcon = F;
137 if (xflag == O_RDWR)
138 X->is_writable = 1;
139
140 if (!fstat(fileno(F), &st)
141 && ((st.st_mode & S_IFMT) == S_IFREG
142 || (st.st_mode & S_IFMT) == S_IFBLK)) {
143 X->is_seekable = 1;
144 X->do_seek = xf_FILE_do_seek;
145 X->do_skip = xf_FILE_do_skip;
146 }
147}
148
149
150/* Open an XFILE by path */
151afs_uint32
152xfopen_path(XFILE * X, int flag, char *path, int mode)
153{
154 FILE *F = 0;
155 int fd = -1, xflag;
156 afs_uint32 code;
157
158 xflag = flag & O_MODE_MASK;
159 if (xflag == O_WRONLY)
160 return ERROR_XFILE_WRONLY;
161
162 if ((fd = open(path, flag, mode)) < 0)
163 return errno;
164 if (!(F = fdopen(fd, (xflag == O_RDONLY) ? "r" : "r+"))) {
165 code = errno;
166 close(fd);
167 return code;
168 }
169
170 prepare(X, F, xflag);
171 return 0;
172}
173
174
175/* Open an XFILE by FILE * */
176afs_uint32
177xfopen_FILE(XFILE * X, int flag, FILE * F)
178{
179 flag &= O_MODE_MASK;
180 if (flag == O_WRONLY)
181 return ERROR_XFILE_WRONLY;
182 prepare(X, F, flag);
183 return 0;
184}
185
186
187/* Open an XFILE by file descriptor */
188afs_uint32
189xfopen_fd(XFILE * X, int flag, int fd)
190{
191 FILE *F;
192
193 flag &= O_MODE_MASK;
194 if (flag == O_WRONLY)
195 return ERROR_XFILE_WRONLY;
196 if (!(F = fdopen(fd, (flag == O_RDONLY) ? "r" : "r+")))
197 return errno;
198 prepare(X, F, flag);
199 return 0;
200}
201
202
203/* open-by-name support for filenames */
204afs_uint32
205xfon_path(XFILE * X, int flag, char *name)
206{
207 return xfopen_path(X, flag, name, 0644);
208}
209
210
211/* open-by-name support for file descriptors */
212afs_uint32
213xfon_fd(XFILE * X, int flag, char *name)
214{
215 int fd = atoi(name);
216 return xfopen_fd(X, flag, fd);
217}
218
219
220/* open-by-name support for standard I/O */
221afs_uint32
222xfon_stdio(XFILE * X, int flag)
223{
224 flag &= O_MODE_MASK;
225 if (flag == O_WRONLY)
226 flag = O_RDWR;
227 return xfopen_FILE(X, flag, (flag == O_RDONLY) ? stdin : stdout);
228}