From 17e5fb8973d9e48ef53a88eb78f845f8a7b41a5b Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 21 Apr 2004 23:22:06 +0000 Subject: add new guys --- src/cmd/news.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/cmd/news.c (limited to 'src/cmd/news.c') diff --git a/src/cmd/news.c b/src/cmd/news.c new file mode 100644 index 00000000..c6a99a30 --- /dev/null +++ b/src/cmd/news.c @@ -0,0 +1,231 @@ +/* + * 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 = "#9/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(const void *a, const 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; + + NEWS = unsharp(NEWS); + + 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