]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/pread.c
Bunch of portability related changes to xfsprogs. Includes some code to
[thirdparty/xfsprogs-dev.git] / io / pread.c
CommitLineData
e246ba5f
NS
1/*
2 * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
3 *
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.
7 *
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.
11 *
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.
18 *
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.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
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) {
67 buffer = realloc(buffer, buffersize = bsize);
68 if (!buffer) {
69 perror("realloc");
70 buffersize = 0;
71 return 0;
72 }
73 }
74 memset(buffer, seed, buffersize);
75 return 1;
76}
77
78static void
79dump_buffer(
80 off64_t offset,
81 ssize_t len)
82{
83 int i, j;
84 char *p;
85
86 for (i = 0, p = (char *)buffer; i < len; i += 16) {
87 char *s = p;
88
89 printf("%08llx: ", (off64_t)i + offset);
90 for (j = 0; j < 16 && i + j < len; j++, p++)
91 printf("%02x ", *p);
92 printf(" ");
93 for (j = 0; j < 16 && i + j < len; j++, s++) {
93d9f139 94 if (isalnum((int)*s))
e246ba5f
NS
95 printf("%c", *s);
96 else
97 printf(".");
98 }
99 printf("\n");
100 }
101}
102
103int
104read_buffer(
105 int fd,
106 off64_t offset,
107 ssize_t count,
108 ssize_t *total,
109 int verbose,
110 int onlyone)
111{
112 ssize_t bytes;
113
114 *total = 0;
115 while (count > 0) {
116 bytes = pread64(fd, buffer, min(count,buffersize), offset);
117 if (bytes == 0)
118 break;
119 if (bytes < 0) {
120 perror("pread64");
121 return 0;
122 }
123 if (verbose)
124 dump_buffer(offset, bytes);
125 *total += bytes;
126 if (onlyone || bytes < count)
127 break;
128 offset += bytes;
129 count -= bytes;
130 }
131 return 1;
132}
133
134static int
135pread_f(
136 int argc,
137 char **argv)
138{
139 off64_t offset;
140 ssize_t count, total;
141 unsigned int bsize = 4096;
142 char *sp;
143 int vflag = 0;
144 int c;
145
146 while ((c = getopt(argc, argv, "b:v")) != EOF) {
147 switch (c) {
148 case 'b':
149 bsize = strtoul(optarg, &sp, 0);
150 if (!sp || sp == optarg) {
151 printf(_("non-numeric bsize -- %s\n"), optarg);
152 return 0;
153 }
154 break;
155 case 'v':
156 vflag = 1;
157 break;
158 default:
159 printf("%s %s\n", pread_cmd.name, pread_cmd.oneline);
160 return 0;
161 }
162 }
163 if (optind != argc - 2) {
164 printf("%s %s\n", pread_cmd.name, pread_cmd.oneline);
165 return 0;
166 }
167 offset = strtoul(argv[optind], &sp, 0);
168 if (!sp || sp == argv[optind]) {
169 printf(_("non-numeric offset argument -- %s\n"), argv[optind]);
170 return 0;
171 }
172 optind++;
173 count = strtoul(argv[optind], &sp, 0);
174 if (!sp || sp == argv[optind]) {
175 printf(_("non-numeric length argument -- %s\n"), argv[optind]);
176 return 0;
177 }
178
179 if (!alloc_buffer(bsize, 0xabababab))
180 return 0;
181
182 if (!read_buffer(fdesc, offset, count, &total, vflag, 0))
183 return 0;
184
185 printf(_("read %u/%u bytes at offset %llu\n"), total, count, offset);
186 return 0;
187}
188
189void
190pread_init(void)
191{
192 pread_cmd.name = _("pread");
193 pread_cmd.altname = _("r");
194 pread_cmd.cfunc = pread_f;
195 pread_cmd.argmin = 2;
196 pread_cmd.argmax = -1;
197 pread_cmd.args = _("[-b bs] [-v] off len");
198 pread_cmd.oneline = _("reads a number of bytes at a specified offset");
199 pread_cmd.help = pread_help;
200
201 add_command(&pread_cmd);
202}