xref: /titanic_41/usr/src/cmd/news/news.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.15	*/
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate /*
29*7c478bd9Sstevel@tonic-gate 	news foo	prints /var/news/foo
30*7c478bd9Sstevel@tonic-gate 	news -a		prints all news items, latest first
31*7c478bd9Sstevel@tonic-gate 	news -n		lists names of new items
32*7c478bd9Sstevel@tonic-gate 	news -s		tells count of new items only
33*7c478bd9Sstevel@tonic-gate 	news		prints items changed since last news
34*7c478bd9Sstevel@tonic-gate */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include <stdio.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
38*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
39*7c478bd9Sstevel@tonic-gate #include <unistd.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
41*7c478bd9Sstevel@tonic-gate #include <setjmp.h>
42*7c478bd9Sstevel@tonic-gate #include <signal.h>
43*7c478bd9Sstevel@tonic-gate #include <dirent.h>
44*7c478bd9Sstevel@tonic-gate #include <pwd.h>
45*7c478bd9Sstevel@tonic-gate #include <time.h>
46*7c478bd9Sstevel@tonic-gate #include <locale.h>
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate #define INDENT 3
49*7c478bd9Sstevel@tonic-gate #define	RD_WR_ALL	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define	DATE_FMT	"%a %b %e %H:%M:%S %Y"
52*7c478bd9Sstevel@tonic-gate /*
53*7c478bd9Sstevel@tonic-gate  *	%a	abbreviated weekday name
54*7c478bd9Sstevel@tonic-gate  *	%b	abbreviated month name
55*7c478bd9Sstevel@tonic-gate  *	%e	day of month
56*7c478bd9Sstevel@tonic-gate  *	%H	hour (24-hour clock)
57*7c478bd9Sstevel@tonic-gate  *	%M	minute
58*7c478bd9Sstevel@tonic-gate  *	%S	second
59*7c478bd9Sstevel@tonic-gate  *	%Y	year
60*7c478bd9Sstevel@tonic-gate  */
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate 	The following items should not be printed.
63*7c478bd9Sstevel@tonic-gate */
64*7c478bd9Sstevel@tonic-gate char	*ignore[] = {
65*7c478bd9Sstevel@tonic-gate 		"core",
66*7c478bd9Sstevel@tonic-gate 		NULL
67*7c478bd9Sstevel@tonic-gate };
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate struct n_file {
70*7c478bd9Sstevel@tonic-gate 	long n_time;
71*7c478bd9Sstevel@tonic-gate 	char n_name[MAXNAMLEN];
72*7c478bd9Sstevel@tonic-gate } *n_list;
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate char	NEWS[] = "/var/news";	/* directory for news items */
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate int	aopt = 0;	/* 1 say -a specified */
77*7c478bd9Sstevel@tonic-gate int	n_count;	/* number of items in NEWS directory */
78*7c478bd9Sstevel@tonic-gate int	number_read;	/* number of items read */
79*7c478bd9Sstevel@tonic-gate int	nopt = 0;	/* 1 say -n specified */
80*7c478bd9Sstevel@tonic-gate int	optsw;		/* for getopt */
81*7c478bd9Sstevel@tonic-gate int	opt = 0;	/* number of options specified */
82*7c478bd9Sstevel@tonic-gate int	sopt = 0;	/* 1 says -s specified */
83*7c478bd9Sstevel@tonic-gate char	stdbuf[BUFSIZ];
84*7c478bd9Sstevel@tonic-gate char	time_buf[50];	/* holds date and time string */
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate jmp_buf	save_addr;
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate main (argc, argv)
89*7c478bd9Sstevel@tonic-gate int	argc;
90*7c478bd9Sstevel@tonic-gate char	**argv;
91*7c478bd9Sstevel@tonic-gate {
92*7c478bd9Sstevel@tonic-gate 	int print_item(), notify(), count(),i;
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	(void)setlocale(LC_ALL, "");
95*7c478bd9Sstevel@tonic-gate 	setbuf (stdout, stdbuf);
96*7c478bd9Sstevel@tonic-gate 	initialize();
97*7c478bd9Sstevel@tonic-gate 	read_dir();
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate 	if (argc <= 1) {
100*7c478bd9Sstevel@tonic-gate 		late_news (print_item, 1);
101*7c478bd9Sstevel@tonic-gate 		ck_num();
102*7c478bd9Sstevel@tonic-gate 	}
103*7c478bd9Sstevel@tonic-gate 	else while ((optsw = getopt(argc, argv, "ans")) != EOF)
104*7c478bd9Sstevel@tonic-gate 		switch(optsw) {
105*7c478bd9Sstevel@tonic-gate 		case 'a':
106*7c478bd9Sstevel@tonic-gate 			aopt++;
107*7c478bd9Sstevel@tonic-gate 			opt++;
108*7c478bd9Sstevel@tonic-gate 			break;
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate 		case 'n':
111*7c478bd9Sstevel@tonic-gate 			nopt++;
112*7c478bd9Sstevel@tonic-gate 			opt++;
113*7c478bd9Sstevel@tonic-gate 			break;
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 		case 's':
116*7c478bd9Sstevel@tonic-gate 			sopt++;
117*7c478bd9Sstevel@tonic-gate 			opt++;
118*7c478bd9Sstevel@tonic-gate 			break;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate 		default:
121*7c478bd9Sstevel@tonic-gate 			fprintf (stderr, "usage: news [-a] [-n] [-s] [items]\n");
122*7c478bd9Sstevel@tonic-gate 			exit (1);
123*7c478bd9Sstevel@tonic-gate 	}
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate         if (opt > 1) {
126*7c478bd9Sstevel@tonic-gate         	fprintf(stderr, "news: options are mutually exclusive\n");
127*7c478bd9Sstevel@tonic-gate         	exit(1);
128*7c478bd9Sstevel@tonic-gate 	}
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate         if (opt > 0 && argc > 2) {
131*7c478bd9Sstevel@tonic-gate         	fprintf(stderr, "news: options are not allowed with file names\n");
132*7c478bd9Sstevel@tonic-gate         	exit(1);
133*7c478bd9Sstevel@tonic-gate 	}
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 	if (aopt) {
136*7c478bd9Sstevel@tonic-gate 		all_news();
137*7c478bd9Sstevel@tonic-gate 		ck_num();
138*7c478bd9Sstevel@tonic-gate 		exit(0);
139*7c478bd9Sstevel@tonic-gate 	}
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	if (nopt) {
142*7c478bd9Sstevel@tonic-gate 		late_news (notify, 0);
143*7c478bd9Sstevel@tonic-gate 		ck_num();
144*7c478bd9Sstevel@tonic-gate 		exit(0);
145*7c478bd9Sstevel@tonic-gate 	}
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	if (sopt) {
148*7c478bd9Sstevel@tonic-gate 		late_news (count, 0);
149*7c478bd9Sstevel@tonic-gate 		exit(0);
150*7c478bd9Sstevel@tonic-gate 	}
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	for (i=1; i<argc; i++) print_item (argv[i]);
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	exit(0);
155*7c478bd9Sstevel@tonic-gate }
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate /*
158*7c478bd9Sstevel@tonic-gate  *	read_dir: get the file names and modification dates for the
159*7c478bd9Sstevel@tonic-gate  *	files in /var/news into n_list; sort them in reverse by
160*7c478bd9Sstevel@tonic-gate  *	modification date. We assume /var/news is the working directory.
161*7c478bd9Sstevel@tonic-gate  */
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate read_dir()
164*7c478bd9Sstevel@tonic-gate {
165*7c478bd9Sstevel@tonic-gate 	struct dirent *nf, *readdir();
166*7c478bd9Sstevel@tonic-gate 	struct stat sbuf;
167*7c478bd9Sstevel@tonic-gate 	char fname[MAXNAMLEN];
168*7c478bd9Sstevel@tonic-gate 	DIR *dirp;
169*7c478bd9Sstevel@tonic-gate 	int i, j;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 	/* Open the current directory */
172*7c478bd9Sstevel@tonic-gate 	if ((dirp = opendir(".")) == NULL) {
173*7c478bd9Sstevel@tonic-gate 		fprintf (stderr, "Cannot open %s\n", NEWS);
174*7c478bd9Sstevel@tonic-gate 		exit (1);
175*7c478bd9Sstevel@tonic-gate 	}
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 	/* Read the file names into n_list */
178*7c478bd9Sstevel@tonic-gate 	n_count = 0;
179*7c478bd9Sstevel@tonic-gate 	while (nf = readdir(dirp)) {
180*7c478bd9Sstevel@tonic-gate 		strncpy (fname, nf->d_name, (unsigned) strlen(nf->d_name) + 1);
181*7c478bd9Sstevel@tonic-gate 		if (nf->d_ino != (ino_t)0 && stat (fname, &sbuf) >= 0
182*7c478bd9Sstevel@tonic-gate 		 && (sbuf.st_mode & S_IFMT) == S_IFREG) {
183*7c478bd9Sstevel@tonic-gate 			register char **p;
184*7c478bd9Sstevel@tonic-gate 			p = ignore;
185*7c478bd9Sstevel@tonic-gate 			while (*p && strncmp (*p, nf->d_name, MAXNAMLEN))
186*7c478bd9Sstevel@tonic-gate 				++p;
187*7c478bd9Sstevel@tonic-gate 			if (!*p) {
188*7c478bd9Sstevel@tonic-gate 				if (n_count++ > 0)
189*7c478bd9Sstevel@tonic-gate 					n_list = (struct n_file *)
190*7c478bd9Sstevel@tonic-gate 						realloc ((char *) n_list,
191*7c478bd9Sstevel@tonic-gate 						(unsigned)
192*7c478bd9Sstevel@tonic-gate 						(sizeof (struct n_file)
193*7c478bd9Sstevel@tonic-gate 						    * n_count));
194*7c478bd9Sstevel@tonic-gate 				else
195*7c478bd9Sstevel@tonic-gate 					n_list = (struct n_file *) malloc
196*7c478bd9Sstevel@tonic-gate 						((unsigned)
197*7c478bd9Sstevel@tonic-gate 						(sizeof (struct n_file) *
198*7c478bd9Sstevel@tonic-gate 						n_count));
199*7c478bd9Sstevel@tonic-gate 				if (n_list == NULL) {
200*7c478bd9Sstevel@tonic-gate 					fprintf (stderr, "No storage\n");
201*7c478bd9Sstevel@tonic-gate 					exit (1);
202*7c478bd9Sstevel@tonic-gate 				}
203*7c478bd9Sstevel@tonic-gate 				n_list[n_count-1].n_time = sbuf.st_mtime;
204*7c478bd9Sstevel@tonic-gate 				strncpy (n_list[n_count-1].n_name,
205*7c478bd9Sstevel@tonic-gate 					nf->d_name, MAXNAMLEN);
206*7c478bd9Sstevel@tonic-gate 			}
207*7c478bd9Sstevel@tonic-gate 		}
208*7c478bd9Sstevel@tonic-gate 	}
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 	/* Sort the elements of n_list in decreasing time order */
211*7c478bd9Sstevel@tonic-gate 	for (i=1; i<n_count; i++)
212*7c478bd9Sstevel@tonic-gate 		for (j=0; j<i; j++)
213*7c478bd9Sstevel@tonic-gate 			if (n_list[j].n_time < n_list[i].n_time) {
214*7c478bd9Sstevel@tonic-gate 				struct n_file temp;
215*7c478bd9Sstevel@tonic-gate 				temp = n_list[i];
216*7c478bd9Sstevel@tonic-gate 				n_list[i] = n_list[j];
217*7c478bd9Sstevel@tonic-gate 				n_list[j] = temp;
218*7c478bd9Sstevel@tonic-gate 			}
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	/* Clean up */
221*7c478bd9Sstevel@tonic-gate 	closedir(dirp);
222*7c478bd9Sstevel@tonic-gate }
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate initialize()
225*7c478bd9Sstevel@tonic-gate {
226*7c478bd9Sstevel@tonic-gate 	if (signal (SIGQUIT, SIG_IGN) != (void(*)())SIG_IGN)
227*7c478bd9Sstevel@tonic-gate 		signal (SIGQUIT, _exit);
228*7c478bd9Sstevel@tonic-gate 	umask (((~(S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) & S_IAMB));
229*7c478bd9Sstevel@tonic-gate 	if (chdir (NEWS) < 0) {
230*7c478bd9Sstevel@tonic-gate 		fprintf (stderr, "Cannot chdir to %s\n", NEWS);
231*7c478bd9Sstevel@tonic-gate 		exit (1);
232*7c478bd9Sstevel@tonic-gate 	}
233*7c478bd9Sstevel@tonic-gate }
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate all_news()
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 	int i;
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate 	for (i=0; i<n_count; i++)
240*7c478bd9Sstevel@tonic-gate 		print_item (n_list[i].n_name);
241*7c478bd9Sstevel@tonic-gate }
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate print_item (f)
244*7c478bd9Sstevel@tonic-gate 	char *f;
245*7c478bd9Sstevel@tonic-gate {
246*7c478bd9Sstevel@tonic-gate 	FILE *fd;
247*7c478bd9Sstevel@tonic-gate 	char fname[MAXNAMLEN+1];
248*7c478bd9Sstevel@tonic-gate 	static int firstitem = 1;
249*7c478bd9Sstevel@tonic-gate 	void onintr();
250*7c478bd9Sstevel@tonic-gate 	struct passwd *getpwuid();
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate 	if (f == NULL) {
253*7c478bd9Sstevel@tonic-gate 		return;
254*7c478bd9Sstevel@tonic-gate 	}
255*7c478bd9Sstevel@tonic-gate 	strncpy (fname, f, MAXNAMLEN);
256*7c478bd9Sstevel@tonic-gate 	fname[MAXNAMLEN] = '\0';
257*7c478bd9Sstevel@tonic-gate 	if ((fd = fopen (fname, "r")) == NULL)
258*7c478bd9Sstevel@tonic-gate 		printf ("Cannot open %s/%s\n", NEWS, fname);
259*7c478bd9Sstevel@tonic-gate 	else {
260*7c478bd9Sstevel@tonic-gate 		register int c, ip, op;
261*7c478bd9Sstevel@tonic-gate 		struct stat sbuf;
262*7c478bd9Sstevel@tonic-gate 		struct passwd *pw;
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 		fstat (fileno (fd), &sbuf);
265*7c478bd9Sstevel@tonic-gate 		if (firstitem) {
266*7c478bd9Sstevel@tonic-gate 			firstitem = 0;
267*7c478bd9Sstevel@tonic-gate 			putchar ('\n');
268*7c478bd9Sstevel@tonic-gate 		}
269*7c478bd9Sstevel@tonic-gate 		if (setjmp(save_addr))
270*7c478bd9Sstevel@tonic-gate 			goto finish;
271*7c478bd9Sstevel@tonic-gate 		if (signal(SIGINT, SIG_IGN) != (void(*)())SIG_IGN)
272*7c478bd9Sstevel@tonic-gate 			signal(SIGINT, onintr);
273*7c478bd9Sstevel@tonic-gate 		printf ("%s ", fname);
274*7c478bd9Sstevel@tonic-gate 		pw = getpwuid (sbuf.st_uid);
275*7c478bd9Sstevel@tonic-gate 		if (pw)
276*7c478bd9Sstevel@tonic-gate 			printf ("(%s)", pw->pw_name);
277*7c478bd9Sstevel@tonic-gate 		else
278*7c478bd9Sstevel@tonic-gate 			printf (".....");
279*7c478bd9Sstevel@tonic-gate 		cftime(time_buf, DATE_FMT, &sbuf.st_mtime);
280*7c478bd9Sstevel@tonic-gate 		printf (" %s\n", time_buf);
281*7c478bd9Sstevel@tonic-gate 		op = 0;
282*7c478bd9Sstevel@tonic-gate 		ip = INDENT;
283*7c478bd9Sstevel@tonic-gate 		while ((c = getc (fd)) != EOF) {
284*7c478bd9Sstevel@tonic-gate 			switch (c) {
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 			case '\r':
287*7c478bd9Sstevel@tonic-gate 			case '\n':
288*7c478bd9Sstevel@tonic-gate 				putchar (c);
289*7c478bd9Sstevel@tonic-gate 				op = 0;
290*7c478bd9Sstevel@tonic-gate 				ip = INDENT;
291*7c478bd9Sstevel@tonic-gate 				break;
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate 			case ' ':
294*7c478bd9Sstevel@tonic-gate 				ip++;
295*7c478bd9Sstevel@tonic-gate 				break;
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate 			case '\b':
298*7c478bd9Sstevel@tonic-gate 				if (ip > INDENT)
299*7c478bd9Sstevel@tonic-gate 					ip--;
300*7c478bd9Sstevel@tonic-gate 				break;
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 			case '\t':
303*7c478bd9Sstevel@tonic-gate 				ip = ((ip - INDENT + 8) & -8) + INDENT;
304*7c478bd9Sstevel@tonic-gate 				break;
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 			default:
307*7c478bd9Sstevel@tonic-gate 				while (ip < op) {
308*7c478bd9Sstevel@tonic-gate 					putchar ('\b');
309*7c478bd9Sstevel@tonic-gate 					op--;
310*7c478bd9Sstevel@tonic-gate 				}
311*7c478bd9Sstevel@tonic-gate 				while ((ip & -8) > (op & -8)) {
312*7c478bd9Sstevel@tonic-gate 					putchar ('\t');
313*7c478bd9Sstevel@tonic-gate 					op = (op + 8) & -8;
314*7c478bd9Sstevel@tonic-gate 				}
315*7c478bd9Sstevel@tonic-gate 				while (ip > op) {
316*7c478bd9Sstevel@tonic-gate 					putchar (' ');
317*7c478bd9Sstevel@tonic-gate 					op++;
318*7c478bd9Sstevel@tonic-gate 				}
319*7c478bd9Sstevel@tonic-gate 				putchar (c);
320*7c478bd9Sstevel@tonic-gate 				ip++;
321*7c478bd9Sstevel@tonic-gate 				op++;
322*7c478bd9Sstevel@tonic-gate 				break;
323*7c478bd9Sstevel@tonic-gate 			}
324*7c478bd9Sstevel@tonic-gate 		}
325*7c478bd9Sstevel@tonic-gate 		fflush (stdout);
326*7c478bd9Sstevel@tonic-gate finish:
327*7c478bd9Sstevel@tonic-gate 		putchar ('\n');
328*7c478bd9Sstevel@tonic-gate 		fclose (fd);
329*7c478bd9Sstevel@tonic-gate 		number_read++;
330*7c478bd9Sstevel@tonic-gate 		if (signal(SIGINT, SIG_IGN) != (void(*)())SIG_IGN)
331*7c478bd9Sstevel@tonic-gate 			signal(SIGINT, SIG_DFL);
332*7c478bd9Sstevel@tonic-gate 	}
333*7c478bd9Sstevel@tonic-gate }
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate late_news (emit, update)
336*7c478bd9Sstevel@tonic-gate 	int (*emit)(), update;
337*7c478bd9Sstevel@tonic-gate {
338*7c478bd9Sstevel@tonic-gate 	long cutoff;
339*7c478bd9Sstevel@tonic-gate 	int i;
340*7c478bd9Sstevel@tonic-gate 	char fname[50], *cp;
341*7c478bd9Sstevel@tonic-gate 	struct stat newstime;
342*7c478bd9Sstevel@tonic-gate 	int fd;
343*7c478bd9Sstevel@tonic-gate 	struct {
344*7c478bd9Sstevel@tonic-gate 		long actime, modtime;
345*7c478bd9Sstevel@tonic-gate 	} utb;
346*7c478bd9Sstevel@tonic-gate 	extern char *getenv();
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate 	/* Determine the time when last called */
349*7c478bd9Sstevel@tonic-gate 	cp = getenv ("HOME");
350*7c478bd9Sstevel@tonic-gate 	if (cp == NULL) {
351*7c478bd9Sstevel@tonic-gate 		fprintf (stderr, "Cannot find HOME variable\n");
352*7c478bd9Sstevel@tonic-gate 		exit (1);
353*7c478bd9Sstevel@tonic-gate 	}
354*7c478bd9Sstevel@tonic-gate 	strcpy (fname, cp);
355*7c478bd9Sstevel@tonic-gate 	strcat (fname, "/");
356*7c478bd9Sstevel@tonic-gate 	strcat (fname, ".news_time");
357*7c478bd9Sstevel@tonic-gate 	cutoff = stat (fname, &newstime) < 0? 0: newstime.st_mtime;
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate 	/* Print the recent items */
360*7c478bd9Sstevel@tonic-gate 	for (i=0; i<n_count && n_list[i].n_time > cutoff; i++) {
361*7c478bd9Sstevel@tonic-gate 		(*emit) (n_list[i].n_name);
362*7c478bd9Sstevel@tonic-gate 		number_read++;
363*7c478bd9Sstevel@tonic-gate 	}
364*7c478bd9Sstevel@tonic-gate 	(*emit) ((char *) NULL);
365*7c478bd9Sstevel@tonic-gate 	fflush (stdout);
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 	if (update) {
368*7c478bd9Sstevel@tonic-gate 		/* Re-create the file and refresh the update time */
369*7c478bd9Sstevel@tonic-gate 		if (n_count > 0 && (fd = creat (fname, RD_WR_ALL)) >= 0) {
370*7c478bd9Sstevel@tonic-gate 			utb.actime = utb.modtime = n_list[0].n_time;
371*7c478bd9Sstevel@tonic-gate 			close (fd);
372*7c478bd9Sstevel@tonic-gate 			utime (fname, &utb);
373*7c478bd9Sstevel@tonic-gate 		}
374*7c478bd9Sstevel@tonic-gate 	}
375*7c478bd9Sstevel@tonic-gate }
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate notify (s)
378*7c478bd9Sstevel@tonic-gate 	char *s;
379*7c478bd9Sstevel@tonic-gate {
380*7c478bd9Sstevel@tonic-gate 	static int first = 1;
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate 	if (s) {
383*7c478bd9Sstevel@tonic-gate 		if (first) {
384*7c478bd9Sstevel@tonic-gate 			first = 0;
385*7c478bd9Sstevel@tonic-gate 			printf ("news:", NEWS);
386*7c478bd9Sstevel@tonic-gate 		}
387*7c478bd9Sstevel@tonic-gate 		printf (" %.14s", s);
388*7c478bd9Sstevel@tonic-gate 	} else if (!first)
389*7c478bd9Sstevel@tonic-gate 		putchar ('\n');
390*7c478bd9Sstevel@tonic-gate }
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
393*7c478bd9Sstevel@tonic-gate count (s)
394*7c478bd9Sstevel@tonic-gate 	char *s;
395*7c478bd9Sstevel@tonic-gate {
396*7c478bd9Sstevel@tonic-gate 	static int nitems = 0;
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	if (s)
399*7c478bd9Sstevel@tonic-gate 		nitems++;
400*7c478bd9Sstevel@tonic-gate 	else {
401*7c478bd9Sstevel@tonic-gate 		if (nitems) {
402*7c478bd9Sstevel@tonic-gate 			printf ("%d news item", nitems);
403*7c478bd9Sstevel@tonic-gate 			if (nitems != 1)
404*7c478bd9Sstevel@tonic-gate 				putchar ('s');
405*7c478bd9Sstevel@tonic-gate 			printf (".\n");
406*7c478bd9Sstevel@tonic-gate 		}
407*7c478bd9Sstevel@tonic-gate 		else printf("No news.\n");
408*7c478bd9Sstevel@tonic-gate 	}
409*7c478bd9Sstevel@tonic-gate }
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate void
412*7c478bd9Sstevel@tonic-gate onintr()
413*7c478bd9Sstevel@tonic-gate {
414*7c478bd9Sstevel@tonic-gate 	sleep(2);
415*7c478bd9Sstevel@tonic-gate 	longjmp(save_addr, 1);
416*7c478bd9Sstevel@tonic-gate }
417*7c478bd9Sstevel@tonic-gate ck_num()
418*7c478bd9Sstevel@tonic-gate {
419*7c478bd9Sstevel@tonic-gate 	if (sopt && !number_read) printf("No news.\n");
420*7c478bd9Sstevel@tonic-gate 	return(0);
421*7c478bd9Sstevel@tonic-gate }
422*7c478bd9Sstevel@tonic-gate 
423