Blob
1 #include <u.h>2 #include <libc.h>3 #include <bio.h>5 unsigned char odata[16];6 unsigned char data[16];7 int ndata;8 unsigned long addr;9 int repeats;10 int swizzle;11 int swizzle8;12 int flush;13 int abase=2;14 int xd(char *, int);15 void xprint(char *, ulong);16 void initarg(void), swizz(void), swizz8(void);17 enum{18 Narg=1019 };20 typedef struct Arg Arg;21 typedef void fmtfn(char *);22 struct Arg23 {24 int ascii; /* 0==none, 1==ascii */25 int loglen; /* 0==1, 1==2, 2==4, 3==8 */26 int base; /* 0==8, 1==10, 2==16 */27 fmtfn *fn; /* function to call with data */28 char *afmt; /* format to use to print address */29 char *fmt; /* format to use to print data */30 }arg[Narg];31 int narg;33 fmtfn fmt0, fmt1, fmt2, fmt3, fmtc;34 fmtfn *fmt[4] = {35 fmt0,36 fmt1,37 fmt2,38 fmt339 };41 char *dfmt[4][3] = {42 " %.3uo", " %.3ud", " %.2ux",43 " %.6uo", " %.5ud", " %.4ux",44 " %.11luo", " %.10lud", " %.8lux",45 " %.22lluo", " %.20llud", " %.16llux",46 };48 char *cfmt[3][3] = {49 " %c", " %c", " %c",50 " %.3s", " %.3s", " %.2s",51 " %.3uo", " %.3ud", " %.2ux",52 };54 char *afmt[2][3] = {55 "%.7luo ", "%.7lud ", "%.7lux ",56 "%7luo ", "%7lud ", "%7lux ",57 };59 Biobuf bin;60 Biobuf bout;62 void63 main(int argc, char *argv[])64 {65 int i, err;66 Arg *ap;68 Binit(&bout, 1, OWRITE);69 err = 0;70 ap = 0;71 while(argc>1 && argv[1][0]=='-' && argv[1][1]){72 --argc;73 argv++;74 argv[0]++;75 if(argv[0][0] == 'r'){76 repeats = 1;77 if(argv[0][1])78 goto Usage;79 continue;80 }81 if(argv[0][0] == 's'){82 swizzle = 1;83 if(argv[0][1])84 goto Usage;85 continue;86 }87 if(argv[0][0] == 'S'){88 swizzle8 = 1;89 if(argv[0][1])90 goto Usage;91 continue;92 }93 if(argv[0][0] == 'u'){94 flush = 1;95 if(argv[0][1])96 goto Usage;97 continue;98 }99 if(argv[0][0] == 'a'){100 argv[0]++;101 switch(argv[0][0]){102 case 'o':103 abase = 0;104 break;105 case 'd':106 abase = 1;107 break;108 case 'x':109 abase = 2;110 break;111 default:112 goto Usage;113 }114 if(argv[0][1])115 goto Usage;116 continue;117 }118 ap = &arg[narg];119 initarg();120 while(argv[0][0]){121 switch(argv[0][0]){122 case 'c':123 ap->ascii = 1;124 ap->loglen = 0;125 if(argv[0][1] || argv[0][-1]!='-')126 goto Usage;127 break;128 case 'o':129 ap->base = 0;130 break;131 case 'd':132 ap->base = 1;133 break;134 case 'x':135 ap->base = 2;136 break;137 case 'b':138 case '1':139 ap->loglen = 0;140 break;141 case 'w':142 case '2':143 ap->loglen = 1;144 break;145 case 'l':146 case '4':147 ap->loglen = 2;148 break;149 case 'v':150 case '8':151 ap->loglen = 3;152 break;153 default:154 Usage:155 fprint(2, "usage: xd [-u] [-r] [-s] [-a{odx}] [-c|{b1w2l4v8}{odx}] ... file ...\n");156 exits("usage");157 }158 argv[0]++;159 }160 if(ap->ascii)161 ap->fn = fmtc;162 else163 ap->fn = fmt[ap->loglen];164 ap->fmt = dfmt[ap->loglen][ap->base];165 ap->afmt = afmt[ap>arg][abase];166 }167 if(narg == 0)168 initarg();169 if(argc == 1)170 err = xd(0, 0);171 else if(argc == 2)172 err = xd(argv[1], 0);173 else for(i=1; i<argc; i++)174 err |= xd(argv[i], 1);175 exits(err? "error" : 0);176 }178 void179 initarg(void)180 {181 Arg *ap;183 ap = &arg[narg++];184 if(narg >= Narg){185 fprint(2, "xd: too many formats (max %d)\n", Narg);186 exits("usage");187 }188 ap->ascii = 0;189 ap->loglen = 2;190 ap->base = 2;191 ap->fn = fmt2;192 ap->fmt = dfmt[ap->loglen][ap->base];193 ap->afmt = afmt[narg>1][abase];194 }196 int197 xd(char *name, int title)198 {199 int fd;200 int i, star;201 Arg *ap;202 Biobuf *bp;204 fd = 0;205 if(name){206 bp = Bopen(name, OREAD);207 if(bp == 0){208 fprint(2, "xd: can't open %s\n", name);209 return 1;210 }211 }else{212 bp = &bin;213 Binit(bp, fd, OREAD);214 }215 if(title)216 xprint("%s\n", (long)name);217 addr = 0;218 star = 0;219 while((ndata=Bread(bp, data, 16)) >= 0){220 if(ndata < 16)221 for(i=ndata; i<16; i++)222 data[i] = 0;223 if(swizzle)224 swizz();225 if(swizzle8)226 swizz8();227 if(ndata==16 && repeats){228 if(addr>0 && data[0]==odata[0]){229 for(i=1; i<16; i++)230 if(data[i] != odata[i])231 break;232 if(i == 16){233 addr += 16;234 if(star == 0){235 star++;236 xprint("*\n", 0);237 }238 continue;239 }240 }241 for(i=0; i<16; i++)242 odata[i] = data[i];243 star = 0;244 }245 for(ap=arg; ap<&arg[narg]; ap++){246 xprint(ap->afmt, addr);247 (*ap->fn)(ap->fmt);248 xprint("\n", 0);249 if(flush)250 Bflush(&bout);251 }252 addr += ndata;253 if(ndata<16){254 xprint(afmt[0][abase], addr);255 xprint("\n", 0);256 if(flush)257 Bflush(&bout);258 break;259 }260 }261 Bterm(bp);262 return 0;263 }265 void266 swizz(void)267 {268 uchar *p, *q;269 int i;270 uchar swdata[16];272 p = data;273 q = swdata;274 for(i=0; i<16; i++)275 *q++ = *p++;276 p = data;277 q = swdata;278 for(i=0; i<4; i++){279 p[0] = q[3];280 p[1] = q[2];281 p[2] = q[1];282 p[3] = q[0];283 p += 4;284 q += 4;285 }286 }288 void289 swizz8(void)290 {291 uchar *p, *q;292 int i;293 uchar swdata[16];295 p = data;296 q = swdata;297 for(i=0; i<16; i++)298 *q++ = *p++;299 p = data;300 q = swdata;301 for(i=0; i<8; i++){302 p[0] = q[7];303 p[1] = q[6];304 p[2] = q[5];305 p[3] = q[4];306 p[4] = q[3];307 p[5] = q[2];308 p[6] = q[1];309 p[7] = q[0];310 p += 8;311 q += 8;312 }313 }315 void316 fmt0(char *f)317 {318 int i;319 for(i=0; i<ndata; i++)320 xprint(f, data[i]);321 }323 void324 fmt1(char *f)325 {326 int i;327 for(i=0; i<ndata; i+=2)328 xprint(f, (data[i]<<8)|data[i+1]);329 }331 void332 fmt2(char *f)333 {334 int i;335 for(i=0; i<ndata; i+=4)336 xprint(f, (u32int)((data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]));337 }339 void340 fmt3(char *f)341 {342 int i;343 unsigned long long v;344 for(i=0; i<ndata; i+=8){345 v = (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3];346 v <<= 32;347 v |= (data[i+4]<<24)|(data[i+1+4]<<16)|(data[i+2+4]<<8)|data[i+3+4];348 if(Bprint(&bout, f, v)<0){349 fprint(2, "xd: i/o error\n");350 exits("i/o error");351 }352 }353 }355 void356 fmtc(char *f)357 {358 int i;360 USED(f);361 for(i=0; i<ndata; i++)362 switch(data[i]){363 case '\t':364 xprint(cfmt[1][2], (long)"\\t");365 break;366 case '\r':367 xprint(cfmt[1][2], (long)"\\r");368 break;369 case '\n':370 xprint(cfmt[1][2], (long)"\\n");371 break;372 case '\b':373 xprint(cfmt[1][2], (long)"\\b");374 break;375 default:376 if(data[i]>=0x7F || ' '>data[i])377 xprint(cfmt[2][2], data[i]);378 else379 xprint(cfmt[0][2], data[i]);380 break;381 }382 }384 void385 xprint(char *fmt, ulong d)386 {387 if(Bprint(&bout, fmt, d)<0){388 fprint(2, "xd: i/o error\n");389 exits("i/o error");390 }391 }