home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
telecom
/
uucp_442
/
src
/
dnews
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-08
|
11KB
|
523 lines
/*
* MAIN.C
*/
#include "defs.h"
#define MSTLEN 64 /* # of forward referenced articles */
char User[32];
NGroup *GBase;
NGroup *CurGroup;
void *GrpDisp;
void *HelpDisp;
void *DataDisp;
void *ScanDisp; /* subject scan display */
char *GroupFile = "T:DNews_Groups";
char *HelpFile = "T:DNews_Help";
char TmpBuf[TMPBSIZE];
long MStack[MSTLEN];
short Mi;
short Mx;
#ifndef LATTICE
void *GfxBase;
void *IntuitionBase;
#endif
Prototype char *FileForArticle(NGroup *, int);
Local NGroup *FindGroupByIndex(int);
Local void HandleKey(int);
Local void UpdateGroupList(char *);
Local void CreateHelpFile();
Local void SetPrevNo();
Local char *TitleForArticle(NGroup *);
int
brk()
{
return(0);
}
void
closlib()
{
if (GfxBase) {
CloseLibrary(GfxBase);
GfxBase = NULL;
}
if (IntuitionBase) {
CloseLibrary(IntuitionBase);
IntuitionBase = NULL;
}
}
main(ac, av)
char **av;
{
onbreak(brk);
atexit(closlib);
IntuitionBase = OpenLibrary("intuition.library", 0);
GfxBase = OpenLibrary("graphics.library", 0);
if (IntuitionBase == NULL || GfxBase == NULL) {
puts("unable to open libraries");
exit(20);
}
FindUser(User, sizeof(User)); /* who am I ? */
LoadGroups(User); /* load newsrc for user */
LoadKillFile(User);
if (GBase == NULL) {
CreateNewsrc(User);
LoadGroups(User);
if (GBase == NULL) {
printf("Unable to find any news!\n");
exit(1);
}
}
LoadDisplayConfig();
UpdateGroupList(GroupFile);
GrpDisp = OpenBrowseDisplay(GroupFile, "h-help", 0);
if (GrpDisp == NULL) {
puts("unable to open window");
exit(1);
}
/*
* Handle browse events
*/
{
void *disp;
int row;
int col;
NGroup *grp;
while (WaitBrowseEvent(&disp, &row, &col)) {
if (disp == GrpDisp) { /* handle main group list */
if (row == -1) { /* close window */
if (col == -1)
break;
HandleKey(col);
continue;
}
if (grp = FindGroupByIndex(row)) {
if (CurGroup)
ClearGroupCache(CurGroup);
CurGroup = grp;
Mi = 0;
Mx = 0;
if (DataDisp)
ChangeBrowseDisplay(DataDisp, FileForArticle(grp, grp->CurNo), TitleForArticle(grp));
else
DataDisp = OpenBrowseDisplay(FileForArticle(grp, grp->CurNo), TitleForArticle(grp), 1);
}
continue;
}
if (disp == HelpDisp) {
if (row == -1) {
if (col == -1) {
CloseBrowseDisplay(HelpDisp);
HelpDisp = NULL;
}
}
continue;
}
if (disp == DataDisp) {
if (row == -1) {
if (col == -1) {
CloseBrowseDisplay(DataDisp);
DataDisp = NULL;
continue;
}
HandleKey(col);
continue;
}
}
}
}
if (GrpDisp)
CloseBrowseDisplay(GrpDisp);
if (HelpDisp)
CloseBrowseDisplay(HelpDisp);
if (DataDisp)
CloseBrowseDisplay(DataDisp);
SaveKillFile(User);
UnloadGroups(User);
SaveDisplayConfig();
remove(GroupFile);
return(0);
}
static void
UpdateGroupList(file)
char *file;
{
FILE *fi;
NGroup *grp;
fi = fopen(file, "w");
if (fi == NULL)
return;
for (grp = GBase; ; grp = grp->Next) {
long unread;
while (grp && grp->Enabled == 0)
grp = grp->Next;
if (grp == NULL)
break;
if ((unread = grp->MaxNo - grp->CurNo) < 0)
unread += 32767;
fprintf(fi, "%-3d %-20s\n", unread, grp->Name);
}
fclose(fi);
}
static void
HandleKey(key)
{
NGroup *grp = CurGroup;
short redisp = 0;
int n;
for (;;) {
if (key != 'm' && key != 'M') {
Mi = 0;
Mx = 0;
}
switch(key) {
case 'h':
if (HelpDisp == NULL) {
CreateHelpFile();
HelpDisp = OpenBrowseDisplay(HelpFile, "HELP", 2);
}
break;
case 'v': /* first unread article */
if (grp) {
n = NextNotInRange(grp->RList, 0);
if (n >= grp->MaxNo + 1)
n = grp->MaxNo;
grp->CurNo = n - 1;
redisp = 1;
key = 's';
continue;
}
break;
case 'M': /* next reference auto-rewind */
case 'm': /* next reference */
/*
* Find an article that references this one.
*/
if (grp->CurNo < grp->MaxNo)
RangeAdd(&grp->RList, grp->CurNo, grp->CurNo);
if (grp) {
char *ref;
short alloced = 0;
if (Mi || Mx == 0) {
ref = NewsMessageIdOf(grp, grp->CurNo);
} else {
short i;
char *tmp;
ref = NULL;
if (tmp = ReferenceLineOf(grp, grp->CurNo)) {
for (i = Mx; i > 0; --i) {
ref = NextRef(&tmp);
if (ref == NULL)
break;
}
}
if (ref) {
ref = strdup(ref);
alloced = 1;
}
}
if (ref) {
for (n = NextNotInRange(grp->RList, grp->CurNo); n < grp->MaxNo; n = NextNotInRange(grp->RList, n)) {
if (FindArticleReferencing(grp, ref, n))
break;
}
if (alloced)
free(ref);
if (n >= grp->MaxNo) { /* no more references */
if (Mi) { /* try refs to previous articles on the same line */
n = MStack[--Mi];
if (grp->CurNo != n) {
SetPrevNo(grp);
grp->CurNo = n;
redisp = 1;
}
continue; /* w/ same key */
}
++Mx; /* try References: fields of original */
continue; /* w/ same key */
}
if (Mi != MSTLEN)
MStack[Mi++] = n;
if (grp->CurNo != n) {
SetPrevNo(grp);
grp->CurNo = n;
redisp = 1;
}
} else {
Mx = 0;
Mi = 0;
if (key == 'M') {
key = 'v';
continue;
}
}
}
break;
case 'g':
if (grp) {
FILE *fi;
long artno = -1;
if (fi = fopen("CON:0/0/200/50/Article?", "w+")) {
fprintf(fi, ": ");
fflush(fi);
if (fgets(TmpBuf, sizeof(TmpBuf), fi))
artno = atoi(TmpBuf);
fclose(fi);
}
if (artno < 0)
artno = 0;
if (artno > grp->MaxNo)
artno = grp->MaxNo;
SetPrevNo(grp);
grp->CurNo = artno;
RangeDel(&grp->RList, artno, artno);
redisp = 1;
}
break;
case 'n': /* mark and go to next article */
case '.':
case '>':
if (grp->CurNo < grp->MaxNo)
RangeAdd(&grp->RList, grp->CurNo, grp->CurNo);
case 's': /* do not mark and go to next article */
SetPrevNo(grp);
grp->CurNo = NextNotInRange(grp->RList, grp->CurNo);
if (grp->CurNo >= grp->MaxNo + 1) {
grp->CurNo = grp->MaxNo;
redisp = 1;
} else {
/*
* skip past killed or non-existant articles, marking them as
* we go
*/
if (ArticleRefKilled(grp, grp->CurNo)) {
RangeAdd(&grp->RList, grp->CurNo, grp->CurNo);
key = 's';
continue;
}
redisp = 1;
}
break;
case '0': /* go to previous article and unmark */
case 'b':
case '<':
if (grp->PrevNo[0]) {
grp->CurNo = grp->PrevNo[0];
movmem(grp->PrevNo + 1, grp->PrevNo, sizeof(grp->PrevNo) - sizeof(grp->PrevNo[0]));
grp->PrevNo[arysize(grp->PrevNo)-1] = 0;
} else if (grp->CurNo > 1)
--grp->CurNo;
redisp = 1;
RangeDel(&grp->RList, grp->CurNo, grp->CurNo);
break;
case 'k': /* kill followups to this article and go to next article */
if (grp->CurNo < grp->MaxNo)
RangeAdd(&grp->RList, grp->CurNo, grp->CurNo);
if (grp) {
char *ref;
if (ref = NewsMessageIdOf(grp, grp->CurNo))
AddKillFile(ref, 0);
if (ref = ReferenceLineOf(grp, grp->CurNo))
AddKillFile(ref, 0);
}
key = 'n';
continue;
case 'K': /* kill followups for 30 days */
if (grp->CurNo < grp->MaxNo)
RangeAdd(&grp->RList, grp->CurNo, grp->CurNo);
if (grp) {
char *ref;
if (ref = NewsMessageIdOf(grp, grp->CurNo))
AddKillFile(ref, 30);
if (ref = ReferenceLineOf(grp, grp->CurNo))
AddKillFile(ref, 30);
}
key = 'n';
continue;
case 'U': /* unkill followups */
if (grp) {
char *ref;
if (ref = NewsMessageIdOf(grp, grp->CurNo))
RemKillFile(ref);
if (ref = ReferenceLineOf(grp, grp->CurNo))
RemKillFile(ref);
}
break;
case CTRL('g'): /* goto specific article and mark as unread */
break;
case '=': /* bring up subject scan window */
case '/': /* search in article */
case CTRL('/'): /* search in all remaining articles*/
case 'N': /* next newsgroup */
case 'B': /* previous newsgroup */
break;
case 'w': /* write article to file */
if (grp) {
char *fn;
if (fn = GetFileName(0)) {
FILE *fi = fopen(FileForArticle(grp, grp->CurNo), "r");
FILE *fo = fopen(fn, "w");
long n;
if (fi && fo) {
while ((n = fread(TmpBuf, 1, sizeof(TmpBuf), fi)) > 0)
fwrite(TmpBuf, 1, n, fo);
}
if (fi)
fclose(fi);
if (fo)
fclose(fo);
}
}
break;
case 'r': /* reply to sender */
case 'R': /* w/ text of current art */
if (grp)
ReplyArticle(key, grp);
break;
case 'f': /* followup to newsgroup */
case 'F': /* w/ text of current art */
if (grp)
FollowUpArticle(key, grp);
break;
case 'p': /* post article (asynch) */
PostArticle(grp); /* grp can be NULL! */
break;
default:
break;
}
break;
}
if (redisp && DataDisp && grp)
ChangeBrowseDisplay(DataDisp, FileForArticle(grp, grp->CurNo), TitleForArticle(grp));
}
static NGroup *
FindGroupByIndex(i)
{
NGroup *grp;
for (grp = GBase; ; grp = grp->Next) {
while (grp && grp->Enabled == 0)
grp = grp->Next;
if (grp == NULL)
break;
if (i == 0)
break;
--i;
}
return(grp);
}
char *
FileForArticle(grp, artno)
NGroup *grp;
{
static char buf[256];
sprintf(buf, "%s/%d", grp->Name, artno);
return(MakeConfigPath(UUNEWS, buf));
}
void
CreateHelpFile()
{
FILE *fi;
if (fi = fopen(HelpFile, "w")) {
fputs(
"use mouse buttons to select newsgroup\n"
"\n"
"h -help\n"
"v -first unread article (usually after m's)\n"
"m -mark article read and follow references, stop at end\n"
"M -mark article read and follow references, 'v' at end\n"
"n -mark article read and goto next\n"
"s -do not mark and goto next unread\n"
"b -return to last read article (history of 8)\n"
"k -kill refs to article (this session only)\n"
"K -kill refs to article for 30 days\n"
"U -unkill refs to article\n"
"w -write article to file\n"
"r -reply to sender of article\n"
"R -reply to sender, include article contents\n"
"f -followup to newsgroup\n"
"F -followup to newsgroup, include article contents\n"
"p -post a new article\n"
"4 -left half of article\n"
"6 -right half of article\n"
"8 -page up\n"
"2 -page down (SPACE also pages down)\n"
"3 -bottom of article\n"
"9 -top of article\n"
"\n", fi
);
fclose(fi);
}
}
char *
TitleForArticle(grp)
NGroup *grp;
{
char *fname = FileForArticle(grp, grp->CurNo);
char *ptr;
ptr = fname + strlen(fname);
while (ptr > fname && *ptr != '/')
--ptr;
--ptr;
while (ptr >= fname && *ptr != '/')
--ptr;
++ptr;
sprintf(TmpBuf, "%s (%d)", ptr, grp->MaxNo - 1);
return(TmpBuf);
}
void
SetPrevNo(grp)
NGroup *grp;
{
if (grp->PrevNo[0] != grp->CurNo) {
movmem(grp->PrevNo, grp->PrevNo + 1, sizeof(grp->PrevNo) - sizeof(grp->PrevNo[0]));
grp->PrevNo[0] = grp->CurNo;
}
}