add new guys
This commit is contained in:
parent
3e63e5c271
commit
17e5fb8973
7 changed files with 2195 additions and 6 deletions
231
src/cmd/news.c
Normal file
231
src/cmd/news.c
Normal file
|
|
@ -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 <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
#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; i<argc; i++)
|
||||
print_item(argv[i]);
|
||||
exits(0);
|
||||
}
|
||||
|
||||
int
|
||||
fcmp(const void *a, const void *b)
|
||||
{
|
||||
long x;
|
||||
|
||||
x = ((File*)b)->time - ((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; i<n; i++) {
|
||||
for(j=0; ignore[j]; j++)
|
||||
if(strcmp(ignore[j], d[i].name) == 0)
|
||||
goto ign;
|
||||
if(na <= n_count) {
|
||||
na += NINC;
|
||||
n_list = realloc(n_list, na*sizeof(File));
|
||||
}
|
||||
n_list[n_count].name = strdup(d[i].name);
|
||||
n_list[n_count].time = d[i].mtime;
|
||||
n_list[n_count].length = d[i].length;
|
||||
n_count++;
|
||||
ign:;
|
||||
}
|
||||
free(d);
|
||||
|
||||
close(fd);
|
||||
qsort(n_list, n_count, sizeof(File), fcmp);
|
||||
}
|
||||
|
||||
void
|
||||
print_item(char *file)
|
||||
{
|
||||
char name[4096], *p, *ep;
|
||||
Dir *dbuf;
|
||||
int f, c;
|
||||
int bol, bop;
|
||||
|
||||
sprint(name, "%s/%s", NEWS, file);
|
||||
f = open(name, OREAD);
|
||||
if(f < 0) {
|
||||
fprint(2, "news: ");
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
strcpy(name, "...");
|
||||
dbuf = dirfstat(f);
|
||||
if(dbuf == nil)
|
||||
return;
|
||||
Bprint(&bout, "\n%s (%s) %s\n", file,
|
||||
dbuf->muid[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<n_count; i++) {
|
||||
if(n_list[i].name[0] == 0) { /* newstime */
|
||||
if(all)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if(n_list[i].length == 0) /* in progress */
|
||||
continue;
|
||||
(*emit)(n_list[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
note(char *file)
|
||||
{
|
||||
|
||||
if(!n_items)
|
||||
Bprint(&bout, "news:");
|
||||
Bprint(&bout, " %s", file);
|
||||
n_items++;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue