#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno;
#include "biffer.h"
extern char *ttyname();
/* how come there is no getopt.h */
extern	int	optind;
extern	char	*optarg;
extern	int	getopt();
extern	char	*getenv();


#define	ROOT	(0)	/* uid of root */


static	char	*progname;

static	void	listopts();
static	void	usage();


main( argc, argv )
int argc;
char *argv[];
{
    FILE *fp;
    char *tty, *p, fname[TTYBIFFRCSIZE];
    int c;
    int otherargs=0, dflag=FALSE, Dflag=FALSE, rflag = FALSE;
    char *hostname = CPNULL, *display = NULL;

    progname = argv[0];
    if ( (p = strrchr( progname, '/' )) != NULL && *(++p) )
	progname = p;

    while ( (c = getopt(argc, argv, "dD:h:r")) != EOF ) {
	switch ( c ) {
	    case 'd':
		dflag = TRUE;
		otherargs++;
		break;
	    case 'D':
		Dflag = TRUE;
		display = optarg;
		otherargs++;
		break;
	    case 'h':
		hostname = optarg;
		otherargs++;
		break;
	    case 'r':
		rflag = TRUE;
		break;
	    default:
		if ( c != '?' )
		    fprintf( stderr, "%s: unrecognized option '%c'\n",
			progname, c );
		usage();
	}
    }
    if ( optind < argc ) {
	fprintf( stderr, "%s: unrecognized trailing options:", progname );
	for ( ; optind < argc; optind++ )
	    fprintf( stderr, " %s", progname );
	usage();
    }
    /* If we have -r, and there was more than one option in the first place,
       tell them they are being silly. */
    if ( rflag && otherargs ) {
	fprintf( stderr, "%s: makes no sense to use -r with other options\n",
	    progname );
	exit( 1 );
    }
    if ( dflag && Dflag ) {
	fprintf( stderr, "%s: makes no sense to use -d and -D\n",
	    progname );
	exit( 1 );
    }
    if ( dflag ) {
	display = getenv( "DISPLAY" );
	if ( ! display ) {
	    fprintf( stderr, "%s: no DISPLAY variable set for -d\n",
		progname );
	    exit( 1 );
	}
    }

    tty = ttyname( fileno(stdin) );
    if ( ! tty ) {
	fprintf( stderr, "%s: ttyname() on stdin failed: %s\n",
	    progname, strerror( errno ) );
	exit( 1 );
    }
	if (!strncmp(tty, "/dev/", 5) && (tty[5] != '\0'))
		tty += 5;        /* remove leading /dev/ from tty */
	for (p=tty; *p; ++p)
		if (*p == '/')
			*p = '_';    /* replace slashes with "_" */

    /* Warn if root, since the person is probably running under "su"
       by accident, and won't get the desired behaviour. */
    if ( getuid() == ROOT )
	fprintf( stderr,
	    "%s: warning: running as root, perhaps not what you want\n",
	    progname );

    (void) sprintf( fname, TTYBIFFRC, tty, getuid() );

    if ( rflag ) {
	if ( unlink( fname ) != 0 && errno != ENOENT ) {
	    fprintf( stderr, "%s: could not unlink '%s': %s\n",
		progname, fname, strerror( errno ) );
	    exit( 1 );
	}
	exit( 0 );
    }

    /* ok - so set the file */
    if ( !otherargs ) {
	/* list any options file that already exists */
	listopts( fname );
	exit( 0 );
    }

    /* and write the file */
    if ( (fp = fopen( fname, "w" )) == FPNULL ) {
	fprintf( stderr, "%s: could not open '%s': %s\n",
	    progname, fname, strerror( errno ) );
	exit( 1 );
    }
    fprintf( fp, "# created by %s\n", progname );
    if ( display )
	fprintf( fp, "display %s\n", display );
    if ( hostname )
	fprintf( fp, "hostname %s\n", hostname );
    (void) fclose( fp );

    exit( 0 );
}


static void
listopts( fname )
char *fname;
{
    FILE *fp;
    int c;

    if ( (fp = fopen( fname, "r" )) != FPNULL ) {
	while ( (c = getc( fp )) != EOF )
	    putc( c, stdout );
	if ( ferror( fp ) )
	    fprintf( stderr,
		"%s: warning: error while reading options file '%s': %s\n",
		fname, strerror( errno ) );
	(void) fclose( fp );
    } else {
	if ( errno != ENOENT ) {
	    fprintf( stderr, "%s: could not open '%s': %s\n",
		progname, fname, strerror( errno ) );
	    exit( 1 );
	}
	/* else do nothing */
    }
}


static void
usage()
{
    fprintf( stderr, "%s: Usage: %s [-d] [-D display] [-h hostname] [-r]\n",
	progname, progname );
    exit( 1 );
}


syntax highlighted by Code2HTML, v. 0.9.1