home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / flistfrontend / src / flrnam.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-21  |  5.4 KB  |  199 lines

  1. #ifndef NO_IDENT
  2. static char *Id = "$Id: flrnam.c,v 1.10 1995/10/21 18:42:11 tom Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Title:    flrnam.c
  7.  * Author:    T.E.Dickey
  8.  * Created:    15 May 1984
  9.  * Last update:
  10.  *        18 Mar 1995, dircmd prototypes
  11.  *        19 Feb 1995, sys utils prototypes
  12.  *        09 Feb 1989, for vms5.0, may have to alter protection to rename
  13.  *        24 Aug 1985, use 'dds_add2' instead of 'dirdata_one'
  14.  *        31 Jul 1985, added log-file tracking
  15.  *        27 Jul 1985, provide wildcard-rename via 'dirseek_spec2' loop.
  16.  *        19 Jul 1985, use 'dirdata_ren'.
  17.  *        16 Jul 1985, corrected use of 'filelist' (=> filelink).
  18.  *        03 Jul 1985, cleanup 'filelist' definition.
  19.  *        09 Mar 1985, add code for special case of renamed-directory.
  20.  *        21 Dec 1984, use 'flist_sysmsg'.
  21.  *        10 Dec 1984, use 'dirent_chk' instead of 'dirent_one'.
  22.  *        06 Sep 1984, use "sysrename"
  23.  *        03 Sep 1984, use "import"
  24.  *        25 Aug 1984, cleanup buffer sizes
  25.  *        15 Jul 1984, use PATHOF()
  26.  *        14 Jul 1984, use $GETMSG
  27.  *        10 Jul 1984, re-coded to DCLARG-list
  28.  *        22 May 1984
  29.  *
  30.  * Function:    This module performs the RENAME function for "FLIST".  The
  31.  *        first argument may be a name outside the file-list.
  32.  *
  33.  * Notes:    If the "versions" option is selected, a rename may uncover
  34.  *        an older version of the same name.  When this is found, must
  35.  *        create a new 'filelist[]' entry at the end of the list.
  36.  *        Even more subtly, a rename may put the target file below
  37.  *        the version-level of an existing file, causing it to vanish.
  38.  *
  39.  *        If the old-file is a directory (e.g., having ".DIR" filetype),
  40.  *        we require that the new-file be also.  FLIST will not permit
  41.  *        the user to accidentally zap himself by renaming a directory
  42.  *        out of existence (or by making a file into a directory).
  43.  *
  44.  *        On the other hand, if the user renames a directory to
  45.  *        another directory, then we must update the display-list
  46.  *        to reflect the altered paths in dependent files.
  47.  *
  48.  * Patch:    Does VMS properly test for a user accidentally creating
  49.  *        a maximum tree higher than 8 levels, e.g., by renaming a
  50.  *        level-2 directory which has dependents down to level-8
  51.  *        into a level-8 directory?
  52.  */
  53.  
  54. #include    <rms.h>
  55. #include    <string.h>
  56.  
  57. #include    "flist.h"
  58. #include    "dirent.h"
  59. #include    "dircmd.h"
  60. #include    "dirdata.h"
  61. #include    "dirpath.h"
  62. #include    "dirseek.h"
  63. #include    "dds.h"
  64. #include    "getprot.h"
  65. #include    "chprot.h"
  66.  
  67. #include    "sysutils.h"
  68.  
  69. import(filelist);
  70. import(V_opt);
  71. import(conv_list);
  72.  
  73. static    void    flrnam_all (char *spec, int len, unsigned status);
  74.  
  75. static    int    curfile;
  76. static    char    *newspec;
  77.  
  78. /*
  79.  * Perform the actual rename.  For ease of use under vms5.0, check to see if we
  80.  * have delete-privilege for the file.  If not, try to set it.  Returns 0 iff
  81.  * no error occurred; otherwise the corresponding RMS status code.
  82.  */
  83. static
  84. doit(char *newspec, char *oldspec, GETPROT *prot_)
  85. {
  86.     unsigned status;
  87.     int    modified = FALSE;
  88. #define    DELETE_MASK     ((XAB$M_NODEL << XAB$V_SYS)\
  89.             | (XAB$M_NODEL << XAB$V_OWN)\
  90.             | (XAB$M_NODEL << XAB$V_GRP)\
  91.             | (XAB$M_NODEL << XAB$V_WLD))
  92.  
  93. #define    UNMASK(name,mask) if ((status = chprot(name, mask, 0)) == RMS$_NORMAL)\
  94.                 status = 0
  95.  
  96.     if (!cmpprot(prot_, "d")) {
  97.         UNMASK(oldspec, prot_->p_mask & ~DELETE_MASK);
  98.         if (status != 0)
  99.             return (status);
  100.         modified = TRUE;
  101.     }
  102.     if (!(status = sysrename(newspec, oldspec))) {
  103.         if (modified)
  104.             UNMASK(newspec, prot_->p_mask);
  105.     }
  106.     return (status);
  107. }
  108.  
  109. /*
  110.  * Initiate a search for files matching the old-specification.  Whenever we
  111.  * find one, call 'flrnam_all' to perform the actual RENAME-operation.
  112.  */
  113. tDIRCMD(flrnam)
  114. {
  115.     char    *oldspec = dclinx (xdcl_, 1, 0);
  116.  
  117.     curfile    = *curfile_;        /* save, in case we do refresh    */
  118.     newspec = dclinx (xdcl_, 2, 0);    /* save, for use in 'flrnam_all'*/
  119.     dirseek_spec2 (oldspec, flrnam_all);
  120. }
  121.  
  122. /*
  123.  * This procedure is called from 'dirseek_spec' after each file-spec is found.
  124.  */
  125. static
  126. void    flrnam_all (char *spec, int len, unsigned status)
  127. {
  128.     FILENT    ztmp,    *z = &ztmp, zold;
  129.     char    oldspec    [MAX_PATH],
  130.         tmpspec    [MAX_PATH],
  131.         fixspec    [MAX_PATH],
  132.         msg    [CRT_COLS];
  133.     int    inx,
  134.         wasdir;
  135.  
  136.     if (status != RMS$_NORMAL)    /* (file not found)    */
  137.         return;
  138.  
  139.     strncpy (oldspec, spec, len);
  140.     oldspec[len] = EOS;
  141.  
  142.     inx = dirent_old_any (z, oldspec, 1);
  143.  
  144.     if (!diropen (zPATHOF(z)))
  145.         return;
  146.  
  147.     wasdir    = dirent_isdir (z);
  148.     zold    = *z;            /* Save, in case this was a directory */
  149.  
  150.     strcpy (tmpspec, newspec);    /* "sysrename" alters output arg */
  151.  
  152.     flist_log ("! rename %s to %s", oldspec, tmpspec);
  153.     if ((status = doit(tmpspec, oldspec, &z->f_getprot)) == 0)
  154.     {
  155.         if (status = dirent_chk (z, tmpspec))
  156.         {
  157.         if (wasdir ^ dirent_isdir(z))
  158.         {
  159.             warn ("Illegal directory-rename");
  160.             (void)doit(strcpy(fixspec, oldspec), tmpspec, &z->f_getprot);
  161.             return;
  162.         }
  163.         if (wasdir)    dirpath_rename (z, &zold);
  164.         }
  165.         else
  166.         return;        /* ? (Probably a bug)        */
  167.  
  168.         dirdata_ren (z, &zold); /* rename the data-object    */
  169.  
  170.         if (inx < 0)    /* renamed new (?) entry into list    */
  171.         inx = dds_add (z);
  172.         else if (! (V_opt || wasdir))
  173.         {
  174.         if (dirhigh (oldspec)) /* Check for uncovering    */
  175.         {
  176.             /*
  177.              * There was a lower version of the 'oldspec' around.
  178.              * Check the new name against the resulting list, using
  179.              * DIRHIGH to allocate a new entry, if needed.
  180.              */
  181.             dirhigh (tmpspec);
  182.             inx = -1;
  183.         }
  184.         }
  185.  
  186.         if (inx >= 0)
  187.         {
  188.         dds_add2 (z, inx);
  189.         if (wasdir && strchr(conv_list, 'p'))
  190.             dds_all (crt_top(), curfile);
  191.         if (! V_opt)    dirhigh (tmpspec);
  192.         }
  193.     }
  194.     else
  195.     {
  196.         flist_sysmsg (status);
  197.     }
  198. }
  199.