Annotation of researchv10dc/cmd/news.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     news foo        prints /usr/news/foo
                      3:  *     news -a         prints all news items, latest first
                      4:  *     news -n         lists names of new items
                      5:  *     news -s         tells count of new items only
                      6:  *     news            prints items changed since last news
                      7:  */
                      8: 
                      9: #include <stdio.h>
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <setjmp.h>
                     13: #include <signal.h>
                     14: #include <ndir.h>
                     15: #include <pwd.h>
                     16: 
                     17: /*
                     18:  *     The following items should not be printed.
                     19:  */
                     20: char *ignore[] = {
                     21:        "core",
                     22:        "dead.letter",
                     23:        NULL
                     24: };
                     25: 
                     26: struct n_file {
                     27:        long n_time;
                     28:        char n_name[MAXNAMLEN];
                     29: } *n_list;
                     30: 
                     31: char NEWS[] = "/usr/news";
                     32: 
                     33: int n_count;
                     34: char stdbuf[BUFSIZ];
                     35: 
                     36: jmp_buf        save_addr;
                     37: 
                     38: main (argc, argv)
                     39:        int argc;
                     40:        char **argv;
                     41: {
                     42:        int print_item(), notify(), count();
                     43: 
                     44:        setbuf (stdout, stdbuf);
                     45:        initialize();
                     46:        read_dir();
                     47:        if (argc <= 1)
                     48:                late_news (print_item, 1);
                     49:        else if (       argc == 2 && argv[1][0] == '-'
                     50:            && argv[1][1] != '\0' && argv[1][2] == '\0')
                     51:                switch (argv[1][1]) {
                     52:                case 'a':
                     53:                        all_news();
                     54:                        break;
                     55: 
                     56:                case 'n':
                     57:                        late_news (notify, 0);
                     58:                        break;
                     59: 
                     60:                case 's':
                     61:                        late_news (count, 0);
                     62:                        break;
                     63: 
                     64:                default:
                     65:                        fprintf (stderr, "news: bad option %s\n", argv[1]);
                     66:                        exit (1);
                     67:                }
                     68:        else {
                     69:                int i;
                     70:                for (i=1; i<argc; i++)
                     71:                        print_item (argv[i]);
                     72:        }
                     73:        return 0;
                     74: }
                     75: 
                     76: /*
                     77:  *     read_dir: get the file names and modification dates for the
                     78:  *     files in /usr/news into n_list; sort them in reverse by
                     79:  *     modification date. We assume /usr/news is the working directory.
                     80:  */
                     81: 
                     82: read_dir()
                     83: {
                     84:        struct direct *nf;
                     85:        struct stat sbuf;
                     86:        char fname[MAXNAMLEN];
                     87:        DIR *dirp;
                     88:        int i, j;
                     89:        char *malloc(), *realloc();
                     90: 
                     91:        /* Open the current directory */
                     92:        if ((dirp = opendir(".")) == NULL) {
                     93:                fprintf (stderr, "news: ");
                     94:                perror (NEWS);
                     95:                exit (1);
                     96:        }
                     97: 
                     98:        /* Read the file names into n_list */
                     99:        n_count = 0;
                    100:        while (nf = readdir(dirp)) {
                    101:                strncpy (fname, nf->d_name, (unsigned) strlen(nf->d_name) + 1);
                    102:                if (nf->d_ino != 0 && stat (fname, &sbuf) >= 0
                    103:                 && (sbuf.st_mode & S_IFMT) == S_IFREG) {
                    104:                        register char **p;
                    105:                        p = ignore;
                    106:                        while (*p && strncmp (*p, nf->d_name, MAXNAMLEN))
                    107:                                ++p;
                    108:                        if (!*p) {
                    109:                                if (n_count++ > 0)
                    110:                                        n_list = (struct n_file *)
                    111:                                                realloc ((char *) n_list,
                    112:                                                (unsigned)
                    113:                                                (sizeof (struct n_file)
                    114:                                                    * n_count));
                    115:                                else
                    116:                                        n_list = (struct n_file *) malloc
                    117:                                                ((unsigned)
                    118:                                                (sizeof (struct n_file) *
                    119:                                                n_count));
                    120:                                if (n_list == NULL) {
                    121:                                        fprintf (stderr, "news: no storage\n");
                    122:                                        exit (1);
                    123:                                }
                    124:                                n_list[n_count-1].n_time = sbuf.st_mtime;
                    125:                                strncpy (n_list[n_count-1].n_name,
                    126:                                        nf->d_name, MAXNAMLEN);
                    127:                        }
                    128:                }
                    129:        }
                    130: 
                    131:        /* Sort the elements of n_list in decreasing time order */
                    132:        for (i=1; i<n_count; i++)
                    133:                for (j=0; j<i; j++)
                    134:                        if (n_list[j].n_time < n_list[i].n_time) {
                    135:                                struct n_file temp;
                    136:                                temp = n_list[i];
                    137:                                n_list[i] = n_list[j];
                    138:                                n_list[j] = temp;
                    139:                        }
                    140: 
                    141:        /* Clean up */
                    142:        closedir(dirp);
                    143: }
                    144: 
                    145: initialize()
                    146: {
                    147:        extern _exit();
                    148:        if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
                    149:                signal (SIGQUIT, _exit);
                    150:        umask (022);
                    151:        if (chdir (NEWS) < 0) {
                    152:                fprintf (stderr, "news: ");
                    153:                perror (NEWS);
                    154:                exit (1);
                    155:        }
                    156: }
                    157: 
                    158: all_news()
                    159: {
                    160:        int i;
                    161: 
                    162:        for (i=0; i<n_count; i++)
                    163:                print_item (n_list[i].n_name);
                    164: }
                    165: 
                    166: print_item (f)
                    167:        char *f;
                    168: {
                    169:        FILE *fd;
                    170:        char fname[MAXNAMLEN+1];
                    171:        static int firstitem = 1;
                    172:        int onintr();
                    173:        struct passwd *getpwuid();
                    174: 
                    175:        if (f == NULL) {
                    176:                return;
                    177:        }
                    178:        strncpy (fname, f, MAXNAMLEN);
                    179:        fname[MAXNAMLEN] = '\0';
                    180:        if ((fd = fopen (fname, "r")) == NULL) {
                    181:                fprintf (stderr, "news: %s/", NEWS);
                    182:                perror (fname);
                    183:        } else {
                    184:                register int c, ip, op;
                    185:                struct stat sbuf;
                    186:                char *ctime();
                    187:                struct passwd *pw;
                    188: 
                    189:                fstat (fileno (fd), &sbuf);
                    190:                if (firstitem) {
                    191:                        firstitem = 0;
                    192:                        putchar ('\n');
                    193:                }
                    194:                if (setjmp(save_addr))
                    195:                        goto finish;
                    196:                if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    197:                        signal(SIGINT, onintr);
                    198:                printf ("%s ", fname);
                    199:                pw = getpwuid (sbuf.st_uid);
                    200:                if (pw)
                    201:                        printf ("(%s)", pw->pw_name);
                    202:                else
                    203:                        printf (".....");
                    204:                printf (" %s\n", ctime (&sbuf.st_mtime));
                    205: 
                    206:                /*
                    207:                 *      copy the news item to the standard output
                    208:                 *
                    209:                 *      ip is the output character position corresponding
                    210:                 *      to the present input character.  op is the
                    211:                 *      actual current output character position.
                    212:                 */
                    213:                while ((c = getc (fd)) != EOF)
                    214:                                putchar (c);
                    215:                fflush (stdout);
                    216: finish:
                    217:                putchar ('\n');
                    218:                fclose (fd);
                    219:                if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    220:                        signal(SIGINT, SIG_DFL);
                    221:        }
                    222: }
                    223: 
                    224: late_news (emit, update)
                    225:        int (*emit)(), update;
                    226: {
                    227:        long cutoff;
                    228:        int i;
                    229:        char fname[50], *getenv(), *cp;
                    230:        struct stat newstime;
                    231:        int fd;
                    232:        struct {
                    233:                long actime, modtime;
                    234:        } utb;
                    235: 
                    236:        /* Determine the time when last called */
                    237:        cp = getenv ("HOME");
                    238:        if (cp == NULL) {
                    239:                fprintf (stderr, "news: cannot find HOME variable\n");
                    240:                exit (1);
                    241:        }
                    242:        strcpy (fname, cp);
                    243:        strcat (fname, "/");
                    244:        strcat (fname, ".news_time");
                    245:        cutoff = stat (fname, &newstime) < 0? 0: newstime.st_mtime;
                    246: 
                    247:        /* Print the recent items */
                    248:        for (i=0; i<n_count && n_list[i].n_time > cutoff; i++)
                    249:                (*emit) (n_list[i].n_name);
                    250:        (*emit) ((char *) NULL);
                    251:        fflush (stdout);
                    252: 
                    253:        if (update) {
                    254:                /* Re-create the file and refresh the update time */
                    255:                if (n_count > 0 && (fd = creat (fname, 0666)) >= 0) {
                    256:                        utb.actime = utb.modtime = n_list[0].n_time;
                    257:                        close (fd);
                    258:                        utime (fname, &utb);
                    259:                }
                    260:        }
                    261: }
                    262: 
                    263: notify (s)
                    264:        char *s;
                    265: {
                    266:        static int first = 1;
                    267: 
                    268:        if (s) {
                    269:                if (first) {
                    270:                        first = 0;
                    271:                        printf ("news:", NEWS);
                    272:                }
                    273:                printf (" %.14s", s);
                    274:        } else if (!first)
                    275:                putchar ('\n');
                    276: }
                    277: 
                    278: /*ARGSUSED*/
                    279: count (s)
                    280:        char *s;
                    281: {
                    282:        static int nitems = 0;
                    283: 
                    284:        if (s)
                    285:                nitems++;
                    286:        else if (nitems) {
                    287:                printf ("%d news item", nitems);
                    288:                if (nitems > 1)
                    289:                        putchar ('s');
                    290:                printf (".\n");
                    291:        }
                    292: 
                    293: }
                    294: 
                    295: onintr()
                    296: {
                    297:        sleep(2);
                    298:        longjmp(save_addr, 1);
                    299: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.