📄 od.c
字号:
/* od - octal dump Author: Andy Tanenbaum */#include <sys/types.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>int bflag, cflag, dflag, oflag, xflag, hflag, vflag;int linenr, width, state, ever;int prevwds[8];long off;char buf[512], buffer[BUFSIZ];int next;int bytespresent;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(long offset, (int argc, char *argv [], int k));_PROTOTYPE(void dumpfile, (void));_PROTOTYPE(void wdump, (short *words, int k, int radix));_PROTOTYPE(void bdump, (char bytes [16 ], int k, int c));_PROTOTYPE(void byte, (int val, int c));_PROTOTYPE(int getwords, (short **words));_PROTOTYPE(int same, (short *w1, int *w2));_PROTOTYPE(void outword, (int val, int radix));_PROTOTYPE(void outnum, (int num, int radix));_PROTOTYPE(void addrout, (long l));_PROTOTYPE(char hexit, (int k));_PROTOTYPE(void usage, (void));int main(argc, argv)int argc;char *argv[];{ int k, flags; char *p; /* Process flags */ setbuf(stdout, buffer); flags = 0; p = argv[1]; if (argc > 1 && *p == '-') { /* Flags present. */ flags++; p++; while (*p) { switch (*p) { case 'b': bflag++; break; case 'c': cflag++; break; case 'd': dflag++; break; case 'h': hflag++; break; case 'o': oflag++; break; case 'v': vflag++; break; case 'x': xflag++; break; default: usage(); } p++; } } else { oflag = 1; } if ((bflag | cflag | dflag | oflag | xflag) == 0) oflag = 1; k = (flags ? 2 : 1); if (bflag | cflag) { width = 8; } else if (oflag) { width = 7; } else if (dflag) { width = 6; } else { width = 5; } /* Process file name, if any. */ p = argv[k]; if (k < argc && *p != '+') { /* Explicit file name given. */ close(0); if (open(argv[k], O_RDONLY) != 0) { fprintf(stderr, "od: cannot open %s\n", argv[k]); exit(1); } k++; } /* Process offset, if any. */ if (k < argc) { /* Offset present. */ off = offset(argc, argv, k); off = (off / 16L) * 16L; lseek(0, off, SEEK_SET); } dumpfile(); addrout(off); printf("\n"); return(0);}long offset(argc, argv, k)int argc;char *argv[];int k;{ int dot, radix; char *p, c; long val; /* See if the offset is decimal. */ dot = 0; p = argv[k]; while (*p) if (*p++ == '.') dot = 1; /* Convert offset to binary. */ radix = (dot ? 10 : 8); val = 0; p = argv[k]; if (*p == '+') p++; while (*p != 0 && *p != '.') { c = *p++; if (c < '0' || c > '9') { printf("Bad character in offset: %c\n", c); exit(1); } val = radix * val + c - '0'; } p = argv[k + 1]; if (k + 1 == argc - 1 && *p == 'b') val = 512L * val; return(val);}void dumpfile(){ int k; short *words; while ((k = getwords(&words))) { /* 'k' is # bytes read */ if (!vflag) { /* ensure 'lazy' evaluation */ if (k == 16 && ever == 1 && same(words, prevwds)) { if (state == 0) { printf("*\n"); state = 1; off += 16; continue; } else if (state == 1) { off += 16; continue; } } } addrout(off); off += k; state = 0; ever = 1; linenr = 1; if (oflag) wdump(words, k, 8); if (dflag) wdump(words, k, 10); if (xflag) wdump(words, k, 16); if (cflag) bdump((char *)words, k, (int)'c'); if (bflag) bdump((char *)words, k, (int)'b'); for (k = 0; k < 8; k++) prevwds[k] = words[k]; for (k = 0; k < 8; k++) words[k] = 0; }}void wdump(words, k, radix)short *words;int k, radix;{ int i; if (linenr++ != 1) printf(" "); for (i = 0; i < (k + 1) / 2; i++) outword(words[i], radix); printf("\n");}void bdump(bytes, k, c)char bytes[16];int k;char c;{ int i; if (linenr++ != 1) printf(" "); for (i = 0; i < k; i++) byte(bytes[i] & 0377, c); printf("\n");}void byte(val, c)int val;char c;{ if (c == 'b') { printf(" "); outnum(val, 7); return; } if (val == 0) printf(" \\0"); else if (val == '\b') printf(" \\b"); else if (val == '\f') printf(" \\f"); else if (val == '\n') printf(" \\n"); else if (val == '\r') printf(" \\r"); else if (val == '\t') printf(" \\t"); else if (val >= ' ' && val < 0177) printf(" %c", val); else { printf(" "); outnum(val, 7); }}int getwords(words)short **words;{ int count; if (next >= bytespresent) { bytespresent = read(0, buf, 512); next = 0; } if (next >= bytespresent) return(0); *words = (short *) &buf[next]; if (next + 16 <= bytespresent) count = 16; else count = bytespresent - next; next += count; return(count);}int same(w1, w2)short *w1;int *w2;{ int i; i = 8; while (i--) if (*w1++ != *w2++) return(0); return(1);}void outword(val, radix)int val, radix;{/* Output 'val' in 'radix' in a field of total size 'width'. */ int i; if (radix == 16) i = width - 4; if (radix == 10) i = width - 5; if (radix == 8) i = width - 6; if (i == 1) printf(" "); else if (i == 2) printf(" "); else if (i == 3) printf(" "); else if (i == 4) printf(" "); outnum(val, radix);}void outnum(num, radix)int num, radix;{/* Output a number with all leading 0s present. Octal is 6 places, * decimal is 5 places, hex is 4 places. */ int d, i; unsigned val; char s[8]; val = (unsigned) num; if (radix == 8) d = 6; else if (radix == 10) d = 5; else if (radix == 16) d = 4; else if (radix == 7) { d = 3; radix = 8; } for (i = 0; i < d; i++) { s[i] = val % radix; val -= s[i]; val = val / radix; } for (i = d - 1; i >= 0; i--) { if (s[i] > 9) printf("%c", 'a' + s[i] - 10); else printf("%c", s[i] + '0'); }}void addrout(l)long l;{ int i; if (hflag == 0) { for (i = 0; i < 7; i++) printf("%c", (int) ((l >> (18 - 3 * i)) & 07) + '0'); } else { for (i = 0; i < 7; i++) printf("%c", hexit((int) ((l >> (24 - 4 * i)) & 0x0F))); }}char hexit(k)int k;{ if (k <= 9) return('0' + k); else return('A' + k - 10);}void usage(){ fprintf(stderr, "Usage: od [-bcdhovx] [file] [ [+] offset [.] [b] ]\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -