[comp.sources.atari.st] v02i035: hexify -- Hexidecimal encode/decode for mailing binaries

koreth@ssyx.ucsc.edu (Steven Grimm) (03/30/89)

Submitted-by: ntomczak@ualtavm.bitnet (Michal Jaegermann)
Posting-number: Volume 2, Issue 35
Archive-name: hexify

[Uuencode is much more efficient, but you can use this to send binaries
 across troublesome networks, such as BITNET (sometimes). -sg]

Here are two C programs which I used to perform a conversion to hex
and back.  Binary restorer is smart enough to find a "BEGIN" line and
create file name.  Both programs will compile with Sozobon C and dLibs
library (and many other compilers, I bet).  [SunOS 4.0's, for one... -sg]

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  dehex.c
#	  hexify.c
#
sed 's/^X//' << 'SHAR_EOF' > dehex.c &&
X/*
X *  Hex-to-binary utility -- conquer BITNET mailers!!
X *
X *  Restore binary file from a text file with hexadecimal digits
X *
X *  Michal Jaegermann, 19 March 1989
X */
X
X#include <stdio.h>
X#include <string.h>
X#define  BSIZE 128
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int ch, count = 0;
X	FILE *fin, *fout;
X	char inbuf[BSIZE+2];
X	char outname[14];
X	
X	if (argc != 2) {
X		fprintf(stderr, "usage: %s <infile>\n", argv[0]);
X		exit(1);
X	}
X	
X	if (NULL == (fin = fopen(argv[1],"r"))){
X		fprintf(stderr, "cannot find input file %s\n", argv[1]);
X		exit(1);
X	}
X	/* search for BEGIN line */
X	for(;;) {
X		if (NULL == fgets(inbuf, BSIZE, fin)){
X			fprintf(stderr, "No BEGIN line\n");
X			fclose(fin);
X			exit(1);
X		}
X		sscanf(inbuf, " %12s", outname);
X		if (0 == strcmp("BEGIN", outname)) break;
X		if ('\n' != inbuf[strlen(inbuf) - 1]) {
X			while ('\n' != (ch = getc(fin))) {
X				; /* eat a remainder of a line */
X			}
X		}
X	}
X	
X	/* get an output file name */
X	sscanf(inbuf, " %*5s %12s", outname);	
X	
X	if (NULL == (fout = fopen(outname,"wb"))){
X		fprintf(stderr, "cannot open output file %s", outname);
X		fclose(fin);
X		exit(1);
X	}
X	
X	/* do the actual job */	
X	while (1 == fscanf(fin, " %02x", &ch)) {
X		putc((char) ch, fout);
X	}
X	fclose(fout);
X
X	/* just a check for completeness */
X	fscanf(fin, " %3s", inbuf);
X	if (0 != strcmp("ND", inbuf)) { /* a little bit of cheating */
X		fprintf(stderr, "%s -- END line not found in %s\n",
X				inbuf, argv[1]);
X	}
X	fclose(fin);
X	exit(0);
X}
X
SHAR_EOF
chmod 0600 dehex.c || echo "restore of dehex.c fails"
sed 's/^X//' << 'SHAR_EOF' > hexify.c &&
X/*
X *  Binary-to-hex utility -- conquer BITNET mailers!!
X *
X *  Rewrite binary file as a text file containing hexadecimal
X *  digits
X *
X *  Michal Jaegermann, 19 March 1989
X */
X
X#include <stdio.h>
X/* LWIDTH bytes --- will put twice as many characters on output line */
X#define LWIDTH 32
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int ch, count = 0;
X	FILE *fin, *fout;
X	
X	if (argc != 3) {
X		fprintf(stderr, "usage: %s <infile> <outfile>\n", argv[0]);
X		exit(1);
X	}
X	
X	if (NULL == (fin = fopen(argv[1],"rb"))){
X		fprintf(stderr, "cannot find input file %s", argv[1]);
X	}
X	if (NULL == (fout = fopen(argv[2],"w"))){
X		fprintf(stderr, "cannot open output file %s", argv[2]);
X	}
X	
X	fprintf(fout, "BEGIN %s\n", argv[1]);
X	while (EOF != (ch = getc(fin))) {
X		fprintf(fout, "%02x", (unsigned) ch);
X		if (LWIDTH == (++count)) {
X			count = 0;
X			fprintf(fout,"\n");
X		}
X	}
X	fprintf(fout, "\nEND\n");
X	/*
X	 * we do not care if we have an extra new line - restore
X	 * utility will gobble it in any case
X	 */
X	exit(0);
X}
X
SHAR_EOF
chmod 0600 hexify.c || echo "restore of hexify.c fails"
exit 0