xref: /onnv-gate/usr/src/cmd/calendar/calprog.c (revision 236:cc3576010d16)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*236Schin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate 
330Sstevel@tonic-gate /*
340Sstevel@tonic-gate  *	/usr/lib/calprog produces an egrep -f file
350Sstevel@tonic-gate  *	that will select today's and tomorrow's
360Sstevel@tonic-gate  *	calendar entries, with special weekend provisions
370Sstevel@tonic-gate  *	used by calendar command
380Sstevel@tonic-gate  */
390Sstevel@tonic-gate 
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include <fcntl.h>
420Sstevel@tonic-gate #include <stdarg.h>
430Sstevel@tonic-gate #include <stdio.h>
440Sstevel@tonic-gate #include <ctype.h>
450Sstevel@tonic-gate #include <sys/types.h>
460Sstevel@tonic-gate #include <time.h>
470Sstevel@tonic-gate #include <sys/stat.h>
480Sstevel@tonic-gate #include <locale.h>
490Sstevel@tonic-gate #include <errno.h>
500Sstevel@tonic-gate 
510Sstevel@tonic-gate 
520Sstevel@tonic-gate #define	DAY	(3600*24L)
530Sstevel@tonic-gate 
540Sstevel@tonic-gate extern  char	*getenv(), *malloc();
550Sstevel@tonic-gate 
560Sstevel@tonic-gate static char	*file;
570Sstevel@tonic-gate static int	old_behavior;
580Sstevel@tonic-gate static int	linenum = 1;
590Sstevel@tonic-gate static time_t	t;
600Sstevel@tonic-gate static char	errmsg[128];
610Sstevel@tonic-gate static char	*errlst[] = {
620Sstevel@tonic-gate /*	0	*/ "error on open of \"%s\", errno = %d",
630Sstevel@tonic-gate /*	1	*/ "could not malloc enough memory",
640Sstevel@tonic-gate /*	2	*/ "error on stat of \"%s\", errno = %d",
650Sstevel@tonic-gate /*	3	*/ "file \"%s\" is not a regular file",
660Sstevel@tonic-gate /*	4	*/ "error in reading the file \"%s\"",
670Sstevel@tonic-gate /*	5	*/ "\"%s\" file: error on line %d",
680Sstevel@tonic-gate /*	6	*/ "\"%s\" file: format descriptions are missing"
690Sstevel@tonic-gate };
700Sstevel@tonic-gate 
710Sstevel@tonic-gate static
720Sstevel@tonic-gate char *month[] = {
730Sstevel@tonic-gate 	"[Jj]an",
740Sstevel@tonic-gate 	"[Ff]eb",
750Sstevel@tonic-gate 	"[Mm]ar",
760Sstevel@tonic-gate 	"[Aa]pr",
770Sstevel@tonic-gate 	"[Mm]ay",
780Sstevel@tonic-gate 	"[Jj]un",
790Sstevel@tonic-gate 	"[Jj]ul",
800Sstevel@tonic-gate 	"[Aa]ug",
810Sstevel@tonic-gate 	"[Ss]ep",
820Sstevel@tonic-gate 	"[Oo]ct",
830Sstevel@tonic-gate 	"[Nn]ov",
840Sstevel@tonic-gate 	"[Dd]ec"
850Sstevel@tonic-gate };
860Sstevel@tonic-gate 
87*236Schin static void read_tmpl(void);
880Sstevel@tonic-gate static void error(const char *fmt, ...);
89*236Schin static void generate(char *);
900Sstevel@tonic-gate 
91*236Schin static void
tprint(time_t t)92*236Schin tprint(time_t t)
930Sstevel@tonic-gate {
940Sstevel@tonic-gate 	struct tm *tm;
950Sstevel@tonic-gate 	tm = localtime(&t);
960Sstevel@tonic-gate 	(void) printf
970Sstevel@tonic-gate 		("(^|[ \t(,;])((%s[^ ]* *|0*%d/|\\*/)0*%d)([^0123456789]|$)\n",
980Sstevel@tonic-gate 		month[tm->tm_mon], tm->tm_mon + 1, tm->tm_mday);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate 
101*236Schin int
main(int argc,char * argv[])102*236Schin main(int argc, char *argv[])
1030Sstevel@tonic-gate {
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1060Sstevel@tonic-gate 	(void) time(&t);
1070Sstevel@tonic-gate 	if (((file = getenv("DATEMSK")) == 0) || file[0] == '\0')
1080Sstevel@tonic-gate 		old_behavior = 1;
1090Sstevel@tonic-gate 	if (old_behavior)
1100Sstevel@tonic-gate 		tprint(t);
1110Sstevel@tonic-gate 	else
1120Sstevel@tonic-gate 		read_tmpl();
1130Sstevel@tonic-gate 	switch (localtime(&t)->tm_wday) {
1140Sstevel@tonic-gate 	case 5:
1150Sstevel@tonic-gate 		t += DAY;
1160Sstevel@tonic-gate 		if (old_behavior)
1170Sstevel@tonic-gate 			tprint(t);
1180Sstevel@tonic-gate 		else
1190Sstevel@tonic-gate 			read_tmpl();
1200Sstevel@tonic-gate 	case 6:
1210Sstevel@tonic-gate 		t += DAY;
1220Sstevel@tonic-gate 		if (old_behavior)
1230Sstevel@tonic-gate 			tprint(t);
1240Sstevel@tonic-gate 		else
1250Sstevel@tonic-gate 			read_tmpl();
1260Sstevel@tonic-gate 	default:
1270Sstevel@tonic-gate 		t += DAY;
1280Sstevel@tonic-gate 		if (old_behavior)
1290Sstevel@tonic-gate 			tprint(t);
1300Sstevel@tonic-gate 		else
1310Sstevel@tonic-gate 			read_tmpl();
1320Sstevel@tonic-gate 	}
133*236Schin 	return (0);
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate 
137*236Schin static void
read_tmpl(void)138*236Schin read_tmpl(void)
1390Sstevel@tonic-gate {
1400Sstevel@tonic-gate 	char	*clean_line();
1410Sstevel@tonic-gate 	FILE  *fp;
1420Sstevel@tonic-gate 	char *bp, *start;
1430Sstevel@tonic-gate 	struct stat sb;
1440Sstevel@tonic-gate 	int	no_empty = 0;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	if ((start = (char *)malloc(512)) == NULL)
1470Sstevel@tonic-gate 		error(errlst[1]);
1480Sstevel@tonic-gate 	if ((fp = fopen(file, "r")) == NULL)
1490Sstevel@tonic-gate 		error(errlst[0], file, errno);
1500Sstevel@tonic-gate 	if (fstat(fileno(fp), &sb) < 0)
1510Sstevel@tonic-gate 		error(errlst[2], file, errno);
1520Sstevel@tonic-gate 	if ((sb.st_mode & S_IFMT) != S_IFREG)
1530Sstevel@tonic-gate 		error(errlst[3], file);
1540Sstevel@tonic-gate 	for (;;) {
1550Sstevel@tonic-gate 		bp = start;
1560Sstevel@tonic-gate 		if (!fgets(bp, 512, fp)) {
1570Sstevel@tonic-gate 			if (!feof(fp)) {
1580Sstevel@tonic-gate 				free(start);
1590Sstevel@tonic-gate 				fclose(fp);
1600Sstevel@tonic-gate 				error(errlst[4], file);
1610Sstevel@tonic-gate 				}
1620Sstevel@tonic-gate 			break;
1630Sstevel@tonic-gate 		}
1640Sstevel@tonic-gate 		if (*(bp+strlen(bp)-1) != '\n')   /* terminating newline? */
1650Sstevel@tonic-gate 			{
1660Sstevel@tonic-gate 			free(start);
1670Sstevel@tonic-gate 			fclose(fp);
1680Sstevel@tonic-gate 			error(errlst[5], file, linenum);
1690Sstevel@tonic-gate 			}
1700Sstevel@tonic-gate 		bp = clean_line(bp);
1710Sstevel@tonic-gate 		if (strlen(bp))  /*  anything left?  */
1720Sstevel@tonic-gate 			{
1730Sstevel@tonic-gate 			no_empty++;
1740Sstevel@tonic-gate 			generate(bp);
1750Sstevel@tonic-gate 			}
1760Sstevel@tonic-gate 	linenum++;
1770Sstevel@tonic-gate 	}
1780Sstevel@tonic-gate 	free(start);
1790Sstevel@tonic-gate 	fclose(fp);
1800Sstevel@tonic-gate 	if (!no_empty)
1810Sstevel@tonic-gate 		error(errlst[6], file);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate char  *
clean_line(char * s)186*236Schin clean_line(char *s)
1870Sstevel@tonic-gate {
1880Sstevel@tonic-gate 	char  *ns;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 	*(s + strlen(s) -1) = (char)0; /* delete newline */
1910Sstevel@tonic-gate 	if (!strlen(s))
1920Sstevel@tonic-gate 		return (s);
1930Sstevel@tonic-gate 	ns = s + strlen(s) - 1; /* s->start; ns->end */
1940Sstevel@tonic-gate 	while ((ns != s) && (isspace(*ns))) {
1950Sstevel@tonic-gate 		*ns = (char)0;	/* delete terminating spaces */
1960Sstevel@tonic-gate 		--ns;
1970Sstevel@tonic-gate 		}
1980Sstevel@tonic-gate 	while (*s)		/* delete beginning white spaces */
1990Sstevel@tonic-gate 		if (isspace(*s))
2000Sstevel@tonic-gate 			++s;
2010Sstevel@tonic-gate 		else
2020Sstevel@tonic-gate 			break;
2030Sstevel@tonic-gate 	return (s);
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate static void
error(const char * fmt,...)2070Sstevel@tonic-gate error(const char *fmt, ...)
2080Sstevel@tonic-gate {
2090Sstevel@tonic-gate 	va_list	args;
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	va_start(args, fmt);
2120Sstevel@tonic-gate 	(void) vsnprintf(errmsg, sizeof (errmsg), fmt, args);
2130Sstevel@tonic-gate 	fprintf(stderr, "%s\n", errmsg);
2140Sstevel@tonic-gate 	va_end(args);
2150Sstevel@tonic-gate 	exit(1);
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate 
218*236Schin static void
generate(char * fmt)219*236Schin generate(char *fmt)
2200Sstevel@tonic-gate {
2210Sstevel@tonic-gate 	char	timebuf[1024];
2220Sstevel@tonic-gate 	char	outbuf[2 * 1024];
2230Sstevel@tonic-gate 	char	*tb, *ob;
2240Sstevel@tonic-gate 	int	space = 0;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	strftime(timebuf, sizeof (timebuf), fmt, localtime(&t));
2270Sstevel@tonic-gate 	tb = timebuf;
2280Sstevel@tonic-gate 	ob = outbuf;
2290Sstevel@tonic-gate 	while (*tb)
230*236Schin 		if (isspace(*tb)) {
2310Sstevel@tonic-gate 			++tb;
2320Sstevel@tonic-gate 			space++;
233*236Schin 		}
2340Sstevel@tonic-gate 		else
2350Sstevel@tonic-gate 			{
236*236Schin 			if (space) {
2370Sstevel@tonic-gate 				*ob++ = '[';
2380Sstevel@tonic-gate 				*ob++ = ' ';
2390Sstevel@tonic-gate 				*ob++ = '\t';
2400Sstevel@tonic-gate 				*ob++ = ']';
2410Sstevel@tonic-gate 				*ob++ = '*';
2420Sstevel@tonic-gate 				space = 0;
2430Sstevel@tonic-gate 				continue;
244*236Schin 			}
245*236Schin 			if (isalpha(*tb)) {
2460Sstevel@tonic-gate 				*ob++ = '[';
2470Sstevel@tonic-gate 				*ob++ = toupper(*tb);
2480Sstevel@tonic-gate 				*ob++ = tolower(*tb++);
2490Sstevel@tonic-gate 				*ob++ = ']';
2500Sstevel@tonic-gate 				continue;
251*236Schin 			}
2520Sstevel@tonic-gate 			else
2530Sstevel@tonic-gate 				*ob++ = *tb++;
2540Sstevel@tonic-gate 				if (*(tb - 1) == '0')
2550Sstevel@tonic-gate 					*ob++ = '*';
2560Sstevel@tonic-gate 			}
2570Sstevel@tonic-gate 	*ob = '\0';
2580Sstevel@tonic-gate 	printf("%s\n", outbuf);
2590Sstevel@tonic-gate }
260