4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
33 news foo prints /var/news/foo
34 news -a prints all news items, latest first
35 news -n lists names of new items
36 news -s tells count of new items only
37 news prints items changed since last news
41 #include <sys/types.h>
53 #define RD_WR_ALL (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
55 #define DATE_FMT "%a %b %e %H:%M:%S %Y"
57 * %a abbreviated weekday name
58 * %b abbreviated month name
60 * %H hour (24-hour clock)
66 The following items should not be printed.
75 char n_name
[MAXNAMLEN
];
78 char NEWS
[] = "/var/news"; /* directory for news items */
80 int aopt
= 0; /* 1 say -a specified */
81 int n_count
; /* number of items in NEWS directory */
82 int number_read
; /* number of items read */
83 int nopt
= 0; /* 1 say -n specified */
84 int optsw
; /* for getopt */
85 int opt
= 0; /* number of options specified */
86 int sopt
= 0; /* 1 says -s specified */
88 char time_buf
[50]; /* holds date and time string */
95 void initialize(void);
96 void late_news(void(*)(), int);
98 void print_item(char *);
102 main(int argc
, char **argv
)
106 (void)setlocale(LC_ALL
, "");
107 setbuf (stdout
, stdbuf
);
112 late_news (print_item
, 1);
115 else while ((optsw
= getopt(argc
, argv
, "ans")) != EOF
)
133 fprintf (stderr
, "usage: news [-a] [-n] [-s] [items]\n");
138 fprintf(stderr
, "news: options are mutually exclusive\n");
142 if (opt
> 0 && argc
> 2) {
143 fprintf(stderr
, "news: options are not allowed with file names\n");
154 late_news (notify
, 0);
160 late_news (count
, 0);
164 for (i
=1; i
<argc
; i
++) print_item (argv
[i
]);
170 * read_dir: get the file names and modification dates for the
171 * files in /var/news into n_list; sort them in reverse by
172 * modification date. We assume /var/news is the working directory.
178 struct dirent
*nf
, *readdir();
180 char fname
[MAXNAMLEN
];
184 /* Open the current directory */
185 if ((dirp
= opendir(".")) == NULL
) {
186 fprintf (stderr
, "Cannot open %s\n", NEWS
);
190 /* Read the file names into n_list */
192 while (nf
= readdir(dirp
)) {
193 strncpy (fname
, nf
->d_name
, (unsigned) strlen(nf
->d_name
) + 1);
194 if (nf
->d_ino
!= (ino_t
)0 && stat (fname
, &sbuf
) >= 0
195 && (sbuf
.st_mode
& S_IFMT
) == S_IFREG
) {
198 while (*p
&& strncmp (*p
, nf
->d_name
, MAXNAMLEN
))
202 n_list
= (struct n_file
*)
203 realloc ((char *) n_list
,
205 (sizeof (struct n_file
)
208 n_list
= (struct n_file
*) malloc
210 (sizeof (struct n_file
) *
212 if (n_list
== NULL
) {
213 fprintf (stderr
, "No storage\n");
216 n_list
[n_count
-1].n_time
= sbuf
.st_mtime
;
217 strncpy (n_list
[n_count
-1].n_name
,
218 nf
->d_name
, MAXNAMLEN
);
223 /* Sort the elements of n_list in decreasing time order */
224 for (i
=1; i
<n_count
; i
++)
226 if (n_list
[j
].n_time
< n_list
[i
].n_time
) {
229 n_list
[i
] = n_list
[j
];
240 if (signal (SIGQUIT
, SIG_IGN
) != (void(*)())SIG_IGN
)
241 signal (SIGQUIT
, _exit
);
242 umask (((~(S_IRWXU
|S_IRGRP
|S_IXGRP
|S_IROTH
|S_IXOTH
)) & S_IAMB
));
243 if (chdir (NEWS
) < 0) {
244 fprintf (stderr
, "Cannot chdir to %s\n", NEWS
);
254 for (i
=0; i
<n_count
; i
++)
255 print_item (n_list
[i
].n_name
);
262 char fname
[MAXNAMLEN
+1];
263 static int firstitem
= 1;
265 struct passwd
*getpwuid();
270 strncpy (fname
, f
, MAXNAMLEN
);
271 fname
[MAXNAMLEN
] = '\0';
272 if ((fd
= fopen (fname
, "r")) == NULL
)
273 printf ("Cannot open %s/%s\n", NEWS
, fname
);
275 register int c
, ip
, op
;
279 fstat (fileno (fd
), &sbuf
);
284 if (setjmp(save_addr
))
286 if (signal(SIGINT
, SIG_IGN
) != (void(*)())SIG_IGN
)
287 signal(SIGINT
, onintr
);
288 printf ("%s ", fname
);
289 pw
= getpwuid (sbuf
.st_uid
);
291 printf ("(%s)", pw
->pw_name
);
294 cftime(time_buf
, DATE_FMT
, &sbuf
.st_mtime
);
295 printf (" %s\n", time_buf
);
298 while ((c
= getc (fd
)) != EOF
) {
318 ip
= ((ip
- INDENT
+ 8) & -8) + INDENT
;
326 while ((ip
& -8) > (op
& -8)) {
345 if (signal(SIGINT
, SIG_IGN
) != (void(*)())SIG_IGN
)
346 signal(SIGINT
, SIG_DFL
);
351 late_news(void(*emit
)(), int update
)
356 struct stat newstime
;
359 long actime
, modtime
;
361 extern char *getenv();
363 /* Determine the time when last called */
364 cp
= getenv ("HOME");
366 fprintf (stderr
, "Cannot find HOME variable\n");
371 strcat (fname
, ".news_time");
372 cutoff
= stat (fname
, &newstime
) < 0? 0: newstime
.st_mtime
;
374 /* Print the recent items */
375 for (i
=0; i
<n_count
&& n_list
[i
].n_time
> cutoff
; i
++) {
376 (*emit
) (n_list
[i
].n_name
);
379 (*emit
) ((char *) NULL
);
383 /* Re-create the file and refresh the update time */
384 if (n_count
> 0 && (fd
= creat (fname
, RD_WR_ALL
)) >= 0) {
385 utb
.actime
= utb
.modtime
= n_list
[0].n_time
;
395 static int first
= 1;
400 printf ("news:", NEWS
);
402 printf (" %.14s", s
);
411 static int nitems
= 0;
417 printf ("%d news item", nitems
);
422 else printf("No news.\n");
430 longjmp(save_addr
, 1);
436 if (sopt
&& !number_read
) printf("No news.\n");