Annotation of researchv10no/cmd/news.c, revision 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.