comparison ffstools/tiffs-rd/cat.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children 1f27fc13eab7
comparison
equal deleted inserted replaced
-1:000000000000 0:e7502631a0f9
1 /*
2 * This C module implements the cat and catino commands.
3 */
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <strings.h>
10 #include <unistd.h>
11 #include "types.h"
12 #include "struct.h"
13 #include "globals.h"
14 #include "pathname.h"
15
16 int cat_mode;
17
18 static u8 hex_buf[16];
19 static int hex_fill;
20 static u32 hex_offset;
21
22 cat_hex_flush()
23 {
24 int i, c;
25
26 printf("%08X: ", hex_offset);
27 for (i = 0; i < 16; i++) {
28 if (i < hex_fill)
29 printf("%02X ", hex_buf[i]);
30 else
31 fputs(" ", stdout);
32 if (i == 7 || i == 15)
33 putchar(' ');
34 }
35 for (i = 0; i < hex_fill; i++) {
36 c = hex_buf[i];
37 if (c < ' ' || c > '~')
38 c = '.';
39 putchar(c);
40 }
41 putchar('\n');
42 }
43
44 cat_hex_byte(inb)
45 {
46 hex_buf[hex_fill++] = inb;
47 if (hex_fill >= 16) {
48 cat_hex_flush();
49 hex_offset += hex_fill;
50 hex_fill = 0;
51 }
52 }
53
54 void
55 cat_chunk(ch)
56 struct chunkinfo *ch;
57 {
58 u8 *p;
59 int c;
60
61 if (!ch->len)
62 return;
63 switch (cat_mode) {
64 case 0:
65 write(1, ch->start, ch->len);
66 return;
67 case 1:
68 for (p = ch->start; p < ch->end; p++) {
69 c = *p;
70 if (c >= ' ' && c <= '~' || c == '\n')
71 putchar(c);
72 else {
73 if (c & 0x80) {
74 putchar('M');
75 putchar('-');
76 c &= 0x7F;
77 }
78 putchar('^');
79 if (c == 0x7F)
80 putchar('?');
81 else
82 putchar(c + '@');
83 }
84 }
85 return;
86 case 2:
87 for (p = ch->start; p < ch->end; p++)
88 cat_hex_byte(*p);
89 return;
90 }
91 }
92
93 void
94 cat_finish()
95 {
96 switch (cat_mode) {
97 case 1:
98 putchar('\n');
99 return;
100 case 2:
101 if (hex_fill)
102 cat_hex_flush();
103 return;
104 }
105 }
106
107 static void
108 segment_cat_callback(inf, opaque)
109 struct inode_info *inf;
110 u_long opaque;
111 {
112 struct chunkinfo chi;
113
114 size_extra_chunk(inf, &chi);
115 cat_chunk(&chi);
116 }
117
118 cmd_cat(argc, argv)
119 char **argv;
120 {
121 extern int optind;
122 int c, headino;
123 struct inode_info *inf;
124 struct chunkinfo chi;
125
126 optind = 0;
127 while ((c = getopt(argc, argv, "hv")) != EOF)
128 switch (c) {
129 case 'h':
130 cat_mode = 2;
131 continue;
132 case 'v':
133 cat_mode = 1;
134 continue;
135 default:
136 usage: fprintf(stderr, "usage: cat [-v|-h] pathname\n");
137 exit(1);
138 }
139 if (argc != optind + 1)
140 goto usage;
141
142 read_ffs_image();
143 find_inode_block();
144 alloc_inode_table();
145 find_root_inode();
146
147 headino = find_pathname(argv[optind]);
148 inf = inode_info[headino];
149 switch (inf->type) {
150 case 0xE1:
151 case 0xF1:
152 break;
153 case 0xF2:
154 fprintf(stderr, "error: the requested object is a directory\n");
155 exit(1);
156 case 0xF3:
157 fprintf(stderr,
158 "error: the requested object is a symlink; use readlink instead of cat\n");
159 exit(1);
160 default:
161 fprintf(stderr, "error: unexpected object type %02X\n",
162 inf->type);
163 exit(1);
164 }
165 size_head_chunk(inf, &chi);
166 cat_chunk(&chi);
167 iterate_seg_file(headino, segment_cat_callback, 0L, 0, 0);
168 cat_finish();
169 exit(0);
170 }
171
172 cmd_catino(argc, argv)
173 char **argv;
174 {
175 extern int optind;
176 int c, headino;
177 struct inode_info *inf;
178 struct chunkinfo chi;
179
180 optind = 0;
181 while ((c = getopt(argc, argv, "hv")) != EOF)
182 switch (c) {
183 case 'h':
184 cat_mode = 2;
185 continue;
186 case 'v':
187 cat_mode = 1;
188 continue;
189 default:
190 usage: fprintf(stderr, "usage: catino [-v|-h] ino\n");
191 exit(1);
192 }
193 if (argc != optind + 1)
194 goto usage;
195 headino = strtoul(argv[optind], 0, 16);
196
197 read_ffs_image();
198 find_inode_block();
199 alloc_inode_table();
200 if (!validate_inode(headino)) {
201 fprintf(stderr, "catino: specified inode number is invalid\n");
202 exit(1);
203 }
204 inf = inode_info[headino];
205 switch (inf->type) {
206 case 0x00:
207 case 0xE1:
208 case 0xF1:
209 case 0xF3:
210 break;
211 case 0xF2:
212 fprintf(stderr, "error: the requested object is a directory\n");
213 exit(1);
214 default:
215 fprintf(stderr, "error: unexpected object type %02X\n",
216 inf->type);
217 exit(1);
218 }
219 if (!inf->len) {
220 fprintf(stderr, "error: requested inode has been reclaimed\n");
221 exit(1);
222 }
223 if (!validate_obj_name(headino, 0)) {
224 fprintf(stderr,
225 "error: no valid name at the beginning of the requested seghead chunk\n");
226 exit(1);
227 }
228 size_head_chunk(inf, &chi);
229 cat_chunk(&chi);
230 iterate_seg_file(headino, segment_cat_callback, 0L, !inf->type, 0);
231 cat_finish();
232 exit(0);
233 }