/** * hex-head.c hex output of the head command. * * Written and Copyright (c) 2009 by Aaron Conole * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the license, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the IMPLIED WARRANTY of MERCHANTIBILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #ifndef BUFSIZ #define BUFSIZ 8192 #endif const char hex_head_usage[] = ": [OPTIONS] [FILE]...\n"; int c_gi = 0, c_cnt=0; long c_len = 0; int scnt = 0; char str[17]; int dump(void* b, int len, FILE *dump){ unsigned char *buf = b; int cnt = 0; FILE *out = stdout; if(dump != NULL) out = dump; for ( ; c_gi < c_len; c_gi++ ){ if ( c_cnt % 16 == 0 ){ fprintf(out, " %s\n%04X: ", str, c_cnt); memset(str, 0, 17); scnt = 0; } if ( buf[cnt] < ' ' || buf[cnt] >= 127 ) str[scnt%16] = '.'; else str[scnt%16] = buf[cnt]; fprintf(out, "%02X ", buf[cnt++]); c_cnt++; scnt++; --len; } fflush(out); return len; } int head(FILE *src, int len, int lines) { long lread = 0; size_t rlen = 0; int olen = 0; char buf[BUFSIZ]; c_len = c_gi = c_cnt = 0; memset(str, 0, 17); scnt = 0; lread = ftell(src); len += lread; c_len = len; while((lines > 0) && (fgets(buf, sizeof(buf), src) != 0)) { rlen = ftell(src) - lread; lread += rlen; if((len != -1) && (lread > len)) /*last group of bytes*/ { rlen = rlen - (lread - len); lines = 0; }else if(len == -1) { c_len = lread; } olen = dump(buf, rlen, stdout); if(buf[rlen - 1] == '\n') lines--; } if(olen == 0) fprintf(stdout, " %s\n", str); else fprintf(stdout, " %*s", 16+(16-olen%16)*2, str); fflush(stdout); fprintf(stdout, "\n"); return 0; } int main(int argc, char *argv[]) { char *buf; char opt; int len = -1, lines = 10, tmplen, i; char pr_head = 1; FILE *fp; if( argc <= 1 ) { fprintf(stderr, "%s%s\n", argv[0], hex_head_usage); return -1; } for (i = 1; i < argc; ++i) { if(argv[i][0] == '-') { opt = argv[i][1]; switch(opt) { case 'v': pr_head = 1; break; case 'q': pr_head = 0; break; case '-': { if(!strncmp("bytes", argv[i]+2, 5)) { tmplen = 0; tmplen = atoi(argv[i]+8); len = tmplen; }else if(!strncmp("lines", argv[i]+2, 5)) { lines = atoi(argv[i]+8); return -1; } else { printf("invalid options\n"); return -1; } } break; case 'c': tmplen = 0; if(++i < argc) tmplen = atoi(argv[i]); if(tmplen < 1) { printf("Invalid length field.\n"); return -1; } len = tmplen; break; case 'n': tmplen = 0; if(++i < argc) tmplen = atoi(argv[i]); if(tmplen < 1) { printf("Invalid lines field.\n"); return -1; } lines = tmplen; break; case 'h': printf("invalid options\n"); return -1; } } else { break; } } if(i >= argc) { head(stdin, len, lines); } else { for(;i %s <==\n", argv[i]); } if(head(src, len, lines) == -1) return -1; if(i < argc - 1) { fprintf(stdout, "\n"); } } } } return 0; }