home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
comms
/
network
/
grn1asrc.lha
/
grnrc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-20
|
13KB
|
510 lines
#include "defs.h"
#include <stdarg.h>
ULONG grnrcVersion = '1.20';
char userName[256], grnrcName[256];
char newsEditor[256], mailEditor[256];
char postNews[256], sendMail[256];
char uunews[256] = "UUNEWS:";
char uulib[256] = "UULIB:";
char uuspool[256] = "UUSPOOL:";
char logfile[256] = "uuspool:logfile";
LOCK lock = 0;
FIB *fib = 0;
LIST groupList;
BOOL treeDirty = 0;
BOOL debug = 0;
/************************************************************************/
/*
* void Abort(void);
*
* Synopsis:
* Cleanup and exit. Can be called anywhere, anytime, including from
* the debugger by setting PC = Abort.
*/
long abort_code = 0;
void Abort(void) {
exit(abort_code);
}
/*
* void panic0(v, s, ...);
* ULONG v;
* char *s;
* ULONG a1,a2,a3,a4;
*
* Synopsis:
* Anywhere you use:
* v = (some function);
* if (!v) {
* printf("some string");
* Abort();
* }
* You can use:
* v = (some function);
* panic0(v, "some string");
* The string and args (a1,a2,a3,a4) are passed to printf...
*/
void panic0(APTR v, char *s, ...) {
FILE *outfp;
va_list va;
va_start(va, s);
if (v) return;
printf("Panic: ");
printf(s, va);
printf("\n");
outfp = fopen(logfile, "a");
if (outfp) {
fprintf(outfp, "GRn panic: ");
fprintf(outfp, s, va);
fprintf(outfp, "\n");
fclose(outfp);
}
abort_code = 999;
va_end(va);
Abort();
}
void panic(char *s,...) {
FILE *outfp;
va_list va;
va_start(va, s);
printf("Panic: ");
printf(s, va);
printf("\n");
outfp = fopen(logfile, "a");
if (outfp) {
fprintf(outfp, "GRn panic: ");
fprintf(outfp, s, va);
fprintf(outfp, "\n");
fclose(outfp);
}
abort_code = 999;
va_end(va);
Abort();
}
/************************************************************************/
BOOL EmptyList(list)
LIST *list;
{
if (list->lh_TailPred == (NODE *)list) return !0;
return 0;
}
/************************************************************************/
UBYTE *mbuf = 0, *mbufp, *mbufe;
void mclose(void) { if (mbuf) { free(mbuf); mbuf = 0; } }
BOOL mopen(char *fn) {
int fd;
ULONG size;
mclose();
fd = open(fn, O_READ);
if (fd == -1) return 0;
size = lseek(fd, 0, 2); lseek(fd, 0, 0);
mbuf = (UBYTE *)malloc(size);
if (!mbuf) { close(fd); return 0; }
read(fd, mbuf, size);
close(fd);
mbufp = mbuf;
mbufe = &mbufp[size];
return !0;
}
BOOL mread(buf, size)
UBYTE *buf;
ULONG size;
{
ULONG i;
if (!mbuf || mbufp == mbufe) return 0;
for (i=0; i<size; i++) *buf++ = (mbufp == mbufe) ? 0 : *mbufp++;
return !0;
}
BOOL mgets(buf)
UBYTE *buf;
{
if (mbufp == mbufe) return 0;
while (mbufp != mbufe && (*buf++ = *mbufp++));
*buf++ = '\0';
return !0;
}
/************************************************************************/
void FixName(dst, src)
char *dst, *src;
{
short i, j;
BOOL ltFlag = 0;
char *d = dst;
for (i=0; src[i]; i++) if (src[i] == '<') ltFlag = !0;
if (*src == '"') {
for (j=1; src[j] && src[j] != '"'; j++) *dst++ = src[j];
*dst++ = '\0';
if (dst-d > 512) printf("FixName1 string to big: %d bytes '%s'\n", dst-d, d);
return;
}
if (*src == '<') {
for (j=1; src[j] && src[j] != '@' && src[j] != '>'; j++) {
if (src[j] == '.')
*dst++ = ' ';
else
*dst++ = src[j];
}
*dst++ = '\0';
if (dst-d > 512) printf("FixName2 string to big: %d bytes '%s'\n", dst-d, d);
return;
}
for (j=0; src[j]; j++) {
if (src[j] == '<') {
if (!j) {
if (strlen(src) > 511) printf("FixName3 string to big: %d bytes '%s'\n", dst-d, src);
strncpy(dst, src, 512);
return;
}
else {
for (i=0; i<j; i++) *dst++ = *src++;
*dst++ = '\0';
if (dst-d > 512) printf("FixName4 string to big: %d bytes '%s'\n", dst-d, d);
return;
}
}
if (src[j] == '(' && !ltFlag) {
j++;
while (src[j] && src[j] != ')') *dst++ = src[j++];
*dst++ = '\0';
if (dst-d > 512) printf("FixName5 string to big: %d bytes '%s'\n", dst-d, d);
return;
}
}
j=-1;
for (i=0; src[i]; i++) if (src[i] == '!') j = i;
if (j != -1) {
j++;
while (src[j] && src[j] != ',' && src[j] != '@') *dst++ = src[j++];
*dst++ = '\0';
}
else {
while (*src && *src != '%' && *src != '@') *dst++ = *src++;
*dst++ = '\0';
}
if (dst-d > 512) printf("FixName6 string to big: %d bytes '%s'\n", dst-d, d);
}
/************************************************************************/
void WriteNewsTree() {
int fd;
ART *ap;
GLIST *gp;
UWORD end = END;
if (!treeDirty) return;
if (debug) printf("Writing news tree\n");
fd = open(grnrcName, O_WRITE);
if (fd == -1) panic("Can't open %s for output", grnrcName);
write(fd, &grnrcVersion, 4);
for (gp = (GLIST *)groupList.lh_Head; gp->node.ln_Succ; gp=(GLIST *)gp->node.ln_Succ) {
write(fd, gp->groupName, strlen(gp->groupName)+1);
write(fd, &gp->hideHeaders, 1);
write(fd, &gp->hideRead, 1);
write(fd, &gp->nextReceived, 4);
write(fd, &gp->sortActive, 2);
// sort the articles in this group by number
SortArticlesByNumber(&gp->artList);
for (ap=(ART *)gp->artList.lh_Head; ap->node.ln_Succ; ap=(ART *)ap->node.ln_Succ) {
write(fd, &ap->state, 2);
write(fd, &ap->filenum, 4);
write(fd, ap->from, strlen(ap->from)+1);
write(fd, ap->subject, strlen(ap->subject)+1);
}
write(fd, &end, 2);
}
close(fd);
treeDirty = 0;
}
void ReadNewsTree() {
ART *ap;
GLIST *gp;
char groupName[256], temp[256];
UWORD endTest;
ULONG pct;
if (debug) printf("GRn - Reading News Tree...\n");
while (1) {
if (!mgets(&groupName[0])) break;
gp = (GLIST *)malloc(sizeof(GLIST));
panic0(gp, "Can't malloc GLIST %d bytes", sizeof(GLIST));
gp->node.ln_Name = &gp->header[0];
AddTail(&groupList, (NODE *)gp);
NewList(&gp->artList);
gp->articles = gp->unread = 0;
mread(&gp->hideHeaders, 1);
mread(&gp->hideRead, 1);
mread(&gp->nextReceived, 4);
mread(&gp->sortActive, 2);
pct = (100*(ULONG)(mbufp-mbuf))/(ULONG)(mbufe-mbuf);
while (1) {
mread(&endTest, 2);
if (endTest == END) break;
ap = (ART *)malloc(sizeof(ART));
panic0(ap, "Can't malloc ART %d bytes", sizeof(ART));
ap->node.ln_Name = &ap->header[0];
ap->state = endTest;
mread(&ap->filenum, 4);
mgets(temp);
ap->from = (char *)malloc(strlen(temp)+1);
panic0(ap->from, "Can't allocate memory for From: field");
strcpy(ap->from, temp);
mgets(temp);
ap->subject = (char *)malloc(strlen(temp)+1);
panic0(ap->subject, "Can't allocate memory for Subject: field");
strcpy(ap->subject, temp);
AddTail(&gp->artList, (NODE *)ap);
gp->articles++;
if (ap->state == UNREAD || ap->state == NEW) gp->unread++;
}
strcpy(gp->groupName, groupName);
sprintf(gp->header, "%-40.40s %6d articles %6d UnRead", gp->groupName, gp->articles, gp->unread);
}
mclose();
}
void UpdateNewsTree() {
GLIST *gp;
ART *ap;
long num, last; // article number
char fname[256], work[512], from[512], subject[512];
FILE *fp;
BOOL flag;
// for each group
for (gp=(GLIST *)groupList.lh_Head; gp->node.ln_Succ; gp = (GLIST *)gp->node.ln_Succ) {
if (debug) printf("GRn - Pruning %s\n", gp->groupName);
// scan through list and check to see if the files are still there!
flag = 0;
for (ap=(ART *)gp->artList.lh_Head; ap->node.ln_Succ; ap = (ART *)ap->node.ln_Succ) {
strcpy(fname, uunews);
AddPart(fname, gp->groupName, 256);
sprintf(work, "%d", ap->filenum);
AddPart(fname, work, 256);
if (!flag) {
lock = Lock(fname, SHARED_LOCK);
if (lock) {
UnLock(lock); lock = 0;
flag = !0;
}
else {
if (ap->state == UNREAD) gp->unread--;
gp->articles--;
Remove((NODE *)ap);
if (ap->subject) free(ap->subject);
if (ap->from) free(ap->from);
free(ap);
treeDirty = !0;
}
}
}
// Find new articles, mark as unread!
if (debug) printf("GRn - Getting new articles for %s\n", gp->groupName);
strcpy(fname, uunews);
AddPart(fname, gp->groupName, 256);
AddPart(fname, ".next", 256);
fp = fopen(fname, "r");
if (fp) {
fgets(work, 512, fp);
fclose(fp);
last = atoi(work);
}
else {
last = 1000000;
}
for (num = gp->nextReceived; num<last; num++) {
strcpy(fname, uunews);
AddPart(fname, gp->groupName, 256);
sprintf(work, "%d", num);
AddPart(fname, work, 256);
fp = fopen(fname, "r");
if (!fp) {
if (last == 1000000) break;
if (debug) printf("skipping %s\n", fname);
continue;
}
ap = (ART *)malloc(sizeof(ART));
panic0(ap, "Can't malloc ART %d bytes", sizeof(ART));
ap->node.ln_Name = &ap->header[0];
ap->state = UNREAD;
ap->filenum = num;
strcpy(from, "UNKNOWN");
strcpy(subject, "NO SUBJECT");
while (fgets(work, 512, fp)) {
work[strlen(work)-1] = '\0';
if (!work[0]) break;
if (!strncmp(work, "From: ", 6)) strcpy(from, &work[6]);
else if (!strncmp(work, "Subject: ", 9)) strcpy(subject, &work[9]);
}
fclose(fp);
FixName(work, from);
ap->from = (char *)malloc(strlen(work)+1);
panic0(ap->from, "Can't allocate memory for From:\n");
strcpy(ap->from, work);
ap->subject = (char *)malloc(strlen(subject)+1);
panic0(ap->subject, "Can't allocate memory for subject:\n");
strcpy(ap->subject, subject);
AddTail(&gp->artList, (NODE *)ap);
gp->articles++;
gp->unread++;
treeDirty = !0;
}
sprintf(gp->header, "%-40.40s %6d articles %6d UnRead", gp->groupName, gp->articles, gp->unread);
if (gp->nextReceived != last) {
gp->nextReceived = last;
treeDirty = !0;
}
}
}
/************************************************************************/
void ParseConfig(void) {
char buf[512], *ps;
FILE *fp;
BOOL uulibFlag = 0;
userName[0] = mailEditor[0] = newsEditor[0] = '\0';
GetVar("USERNAME", &userName[0], 256, GVF_GLOBAL_ONLY);
GetVar("NEWSEDITOR", &newsEditor[0], 256, GVF_GLOBAL_ONLY);
GetVar("MAILEDITOR", &newsEditor[0], 256, GVF_GLOBAL_ONLY);
GetVar("SENDMAIL", &sendMail[0], 256, GVF_GLOBAL_ONLY);
GetVar("POSTNEWS", &postNews[0], 256, GVF_GLOBAL_ONLY);
if (userName[0] && newsEditor[0] && mailEditor[0] && sendMail[0] && postNews[0]) return;
fp = fopen("s:uuconfig", "r");
if (!fp) {
fp = fopen("uulib:config", "r");
panic0(fp, "Can't open uulib:config");
uulibFlag = !0;
}
while (fgets(buf, 512, fp) && (!userName[0] || !newsEditor[0] || !mailEditor[0] || !sendMail[0] || !postNews[0])) {
buf[strlen(buf)-1] = '\0';
if (userName[0] == '\0' && !strnicmp(buf, "UserName", 8)) {
ps = &buf[8];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps == '\0') panic("s:uuconfig or uulib:config UserName is NULL");
strcpy(userName, ps);
}
else if (newsEditor[0] == '\0' && !strnicmp(buf, "NewsEditor", 10)) {
ps = &buf[10];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps == '\0') panic("s:uuconfig or uulib:config NewsEditor is NULL");
strcpy(newsEditor, ps);
}
else if (mailEditor[0] == '\0' && !strnicmp(buf, "MailEditor", 10)) {
ps = &buf[10];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps == '\0') panic("s:uuconfig or uulib:config MailEditor is NULL");
strcpy(mailEditor, ps);
}
else if (sendMail[0] == '\0' && !strnicmp(buf, "SendMail", 8)) {
ps = &buf[8];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps == '\0') panic("s:uuconfig or uulib:config Sendmail is NULL");
strcpy(sendMail, ps);
}
else if (postNews[0] == '\0' && !strnicmp(buf, "PostNews", 8)) {
ps = &buf[8];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps == '\0') panic("s:uuconfig or uulib:config Postnews is NULL");
strcpy(postNews, ps);
}
else if (!strnicmp(buf, "UUNews", 6)) {
ps = &buf[6];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps) strcpy(uunews, ps);
}
else if (!uulibFlag && !strnicmp(buf, "UUlib", 5)) {
ps = &buf[5];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps) strcpy(uulib, ps);
}
else if (!strnicmp(buf, "UUSpool", 7)) {
ps = &buf[7];
while (*ps == ' ' || *ps == '\t') ps++;
if (*ps) strcpy(uuspool, ps);
}
}
fclose(fp);
if (userName[0]) {
strcpy(grnrcName, uulib);
sprintf(buf, "%s.grnrc", userName);
AddPart(grnrcName, buf, 256);
}
else
panic("s:uuconfig or uulib:config must contain UserName!");
if (newsEditor[0] && !mailEditor[0])
strcpy(mailEditor, newsEditor);
else if (!newsEditor[0] && mailEditor[0])
strcpy(newsEditor, mailEditor);
panic0((APTR)newsEditor[0], "s:uuconfig or uulib:config must contain NewsEditor");
panic0((APTR)mailEditor[0], "s:uuconfig or uulib:config must contain MailEditor");
if (!sendMail[0]) strcpy(sendMail, "SendMail");
if (!postNews[0]) strcpy(postNews, "PostNews");
strcpy(logfile, uuspool);
AddPart(logfile, "logfile", 256);
}
/************************************************************************/
void main(int ac, char *av[]) {
ULONG testver = 0x0a0a5050;
char buf[256];
if (ac < 2) {
printf("Usage: GRnrc username\n");
printf("\tUpdates user .grnrc file!\n");
exit(999);
}
if (ac > 2) debug = !0;
fib = (FIB *)AllocDosObject(DOS_FIB, TAG_DONE);
panic0(fib, "Can't AllocDosObject(DOS_FIB)");
NewList(&groupList);
ParseConfig();
strcpy(userName, av[1]);
strcpy(grnrcName, uulib);
sprintf(buf, "%s.grnrc", userName);
AddPart(grnrcName, buf, 256);
if (!mopen(grnrcName)) panic("Can't open %s\n", grnrcName);
mread(&testver, 4);
if (testver != grnrcVersion) panic("grnrc is wrong version, delete it and run GRn again");
ReadNewsTree();
UpdateNewsTree();
WriteNewsTree();
}