Created od, with improvements suggested by FRIGN
This commit is contained in:
		
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							@@ -54,7 +54,7 @@ Authors/contributors include:
 | 
				
			|||||||
© 2014 Ari Malinen <ari.malinen@gmail.com>
 | 
					© 2014 Ari Malinen <ari.malinen@gmail.com>
 | 
				
			||||||
© 2014 Brandon Mulcahy <brandon@jangler.info>
 | 
					© 2014 Brandon Mulcahy <brandon@jangler.info>
 | 
				
			||||||
© 2014 Adria Garriga <rhaps0dy@installgentoo.com>
 | 
					© 2014 Adria Garriga <rhaps0dy@installgentoo.com>
 | 
				
			||||||
© 2014 Greg Reagle <greg.reagle@umbc.edu>
 | 
					© 2014-2015 Greg Reagle <greg.reagle@umbc.edu>
 | 
				
			||||||
© 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
 | 
					© 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
 | 
				
			||||||
© 2015 Quentin Rameau <quinq@quinq.eu.org>
 | 
					© 2015 Quentin Rameau <quinq@quinq.eu.org>
 | 
				
			||||||
© 2015 Dionysis Grigoropoulos <info@erethon.com>
 | 
					© 2015 Dionysis Grigoropoulos <info@erethon.com>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							@@ -115,6 +115,7 @@ BIN =\
 | 
				
			|||||||
	nice\
 | 
						nice\
 | 
				
			||||||
	nl\
 | 
						nl\
 | 
				
			||||||
	nohup\
 | 
						nohup\
 | 
				
			||||||
 | 
						od\
 | 
				
			||||||
	paste\
 | 
						paste\
 | 
				
			||||||
	printenv\
 | 
						printenv\
 | 
				
			||||||
	printf\
 | 
						printf\
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								README
									
									
									
									
									
								
							@@ -54,6 +54,7 @@ The following tools are implemented:
 | 
				
			|||||||
=*|o nice        .
 | 
					=*|o nice        .
 | 
				
			||||||
#*|o nl          .
 | 
					#*|o nl          .
 | 
				
			||||||
=*|o nohup       .
 | 
					=*|o nohup       .
 | 
				
			||||||
 | 
					     od          a lot
 | 
				
			||||||
#*|o paste       .
 | 
					#*|o paste       .
 | 
				
			||||||
=*|x printenv    .
 | 
					=*|x printenv    .
 | 
				
			||||||
#*|o printf      .
 | 
					#*|o printf      .
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO
									
									
									
									
									
								
							@@ -10,7 +10,6 @@ diff
 | 
				
			|||||||
ed
 | 
					ed
 | 
				
			||||||
getconf
 | 
					getconf
 | 
				
			||||||
install
 | 
					install
 | 
				
			||||||
od
 | 
					 | 
				
			||||||
patch
 | 
					patch
 | 
				
			||||||
pathchk
 | 
					pathchk
 | 
				
			||||||
stty
 | 
					stty
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								od.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								od.1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					.Dd September 28, 2015
 | 
				
			||||||
 | 
					.Dt OD 1
 | 
				
			||||||
 | 
					.Os sbase
 | 
				
			||||||
 | 
					.Sh NAME
 | 
				
			||||||
 | 
					.Nm od
 | 
				
			||||||
 | 
					.Nd octal dump
 | 
				
			||||||
 | 
					.Sh SYNOPSIS
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					.Op Fl A Ar d|o|x|n
 | 
				
			||||||
 | 
					.Op Fl t Ar a|c|d|o|u|x
 | 
				
			||||||
 | 
					.Op Ar file...
 | 
				
			||||||
 | 
					.Sh DESCRIPTION
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					writes an octal dump of each
 | 
				
			||||||
 | 
					.Ar file
 | 
				
			||||||
 | 
					to stdout.  If no
 | 
				
			||||||
 | 
					.Ar file
 | 
				
			||||||
 | 
					is given, then
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					reads from stdin.
 | 
				
			||||||
 | 
					.Sh OPTIONS
 | 
				
			||||||
 | 
					.Bl -tag -width Ds
 | 
				
			||||||
 | 
					.It Fl A Ar d|o|x|n
 | 
				
			||||||
 | 
					Display the address in base \fId\fRecimal | \fIo\fRctal |
 | 
				
			||||||
 | 
					he\fIx\fRadecimal | \fIn\fRone.  If unspecified, the default is octal.
 | 
				
			||||||
 | 
					.It Fl t Ar a|c|d|o|u|x
 | 
				
			||||||
 | 
					Display the content as n\fIa\fRmed character, \fIc\fRharacter, signed
 | 
				
			||||||
 | 
					\fId\fRecimal, \fIo\fRctal, \fIu\fRnsigned decimal, or
 | 
				
			||||||
 | 
					he\fIx\fRadecimal.  If unspecified, the default is octal.
 | 
				
			||||||
 | 
					.El
 | 
				
			||||||
							
								
								
									
										177
									
								
								od.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								od.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
				
			|||||||
 | 
					/* See LICENSE file for copyright and license details. */
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char addr_radix = 'o';
 | 
				
			||||||
 | 
					static char *type = "o";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					usage(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						eprintf("usage: %s [-A d|o|x|n] [-t a|c|d|o|u|x] [file ...]\n", argv0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					print_address(FILE *f, size_t addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (addr_radix) {
 | 
				
			||||||
 | 
						case 'x':
 | 
				
			||||||
 | 
							fprintf(f, "%06zx ", addr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'd':
 | 
				
			||||||
 | 
							fprintf(f, "%06zd ", addr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'n':
 | 
				
			||||||
 | 
							fprintf(f, "%s", " ");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'o':
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							fprintf(f, "%06zo ", addr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char char_string[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *
 | 
				
			||||||
 | 
					escaped_char(unsigned char c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (c) {
 | 
				
			||||||
 | 
						case '\0':
 | 
				
			||||||
 | 
							return "\\0";
 | 
				
			||||||
 | 
						case '\a':
 | 
				
			||||||
 | 
							return "\\a";
 | 
				
			||||||
 | 
						case '\b':
 | 
				
			||||||
 | 
							return "\\b";
 | 
				
			||||||
 | 
						case '\t':
 | 
				
			||||||
 | 
							return "\\t";
 | 
				
			||||||
 | 
						case '\n':
 | 
				
			||||||
 | 
							return "\\n";
 | 
				
			||||||
 | 
						case '\v':
 | 
				
			||||||
 | 
							return "\\v";
 | 
				
			||||||
 | 
						case '\f':
 | 
				
			||||||
 | 
							return "\\f";
 | 
				
			||||||
 | 
						case '\r':
 | 
				
			||||||
 | 
							return "\\r";
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							char_string[0] = c;
 | 
				
			||||||
 | 
							char_string[1] = '\0';
 | 
				
			||||||
 | 
							return char_string;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *
 | 
				
			||||||
 | 
					named_char(unsigned char c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const int table_size = 33;
 | 
				
			||||||
 | 
						static const char * named_chars[] = {"nul", "soh", "stx", "etx", "eot", 
 | 
				
			||||||
 | 
						 "enq", "ack", "bel", "bs", "ht", "nl", "vt", "ff", "cr", "so", "si", 
 | 
				
			||||||
 | 
						 "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em", 
 | 
				
			||||||
 | 
						 "sub", "esc", "fs", "gs", "rs", "us", "sp"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c &= ~128; /* clear high bit of byte, as required by standard */
 | 
				
			||||||
 | 
						if (c < table_size) {
 | 
				
			||||||
 | 
							return named_chars[c];
 | 
				
			||||||
 | 
						} else if (c == 127) {
 | 
				
			||||||
 | 
							return "del"; 
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							char_string[0] = c;
 | 
				
			||||||
 | 
							char_string[1] = '\0';
 | 
				
			||||||
 | 
							return char_string;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					print_content(FILE *f, char type, unsigned char cont)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case 'a':
 | 
				
			||||||
 | 
							fprintf(f, "%3s ", named_char(cont));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'c':
 | 
				
			||||||
 | 
							fprintf(f, "%3s ", escaped_char(cont));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'd':
 | 
				
			||||||
 | 
							fprintf(f, "%4hhd ", cont);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'o':
 | 
				
			||||||
 | 
							fprintf(f, "%03hho ", cont);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'u':
 | 
				
			||||||
 | 
							fprintf(f, "%3hhu ", cont);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'x':
 | 
				
			||||||
 | 
							fprintf(f, "%02hhx ", cont);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					od(FILE *fp_in, const char *name_in, FILE *fp_out, const char *name_out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned char buf[BUFSIZ];
 | 
				
			||||||
 | 
						size_t addr, buf_size, i;
 | 
				
			||||||
 | 
						const size_t bytes_per_line = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addr = 0;
 | 
				
			||||||
 | 
						for (; (buf_size = fread(buf, 1, BUFSIZ, fp_in)); ) {
 | 
				
			||||||
 | 
							for (i = 0; i < buf_size; ++i, ++addr) {
 | 
				
			||||||
 | 
								if ((addr % bytes_per_line) == 0) {
 | 
				
			||||||
 | 
									if (addr != 0) fprintf(fp_out, "%s", "\n");
 | 
				
			||||||
 | 
									print_address(fp_out, addr);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								print_content(fp_out, type[0], buf[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (feof(fp_in) || ferror(fp_in) || ferror(fp_out))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fprintf(fp_out, "\n%.7zx \n", addr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					main(int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *fp;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					    char *s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ARGBEGIN {
 | 
				
			||||||
 | 
						case 'A':
 | 
				
			||||||
 | 
							s = EARGF(usage());
 | 
				
			||||||
 | 
							if (strlen(s) > 1 || !strchr("doxn", s[0]))
 | 
				
			||||||
 | 
								usage();
 | 
				
			||||||
 | 
							addr_radix = s[0];
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 't':
 | 
				
			||||||
 | 
							type = EARGF(usage());
 | 
				
			||||||
 | 
							if (strlen(type) > 1 || !strchr("acdoux", type[0]))
 | 
				
			||||||
 | 
								usage();
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							usage();
 | 
				
			||||||
 | 
						} ARGEND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!argc) {
 | 
				
			||||||
 | 
							od(stdin, "<stdin>", stdout, "<stdout>");
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							for (; *argv; argc--, argv++) {
 | 
				
			||||||
 | 
								if (!strcmp(*argv, "-")) {
 | 
				
			||||||
 | 
									*argv = "<stdin>";
 | 
				
			||||||
 | 
									fp = stdin;
 | 
				
			||||||
 | 
								} else if (!(fp = fopen(*argv, "r"))) {
 | 
				
			||||||
 | 
									weprintf("fopen %s:", *argv);
 | 
				
			||||||
 | 
									ret = 1;
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								od(fp, *argv, stdout, "<stdout>");
 | 
				
			||||||
 | 
								if (fp != stdin && fshut(fp, *argv))
 | 
				
			||||||
 | 
									ret = 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user