#include #include #include 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 ); }