home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / network / grn1asrc.lha / builddir.c < prev    next >
C/C++ Source or Header  |  1992-05-20  |  5KB  |  223 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 FullPath [256];    /* The full pathname of the directory being scanned */
  15. static char *fp;           /* points to start of FullPath */
  16. static char *curpath;           /* points to end of FullPath */
  17.  
  18. static int group_count = 0;    /* How many groups did we find? */
  19. static int got_ctrl_c  = 0;    /* CTRL-C while building the list */
  20.  
  21. static int brk (void)
  22. {
  23.     return 0;
  24. }
  25.  
  26. static int RecurseAndBuild (struct FileInfoBlock *fib)
  27. {
  28.     /*
  29.         Watch the stack. If using DICE, compile with -gs.
  30.     */
  31.     char *p;           /* temporary to save curpath */
  32.     int got_result;        /* this is a valid entry */
  33.     int err;           /* save IoErr() while cleaning up */
  34.     BPTR dir_lock = NULL;  /* directory to examine */
  35.     struct FileInfoBlock *newfib = NULL;
  36.     GLIST *gp = NULL;      /* our working grouplist entry */
  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 (RecurseAndBuild (newfib)) {
  70.                     goto die;
  71.                 }
  72.                 break;
  73.             case ST_SOFTLINK:
  74.                 break;
  75.                 /* FIXME! If I get fixed here, Rnews doesn't  */
  76.                 /* care, and we can have uunews: split across */
  77.                 /* multiple partitions                  */
  78.             case ST_FILE:
  79.             case ST_LINKFILE:
  80.                 /*
  81.                     Theory: if it has a file, either numeric
  82.                     or otherwise, it is a valid newsgroup.
  83.                     If it doesn't have AT LEAST a .next file,
  84.                     then it isn't. We have to show empty
  85.                     newsgroups for subscription purposes.
  86.                 */
  87.                 got_result = 1;
  88.                 break;
  89.             default:
  90.                 printf ("Got a Directory Entry of type %d, I don't know what to do with it. Ignoring\n", newfib->fib_DirEntryType);
  91.                 break;
  92.         } /* end of switch */
  93.     } /* end of while ExNext */
  94.  
  95.     err = IoErr ();
  96.     FreeDosObject (DOS_FIB, newfib);
  97.     newfib = NULL;
  98.     UnLock (dir_lock);
  99.     dir_lock = NULL;
  100.  
  101.     if (err && (err != ERROR_NO_MORE_ENTRIES)) {
  102.         goto die;
  103.     }
  104.     /*
  105.         Process each individual newsgroup HERE!
  106.     */
  107.     if (got_result) {
  108.         gp = (GLIST *) malloc (sizeof (GLIST));
  109.         panic0 (gp, "Can't malloc GLIST %d bytes\n", sizeof (GLIST));
  110.         gp->node.ln_Name = &gp->header [0];
  111.         strcpy (gp->groupName, FileNameToNewsGroup (strchr (fp, ':') + 1));
  112.         /* we KNOW that UUNEWS: is in 'fp' above! */
  113.         strcpy (gp->header, gp->groupName);
  114.         AddTail (&groupList, (NODE *) gp);
  115.         group_count++;
  116.     }
  117. #ifdef TEST
  118.     printf ("%s\t\t\t", fp);
  119.     if (got_result == 0)
  120.         printf ("dir\n");
  121.     else
  122.         printf ("newsgroup\n");
  123. #endif
  124.  
  125.     curpath = p;
  126.     *curpath = '\0';
  127.  
  128.     return 0;
  129.  
  130. die:
  131.  
  132. #ifdef TEST
  133.     printf ("Cleaning up level %d\n", recurse_level - 1);
  134. #endif
  135.     if (newfib)
  136.         FreeDosObject (DOS_FIB, NULL);
  137.     if (dir_lock)
  138.         UnLock (dir_lock);
  139.  
  140.     return 1;
  141. }
  142.  
  143. int BuildHierarchicalList (void)
  144. {
  145.     int r;
  146.  
  147.     /*
  148.         BuildHierarchicalList does the setup work for building the
  149.         Hierarchical newsgroup list. It is the external interface.
  150.  
  151.         It returns the number of items as the result if successful.
  152.         On failure, it returns the negative of that number.
  153.  
  154.         We do locking, and cleanup, so the RecurseAndBuild doesn't have
  155.         to worry about it.
  156.  
  157.         We know that the normal CTRL-C handler is Abort(). So that
  158.         we can clean up properly, we replace it, and restore it when
  159.         we are done. This does mean that it may take TWO CTRL-C's to
  160.         get out of the program if it is done when the build is in
  161.         process, although I try to check for it (there is a possible
  162.         race condition).
  163.     */
  164.  
  165.     fp = FullPath;
  166.     curpath = fp;
  167.     group_count = 0;
  168.  
  169.     uunews_lock = Lock ("UUNEWS:", SHARED_LOCK);
  170.     onbreak (brk);
  171.     got_ctrl_c = 0;
  172.  
  173.     if (Examine (uunews_lock, &uunews_fib)) {
  174.         r = RecurseAndBuild (&uunews_fib);
  175.     }
  176.     UnLock (uunews_lock);
  177.  
  178.     if (got_ctrl_c)
  179.         Abort ();
  180.     onbreak (Abort);
  181.  
  182.     if (r)
  183.         return -group_count;
  184.     else
  185.         return group_count;
  186.     /* NOTREACHED */
  187. }
  188.  
  189. char *FileNameToNewsGroup (char *filename)
  190. {
  191.     static char newsgroup [512];
  192.     char *p;
  193.  
  194.     p = newsgroup;
  195.     memset (p, 0, 512);
  196.     strcpy (p, filename);
  197.     while (*p) {
  198.         if (*p == '/')
  199.             *p = '.';
  200.         p++;
  201.     }
  202.     /* printf ("FNTNG: '%s' --> '%s'\n", filename, newsgroup); */
  203.     return newsgroup;
  204. }
  205.  
  206. char *NewsGroupToFileName (char *newsgroup)
  207. {
  208.     static char filename [512];
  209.     char *p;
  210.  
  211.     p = filename;
  212.     memset (p, 0, 512);
  213.     strcpy (p, newsgroup);
  214.     if (hierarchical)
  215.         while (*p) {
  216.             if (*p == '.')
  217.                 *p = '/';
  218.             p++;
  219.         }
  220.     /* printf ("NGTFN: '%s' --> '%s'\n", newsgroup, filename); */
  221.     return filename;
  222. }
  223.