home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d079 / monproc.lha / MonProc / getdir.c next >
Encoding:
C/C++ Source or Header  |  1987-06-04  |  6.0 KB  |  184 lines

  1. /*  GETDIR.C  - Does some simple lock and device-list manipulation
  2.  *
  3.  *  Copywrite (c) 1987 by Davide P. Cervone
  4.  *  This code may be used so long as this copywrite notice is left in tact.
  5.  */
  6.  
  7. #include "exec/types.h"
  8. #include "exec/memory.h"
  9. #include "libraries/dos.h"
  10. #include "libraries/dosextens.h"
  11.  
  12. #define BCPL(x,y)         ((struct x *)(BADDR(y)))
  13. #define BCPL_TO_CHAR(y)   ((char *)(BADDR(y)))
  14. #define FILELOCK(x)       BCPL(FileLock,x)
  15. #define DEVLIST(x)        BCPL(DeviceList,x)
  16.  
  17. #define FIBSIZE           ((ULONG)sizeof(struct FileInfoBlock))
  18. #define RETURN(dir)       return((*dir == '\0')? NULL: dir)
  19.  
  20.  
  21. /*
  22.  *  BSTRcopy()
  23.  *
  24.  *  Copies a BCPL string into a C string and returns the length of the
  25.  *  string.
  26.  */
  27.  
  28. BSTRcpy(to,BCPLfrom)
  29. char *to, *BCPLfrom;
  30. {
  31.    char *from = BCPL_TO_CHAR(BCPLfrom);
  32.  
  33.    strncpy(to,from+1,(int)(*from));
  34.    *(to+(*from)) = '\0';
  35.    return((int) *from);
  36. }
  37.  
  38.  
  39. /*
  40.  *  GetPathFromLock()
  41.  *
  42.  *  GetPathFromLock looks up the path name to the file or directory specified
  43.  *  by the lock.  The volume name is included in the returned string. 
  44.  *  If an error occurs, the function returns NULL, and the path name is set
  45.  *  to an empty string (a null byte).  The lock remains intact (it is not
  46.  *  UnLocked).
  47.  *
  48.  *      dir         a pointer to a string area where the path name
  49.  *                  will be stored.  No check is made to be sure that
  50.  *                  the path name fits.
  51.  *      lock        a lock on the file or directory whose path is to
  52.  *                  be found.
  53.  *
  54.  *  Note:  there seems to be a problem with the RAM: device (AmigaDOS v1.1).  
  55.  *  ParentDir() always returns NULL for a lock on the RAM-disk;  Therefore, 
  56.  *  GetPathFromLock() always returns "RAM:" for any lock on the RAM: device.
  57.  *
  58.  *  Note:  this function finds the complete path name to the locked object,
  59.  *  including the volume name.  ASSIGNed names will be translated to their
  60.  *  physical names.  For instance, if you CD to the C: directory, and
  61.  *  C: is ASSIGNed as SYS:C, and SYS: is ASSIGNed as your boot disk, and
  62.  *  your boot disk is named "WorkBench", then if you call GetPathFromLock()
  63.  *  with a lock in the C: directory, you will get back the string 
  64.  *  "WorkBench:c", not "C:".
  65.  */
  66.  
  67. char *GetPathFromLock(dir,lock)
  68. char *dir;
  69. struct FileLock *lock;
  70. {
  71.    struct FileLock *CurDir, *OldDir, *DupLock(), *ParentDir();
  72.    struct FileInfoBlock *fib, *AllocMem();
  73.    char *subdir = dir, *s, *s1, c;
  74.    int len;
  75.  
  76. /*
  77.  *  Clear the path name, and duplicate the lock (so we can UnLock our 
  78.  *  duplicate without destroying the user's lock).  If DupLock returned
  79.  *  NULL, then there was an error.  (An exclusive write lock, perhaps?)
  80.  */
  81.  
  82.    *dir = '\0';
  83.    CurDir = DupLock(lock);
  84.    if (CurDir == NULL) return(NULL);
  85.  
  86. /*
  87.  *  the FileInfoBlock must be longword alligned, so use AllocMem
  88.  */
  89.    fib = AllocMem(FIBSIZE,MEMF_CLEAR | MEMF_PUBLIC);
  90.    if (fib != NULL)
  91.    {
  92. /*
  93.  *  Get the device name from the volume entry in the device list
  94.  *  that is pointed to by the file lock.  Since the device list is
  95.  *  a shared list, use Forbid() and Permit() so it doesn't change while
  96.  *  we are looking at it.  Add a colon, and set the subdir pointer to
  97.  *  the character following the volume name.  Subdirectory names will be
  98.  *  added starting there.
  99.  */
  100.       Forbid();
  101.       subdir += BSTRcpy(dir,DEVLIST(FILELOCK(CurDir)->fl_Volume)->dl_Name);
  102.       Permit();
  103.       *subdir++ = ':';
  104.       *subdir   = '\0';
  105. /*
  106.  *  While we have a valid lock (ParentDir() will return a NULL pointer
  107.  *  when we reach the root of the disk), examine the directory (or file)
  108.  *  that we have locked.  If we can't examine it, give an error, otherwise
  109.  *  move up to the parent dir and unlock the old directory lock.  If we haven't
  110.  *  moved up past the root, then we want to add the directory name (found
  111.  *  in the FileInfoBlock structure returned by Examine()) to the path name.
  112.  *  To do so, we shift any existing sub-directory names to the right leaving
  113.  *  enough room for the new directory name (plus a slash, if needed).
  114.  *
  115.  *  Note:  the highest directory on a disk (the root), seems to have the same 
  116.  *  name as the disk itself (look at the ASSIGN list, for instance), so 
  117.  *  ParentDir() does not return NULL until we move past the root, that's why
  118.  *  the ParentDir() call comes before we add the directory name into the 
  119.  *  string.
  120.  *
  121.  *  For instance, if the current directory is "disk:a/b/c/d", and
  122.  *  the CurDir lock is on "d", then the calls to ParentDir() will
  123.  *  produce locks on "c", "b", "a", "disk", and then NULL.
  124.  */
  125.       while (CurDir != NULL)
  126.       {
  127.          if (!Examine(CurDir,fib))
  128.          {
  129.             *dir = '\0';
  130.             UnLock(CurDir);
  131.             CurDir = NULL;
  132.          } else {
  133.             OldDir = CurDir;
  134.             CurDir = ParentDir(OldDir);
  135.             UnLock(OldDir);
  136.  
  137.             if (CurDir != NULL)
  138.             {
  139.                len = strlen(fib->fib_FileName);
  140.                for (s=subdir+strlen(subdir), s1=s+len+1;
  141.                   s >= subdir; *s1-- = *s--);
  142.                c = *subdir;
  143.                strcpy(subdir,fib->fib_FileName);
  144.                *s1 = (c != '\0')? '/': c;
  145.             }
  146.          }
  147.       }
  148.       FreeMem(fib,FIBSIZE);
  149.    }
  150.    RETURN(dir);
  151. }
  152.  
  153.  
  154. /*
  155.  *  GetInfoVolume()
  156.  *
  157.  *  GetInfoVolume looks up the volume name from an InfoData structure and
  158.  *  returns a C string containing the name.
  159.  *
  160.  *      name        a pointer to a string area where the volume name
  161.  *                  will be stored.  No check is made to be sure that
  162.  *                  the name fits.
  163.  *      info        an InfoData structure that has been filed in by a call
  164.  *                  to Info().
  165.  *
  166.  */
  167.  
  168. void GetInfoVolume(name,info)
  169. char *name;
  170. struct InfoData *info;
  171. {
  172. /*
  173.  *  Get the device name from the volume entry in the device list
  174.  *  that is pointed to by the InfoData.  Since the device list is
  175.  *  a shared list, use Forbid() and Permit() so it doesn't change while
  176.  *  we are looking at it.  Add a colon for looks.
  177.  */
  178.    Forbid();
  179.    name += BSTRcpy(name,DEVLIST(info->id_VolumeNode)->dl_Name);
  180.    Permit();
  181.    *name++ = ':';
  182.    *name   = '\0';
  183. }
  184.