Asort - active file sorting program
Larry Marek
larry at ihuxf.UUCP
Sun Oct 16 04:22:01 AEST 1983
Most people like to keep the "active" file in some specific order, so
that certain related newsgroups can be read sequentially. Rather than edit
the file by hand, my friend Alan Hastings came up with this program. When it
complete, the active file will be sorted according to the template "master",
any groups that did not have a match will be at the end of the file. It will
leave the original file in "active.old"
Usage: asort active < master
asort.c:
-----
#define PARANOID /* copy file before nuking it */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
/*
* asort.c
* sort active newsgroup file according to template file
*
* Alan Hastings BTL IH 7/28/82
*
* assumptions: active files don't get very big, newsgroups not found in
* the template belong at the end, pathname does not exceed
* LSIZE characters, directory where active file lives is
* writable.
*
* A temporary file is created in the same directory as the target
* file, so it may be built and linked in, minimizing the chance
* of corrupting the active file. Signals are ignored.
*/
#define LSIZE 128 /* max chars/input line */
#define MAXGRP 500 /* max newsgroups in active file */
#define EOA (char *)(-1) /* End Of Array marker */
#define USED (char *)0 /* marker to remove name from array */
#define AMODE 0666 /* active file mode: rw-rw-rw */
char temp[LSIZE]; /* temp file name */
main(argc, argv)
int argc;
char **argv;
{
extern char *malloc(), *strcpy(), *strrchr(), *mktemp(), *strchr();
extern int (*signal())();
FILE *in, *out;
char lbuf[LSIZE], *a[MAXGRP];
register char *ta, *tta, **t;
int count;
struct stat stbuf;
unsigned asize;
if (argc != 2) {
fprintf(stderr, "usage: %s pathname\n", argv[0]);
return(1);
}
(void) signal(SIGHUP, SIG_IGN);
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
/*
* only argument is pathname of file to sort
*/
if ((in = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[1]);
return(2);
}
/*
* fstat to get size
*/
if (fstat(fileno(in), &stbuf) < 0) {
fprintf(stderr, "%s: cannot stat %s\n", argv[0], argv[1]);
return(3);
}
/*
* create a virtual file in data space
*/
if ((tta = malloc(asize = (unsigned)stbuf.st_size)) == (char *)0) {
fprintf(stderr, "%s: not enough mem\n", argv[0]);
return(4);
}
if (fread(tta, sizeof(char), (int)asize, in) != (int)asize) {
fprintf(stderr, "%s: read error on %s\n", argv[0], argv[1]);
return(5);
}
(void) fclose(in);
/*
* replace \n with \0 in our `virtual' file
* and set up pointers to the resulting strings
*/
for (t = a, ta = tta; ta < tta + asize && t < &a[MAXGRP]; t++) {
for (*t = ta; *ta != '\n' && ta < tta + asize; ta++)
;
*ta++ = '\0';
}
*t = EOA;
/*
* make a unique file name -- .../ASORTxxxxxx
*/
(void) strcpy(temp, argv[1]);
if (tta = strrchr(temp, '/'))
*++tta = '\0';
else
tta = temp;
(void) strcpy(tta, "ASORTXXXXXX");
(void) mktemp(tta);
if ((out = fopen(temp, "w")) == NULL) {
fprintf(stderr, "%s: cannot creat %s\n", argv[0], temp);
return(6);
}
(void) chmod(temp, AMODE);
/*
* template had better be on stdin...
*/
while (gets(lbuf) != NULL)
for (t = a; *t != EOA; t++) {
count = abs((int) (*t) - (int) strchr(*t, ' '));
if (*t != USED && strncmp(*t, lbuf, count) == 0) {
/*
* found one, print it + mark it used
*/
fprintf(out, "%s\n", *t);
*t = USED;
}
}
/*
* find names that weren't in the template and stuff them on the end
*/
for (t = a; *t != EOA; t++)
if (*t != USED)
fprintf(out, "%s\n", *t);
(void) fclose(out);
#ifdef PARANOID
{
char savname[LSIZE], *strcat();
(void) strcat(strcpy(savname, argv[1]), ".old");
(void) unlink(savname); /* in case it's there */
if (link(argv[1], savname) < 0) {
fprintf(stderr, "%s: cannot link %s to %s\n",
argv[0], argv[1], savname);
done(7);
}
}
#endif PARANOID
/*
* check to see if the active file has changed whilst we were
* mucking about
*/
if (stat(argv[1], &stbuf) < 0) {
fprintf(stderr, "%s: cannot re-stat %s!!!\n", argv[0], argv[1]);
done(8);
}
if ((unsigned)stbuf.st_size != asize) {
fprintf(stderr, "%s: new newsgroup arrived--aborting\n",
argv[0]);
done(9);
}
(void) unlink(argv[1]);
if (link(temp, argv[1]) < 0) {
fprintf(stderr, "%s: cannot link %s to %s!!!!\n",
argv[0], temp, argv[1]);
return(10); /* leave the temp file there... */
}
done(0);
/* NOTREACHED */
}
done(retval)
int retval;
{
(void) unlink(temp);
exit(retval);
}
--
Larry Marek
ihnp4!ihuxf!larry
More information about the Comp.sources.unix
mailing list