home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / stefanb_src / dospath / src / build.c next >
Encoding:
C/C++ Source or Header  |  1996-08-25  |  7.0 KB  |  255 lines

  1. /*
  2.  * build.c  V1.0
  3.  *
  4.  * Build a path lish
  5.  *
  6.  * (c) 1996 Stefan Becker
  7.  */
  8.  
  9. #include "dospath.h"
  10.  
  11. /* Build path list from string array  */
  12. static struct PathListEntry *BuildFromArray(const char **array,
  13.                                             struct PathListEntry **anchor,
  14.                                             struct DOSPathBase *dpb)
  15. {
  16.  struct PathListEntry *head = NULL; /* Head of new path list */
  17.  
  18.  DEBUGLOG(kprintf("Build: Array 0x%08lx Anchor 0x%08lx Base 0x%08lx\n",
  19.                   array, anchor, dpb);)
  20.  
  21.  /* Array valid? */
  22.  if (array) {
  23.   struct Library       *DOSBase = dpb->dpb_DOSBase;
  24.   struct FileInfoBlock *fib;
  25.  
  26.   /* Allocate FIB */
  27.   if (fib = AllocDosObject(DOS_FIB, NULL)) {
  28.    struct PathListEntry *current = anchor ? *anchor : NULL; /* Current entry */
  29.    struct PathListEntry *next    = NULL;                    /* Next entry    */
  30.    const char           *path;
  31.  
  32.    DEBUGLOG(kprintf("Build: FIB 0x%08lx\n", fib);)
  33.  
  34.    /* Scan array */
  35.    while (path = *array++) {
  36.  
  37.     DEBUGLOG(kprintf("Build: Next Path %s (0x%08lx)\n", path, path);)
  38.  
  39.     /* Allocate memory for next path list entry (only if not yet allocated!) */
  40.     /* Note: Please use AllocVec otherwise DOS gets mightely confused :-)    */
  41.     if ((next != NULL) ||
  42.         (next = AllocVec(sizeof(struct PathListEntry), MEMF_PUBLIC))) {
  43.  
  44.      DEBUGLOG(kprintf("Build: Entry 0x%08lx\n", next);)
  45.  
  46.      /* Lock next path */
  47.      if (next->ple_Lock = Lock(path, SHARED_LOCK)) {
  48.  
  49.       DEBUGLOG(kprintf("Build: Lock 0x%08lx\n", next->ple_Lock);)
  50.  
  51.       /* Is this a directory lock? */
  52.       if (Examine(next->ple_Lock, fib) && (fib->fib_DirEntryType > 0)) {
  53.  
  54.        /* Directory lock, clear pointer to next node */
  55.        next->ple_Next = NULL;
  56.  
  57.        /* Set head pointer */
  58.        if (head == NULL) head = next;
  59.  
  60.        /* Append new entry after current entry */
  61.        if (current) current->ple_Next = MKBADDR(next);
  62.  
  63.        /* Move current pointer */
  64.        current = next;
  65.  
  66.        /* Clear next pointer. A new entry must be allocated in the next round. */
  67.        next = NULL;
  68.  
  69.       } else
  70.  
  71.        /* This is no directory lock, release it */
  72.        UnLock(next->ple_Lock);
  73.      }
  74.  
  75.      /* Couldn't allocate memory for next path list entry */
  76.     } else {
  77.  
  78.      /* Free path list */
  79.      FreePathList(head, dpb);
  80.  
  81.      /* Clear head pointer */
  82.      head = NULL;
  83.  
  84.      /* If anchor was supplied remove new list from chain */
  85.      if (anchor && *anchor) (*anchor)->ple_Next = NULL;
  86.  
  87.      /* Leave loop */
  88.      break;
  89.     }
  90.    }
  91.  
  92.    /* Next path list entry already allocated? Free it! */
  93.    if (next) FreeVec(next);
  94.  
  95.    /* If anchor is valid and copy was successful then return end of list */
  96.    if (anchor && head) *anchor = current;
  97.  
  98.    /* Free FIB */
  99.    FreeDosObject(DOS_FIB, fib);
  100.   }
  101.  }
  102.  
  103.  DEBUGLOG(kprintf("Build: Head 0x%08lx Anchor 0x%08lx\n", head, anchor);)
  104.  
  105.  /* Return pointer to head of new path list */
  106.  return(head);
  107. }
  108.  
  109. /* Build path list from Exec list */
  110. static struct PathListEntry *BuildFromList(struct List *list,
  111.                                            struct PathListEntry **anchor,
  112.                                            struct DOSPathBase *dpb)
  113. {
  114.  struct PathListEntry *head = NULL; /* Head of new path list */
  115.  
  116.  DEBUGLOG(kprintf("Build: List 0x%08lx Anchor 0x%08lx Base 0x%08lx\n",
  117.                   list, anchor, dpb);)
  118.  
  119.  /* list valid? */
  120.  if (list) {
  121.   struct Library       *DOSBase = dpb->dpb_DOSBase;
  122.   struct FileInfoBlock *fib;
  123.  
  124.   /* Allocate FIB */
  125.   if (fib = AllocDosObject(DOS_FIB, NULL)) {
  126.    struct PathListEntry *current = anchor ? *anchor : NULL; /* Current entry */
  127.    struct PathListEntry *next    = NULL;                    /* Next entry    */
  128.    struct Node          *node;
  129.  
  130.    DEBUGLOG(kprintf("Build: FIB 0x%08lx\n", fib);)
  131.  
  132.    /* Scan Exec list */
  133.    for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ) {
  134.     const char *path;
  135.  
  136.     /* Name pointer valid? */
  137.     if (path = node->ln_Name) {
  138.  
  139.      DEBUGLOG(kprintf("Build: Next Path %s (0x%08lx)\n", path, path);)
  140.  
  141.      /* Allocate memory for next path list entry (only if not yet allocated!) */
  142.      /* Note: Please use AllocVec otherwise DOS gets mightely confused :-)    */
  143.      if ((next != NULL) ||
  144.          (next = AllocVec(sizeof(struct PathListEntry), MEMF_PUBLIC))) {
  145.  
  146.       DEBUGLOG(kprintf("Build: Entry 0x%08lx\n", next);)
  147.  
  148.       /* Lock next path */
  149.       if (next->ple_Lock = Lock(path, SHARED_LOCK)) {
  150.  
  151.        DEBUGLOG(kprintf("Build: Lock 0x%08lx\n", next->ple_Lock);)
  152.  
  153.        /* Is this a directory lock? */
  154.        if (Examine(next->ple_Lock, fib) && (fib->fib_DirEntryType > 0)) {
  155.  
  156.         /* Directory lock, clear pointer to next node */
  157.         next->ple_Next = NULL;
  158.  
  159.         /* Set head pointer */
  160.         if (head == NULL) head = next;
  161.  
  162.         /* Append new entry after current entry */
  163.         if (current) current->ple_Next = MKBADDR(next);
  164.  
  165.         /* Move current pointer */
  166.         current = next;
  167.  
  168.         /* Clear next pointer. A new entry must be allocated in the next round. */
  169.         next = NULL;
  170.  
  171.        } else
  172.  
  173.         /* This is no directory lock, release it */
  174.         UnLock(next->ple_Lock);
  175.       }
  176.  
  177.       /* Couldn't allocate memory for next path list entry */
  178.      } else {
  179.  
  180.       /* Free path list */
  181.       FreePathList(head, dpb);
  182.  
  183.       /* Clear head pointer */
  184.       head = NULL;
  185.  
  186.       /* If anchor was supplied remove new list from chain */
  187.       if (anchor && *anchor) (*anchor)->ple_Next = NULL;
  188.  
  189.       /* Leave loop */
  190.       break;
  191.      }
  192.     }
  193.    }
  194.  
  195.    /* Next path list entry already allocated? Free it! */
  196.    if (next) FreeVec(next);
  197.  
  198.    /* If anchor is valid and copy was successful then return end of list */
  199.    if (anchor && head) *anchor = current;
  200.  
  201.    /* Free FIB */
  202.    FreeDosObject(DOS_FIB, fib);
  203.   }
  204.  }
  205.  
  206.  DEBUGLOG(kprintf("Build: Head 0x%08lx Anchor 0x%08lx\n", head, anchor);)
  207.  
  208.  /* Return pointer to head of new path list */
  209.  return(head);
  210. }
  211.  
  212. /* Entry point */
  213. __geta4 struct PathListEntry *BuildPathListTagList(
  214.                                             __A0 struct PathListEntry **anchor,
  215.                                             __A1 struct TagItem *tags,
  216.                                             __A6 struct DOSPathBase *dpb)
  217. {
  218.  struct PathListEntry *head = NULL; /* Head of new path list */
  219.  
  220.  DEBUGLOG(kprintf("Build: Anchor 0x%08lx Tags 0x%08lx Base 0x%08lx\n",
  221.                   anchor, tags, dpb);)
  222.  
  223.  /* Tags valid? */
  224.  if (tags) {
  225.   struct Library *UtilityBase = dpb->dpb_UtilityBase;
  226.   struct TagItem *ti;
  227.   struct TagItem *tistate     = tags;
  228.  
  229.   /* Scan tag item list */
  230.   while (ti = NextTagItem(&tistate)) {
  231.    struct PathListEntry *new = NULL;
  232.  
  233.    /* Which tag? */
  234.    switch (ti->ti_Tag) {
  235.  
  236.     case DOSPath_BuildFromArray:
  237.      new = BuildFromArray((const char **) ti->ti_Data, anchor, dpb);
  238.      break;
  239.  
  240.     case DOSPath_BuildFromList:
  241.      new = BuildFromList((struct List *) ti->ti_Data, anchor, dpb);
  242.      break;
  243.    }
  244.  
  245.    /* Head pointer already set? */
  246.    if (head == NULL) head = new;
  247.   }
  248.  }
  249.  
  250.  DEBUGLOG(kprintf("Build: Head 0x%08lx Anchor 0x%08lx\n", head, anchor);)
  251.  
  252.  /* Return pointer to head of new path list */
  253.  return(head);
  254. }
  255.