home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / comm / revrdist.sit / RevRdist / RevRdist src / path.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-06  |  7.1 KB  |  299 lines  |  [TEXT/KAHL]

  1. /*
  2.  * path.c - routines for manipulating Mac file paths
  3.  * and RevRdist file_info structures.
  4.  */
  5.  
  6. #include "RevRdist.h"
  7.  
  8. extern void lastpart (StringPtr);
  9.  
  10.  
  11.  
  12. /*
  13.  *=========================================================================
  14.  * freeInfo (fi) - zap contents of file_info structure
  15.  * entry:    fi = pointer to structure
  16.  *=========================================================================
  17.  */
  18.  
  19. void
  20. freeInfo (fi)
  21.     file_info_t *        fi;
  22. {
  23.     if (fi->f_path)
  24.         DisposHandle ((Handle) fi->f_path);
  25.     ZEROAT (fi);
  26. }
  27.  
  28.  
  29. /*
  30.  *=========================================================================
  31.  * fullpath (path, vRefNum, dirID) - construct absolute path
  32.  * entry:    path = input partial path
  33.  *            vRefNum = volume or working directory path is relative to
  34.  *            dirID = parent id of path
  35.  *                    can be 0 if path and vRefNum are from standard file
  36.  * returns:    path, edited in place
  37.  *                path is the empty string on error
  38.  *=========================================================================
  39.  */
  40. StringPtr
  41. fullpath (path, vRefNum, dirID)
  42.     StringPtr    path;
  43.     Integer        vRefNum;
  44.     Longint        dirID;
  45. {
  46.     OSErr        result;
  47.     Size        len;                /* string lengths */
  48.     int            offset;                /* offset of first in-use char in tname */
  49.      CInfoPBRec    ci;
  50.      Str255        dname;                /* path component name */
  51.      Str255        tname;                /* temp space */
  52. #define    dp        ci.dirInfo
  53.  
  54.     offset = sizeof(tname);
  55.     len = path[0];
  56.     if (len == 0)
  57.         return;
  58.     /*
  59.      * Find the folder containing the supplied file/folder
  60.      */
  61.     ZERO(ci);
  62.     ci.hFileInfo.ioNamePtr = path;
  63.     ci.hFileInfo.ioVRefNum = vRefNum;
  64.     ci.hFileInfo.ioDirID = dirID;
  65.     result = PBGetCatInfo(&ci, FALSE);
  66.  
  67.      dp.ioNamePtr = dname;
  68.     COPYPS (path, dname);
  69.     lastpart (dname);
  70.      path[0] = 0;
  71.     if (result == noErr)
  72.     {
  73.         if (ci.hFileInfo.ioFlAttrib & 0x10)
  74.             tname[--offset] = ':';        /* trailing colon on folder names */
  75.         for (;;)
  76.         {
  77.             /*
  78.              * Insert current component (in dname) into tname
  79.              */
  80.             len = dname[0];
  81.             offset -= len;
  82.             if (offset <= 0)
  83.                 return;
  84.             BlockMove (dname+1, tname+offset, len);
  85.             tname[--offset] = ':';
  86.             /*
  87.              * Look up its parent
  88.              */
  89.             if (dp.ioDrDirID == ROOTDIRID)
  90.                 break;
  91.             dp.ioDrDirID = dp.ioDrParID;
  92.              dp.ioDrParID = 0;
  93.              dp.ioFDirIndex = -1;
  94.             dname[0] = '\0';
  95.             if (result = PBGetCatInfo(&ci,0))
  96.                 return;
  97.         }
  98.         len = sizeof(tname) - offset;        /* includes length byte */
  99.         tname[offset] = len - 1;
  100.         BlockMove (&tname[offset], path, len);
  101.     }
  102.     return path;
  103. }
  104.  
  105.  
  106.  
  107.  
  108. /*
  109.  *=========================================================================
  110.  * getInfoByPath (path, fi) - fill in file_list structure from file path
  111.  * entry:    path = full or partial path name
  112.  *            fi = pointer to (possibly) partially filled in file_list struct
  113.  *            If fi->f_ref is set, then it and fi->f_info.ctype identify 
  114.  *                file/folder.
  115.  *            Otherwise, path and fi->f_vol identify it (these could be set
  116.  *                from Standard File).
  117.  * returns:    0 if no errors, all of fi now set
  118.  *            else OSErr, fi possibly modified
  119.  *=========================================================================
  120.  */
  121. OSErr
  122. getInfoByPath (path, fi)
  123.     StringPtr            path;
  124.     file_info_t *        fi;
  125. {
  126.     cnode_t *            cn;                /* points to f_info in fi */
  127.     ctype_t                ct;                /* are we working on a file or folder */
  128.     Longint                dirID;            /* file/folder directory id */
  129.     OSErr                error;
  130.     Integer                idx;            /* for indexing through folder */
  131.     Longint                parID;            /* parent ID */
  132.     StringHandle        sh;                /* temp ptr to full path name */
  133.     Integer                vol;            /* volume reference number */
  134.     CInfoPBRec            ci;
  135.     FCBPBRec            fcb;
  136.     HParamBlockRec        pb;
  137.     WDPBRec                wd;
  138.     Str255                s;
  139.  
  140.     cn = &fi->f_info;
  141.     COPYPS (path, s);
  142.     /*
  143.      * Collect enough information for a PBGetCatInfo call.
  144.      *
  145.      * If we have a reference number,
  146.      *    If it is for a folder, the reference is a working directory ref number,
  147.      *        use it to get the volume and directory id.
  148.      *    Otherwise, it is for a file.  Use PBGetFCBInfo to get file's volume,
  149.      *        parent ID, and file number.
  150.      * If we don't have a reference number, then path and (possibly zero) vol
  151.      *        have to suffice.  However, in this case, use PBHGetVInfo to get
  152.      *        volume.
  153.      */
  154.     if (fi->f_ref)
  155.     {
  156.         if ((ct = cn->ctype) == C_FOLDER)
  157.         {
  158.             ZERO (wd);
  159.             wd.ioVRefNum = fi->f_ref;
  160.             wd.ioWDIndex = 0;
  161.             if (error = PBGetWDInfo (&wd, false))
  162.                 return error;
  163.             vol = wd.ioWDVRefNum;
  164.             dirID = wd.ioWDDirID;
  165.             parID = 0;
  166.         }
  167.         else
  168.         {
  169.             ZERO (fcb);
  170.             fcb.ioRefNum = fi->f_ref;
  171.             fcb.ioFCBIndx = 0;
  172.             if (error = PBGetFCBInfo (&fcb, false))
  173.                 return error;
  174.             vol = fcb.ioFCBVRefNum;
  175.             dirID = fcb.ioFCBFlNm;
  176.             parID = fcb.ioFCBParID;
  177.         }
  178.     }
  179.     else
  180.     {
  181.         ZERO (ci);
  182.         COPYPS (path, s);
  183.         ci.hFileInfo.ioNamePtr = s;
  184.         ci.hFileInfo.ioVRefNum = fi->f_vol;
  185.         if (error = PBGetCatInfo (&ci, false))
  186.             return error;
  187.         ct = (ci.hFileInfo.ioFlAttrib & 0x10) ? C_FOLDER : C_FILE;
  188.         dirID = ci.hFileInfo.ioDirID;
  189.         parID = ci.hFileInfo.ioFlParID;
  190.         
  191.         vol = fi->f_vol;
  192.         ZERO (pb);
  193.         pb.volumeParam.ioNamePtr = s;
  194.         pb.volumeParam.ioVRefNum = vol;
  195.         pb.volumeParam.ioVolIndex = -1;
  196.         if (error = PBHGetVInfo (&pb, false))
  197.             return error;
  198.         vol = pb.volumeParam.ioVRefNum;
  199.     }
  200.     /*
  201.      * Finally, we have enough information to call PBGetCatInfo so that it
  202.      * will return the file/folder name with correct capitalization.
  203.      * For folders, a single call gets us what we want, but for files, we
  204.      * must step through the parent directory until we get back the file
  205.      * matching our dirID.
  206.      */
  207.     ZERO (ci);
  208.     ci.hFileInfo.ioNamePtr = s;
  209.     if (ct == C_FOLDER)
  210.     {
  211.         s[0] = 0;
  212.         ci.dirInfo.ioVRefNum = vol;
  213.         ci.dirInfo.ioDrDirID = dirID;
  214.         ci.dirInfo.ioFDirIndex = -1;
  215.         if (error = PBGetCatInfo (&ci, false))
  216.             return error;
  217.         parID = ci.dirInfo.ioDrParID;
  218.     }
  219.     else
  220.     {
  221.         for (idx = 1; ; idx++)
  222.         {
  223.             s[0] = 0;
  224.             ci.hFileInfo.ioVRefNum = vol;
  225.             ci.hFileInfo.ioFDirIndex = idx;
  226.             ci.hFileInfo.ioDirID = parID;
  227.             if (error = PBGetCatInfo (&ci, false))
  228.                 return error;
  229.             if (ci.hFileInfo.ioDirID == dirID)
  230.                 break;
  231.         }
  232.     }
  233.     /*
  234.      * Whew!  Finally have the info.  Fill in fi.
  235.      */
  236.     saveCatInfo (&ci, cn);
  237.     fi->f_vol = vol;
  238.     fi->f_set = true;
  239.     sh = fi->f_path;
  240.     if (sh)
  241.         DisposHandle ((Handle) sh);
  242.     sh = 0;
  243.     (void) fullpath (s, vol, parID);
  244.     sh = (StringHandle) NewHandle ((Size) s[0] + 1);
  245.     if (sh)
  246.         COPYPS (s, *sh);
  247.     else
  248.         error = MemError ();
  249.     fi->f_path = sh;
  250.     return error;
  251. }
  252.  
  253.  
  254.  
  255. /*
  256.  *=========================================================================
  257.  * lastpart(path) - given a path (absolute or partial), return its last
  258.  *                    component.
  259.  * entry:    path = path string to examine.
  260.  * returns:    path = last part of path
  261.  *=========================================================================
  262.  */
  263. void
  264. lastpart (path)
  265. register StringPtr    path;
  266. {
  267. register int        i, len;
  268.     int                nexttolast, last;    /* posns of colons in path */
  269.     
  270.     len = path[0];
  271.     /*
  272.      * Find the interesting colons
  273.      */
  274.     for (last = 0, i = 1; i <= len; i++)
  275.     {
  276.         if (path[i] == ':')
  277.         {
  278.             nexttolast = last;
  279.             last = i;
  280.         }
  281.     }
  282.     /*
  283.      * If there are no colons, it's already as short as can be.
  284.      */
  285.     if (last == 0)
  286.         return;
  287.     /*
  288.      * Ignore a final colon in deciding where to split
  289.      */
  290.     if (last == len)
  291.         last = nexttolast;
  292.     /*
  293.      * Return from last+1 to the end.
  294.      */
  295.     len -= last;
  296.     BlockMove (path+last+1, path+1, len);
  297.     path[0] = len;
  298.     return;
  299. }