4.3BSD/usr/contrib/dipress/src/bin/ipf/ipf.c.ucb

/*
 *  Interpress utility - count the number of pages in a interpress file
 *
 *  Written for Xerox Corporation by Lee Moore & William LeFebvre
 *
 * Copyright (c) 1984, 1985 Xerox Corp.
 *
 * History:
 *	 2-sep-85 lee moore	created out of iptotext.c
 */

#ifdef vax11c
# include stdio
# include setjmp
# include ctype
# include "iptokens.h"
# include "ipnames.h"
#else
# include <stdio.h>
# include <setjmp.h>
# include <ctype.h>
# include <sys/types.h>
# include <sys/time.h>
# include "iptokens.h"
# include "ipnames.h"
#endif

jmp_buf next_file;

extern int errno;

main(argc, argv)

int  argc;
char *argv[];

{
    FILE *acctFile = stdout;
    int c,
	pageCount;
    char *login,
	 *host;
    extern int optind;
    extern char *optarg;
    char *getdate(), *date, *xtra;

    login = "";
    host = "";
    date = "";
    xtra = "";

    while ((c = getopt(argc, argv, "cdw:l:i:n:h:x:")) != EOF)
	switch (c) {
		case 'c':
		case 'w':
		case 'l':
		case 'i':
			break;

		case 'n':
			login = optarg;
			break;

		case 'h':
			host = optarg;
			break;

		case 'x':
			xtra = optarg;
			break;

		case 'd':
			date = getdate();
			break;

		default:
			printf("option '%c' not allowed\n");
	}

    pageCount = do_file(stdin);

    if( pageCount < 0 )
	exit(2);

    if (argc - optind == 1)
    {

	if( (acctFile = fopen(argv[optind], "a")) == NULL ) {
	    fprintf(stderr, "ipf: can't open acct file: %s\n", argv[optind]);
	    exit(2);
	}
    }

    fprintf(acctFile, "%s %s %d%s%s\n",
		host, login, pageCount + 1, date, xtra);

    exit(0);

}


/*
 * process one file
 */

do_file(file)
FILE *file;
{
# define  Buffsize	256
    char buff[Buffsize];
    char *ptr;
    int len;
    int bodyDepth;	/* how many bodies down we are */
    register int bodyCount,	/* how many bodies we have seen so far */
    		 val,
    		 byte;		/* has to be "int" for stdio EOF detection */
				/* stdio is a pile! */
    int hlen;

    hlen = strlen(IP_Header);

    /* for error recovery */
    if (setjmp(next_file) != 0)
    {
	return -1;
    }

    /* get the header */
    for (hlen = 0, ptr = buff; hlen < Buffsize; hlen++)
    {
	if ((*ptr++ = getnoeofc(file)) == ' ')
	    break;
    }
    *ptr = '\0';

    /* check the validity of the header */
    if (strcmp(buff, IP_Header) != 0)
    {
	fprintf(stderr, " (INVALID HEADER!)");
    }

    bodyDepth = 0;
    bodyCount = 0;

    /* main loop */
    while ((byte = getc(file)) != EOF)
    {
	if ((byte & 0200) == 0)
	{
	    /* a short number */
	    val = (byte << 8) + getnoeofc(file) - INTEGER_ZERO;
	}
	else
	{
	    /* something else */
	    switch(byte >> 5)
	    {
		case (SHORT_OP >> 5):
		    break;

		case (LONG_OP >> 5):
		    val = ((byte & 037) << 8) + getnoeofc(file);
		    if( val == OP_beginBody )
		    {
			bodyDepth++;
		    } 
		    else if( val == OP_endBody )
		    {
			bodyDepth--;

			/* is this a top level body? */
			if( bodyDepth == 0 )
			    bodyCount++;
		    }
		    break;

		case (SHORT_SEQUENCE >> 5):
		    len = getnoeofc(file);
		    eatBytes(file, len);
		    break;

		case (LONG_SEQUENCE >> 5):
		    len  =  getnoeofc(file) << 16;
		    len += (getnoeofc(file) << 8);
		    len += getnoeofc(file);
		    eatBytes(file, len);
		    break;
	    }
	}
    }

    return bodyCount - 1;	/* the preamble is an extra body */
}


/*
 * get a character
 */

getnoeofc(file)

FILE *file;

{
    register int val;

#ifdef vax11c
    val= getc(file);
    if ( feof(file) )
#else
    if ((val = getc(file)) == EOF)
#endif
    {
	fprintf(stderr, "Unexpected EOF!");
	longjmp(next_file, 1);
    }
    return(val);
}


/*
 * read some bytes from the input stream
 */

eatBytes(file, length)
FILE *file;
int length;

{
    register int count;

    count = length;

    while(count-- > 0)
    {
	(void) getnoeofc(file);
    }
}

char *
getdate()
{
	static char buf[30];
#ifdef vax11c
	*buf = 0;
#else
	struct timeval tv;
	struct timezone tz;
	struct tm *tmp;
	 
	gettimeofday(&tv, &tz);
	tmp = localtime(&tv.tv_sec);
	sprintf(buf, " %d/%d-%02d:%02d",
		tmp->tm_mon+1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min);
#endif
	return buf;
}