[net.sources] modified vtclock for 4.1 Bsd Berkley Unix

shacklet@ittral.UUCP (Captain Electron) (12/05/83)

It seems the rest of this didn't get out the last time. This is the
modified vtclock program for 4.1 bsd berkley Unix. Originally some of
this program didn't work with our "C" compiler and some of the
commands were exclusively for the bell labs version. The swc program
ran OK with no mods.

		     Cliff Shackelton 
		     ITT Telecom
/*
****************************************************************************
**
**	program = vtclock.c
**
**	 author = R.J. Esposito
**
**	Vtclock provides a visual clock display every minute on
**	a real-time basis.  The display is visable in the lower
**	right-hand corner (row 24, col 56-80) of the screen.
**	Vtclock could be modified to perform on other video
**	terminals, provided they incorporate the cursor save
**	function within their command repertoire.
**
**	Vtclock should be called from the user's .profile for
**	conveinence, but could be called from the shell.
**	It should be run as a backround process, since cursor
**	saving is done prior to clock display.
**
**	An interface program 'swc.c' is used to switch the display
**	on/off depending on it's previous state.  Vtclock saves it's
**	pid in the user's home directory in '.clock_pid'.  Swc reads
**	this file to send the SIGUSR1 (16) signal to vtclock for
**	display switching.  This file is removed when vtclock dies
**	(SIGHUP).
**
**	NOTE:  Some strange things may occur when emacs is used in
**	       conjunction with vtclock.  It may be wise to turn off
**	       the display (swc) prior to entering emacs, and then
**	       turning it back on (swc) after completion.  If you're
**	       a die-hard (like me!) just use the ^L to re-draw the
**	       display.
**
****************************************************************************
*/

#include <stdio.h>
#include <time.h>
#include <signal.h>

#define SCROLL	"\33[0;23r"	/* set the scroll region (0 to 23) */
#define WINDOW	"\33[0m\33[24;56f\33[7m                         \33[24;59f"
#define SAVE	"\0337"		/* save cursor = ESC7 */
				/* This MUST be typed-in from keyboard */
#define RESTORE	"\338"		/* restore cursor */
#define CLWIN	"\33[0m\33[24;56f                         "
#define ATT_OFF	"\33[0m"

struct tm *localtime(), *tp;

char *asctime();
char *getenv();
char *strcpy(), *strcat();
char pid_file[100];

long time(), tloc;
unsigned sleep();
int (*signal())();
int die(), on_off(), pm;
int is_on = 1;

FILE *fp;

main()
{
	unsigned sec_diff;

	setbuf(stdout, (char *)0);
	(void )strcpy(pid_file, getenv("HOME"));
	(void )strcat(pid_file, "/.clock_pid");

	if((fp=fopen(pid_file, "w")) == NULL) {
		(void )puts("can't open clocl_pid");
		exit(1);
	}

	(void )fprintf(fp, "%d\n", getpid());
	(void )fclose(fp);

	(void )signal(SIGHUP, die);
	tloc = time ((long *)0);
	tp = localtime(&tloc);

	fixtime(tp->tm_hour);

	(void )printf("%s%s%16.16s", SAVE, WINDOW, asctime(tp));
	if (pm)
		(void )fputs(" PM", stdout);
	else
		(void )fputs(" AM", stdout);

	(void )printf("%s%s%s", SCROLL, ATT_OFF, RESTORE);
	(void )signal(16, on_off);

	for (;;) {	/* forever loop until hung-up */

		tp = localtime(&tloc);
		sec_diff = 60 - tp->tm_sec;
		(void )sleep(sec_diff);
		tloc = time((long *)0);
		tp = localtime(&tloc);

		fixtime(tp->tm_hour);

		if (is_on) {
			if (tp->tm_min == 00)	/* hourly chime */
				(void )fputs("\7\7", stdout);

			(void )printf("%s%s%16.16s", SAVE, WINDOW, asctime(tp));
			if (pm)
				(void )fputs(" PM", stdout);
			else
				(void )fputs(" AM", stdout);

			(void )printf("%s%s%s", SCROLL, ATT_OFF, RESTORE);
		}
	}
}

die()	/* enter here when hung-up */
{

	(void )unlink(pid_file);
	exit(0);
}

on_off()	/* routine used by swc to switch display on/off */
{

	if (is_on) {
		is_on = 0;
		(void )printf("%s%s\33[0;24r%s", SAVE, CLWIN, RESTORE);
	} else 
		is_on = 1;
	(void )signal(16, on_off);
}

fixtime(hour)
int hour;
{

	switch(hour) {		/* correct for AM/PM */

		case 0:
			tp->tm_hour = 12;
			pm = 0;
			break;

		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
		case 11:
			pm = 0;
			break;

		case 12:
			pm = 1;
			break;

		case 13:
		case 14:
		case 15:
		case 16:
		case 17:
		case 18:
		case 19:
		case 20:
		case 21:
		case 22:
		case 23:
			tp->tm_hour -= 12;
			pm = 1;
			break;
	}
}