/* * news foo prints /lib/news/foo * news -a prints all news items, latest first * news -n lists names of new items * news prints items changed since last news */ #include #include #include #define NINC 50 /* Multiples of directory allocation */ char NEWS[] = "/lib/news"; char TFILE[] = "%s/lib/newstime"; /* * The following items should not be printed. */ char* ignore[] = { "core", "dead.letter", 0 }; typedef struct { long time; char *name; vlong length; } File; File* n_list; int n_count; int n_items; Biobuf bout; int fcmp(void *a, void *b); void read_dir(int update); void print_item(char *f); void eachitem(void (*emit)(char*), int all, int update); void note(char *s); void main(int argc, char *argv[]) { int i; Binit(&bout, 1, OWRITE); if(argc == 1) { eachitem(print_item, 0, 1); exits(0); } ARGBEGIN{ case 'a': /* print all */ eachitem(print_item, 1, 0); break; case 'n': /* names only */ eachitem(note, 0, 0); if(n_items) Bputc(&bout, '\n'); break; default: fprint(2, "news: bad option %c\n", ARGC()); exits("usage"); }ARGEND for(i=0; itime - ((File*)a)->time; if(x < 0) return -1; if(x > 0) return 1; return 0; } /* * read_dir: get the file names and modification dates for the * files in /usr/news into n_list; sort them in reverse by * modification date. */ void read_dir(int update) { Dir *d; char newstime[100], *home; int i, j, n, na, fd; n_count = 0; n_list = malloc(NINC*sizeof(File)); na = NINC; home = getenv("home"); if(home) { sprint(newstime, TFILE, home); d = dirstat(newstime); if(d != nil) { n_list[n_count].name = strdup(""); n_list[n_count].time =d->mtime-1; n_list[n_count].length = 0; n_count++; free(d); } if(update) { fd = create(newstime, OWRITE, 0644); if(fd >= 0) close(fd); } } fd = open(NEWS, OREAD); if(fd < 0) { fprint(2, "news: "); perror(NEWS); exits(NEWS); } n = dirreadall(fd, &d); for(i=0; imuid[0]? dbuf->muid : dbuf->uid, asctime(localtime(dbuf->mtime))); free(dbuf); bol = 1; /* beginning of line ...\n */ bop = 1; /* beginning of page ...\n\n */ for(;;) { c = read(f, name, sizeof(name)); if(c <= 0) break; p = name; ep = p+c; while(p < ep) { c = *p++; if(c == '\n') { if(!bop) { Bputc(&bout, c); if(bol) bop = 1; bol = 1; } continue; } if(bol) { Bputc(&bout, '\t'); bol = 0; bop = 0; } Bputc(&bout, c); } } if(!bol) Bputc(&bout, '\n'); close(f); } void eachitem(void (*emit)(char*), int all, int update) { int i; read_dir(update); for(i=0; i