Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tools / dumpscan / xf_profile.c
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_profile.c - XFILE routines for read/write profiling */
30
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <fcntl.h>
36 #include <errno.h>
37
38 #include "xfiles.h"
39 #include "xf_errs.h"
40
41 #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
42
43 typedef struct {
44 XFILE content;
45 XFILE profile;
46 } PFILE;
47
48
49 /* do_read for profiled xfiles */
50 static afs_uint32
51 xf_PROFILE_do_read(XFILE * X, void *buf, afs_uint32 count)
52 {
53 PFILE *PF = X->refcon;
54 afs_uint32 err;
55
56 err = xfread(&PF->content, buf, count);
57 xfprintf(&PF->profile, "R %ld =%ld\n", (long)count, (long)err);
58 return err;
59 }
60
61
62 /* do_write for profiled xfiles */
63 static afs_uint32
64 xf_PROFILE_do_write(XFILE * X, void *buf, afs_uint32 count)
65 {
66 PFILE *PF = X->refcon;
67 afs_uint32 err;
68
69 err = xfwrite(&PF->content, buf, count);
70 xfprintf(&PF->profile, "W %ld =%ld\n", (long)count, (long)err);
71 return err;
72 }
73
74
75 /* do_tell for profiled xfiles */
76 static afs_uint32
77 xf_PROFILE_do_tell(XFILE * X, dt_uint64 * offset)
78 {
79 PFILE *PF = X->refcon;
80 afs_uint32 err;
81
82 err = xftell(&PF->content, offset);
83 if (err)
84 xfprintf(&PF->profile, "TELL ERR =%ld\n", (long)err);
85 else
86 xfprintf(&PF->profile, "TELL %s =0\n", hexify_int64(offset, 0));
87 return err;
88 }
89
90
91 /* do_seek for profiled xfiles */
92 static afs_uint32
93 xf_PROFILE_do_seek(XFILE * X, dt_uint64 * offset)
94 {
95 PFILE *PF = X->refcon;
96 afs_uint32 err;
97
98 err = xfseek(&PF->content, offset);
99 xfprintf(&PF->profile, "SEEK %s =%ld\n", hexify_int64(offset, 0),
100 (long)err);
101 return err;
102 }
103
104
105 /* do_skip for profiled xfiles */
106 static afs_uint32
107 xf_PROFILE_do_skip(XFILE * X, afs_uint32 count)
108 {
109 PFILE *PF = X->refcon;
110 afs_uint32 err;
111
112 err = xfskip(&PF->content, count);
113 xfprintf(&PF->profile, "SKIP %ld =%ld\n", (long)count, (long)err);
114 return err;
115 }
116
117
118 /* do_close for profiled xfiles */
119 static afs_uint32
120 xf_PROFILE_do_close(XFILE * X)
121 {
122 PFILE *PF = X->refcon;
123 afs_uint32 err, err2;
124
125 err = xfclose(&PF->content);
126 err2 = xfclose(&PF->profile);
127 free(PF);
128 return err ? err : err2;
129 }
130
131
132 /* Open a profiled XFILE */
133 afs_uint32
134 xfopen_profile(XFILE * X, int flag, char *xname, char *profile)
135 {
136 PFILE *PF;
137 afs_uint32 err;
138
139 PF = calloc(1, sizeof(*PF));
140 if (!PF)
141 return ENOMEM;
142
143 err = xfopen(&PF->profile, O_RDWR | O_CREAT | O_TRUNC, profile);
144 if (err) {
145 free(PF);
146 return err;
147 }
148
149 err = xfopen(&PF->content, flag, xname);
150 if (err) {
151 xfclose(&PF->profile);
152 free(PF);
153 return err;
154 }
155
156 memset(X, 0, sizeof(*X));
157 X->refcon = PF;
158 X->do_read = xf_PROFILE_do_read;
159 X->do_write = xf_PROFILE_do_write;
160 X->do_tell = xf_PROFILE_do_tell;
161 X->do_close = xf_PROFILE_do_close;
162 X->is_writable = PF->content.is_writable;
163 if (PF->content.is_seekable) {
164 X->is_seekable = 1;
165 X->do_seek = xf_PROFILE_do_seek;
166 X->do_skip = xf_PROFILE_do_skip;
167 }
168 xfprintf(&PF->profile, "OPEN %s\n", xname);
169 return 0;
170 }
171
172
173 afs_uint32
174 xfon_profile(XFILE * X, int flag, char *name)
175 {
176 char *x, *profile, *xname;
177 afs_uint32 err;
178
179 if (!(name = strdup(name)))
180 return ENOMEM;
181
182 profile = "-";
183 xname = name;
184 for (x = name; *x; x++) {
185 if (x[0] == ':' && x[1] == ':') {
186 *x = 0;
187 profile = name;
188 xname = x + 2;
189 break;
190 }
191 }
192 if (!*name)
193 profile = "-";
194 err = xfopen_profile(X, flag, xname, profile);
195 free(name);
196 return err;
197 }