f043849377f9598a5c0fdd8f061138b7c8344707
[openafs.git] / src / tools / 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, u_int64 * 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, u_int64 * 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 = malloc(sizeof(*PF));
140     if (!PF)
141         return ENOMEM;
142     memset(PF, 0, sizeof(*PF));
143
144     err = xfopen(&PF->profile, O_RDWR | O_CREAT | O_TRUNC, profile);
145     if (err) {
146         free(PF);
147         return err;
148     }
149
150     err = xfopen(&PF->content, flag, xname);
151     if (err) {
152         xfclose(&PF->profile);
153         free(PF);
154         return err;
155     }
156
157     memset(X, 0, sizeof(*X));
158     X->refcon = PF;
159     X->do_read = xf_PROFILE_do_read;
160     X->do_write = xf_PROFILE_do_write;
161     X->do_tell = xf_PROFILE_do_tell;
162     X->do_close = xf_PROFILE_do_close;
163     X->is_writable = PF->content.is_writable;
164     if (PF->content.is_seekable) {
165         X->is_seekable = 1;
166         X->do_seek = xf_PROFILE_do_seek;
167         X->do_skip = xf_PROFILE_do_skip;
168     }
169     xfprintf(&PF->profile, "OPEN %s\n", xname);
170     return 0;
171 }
172
173
174 afs_uint32
175 xfon_profile(XFILE * X, int flag, char *name)
176 {
177     char *x, *profile, *xname;
178     afs_uint32 err;
179
180     if (!(name = strdup(name)))
181         return ENOMEM;
182
183     profile = "-";
184     xname = name;
185     for (x = name; *x; x++) {
186         if (x[0] == ':' && x[1] == ':') {
187             *x = 0;
188             profile = name;
189             xname = x + 2;
190             break;
191         }
192     }
193     if (!*name)
194         profile = "-";
195     err = xfopen_profile(X, flag, xname, profile);
196     free(name);
197     return err;
198 }