home *** CD-ROM | disk | FTP | other *** search
- #include "defs.h"
-
- extern int Abort (void); /* IMPORT */
- extern int hierarchical; /* IMPORT */
- extern LIST groupList; /* IMPORT */
-
- char *FileNameToNewsGroup (char *filename); /* EXPORT */
- char *NewsGroupToFileName (char *newsgroup); /* EXPORT */
- int BuildHierarchicalList (void); /* EXPORT */
-
- static struct FileInfoBlock uunews_fib;
- static BPTR uunews_lock;
-
- static char *fp; /* points to start of FullPath */
- static char *curpath; /* points to end of FullPath */
-
- static int group_count = 0; /* How many groups did we find? */
- static int got_ctrl_c = 0; /* CTRL-C while building the list */
-
- static int brk (void)
- {
- return 0;
- }
-
- static int RecurseAndBuild (struct FileInfoBlock *fib)
- {
- /*
- Watch the stack. If using DICE, compile with -gs.
- */
- char *p; /* temporary to save curpath */
- int got_result; /* this is a valid entry */
- int err; /* save IoErr() while cleaning up */
- BPTR dir_lock = NULL; /* directory to examine */
- struct FileInfoBlock *newfib = NULL;
- GLIST *gp = NULL; /* our working grouplist entry */
- char *ptr; /* points to 'fixed' groupname */
-
- /*
- This is easier to do with the Unix routines, but LOTS slower.
- */
-
- newfib = (struct FileInfoBlock *) AllocDosObject (DOS_FIB, NULL);
- if (!newfib) {
- goto die;
- }
- memcpy (newfib, fib, sizeof (struct FileInfoBlock));
-
- if (fib != &uunews_fib)
- AddPart (fp, newfib->fib_FileName, 256);
- else
- strcpy (fp, "UUNEWS:");
- p = curpath;
- curpath = fp + strlen (fp);
-
- dir_lock = Lock (fp, SHARED_LOCK);
-
- got_result = 0;
- while (ExNext (dir_lock, newfib)) {
- if (CheckSignal (SIGBREAKF_CTRL_C)) {
- got_ctrl_c = 1;
- goto die;
- }
- switch (newfib->fib_DirEntryType) {
- case ST_ROOT:
- /* why would I get this? */
- break;
- case ST_USERDIR:
- case ST_LINKDIR:
- if (strcmp (newfib->fib_FileName, "in.coming") == 0)
- continue;
- if (strcmp (newfib->fib_FileName, "out.going") == 0)
- continue;
- if (RecurseAndBuild (newfib)) {
- goto die;
- }
- break;
- case ST_SOFTLINK:
- break;
- /* FIXME! If I get fixed here, Rnews doesn't */
- /* care, and we can have uunews: split across */
- /* multiple partitions */
- case ST_FILE:
- case ST_LINKFILE:
- /*
- Theory: if it has a file, either numeric
- or otherwise, it is a valid newsgroup.
- If it doesn't have AT LEAST a .next file,
- then it isn't. We have to show empty
- newsgroups for subscription purposes.
- */
- got_result = 1;
- break;
- default:
- printf ("Got a Directory Entry of type %d, I don't know what to do with it. Ignoring\n", newfib->fib_DirEntryType);
- break;
- } /* end of switch */
- } /* end of while ExNext */
-
- err = IoErr ();
- FreeDosObject (DOS_FIB, newfib);
- newfib = NULL;
- UnLock (dir_lock);
- dir_lock = NULL;
-
- if (err && (err != ERROR_NO_MORE_ENTRIES)) {
- goto die;
- }
- /*
- Process each individual newsgroup HERE!
- */
- if (got_result) {
- ptr = FileNameToNewsGroup (strchr (fp, ':') + 1);
- gp = AllocGLIST (ptr, ptr);
- AddTail (&groupList, (NODE *) gp);
- group_count++;
- }
-
- curpath = p;
- *curpath = '\0';
-
- return 0;
-
- die:
- if (newfib)
- FreeDosObject (DOS_FIB, NULL);
- if (dir_lock)
- UnLock (dir_lock);
-
- return 1;
- }
-
- int BuildHierarchicalList (void)
- {
- int r;
-
- /*
- BuildHierarchicalList does the setup work for building the
- Hierarchical newsgroup list. It is the external interface.
-
- It returns the number of items as the result if successful.
- On failure, it returns the negative of that number.
-
- We do locking, and cleanup, so the RecurseAndBuild doesn't have
- to worry about it.
-
- We know that the normal CTRL-C handler is Abort(). So that
- we can clean up properly, we replace it, and restore it when
- we are done. This does mean that it may take TWO CTRL-C's to
- get out of the program if it is done when the build is in
- process, although I try to check for it (there is a possible
- race condition).
- */
-
- fp = malloc (256); /* the FullPath buffer */
- curpath = fp;
- group_count = 0;
-
- uunews_lock = Lock ("UUNEWS:", SHARED_LOCK);
- onbreak (brk);
- got_ctrl_c = 0;
-
- if (Examine (uunews_lock, &uunews_fib)) {
- r = RecurseAndBuild (&uunews_fib);
- }
- UnLock (uunews_lock);
- free (fp);
-
- if (got_ctrl_c)
- Abort ();
- onbreak (Abort);
-
- if (r)
- return -group_count;
- else
- return group_count;
- /* NOTREACHED */
- }
-
- char *FileNameToNewsGroup (char *filename)
- {
- static char newsgroup [512];
- char *p;
-
- p = newsgroup;
- memset (p, 0, 512);
- strcpy (p, filename);
- while (*p) {
- if (*p == '/')
- *p = '.';
- p++;
- }
- return newsgroup;
- }
-
- char *NewsGroupToFileName (char *newsgroup)
- {
- static char filename [512];
- char *p;
-
- p = filename;
- memset (p, 0, 512);
- strcpy (p, newsgroup);
- if (hierarchical)
- while (*p) {
- if (*p == '.')
- *p = '/';
- p++;
- }
- return filename;
- }
-