home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / network / grn1src.lha / builddir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-07  |  6.8 KB  |  211 lines

  1. #include "defs.h"
  2.  
  3. extern int Abort (void);                        /* IMPORT */
  4. extern int hierarchical;                        /* IMPORT */
  5. extern LIST groupList;                          /* IMPORT */
  6.  
  7. char *FileNameToNewsGroup (char *filename);     /* EXPORT */
  8. char *NewsGroupToFileName (char *newsgroup);    /* EXPORT */
  9. int BuildHierarchicalList (void);               /* EXPORT */
  10.  
  11. static struct FileInfoBlock uunews_fib;
  12. static BPTR                 uunews_lock;
  13.  
  14. static char *fp;               /* points to start of FullPath */
  15. static char *curpath;          /* points to end of FullPath */
  16.  
  17. static int group_count = 0;    /* How many groups did we find? */
  18. static int got_ctrl_c  = 0;    /* CTRL-C while building the list */
  19.  
  20. static int brk (void)
  21. {
  22.         return 0;
  23. }
  24.  
  25. static int RecurseAndBuild (struct FileInfoBlock *fib)
  26. {
  27.         /*
  28.             Watch the stack. If using DICE, compile with -gs.
  29.         */
  30.         char *p;               /* temporary to save curpath */
  31.         int got_result;        /* this is a valid entry */
  32.         int err;               /* save IoErr() while cleaning up */
  33.         BPTR dir_lock = NULL;  /* directory to examine */
  34.         struct FileInfoBlock *newfib = NULL;
  35.         GLIST *gp = NULL;      /* our working grouplist entry */
  36.         char *ptr;             /* points to 'fixed' groupname */
  37.  
  38.         /*
  39.             This is easier to do with the Unix routines, but LOTS slower.
  40.         */
  41.  
  42.         newfib = (struct FileInfoBlock *) AllocDosObject (DOS_FIB, NULL);
  43.         if (!newfib) {
  44.                 goto die;
  45.         }
  46.         memcpy (newfib, fib, sizeof (struct FileInfoBlock));
  47.  
  48.         if (fib != &uunews_fib)
  49.                 AddPart (fp, newfib->fib_FileName, 256);
  50.         else
  51.                 strcpy (fp, "UUNEWS:");
  52.         p = curpath;
  53.         curpath = fp + strlen (fp);
  54.  
  55.         dir_lock = Lock (fp, SHARED_LOCK);
  56.  
  57.         got_result = 0;
  58.         while (ExNext (dir_lock, newfib)) {
  59.                 if (CheckSignal (SIGBREAKF_CTRL_C)) {
  60.                         got_ctrl_c = 1;
  61.                         goto die;
  62.                 }
  63.                 switch (newfib->fib_DirEntryType) {
  64.                         case ST_ROOT:
  65.                                 /* why would I get this? */
  66.                                 break;
  67.                         case ST_USERDIR:
  68.                         case ST_LINKDIR:
  69.                                 if (strcmp (newfib->fib_FileName, "in.coming") == 0)
  70.                                         continue;
  71.                                 if (strcmp (newfib->fib_FileName, "out.going") == 0)
  72.                                         continue;
  73.                                 if (RecurseAndBuild (newfib)) {
  74.                                         goto die;
  75.                                 }
  76.                                 break;
  77.                         case ST_SOFTLINK:
  78.                                 break;
  79.                                 /* FIXME! If I get fixed here, Rnews doesn't  */
  80.                                 /* care, and we can have uunews: split across */
  81.                                 /* multiple partitions                        */
  82.                         case ST_FILE:
  83.                         case ST_LINKFILE:
  84.                                 /*
  85.                                     Theory: if it has a file, either numeric
  86.                                     or otherwise, it is a valid newsgroup.
  87.                                     If it doesn't have AT LEAST a .next file,
  88.                                     then it isn't. We have to show empty
  89.                                     newsgroups for subscription purposes.
  90.                                 */
  91.                                 got_result = 1;
  92.                                 break;
  93.                         default:
  94.                                 printf ("Got a Directory Entry of type %d, I don't know what to do with it. Ignoring\n", newfib->fib_DirEntryType);
  95.                                 break;
  96.                 } /* end of switch */
  97.         } /* end of while ExNext */
  98.  
  99.         err = IoErr ();
  100.         FreeDosObject (DOS_FIB, newfib);
  101.         newfib = NULL;
  102.         UnLock (dir_lock);
  103.         dir_lock = NULL;
  104.  
  105.         if (err && (err != ERROR_NO_MORE_ENTRIES)) {
  106.                 goto die;
  107.         }
  108.         /*
  109.             Process each individual newsgroup HERE!
  110.         */
  111.         if (got_result) {
  112.                 ptr = FileNameToNewsGroup (strchr (fp, ':') + 1);
  113.                 gp = AllocGLIST (ptr, ptr);
  114.                 AddTail (&groupList, (NODE *) gp);
  115.                 group_count++;
  116.         }
  117.  
  118.         curpath = p;
  119.         *curpath = '\0';
  120.  
  121.         return 0;
  122.  
  123. die:
  124.         if (newfib)
  125.                 FreeDosObject (DOS_FIB, NULL);
  126.         if (dir_lock)
  127.                 UnLock (dir_lock);
  128.  
  129.         return 1;
  130. }
  131.  
  132. int BuildHierarchicalList (void)
  133. {
  134.         int r;
  135.  
  136.         /*
  137.             BuildHierarchicalList does the setup work for building the
  138.             Hierarchical newsgroup list. It is the external interface.
  139.  
  140.             It returns the number of items as the result if successful.
  141.             On failure, it returns the negative of that number.
  142.  
  143.             We do locking, and cleanup, so the RecurseAndBuild doesn't have
  144.             to worry about it.
  145.  
  146.             We know that the normal CTRL-C handler is Abort(). So that
  147.             we can clean up properly, we replace it, and restore it when
  148.             we are done. This does mean that it may take TWO CTRL-C's to
  149.             get out of the program if it is done when the build is in
  150.             process, although I try to check for it (there is a possible
  151.             race condition).
  152.         */
  153.  
  154.         fp = malloc (256); /* the FullPath buffer */
  155.         curpath = fp;
  156.         group_count = 0;
  157.  
  158.         uunews_lock = Lock ("UUNEWS:", SHARED_LOCK);
  159.         onbreak (brk);
  160.         got_ctrl_c = 0;
  161.  
  162.         if (Examine (uunews_lock, &uunews_fib)) {
  163.                 r = RecurseAndBuild (&uunews_fib);
  164.         }
  165.         UnLock (uunews_lock);
  166.         free (fp);
  167.  
  168.         if (got_ctrl_c)
  169.                 Abort ();
  170.         onbreak (Abort);
  171.  
  172.         if (r)
  173.                 return -group_count;
  174.         else
  175.                 return group_count;
  176.         /* NOTREACHED */
  177. }
  178.  
  179. char *FileNameToNewsGroup (char *filename)
  180. {
  181.         static char newsgroup [512];
  182.         char *p;
  183.  
  184.         p = newsgroup;
  185.         memset (p, 0, 512);
  186.         strcpy (p, filename);
  187.         while (*p) {
  188.                 if (*p == '/')
  189.                         *p = '.';
  190.                 p++;
  191.         }
  192.         return newsgroup;
  193. }
  194.  
  195. char *NewsGroupToFileName (char *newsgroup)
  196. {
  197.         static char filename [512];
  198.         char *p;
  199.  
  200.         p = filename;
  201.         memset (p, 0, 512);
  202.         strcpy (p, newsgroup);
  203.         if (hierarchical)
  204.                 while (*p) {
  205.                         if (*p == '.')
  206.                                 *p = '/';
  207.                         p++;
  208.                 }
  209.         return filename;
  210. }
  211.