Ok,

Resubmitting for review.

I removed the setup_cmddsc, and the unneeded readdir stuff, so this patch is what is needed for getting the symbolic links to be encoded and decoded properly in VMS.C and for CWD in pathtools.

-John
[EMAIL PROTECTED]
Personal Opinion Only


--- /rsync_root/perl/lib/cwd.pm Sun Oct 19 05:26:56 2008
+++ lib/cwd.pm  Wed Oct 22 23:56:34 2008
@@ -647,23 +647,15 @@
     return $ENV{'DEFAULT'} unless @_;
     my $path = shift;
 
-    if (-l $path) {
-        my $link_target = readlink($path);
-        die "Can't resolve link $path: $!" unless defined $link_target;
-           
-        return _vms_abs_path($link_target);
-    }
-
-    if (defined &VMS::Filespec::vms_realpath) {
-        my $path = $_[0];
+    if (defined &VMS::Filespec::vmsrealpath) {
         if ($path =~ m#(?<=\^)/# ) {
             # Unix format
-            return VMS::Filespec::vms_realpath($path);
+            return VMS::Filespec::unixrealpath($path);
         }
 
        # VMS format
 
-       my $new_path = VMS::Filespec::vms_realname($path); 
+       my $new_path = VMS::Filespec::vmsrealpath($path);
 
        # Perl expects directories to be in directory format
        $new_path = VMS::Filespec::pathify($new_path) if -d $path;
@@ -673,6 +665,13 @@
     # Fallback to older algorithm if correct ones are not
     # available.
 
+    if (-l $path) {
+        my $link_target = readlink($path);
+        die "Can't resolve link $path: $!" unless defined $link_target;
+
+        return _vms_abs_path($link_target);
+    }
+
     # may need to turn foo.dir into [.foo]
     my $pathified = VMS::Filespec::pathify($path);
     $path = $pathified if defined $pathified;
--- /rsync_root/perl/ext/cwd/t/cwd.t    Tue Jan 22 22:17:18 2008
+++ ext/cwd/t/cwd.t     Wed Oct 22 23:32:36 2008
@@ -173,6 +173,15 @@
                                 $ENV{PERL_CORE} ? $Test_Dir : 
File::Spec->catdir('t', $Test_Dir)
                                                 )
                                   );
+    if ($^O eq 'VMS') {
+       # Not easy to predict the physical volume name
+       $want = $ENV{PERL_CORE} ? $Test_Dir : File::Spec->catdir('t', 
$Test_Dir);
+
+       # So just use the relative volume name
+       $want =~ s/^\[//;
+
+       $want = quotemeta($want);
+    }
 
     like($abs_path,      qr|$want$|i);
     like($fast_abs_path, qr|$want$|i);
--- /rsync_root/perl/vms/vms.c  Wed Oct 22 19:26:20 2008
+++ vms/vms.c   Wed Oct 29 22:04:08 2008
@@ -12990,14 +12990,41 @@
 /*
  * A thin wrapper around decc$symlink to make sure we follow the 
  * standard and do not create a symlink with a zero-length name.
+ *
+ * Also in ODS-2 mode, existing tests assume that the link target
+ * will be converted to UNIX format.
  */
-/*{{{ int my_symlink(const char *path1, const char *path2)*/
-int my_symlink(const char *path1, const char *path2) {
-  if (!path2 || !*path2) {
+/*{{{ int my_symlink(pTHX_ const char *contents, const char *link_name)*/
+int Perl_my_symlink(pTHX_ const char *contents, const char *link_name) {
+  if (!link_name || !*link_name) {
     SETERRNO(ENOENT, SS$_NOSUCHFILE);
     return -1;
   }
-  return symlink(path1, path2);
+
+  if (decc_efs_charset) {
+      return symlink(contents, link_name);
+  } else {
+      int sts;
+      char * utarget;
+
+      /* Unless we are in ODS-5 mode, convert the symlink target to UNIX */
+      /* because in order to work, the symlink target must be in UNIX format */
+
+      /* As symbolic links can hold things other than files, we will only do */
+      /* the conversion in in ODS-2 mode */
+
+      Newx(utarget, VMS_MAXRSS + 1, char);
+      if (do_tounixspec(contents, utarget, 0, NULL) == NULL) {
+
+          /* This should not fail, as an untranslatable filename */
+          /* should be passed through */
+          utarget = (char *)contents;
+      }
+      sts = symlink(utarget, link_name);
+      Safefree(utarget);
+      return sts;
+  }
+
 }
 /*}}}*/
 
@@ -13203,7 +13230,100 @@
                        if (haslower) __mystrtolower(rslt);
                    }
                }
-       }
++      } else {
++
++          /* Now for some hacks to deal with backwards and forward */
++          /* compatibilty */
++          if (!decc_efs_charset) {
++
++              /* 1. ODS-2 mode wants to do a syntax only translation */
++              rslt = do_rmsexpand(filespec, outbuf,
++                                  0, NULL, 0, NULL, utf8_fl);
++
++          } else {
++              if (decc_filename_unix_report) {
++                  char * dir_name;
++                  char * vms_dir_name;
++                  char * file_name;
++
++                  /* 2. ODS-5 / UNIX report mode should return a failure */
++                  /*    if the parent directory also does not exist */
++                  /*    Otherwise, get the real path for the parent */
++                  /*    and add the child to it.
++
++                  /* basename / dirname only available for VMS 7.0+ */
++                  /* So we may need to implement them as common routines */
++
++                  Newx(dir_name, VMS_MAXRSS + 1, char);
++                  Newx(vms_dir_name, VMS_MAXRSS + 1, char);
++                  dir_name[0] = '\0';
++                  file_name = NULL;
++
++                  /* First try a VMS parse */
++                  sts = vms_split_path
++                        (filespec,
++                         &v_spec,
++                         &v_len,
++                         &r_spec,
++                         &r_len,
++                         &d_spec,
++                         &d_len,
++                         &n_spec,
++                         &n_len,
++                         &e_spec,
++                         &e_len,
++                         &vs_spec,
++                         &vs_len);
++
++                  if (sts == 0) {
++                      /* This is VMS */
++
++                      int dir_len = v_len + r_len + d_len + n_len;
++                      if (dir_len > 0) {
++                         strncpy(dir_name, filespec, dir_len);
++                         dir_name[dir_len] = '\0';
++                         file_name = (char *)&filespec[dir_len + 1];
++                      }
++                  } else {
++                      /* This must be UNIX */
++                      char * tchar;
++
++                      tchar = strrchr(filespec, '/');
++
+                       if (tchar != NULL) {
+                           int dir_len = tchar - filespec;
+                           strncpy(dir_name, filespec, dir_len);
+                           dir_name[dir_len] = '\0';
+                           file_name = (char *) &filespec[dir_len + 1];
+                       }
+                   }
+
+                   /* Dir name is defaulted */
+                   if (dir_name[0] == 0) {
+                       dir_name[0] = '.';
+                       dir_name[1] = '\0';
+                   }
+
+                   /* Need realpath for the directory */
+                   sts = vms_fid_to_name(vms_dir_name,
+                                         VMS_MAXRSS + 1,
+                                         dir_name);
+
+                   if (sts == 0) {
+                       /* Now need to pathify it.
+                       char *tdir = do_pathify_dirspec(vms_dir_name,
+                                                       outbuf, utf8_fl);
+
+                       /* And now add the original filespec to it */
+                       if (file_name != NULL) {
+                           strcat(outbuf, file_name);
+                       }
+                       return outbuf;
+                   }
+                   Safefree(vms_dir_name);
+                   Safefree(dir_name);
+               }
+            }
 
         Safefree(vms_spec);
     }
--- /rsync_root/perl/vms/vmsish.h       Fri Jun 13 19:00:12 2008
+++ vms/vmsish.h        Sun Oct 26 23:10:22 2008
@@ -276,7 +276,7 @@
 #define my_endpwent()          Perl_my_endpwent(aTHX)
 #define my_getlogin            Perl_my_getlogin
 #ifdef HAS_SYMLINK
-#  define my_symlink           Perl_my_symlink
+#  define my_symlink(a, b)     Perl_my_symlink(aTHX_ a, b)
 #endif
 #define init_os_extras         Perl_init_os_extras
 #define vms_realpath(a, b, c)  Perl_vms_realpath(aTHX_ a,b,c)
@@ -970,7 +970,7 @@
 int     my_fclose (FILE *);
 int     my_fwrite (const void *, size_t, size_t, FILE *);
 #ifdef HAS_SYMLINK
-int     my_symlink(const char *path1, const char *path2);
+int     Perl_my_symlink(pTHX_ const char *path1, const char *path2);
 #endif
 int    Perl_my_flush (pTHX_ FILE *);
 struct passwd *        Perl_my_getpwnam (pTHX_ const char *name);

Reply via email to