51
51
static const char *cmdname = "cat";
52
52
#define CAT_VERSION "0.0.1"
53
53
#define CAT_DEFAULT_BUFLEN 1024
54
#define CAT_FULL_FILE 0
55
static const char *cat_oops = "That option is not yet supported\n";
56
56
static const char *hexchars = "0123456789abcdef";
58
58
static bool paging_enabled = false;
165
static unsigned int cat_file(const char *fname, size_t blen, bool hex)
165
static unsigned int cat_file(const char *fname, size_t blen, bool hex,
166
off64_t head, off64_t tail, bool tail_first)
167
168
int fd, bytes = 0, count = 0, reads = 0;
168
169
char *buff = NULL;
171
size_t offset = 0, copied_bytes = 0;
172
off64_t file_size = 0, length = 0;
172
174
fd = open(fname, O_RDONLY);
187
if (tail != CAT_FULL_FILE) {
188
file_size = lseek(fd, 0, SEEK_END);
189
if (head == CAT_FULL_FILE) {
192
} else if (tail_first) {
201
lseek(fd, (tail >= file_size) ? 0 : (file_size - tail), SEEK_SET);
203
lseek(fd, ((head - tail) >= file_size) ? 0 : (head - tail), SEEK_SET);
186
bytes = read(fd, buff, blen);
209
bytes = read(fd, buff + copied_bytes, (
210
(length != CAT_FULL_FILE && length - (off64_t)count <= (off64_t)(blen - copied_bytes)) ?
211
(size_t)(length - count) :
212
(blen - copied_bytes) ) );
213
bytes += copied_bytes;
189
217
buff[bytes] = '\0';
191
219
for (i = 0; i < bytes && !should_quit; i++) {
193
221
paged_char(hexchars[((uint8_t)buff[i])/16]);
194
222
paged_char(hexchars[((uint8_t)buff[i])%16]);
223
paged_char(((count+i+1) & 0xf) == 0 ? '\n' : ' ');
197
226
wchar_t c = str_decode(buff, &offset, bytes);
199
228
/* Reached end of string */
230
} else if (c == U_SPECIAL && offset + 2 >= (size_t)bytes) {
231
/* If an extended character is cut off due to the size of the buffer,
232
we will copy it over to the next buffer so it can be read correctly. */
233
copied_bytes = bytes - offset + 1;
234
memcpy(buff, buff + offset - 1, copied_bytes);
208
} while (bytes > 0 && !should_quit);
244
} while (bytes > 0 && !should_quit && (count < length || length == CAT_FULL_FILE));
211
247
if (bytes == -1) {
222
258
/* Main entry point for cat, accepts an array of arguments */
223
259
int cmd_cat(char **argv)
225
unsigned int argc, i, ret = 0, buffer = 0;
261
unsigned int argc, i, ret = 0;
264
aoff64_t head = CAT_FULL_FILE, tail = CAT_FULL_FILE;
227
265
bool hex = false;
228
266
bool more = false;
267
bool tailFirst = false;
229
268
sysarg_t rows, cols;
253
292
printf("%s\n", CAT_VERSION);
254
293
return CMD_SUCCESS;
256
printf("%s", cat_oops);
295
if (!optarg || str_uint64_t(optarg, NULL, 10, false, &head) != EOK ) {
296
puts("Invalid head size\n");
259
printf("%s", cat_oops);
301
if (!optarg || str_uint64_t(optarg, NULL, 10, false, &tail) != EOK ) {
302
puts("Invalid tail size\n");
305
if (head == CAT_FULL_FILE)
262
printf("%s", cat_oops);
309
if (!optarg || str_size_t(optarg, NULL, 10, false, &buffer) != EOK ) {
310
puts("Invalid buffer size\n");
296
346
for (i = optind; argv[i] != NULL && !should_quit; i++)
297
ret += cat_file(argv[i], buffer, hex);
347
ret += cat_file(argv[i], buffer, hex, head, tail, tailFirst);
300
350
return CMD_FAILURE;