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>
56 #define RD_WR_ALL (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
58 #define DATE_FMT "%a %b %e %H:%M:%S %Y"
60 * %a abbreviated weekday name
61 * %b abbreviated month name
63 * %H hour (24-hour clock)
69 The following items should not be printed.
78 char n_name
[MAXNAMLEN
];
81 char NEWS
[] = "/var/news"; /* directory for news items */
83 int aopt
= 0; /* 1 say -a specified */
84 int n_count
; /* number of items in NEWS directory */
85 int number_read
; /* number of items read */
86 int nopt
= 0; /* 1 say -n specified */
87 int optsw
; /* for getopt */
88 int opt
= 0; /* number of options specified */
89 int sopt
= 0; /* 1 says -s specified */
91 char time_buf
[50]; /* holds date and time string */
98 void initialize(void);
99 void late_news(void(*)(), int);
101 void print_item(char *);
105 main(int argc
, char **argv
)
109 (void)setlocale(LC_ALL
, "");
110 setbuf (stdout
, stdbuf
);
115 late_news (print_item
, 1);
118 else while ((optsw
= getopt(argc
, argv
, "ans")) != EOF
)
136 fprintf (stderr
, "usage: news [-a] [-n] [-s] [items]\n");
141 fprintf(stderr
, "news: options are mutually exclusive\n");
145 if (opt
> 0 && argc
> 2) {
146 fprintf(stderr
, "news: options are not allowed with file names\n");
157 late_news (notify
, 0);
163 late_news (count
, 0);
167 for (i
=1; i
<argc
; i
++) print_item (argv
[i
]);
173 * read_dir: get the file names and modification dates for the
174 * files in /var/news into n_list; sort them in reverse by
175 * modification date. We assume /var/news is the working directory.
181 struct dirent
*nf
, *readdir();
183 char fname
[MAXNAMLEN
];
187 /* Open the current directory */
188 if ((dirp
= opendir(".")) == NULL
) {
189 fprintf (stderr
, "Cannot open %s\n", NEWS
);
193 /* Read the file names into n_list */
195 while (nf
= readdir(dirp
)) {
196 strncpy (fname
, nf
->d_name
, (unsigned) strlen(nf
->d_name
) + 1);
197 if (nf
->d_ino
!= (ino_t
)0 && stat (fname
, &sbuf
) >= 0
198 && (sbuf
.st_mode
& S_IFMT
) == S_IFREG
) {
201 while (*p
&& strncmp (*p
, nf
->d_name
, MAXNAMLEN
))
205 n_list
= (struct n_file
*)
206 realloc ((char *) n_list
,
208 (sizeof (struct n_file
)
211 n_list
= (struct n_file
*) malloc
213 (sizeof (struct n_file
) *
215 if (n_list
== NULL
) {
216 fprintf (stderr
, "No storage\n");
219 n_list
[n_count
-1].n_time
= sbuf
.st_mtime
;
220 strncpy (n_list
[n_count
-1].n_name
,
221 nf
->d_name
, MAXNAMLEN
);
226 /* Sort the elements of n_list in decreasing time order */
227 for (i
=1; i
<n_count
; i
++)
229 if (n_list
[j
].n_time
< n_list
[i
].n_time
) {
232 n_list
[i
] = n_list
[j
];
243 if (signal (SIGQUIT
, SIG_IGN
) != (void(*)())SIG_IGN
)
244 signal (SIGQUIT
, _exit
);
245 umask (((~(S_IRWXU
|S_IRGRP
|S_IXGRP
|S_IROTH
|S_IXOTH
)) & S_IAMB
));
246 if (chdir (NEWS
) < 0) {
247 fprintf (stderr
, "Cannot chdir to %s\n", NEWS
);
257 for (i
=0; i
<n_count
; i
++)
258 print_item (n_list
[i
].n_name
);
265 char fname
[MAXNAMLEN
+1];
266 static int firstitem
= 1;
268 struct passwd
*getpwuid();
273 strncpy (fname
, f
, MAXNAMLEN
);
274 fname
[MAXNAMLEN
] = '\0';
275 if ((fd
= fopen (fname
, "r")) == NULL
)
276 printf ("Cannot open %s/%s\n", NEWS
, fname
);
278 register int c
, ip
, op
;
282 fstat (fileno (fd
), &sbuf
);
287 if (setjmp(save_addr
))
289 if (signal(SIGINT
, SIG_IGN
) != (void(*)())SIG_IGN
)
290 signal(SIGINT
, onintr
);
291 printf ("%s ", fname
);
292 pw
= getpwuid (sbuf
.st_uid
);
294 printf ("(%s)", pw
->pw_name
);
297 cftime(time_buf
, DATE_FMT
, &sbuf
.st_mtime
);
298 printf (" %s\n", time_buf
);
301 while ((c
= getc (fd
)) != EOF
) {
321 ip
= ((ip
- INDENT
+ 8) & -8) + INDENT
;
329 while ((ip
& -8) > (op
& -8)) {
348 if (signal(SIGINT
, SIG_IGN
) != (void(*)())SIG_IGN
)
349 signal(SIGINT
, SIG_DFL
);
354 late_news(void(*emit
)(), int update
)
359 struct stat newstime
;
362 extern char *getenv();
364 /* Determine the time when last called */
365 cp
= getenv ("HOME");
367 fprintf (stderr
, "Cannot find HOME variable\n");
372 strcat (fname
, ".news_time");
373 cutoff
= stat (fname
, &newstime
) < 0? 0: newstime
.st_mtime
;
375 /* Print the recent items */
376 for (i
=0; i
<n_count
&& n_list
[i
].n_time
> cutoff
; i
++) {
377 (*emit
) (n_list
[i
].n_name
);
380 (*emit
) ((char *) NULL
);
384 /* Re-create the file and refresh the update time */
385 if (n_count
> 0 && (fd
= creat (fname
, RD_WR_ALL
)) >= 0) {
386 utb
.actime
= utb
.modtime
= n_list
[0].n_time
;
396 static int first
= 1;
401 printf ("news:", NEWS
);
403 printf (" %.14s", s
);
412 static int nitems
= 0;
418 printf ("%d news item", nitems
);
423 else printf("No news.\n");
431 longjmp(save_addr
, 1);
437 if (sopt
&& !number_read
) printf("No news.\n");