2.11BSD/src/usr.bin/mkerrlst/mkerrlst.c

Compare this file to the similar file:
Show the results in this format:

/*
 *      Program Name:   mkerrlst.c
 *      Date: March 5, 1996
 *      Author: S.M. Schultz
 *
 *      -----------------   Modification History   ---------------
 *      Version Date            Reason For Modification
 *      1.0     05Mar96         1. Initial release into the public domain.
 *	1.1	14Mar96		2. Add ability to take messages from a file
 *				   in place of a fixed array.
*/

/*
 * mkerrlst - writes the error messages from sys_errlist[] or a input file of
 *	      strings to a formatted file prepending a header for quick access.
 *
 * This code can be used as a template for creating additional error message
 * files.  The "-o" option can be used to specify a different output file 
 * than _PATH_SYSERRLST.  The "-i" option is used to specify an input file
 * of error messages (one per line, maximum length 80 characters).  Error
 * messages are numbered starting at 0.
 *
 * If no "-i" option is used the sys_errlist[] array is used by default.
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <errlst.h>
#include <string.h>

	int	outf;
	struct	iovec	iov[2];
	off_t	msgoff;
	char	*outfn, *infn, *msg, *getmsg();
	struct	ERRLSTHDR	ehdr;
	FILE	*infp;

extern	char	*__progname;
extern	char	*sys_errlist[];
extern	int	sys_nerr;

main(argc,argv)
	{
	register int	c;
	int	len, maxlen = -1;

	while	((c = getopt(argc, argv, "o:i:")) != EOF)
		{
		switch	(c)
			{
			case	'o':
				outfn = optarg;
				break;
			case	'i':
				infn = optarg;
				break;
			case	'?':
			default:
				usage();
			}
		}

	if	(!outfn)
		outfn = _PATH_SYSERRLST;

	if	((outf = open(outfn, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
		err(1, "can't create %s", outfn);
	if	(fchmod(outf, 0644) < 0)
		err(1, "fchmod(%d,644)", outf);

	if	(infn)
		{
		infp = fopen(infn, "r");
		if	(!infp)
			err(1, "fopen(%s, r) failed\n", infn);
		}

	for	(c = 0; msg = getmsg(c, infp); c++)
		{
		len = strlen(msg);
		if	(len > maxlen)
			maxlen = len;
		}

	if	(infp)
		rewind(infp);

/*
 * Adjust the count so that the int written to the file is the highest valid
 * message number rather than the number of the first invalid error number.
 *
 * At the present time nothing much uses the maximum message length.
*/
	ehdr.magic = ERRMAGIC;
	ehdr.maxmsgnum = c - 1;
	ehdr.maxmsglen = maxlen;
	if	(write(outf, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
		err(1, "write");

	msgoff = sizeof (ehdr) + ((off_t)sizeof (struct ERRLST) * sys_nerr);
	iov[0].iov_base = (caddr_t)&msgoff;
	iov[0].iov_len = sizeof (off_t);

	iov[1].iov_len = sizeof (int);

	for	(c = 0; msg = getmsg(c, infp); c++)
		{
		len = strlen(msg);
		iov[1].iov_base = (caddr_t)&len;
		writev(outf, iov, 2);
		msgoff += len;
		msgoff++;		/* \n between messages */
		}

	iov[1].iov_base = "\n";
	iov[1].iov_len = 1;

	if	(infp)
		rewind(infp);

	for	(c = 0; msg = getmsg(c, infp); c++)
		{
		iov[0].iov_base = msg;
		iov[0].iov_len = strlen(iov[0].iov_base);
		writev(outf, iov, 2);
		}
	close(outf);
	if	(infp)
		fclose(infp);
	exit(0);
	}

char *
getmsg(c, fp)
	int	c;
	FILE	*fp;
	{
	static	char	buf[81];
	register char	*cp;

	if	(fp)
		{
		cp = fgets(buf, sizeof (buf) - 1, fp);
		if	(!cp)
			return(NULL);
		cp = index(buf, '\n');
		if	(cp)
			*cp = '\0';
		return(buf);
		}
	if	(c < sys_nerr)
		return(sys_errlist[c]);
	return(NULL);
	}

usage()
	{
	fprintf(stderr, "usage: %s -o filename\n", __progname);
	exit(1);
	}