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