FreeCalypso > hg > freecalypso-tools
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 } |