solomon (03/26/83)
/* mkhistory.c - munge around in the spool files and see what's there. * Written by solomon@uwisc, 3/23/83. * * To compile: * cc mkhistory.o header.o funcs.o getdate.o rextern.o * * Currrent version produces (on stdout) a replica of what * /usr/lib/news/history should look like, modulo the following differences: * The history file contains "file names" that are longer than 14 characters, * and in the case of multiple file names for the same item, the file names * are in arbitrary order. The output of this program has the actual file * names (truncated to 14 chars) and lists them in alphabetical order. * For example, the line * zehntel.838 Fri Mar 11 05:48:22 1983 net.unix-wizards/1769 * would appear * zehntel.838 Fri Mar 11 05:48:22 1983 net.unix-wizar/1769 * and * spanky.236 Fri Mar 11 05:47:01 1983 net.politics/245 net.philosophy/68 * would appear * spanky.236 Fri Mar 11 05:47:01 1983 net.philosophy/68 net.politics/245 * * See the shell file "fixhist.sh" for a program that takes the history file * produces something suitable for diff. * */ #include "params.h" #include <dir.h> #define MAXID 16 #define MAXFNAME 24 #define MAXITEMS 3000 struct item { char id[MAXID]; time_t dtime; char fname[MAXFNAME]; short inum; } table[MAXITEMS]; int nitems = 0; #define SPOOLDIR "/usr/spool/news" #define NAMESIZE 256 char *sprintf(), *strncpy(), *ctime(); main(argc,argv) char **argv; { char group[NAMESIZE], file[NAMESIZE]; char groupname[NAMESIZE], filename[NAMESIZE]; int spool, dir, i; FILE *item; int comp(); spool = open(SPOOLDIR,0); if (spool<0) { perror(SPOOLDIR); exit(1); } while (getname(spool,group)) { (void) sprintf(groupname,"%s/%s",SPOOLDIR,group); dir = open(groupname,0); if (dir<0) { perror(groupname); exit(1); } while (i = getname(dir,file)) { (void) sprintf(filename,"%s/%s",groupname,file); item = fopen(filename,"r"); if (item==NULL) { perror(filename); exit(1); } dofile(item,group,file,i); (void) fclose(item); } (void) close(dir); } fprintf(stderr,"start of sort\n"); (void) fflush(stderr); qsort(table,nitems,sizeof (struct item),comp); dumpitems(); exit(0); } int comp(a,b) struct item *a, *b; { register temp; if (temp = a->dtime - b->dtime) return temp; return strcmp(a->fname,b->fname); } int getname(fd,result) int fd; char *result; { struct dir dirent; int n; /* Get the next file name from fd (which is an open directory file). * Skip all names that start with ".". Return 0 for EOF, the inum * of the file ow. * Terminate result with a NULL (assume there is room for DIRSIZ+1 * chars). */ for(;;){ n = read(fd,(char *)(&dirent),sizeof dirent); if (n!=sizeof dirent) return 0; if (dirent.d_ino==0) continue; if (dirent.d_name[0]=='.') continue; strncpy(result,dirent.d_name,DIRSIZ); result[DIRSIZ] = '\0'; return dirent.d_ino; } } dofile(fi,group,file,ino) FILE *fi; char *group, *file; { register struct item *iptr; if (hread(&header,fi)==NULL) { fprintf(stderr,"%s/%s\n",group,file); printf("syntax error\n"); return; } iptr = &table[nitems++]; strncpy(iptr->id,header.ident,MAXID); (void) sprintf(iptr->fname,"%s/%s",group,file); iptr->dtime = cgtdate(header.recdate); iptr->inum = ino; } dumpitems() { register int i,j; char *temp; table[nitems].inum = 0; /* sentinel */ for(i=0; i<nitems;) { for (j=i+1;table[j].inum == table[i].inum; j++) ; /* * now table[i..j-1] contain the same inum */ temp = ctime(&table[i].dtime); (void) nstrip(temp); printf("%s\t%s\t",table[i].id, temp); while (i<j) { printf("%s ",table[i++].fname); } putchar('\n'); } } xerror(message) char *message; { printf("mkhistory: %s.\n", message); (void) fflush(stdout); exit(1); } /* last line of mkhistory.c */