]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/pread.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / io / pread.c
CommitLineData
e246ba5f
NS
1/*
2 * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
dfc130f3 3 *
e246ba5f
NS
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
dfc130f3 7 *
e246ba5f
NS
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dfc130f3 11 *
e246ba5f
NS
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
dfc130f3 18 *
e246ba5f
NS
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
dfc130f3 22 *
e246ba5f
NS
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
dfc130f3
RC
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
e246ba5f
NS
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include <libxfs.h>
34#include <ctype.h>
35#include "command.h"
36#include "input.h"
37#include "init.h"
38
39static cmdinfo_t pread_cmd;
40
41static void
42pread_help(void)
43{
44 printf(_(
45"\n"
46" reads a range of bytes in a specified block size from the given offset\n"
47"\n"
48" Example:\n"
49" 'read -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n"
50"\n"
51" Reads a segment of the currently open file, optionally dumping it to the\n"
52" standard output stream (with -v option) for subsequent inspection.\n"
53" The reads are performed in sequential blocks starting at offset, with the\n"
54" blocksize tunable using the -b option (default blocksize is 4096 bytes).\n"
55"\n"));
56}
57
58void *buffer;
59ssize_t buffersize;
60
61int
62alloc_buffer(
63 ssize_t bsize,
64 unsigned int seed)
65{
66 if (bsize > buffersize) {
ae8d6a95 67 if (buffer)
68 free(buffer);
69 buffer = memalign(getpagesize(), buffersize = bsize);
e246ba5f 70 if (!buffer) {
ae8d6a95 71 perror("memalign");
e246ba5f
NS
72 buffersize = 0;
73 return 0;
74 }
75 }
76 memset(buffer, seed, buffersize);
77 return 1;
78}
79
80static void
81dump_buffer(
82 off64_t offset,
83 ssize_t len)
84{
85 int i, j;
86 char *p;
87
88 for (i = 0, p = (char *)buffer; i < len; i += 16) {
89 char *s = p;
90
91 printf("%08llx: ", (off64_t)i + offset);
92 for (j = 0; j < 16 && i + j < len; j++, p++)
93 printf("%02x ", *p);
94 printf(" ");
95 for (j = 0; j < 16 && i + j < len; j++, s++) {
93d9f139 96 if (isalnum((int)*s))
e246ba5f
NS
97 printf("%c", *s);
98 else
99 printf(".");
100 }
101 printf("\n");
102 }
103}
104
105int
106read_buffer(
107 int fd,
108 off64_t offset,
109 ssize_t count,
110 ssize_t *total,
111 int verbose,
112 int onlyone)
113{
114 ssize_t bytes;
115
116 *total = 0;
117 while (count > 0) {
118 bytes = pread64(fd, buffer, min(count,buffersize), offset);
119 if (bytes == 0)
120 break;
121 if (bytes < 0) {
122 perror("pread64");
123 return 0;
124 }
125 if (verbose)
126 dump_buffer(offset, bytes);
127 *total += bytes;
128 if (onlyone || bytes < count)
129 break;
130 offset += bytes;
131 count -= bytes;
132 }
133 return 1;
134}
135
136static int
137pread_f(
138 int argc,
139 char **argv)
140{
141 off64_t offset;
142 ssize_t count, total;
143 unsigned int bsize = 4096;
144 char *sp;
145 int vflag = 0;
146 int c;
147
148 while ((c = getopt(argc, argv, "b:v")) != EOF) {
149 switch (c) {
150 case 'b':
151 bsize = strtoul(optarg, &sp, 0);
152 if (!sp || sp == optarg) {
153 printf(_("non-numeric bsize -- %s\n"), optarg);
154 return 0;
155 }
156 break;
157 case 'v':
158 vflag = 1;
159 break;
160 default:
161 printf("%s %s\n", pread_cmd.name, pread_cmd.oneline);
162 return 0;
163 }
164 }
165 if (optind != argc - 2) {
166 printf("%s %s\n", pread_cmd.name, pread_cmd.oneline);
167 return 0;
168 }
169 offset = strtoul(argv[optind], &sp, 0);
170 if (!sp || sp == argv[optind]) {
171 printf(_("non-numeric offset argument -- %s\n"), argv[optind]);
172 return 0;
173 }
174 optind++;
175 count = strtoul(argv[optind], &sp, 0);
176 if (!sp || sp == argv[optind]) {
177 printf(_("non-numeric length argument -- %s\n"), argv[optind]);
178 return 0;
179 }
180
181 if (!alloc_buffer(bsize, 0xabababab))
182 return 0;
183
184 if (!read_buffer(fdesc, offset, count, &total, vflag, 0))
185 return 0;
186
187 printf(_("read %u/%u bytes at offset %llu\n"), total, count, offset);
188 return 0;
189}
190
191void
192pread_init(void)
193{
194 pread_cmd.name = _("pread");
195 pread_cmd.altname = _("r");
196 pread_cmd.cfunc = pread_f;
197 pread_cmd.argmin = 2;
198 pread_cmd.argmax = -1;
199 pread_cmd.args = _("[-b bs] [-v] off len");
200 pread_cmd.oneline = _("reads a number of bytes at a specified offset");
201 pread_cmd.help = pread_help;
202
203 add_command(&pread_cmd);
204}