[comp.sources.misc] v07i089: marquis -- scroll a message on the status line of a terminal

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (07/22/89)

Posting-number: Volume 7, Issue 89
Submitted-by: falcon@gorn.santa-cruz.ca.us (frederick smythe)
Archive-name: marquis

[[Warning:  when he says "System V", he means Xenix.  If SysV.3.2 has nap(),
  it will work there as well.  ++bsa]]

: to unbundle, sh this file -- DO NOT use csh
: This is SHAR archive format.
: Archive created Mon Jul 10 21:45:00 PDT 1989
: Packed by falcon@gorn (frederick smythe)
echo x - makefile
sed 's/^X//' > makefile <<'+FUNKY+STUFF+'
X# for sysv
XCFLAGS = -DSYSV -O
XLDFLAGS = -lx -ltermcap
X
X# for non-sysv
X#CFLAGS = -O
X#LDFLAGS = -ltermcap
X
XBINDIR = /usr/gorn/bin
X
Xall: marquis
X
Xinstall: marquis
X	@mv -f marquis $(BINDIR)/marquis
X	@chmod 711 $(BINDIR)/marquis
X	@l $(BINDIR)/marquis
X
Xmarquis: marquis.o
X	cc marquis.o -s -o marquis $(LDFLAGS)
X	@rm marquis.o
+FUNKY+STUFF+
chmod u=rw,g=,o= makefile
echo x - marquis.1
sed 's/^X//' > marquis.1 <<'+FUNKY+STUFF+'
X.TH MARQUIS 1
X.UC 5
X.SH NAME
Xmarquis \- scroll a message on the status line of a terminal
X.SH SYNOPSIS
Xmarquis { "string" | /filename } [ naptime ]
X.SH DESCRIPTION
X\fIMarquis\fR allows you to take a string or 
Xthe contents of a file and have it scroll across
Xthe status line of your terminal.  It is annoying at times
Xand helpful at other times.  It can be used for displaying
Xuseful reminders or just simple messages.  Upon invocation the pid
Xof the marquis process is printed to stdout so it can be captured
Xwith "set mpid=`marquis /etc/motd`".
X.SH USAGE
XThe first argument to marquis must be present.  If it begins
Xwith a forward slash (/) it is interpreted to be the name of a
Xfile to read the data from.  If it is not led by a slash, it is
Xinterpreted as a string.  An optional second argument may be
Xspecified which will change the naptime between updates from the
Xdefault of 150 ms.
X.SH EXAMPLES
XTo display "YUeYUeyUEyuEyuEyuE":
X.sp
X.br
X% marquis YUeYUeyUEyuEyuEyuE
X.sp
X.br
XTo display "FlaPaFLAppAFlAPFlAP FlaPflAp" using 300ms as the naptime:
X.sp
X.br
X% marquis "FlaPaFLAppAFlAPFlAP  FlaPflAp" 300
X.sp
X.br
XTo display the contents of "madonna.dat" using 100ms as the naptime:
X.sp
X.br
X% marquis /path/to/madonna.dat 100
X.SH BUGS
XThis program was never really finished so it has no _real_
Xargument processing.  Future features might be periodic checking
Xof a file to see if its contents should be reloaded as the data.
X.sp
X.br
XPlease send any problems, questions, or suggestions to the author.
X.SH AUTHOR
Xfrederick smythe, esquire (falcon@gorn.santa-cruz.ca.us)
+FUNKY+STUFF+
chmod u=rw,g=,o= marquis.1
echo x - marquis.c
sed 's/^X//' > marquis.c <<'+FUNKY+STUFF+'
X/********
X * @(#) marquis.c    falcon@gorn.santa-cruz.ca.us    03/28/89
X *
X * marquis is a program to display a string of characters scrolling
X * across the status line of a terminal.  it works best at high baud
X * rate direct terminals, obiviously, but can work ok even at 2400 baud.
X * (i use it at 19.2k myself)
X *
X * Idea blamed on: mikeha@sco.COM
X * 
X * Copyright: feel free to distribute this chunk 'o code freely as long
X *            as this original header is included.  also feel free to modify
X *            to your liking, but modifications from the original must be
X *            noted by means of inline comments. if modifications are made,
X *            please send a copy of the diffs back to me.
X *
X * vi: set ts=4 sw=4 ai
X */
X
X#include	<stdio.h>
X#include	<sgtty.h>
X#include	<signal.h>
X#define		stderR		stderr
X
Xchar	gosl[10],
X		lvsl[10],	/* go status line and leave status line */
X    	bp[1024],	/* buffers for tgetent () */
X		buffer[200];/* ^^^^^^^^^^^^^ */
X	
Xextern	char	*malloc (),
X				*getenv ();
Xvoid	rotate (),
X		tinit ();
Xchar	*tget (),
X		*getthatstringfromafilecalled (/*filename would be here*/);
Xint		cleanup ();
X
Xmain ( argc, argv )
Xint		argc;
Xchar	**argv;
X{
X	char	*str,			/* the string to be displayed */
X			buf[BUFSIZ];	/* temporary buffer */
X	long	naptime = 150L;	/* default micro seconds between updates */
X	int		len,
X			pid;
X
X	/*
X	 * make sure termcap can handle sysline
X	 */
X	tinit ();
X
X	/*
X	 * first argument is either the string to be displayed
X	 * or the name of a file to be displayed (if it begins with a /)
X	 */
X	if ( argv[1][0] == '/' )
X	{
X		str = getthatstringfromafilecalled (argv[1]);
X	}
X	else
X	{
X		len = strlen (argv[1]);
X		len = strlen (argv[1]) < 80 ? 80 : len;
X		str = malloc (len+1);
X		(void) sprintf (str, "%-79s", argv[1]);
X	}
X
X	/*
X	 * save these termcap values 
X	 */
X	(void) strcpy (gosl, tget ("ts"));
X	(void) strcpy (lvsl, tget ("fs"));
X
X	/*
X	 * if they dont have both entries, forget 'em and exit
X	 */
X	if ( !gosl[0] || !lvsl[0] )
X	{
X		(void) fputs 
X			("your terminal doesn't have status line capabilties, you nobk!\n", 
X			stderR);
X		(void) exit (1);
X	}	
X
X	/*
X	 * if there is another argument, it is an override
X	 * naptime
X	 */
X	if ( argc > 2 )
X	{
X		naptime = atol (argv[2]);
X	}
X
X	/*
X	 * fork off and die, printing the pid first
X	 */
X	if ( (pid = fork ()) )
X	{
X		(void) printf ("%d\r\n", pid);
X		(void) exit (0);
X	}
X
X	/*
X	 * ignore sigint/sigquit and catch
X	 * sigterm and sighup to clear the status line and exit
X	 */
X	(void) signal (SIGINT, SIG_IGN);
X	(void) signal (SIGQUIT, SIG_IGN);
X	(void) signal (SIGTERM, cleanup);
X	(void) signal (SIGHUP, cleanup);
X
X	/*
X	 * infinite looooooooooooooop
X	 */
X	for ( ; ; )
X	{
X		(void) sprintf (buf, "%s%-79.79s%s", gosl, str, lvsl);
X		(void) write (1, buf, strlen (buf));
X		rotate (str);
X		(void) nap (naptime);
X	}
X}
X
X/*
X * rotate () -- takes a string and shifts it one character to the left, with
X *              wrapping
X */
Xvoid
Xrotate (str)
Xchar	*str;
X{
X	char	p = *str;
X	long	len = strlen (str);
X
X	(void) strncpy (str, str+1, len - 1);
X	str[len] = '\0';
X	str[len-1] = p;
X}
X
X/*
X * tinit () -- makes sure we have a valid termcap 
X */
Xvoid
Xtinit()
X{
X	char	*name;
X
X    switch (tgetent (bp, name = getenv("TERM")) ) 
X	{
X		case -1:
X			(void) printf ("can't open termcap file.\n");
X			(void) exit (-1);
X		case 0:
X			(void) printf ("No termcap entry for %s.\n", name);
X			(void) exit (-1);
X	}
X}
X	
X/*
X * tget () -- returns the termcap entry for the passed code
X */
Xchar *
Xtget (code)
Xchar	*code;
X{
X    char	*area = buffer,
X    		*tgetstr();
X
X    return (tgetstr (code, &area));
X}
X
X/*
X * getthatstringfromafilecalled () -- reads in a file into a character buffer, 
X *                                    replacing special characters with spaces
X */
X
X#include	<sys/types.h>
X#include	<sys/stat.h>
X
Xchar *
Xgetthatstringfromafilecalled (filename)
Xchar	*filename;
X{
X	FILE	*fp;			/* file pointer to zis file */
X	struct	stat	sbuf;	/* stat buffer */
X	char	*buf,			/* buffer to hold contents of file */
X			*start;			/* pointer to start of resulting string */
X
X	/*
X	 * get the size of the file
X	 */
X	if ( stat (filename, &sbuf) < 0 )
X	{
X		(void) perror (filename);
X		(void) exit (2);
X	}
X
X	/*
X	 * open the file for reading, if it fails, just exit
X	 */
X	if ( (fp = fopen (filename, "r")) == (FILE *) NULL )
X	{
X		(void) perror (filename);
X		(void) exit (2);
X	}
X
X	/*
X	 * malloc mr. memory
X	 */
X	if ( (buf = malloc (sbuf.st_size)) == (char *) NULL )
X	{
X		(void) fprintf (stderr, "cannot malloc %ld bytes!\n", sbuf.st_size);
X		(void) fclose (fp);
X		(void) exit (2);
X	}
X
X	/*
X	 * now read it in and null terminate it
X	 */
X	(void) fread (buf, sbuf.st_size, 1, fp);
X	buf[sbuf.st_size] = '\0';
X
X	/*
X	 * save the starting position to return,
X	 * and then convert all newlines and tabs into spaces
X	 */
X	start = buf;
X
X	while ( *buf != '\0' )
X	{
X		if ( *buf == '\n' || *buf == '\t' || *buf == '\r' )
X		{
X			*buf = ' ';
X		}
X
X		++buf;
X	}
X
X	return (start);
X}
X
X/*
X * cleanup () -- clear the status line and exit
X */
Xint
Xcleanup (sig)
Xint	sig;
X{
X	char	buf[25];
X	
X	(void) sprintf (buf, "%s%s", gosl, lvsl);
X	(void) write (1, buf, strlen (buf));
X	(void) sprintf (buf, "marquis: got signal #%d\n\r", sig);
X	(void) write (1, buf, strlen (buf));
X	(void) exit (0);
X}
X
X#ifndef	SYSV
X
X#include	<sys/time.h>
Xint			nil ();
X
Xnap (usec)
Xlong	usec;
X{
X	(void) timer (usec);
X	(void) pause ();
X}
X
Xint
Xtimer (usec)
Xlong	usec;
X{
X    struct itimerval temptime;
X    struct itimerval uptime;
X
X    uptime.it_interval.tv_sec = 0;
X    uptime.it_interval.tv_usec = usec;
X    uptime.it_value.tv_sec = 1;
X    uptime.it_value.tv_usec = 0;
X
X    signal (SIGALRM, nil);
X    return (setitimer (0, &uptime, &temptime));
X}
X
Xint nil () {}
X
X#endif	/* !SYSV */
+FUNKY+STUFF+
chmod u=rw,g=,o= marquis.c
echo Unpacking complete.
exit 0