[patch] Lib/File/Path.t (post 5.8.9) catdir used instead of catfile

2008-12-06 Thread John E. Malmberg
In the test to see what happens if you try to create a file with the 
same name as a directory, catdir is used to create the file 
specification instead of catfile.


The operation is expected to fail usually.

However on VMS, directories and files can appear to have the same name, 
especially when VMS is reporting filenames in Unix syntax.


So this test should be skipped on VMS.

-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /rsync_root/perl/lib/File/Path.tThu Dec  4 15:49:40 2008
+++ lib/File/Path.t Sat Dec  6 03:40:52 2008
@@ -341,7 +341,9 @@
 
 # see what happens if a file exists where we want a directory
 SKIP: {
-my $entry = catdir($tmp_base, file);
+my $entry = catfile($tmp_base, file);
+skip VMS can have a file and a directory with the same name., 4
+if $Is_VMS;
 skip Cannot create $entry, 4 unless open OUT,  $entry;
 print OUT test file, safe to delete\n, scalar(localtime), \n;
 close OUT;


[patch@35050] replace pathify_dirspec in VMS with new version

2008-12-06 Thread John E. Malmberg
The mp_do_pathify_dirspec needed enhancements to more accurately parse 
VMS file specifications, and also to handle UNIX file specifications the 
same way that mp_do_tovmspath() does.


It was simpler to replace than to try to modify the existing routine.

In addition this is the start of fixing issues where routines can be 
called with a null thread context, by removing the thread context where 
it is not needed.


More patches will be following this.

-John
[EMAIL PROTECTED]
Personal Opinion Only
--- /rsync_root/perl/vms/vms.c  Fri Dec  5 12:13:19 2008
+++ vms/vms.c   Sat Dec  6 03:31:43 2008
@@ -362,6 +362,40 @@
 int decc_dir_barename = 0;
 
 static int vms_debug_on_exception = 0;
+static int vms_debug_fileify = 0;
+
+
+/* Simple logical name translation */
+static int simple_trnlnm
+   (const char * logname,
+char * value,
+int value_len)
+{
+const $DESCRIPTOR(table_dsc, LNM$FILE_DEV);
+const unsigned long attr = LNM$M_CASE_BLIND;
+struct dsc$descriptor_s name_dsc;
+int status;
+unsigned short result;
+struct itmlst_3 itlst[2] = {{value_len, LNM$_STRING, value, result},
+{0, 0, 0, 0}};
+
+name_dsc.dsc$w_length = strlen(logname);
+name_dsc.dsc$a_pointer = (char *)logname;
+name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+name_dsc.dsc$b_class = DSC$K_CLASS_S;
+
+status = sys$trnlnm(attr, table_dsc, name_dsc, 0, itlst);
+
+if ($VMS_STATUS_SUCCESS(status)) {
+
+/* Null terminate and return the string */
+   /*--*/
+   value[result] = 0;
+return result;
+}
+
+return 0;
+}
 
 /* Is this a UNIX file specification?
  *   No longer a simple check with EFS file specs
@@ -888,6 +922,27 @@
 }
 
 
+/* Routine to determine if the file specification ends with .dir */
+static int is_dir_ext(char * e_spec, int e_len, char * vs_spec, int vs_len) {
+
+/* e_len must be 4, and version must be = 2 characters */
+if (e_len != 4 || vs_len  2)
+return 0;
+
+/* If a version number is present, it needs to be one */
+if ((vs_len == 2)  (vs_spec[1] != '1'))
+return 0;
+
+/* Look for the DIR on the extension */
+if ((toupper(e_spec[1]) == 'D') 
+(toupper(e_spec[2]) == 'I') 
+(toupper(e_spec[3]) == 'R')) {
+return 1;
+}
+return 0;
+}
+
+
 /* my_maxidx
  * Routine to retrieve the maximum equivalence index for an input
  * logical name.  Some calls to this routine have no knowledge if
@@ -6236,280 +6291,434 @@
 char *Perl_fileify_dirspec_utf8_ts(pTHX_ const char *dir, char *buf, int * 
utf8_fl)
 { return do_fileify_dirspec(dir,buf,1,utf8_fl); }
 
-/*{{{ char *pathify_dirspec[_ts](char *path, char *buf)*/
-static char *mp_do_pathify_dirspec(pTHX_ const char *dir,char *buf, int ts, 
int * utf8_fl)
-{
-static char __pathify_retbuf[VMS_MAXRSS];
-unsigned long int retlen;
-char *retpath, *cp1, *cp2, *trndir;
+static char * int_pathify_dirspec_simple(const char * dir, char * buf,
+char * v_spec, int v_len, char * r_spec, int r_len,
+char * d_spec, int d_len, char * n_spec, int n_len,
+char * e_spec, int e_len, char * vs_spec, int vs_len) {
+
+/* VMS specification - Try to do this the simple way */
+if ((v_len + r_len + d_len)  0) {
+int is_dir;
+
+/* No name or extension component, already a directory */
+if ((n_len + e_len + vs_len) == 0) {
+strcpy(buf, dir);
+return buf;
+}
+
+/* Special case, we may get [.foo]bar instead of [.foo]bar.dir */
+/* This results from catfile() being used instead of catdir() */
+/* So even though it should not work, we need to allow it */
+
+/* If this is .DIR;1 then do a simple conversion */
+is_dir = is_dir_ext(e_spec, e_len, vs_spec, vs_len);
+if (is_dir || (e_len == 0)) {
+ int len;
+ len = v_len + r_len + d_len - 1;
+ char dclose = d_spec[d_len - 1];
+ strncpy(buf, dir, len);
+ buf[len] = '.';
+ len++;
+ strncpy(buf[len], n_spec, n_len);
+ len += n_len;
+ buf[len] = dclose;
+ buf[len + 1] = '\0';
+ return buf;
+}
+
+#ifdef HAS_SYMLINK
+else {
+/* In the olden days, a directory needed to have a .DIR */
+/* extension to be a valid directory, but now it could  */
+/* be a symbolic link */
+int len;
+len = v_len + r_len + d_len - 1;
+char dclose = d_spec[d_len - 1];
+strncpy(buf, dir, len);
+buf[len] = '.';
+len++;
+strncpy(buf[len], n_spec, n_len);
+len += n_len;
+if (e_len  0) {
+if (decc_efs_charset) {
+buf[len] = '^';
+len++;
+strncpy(buf[len], e_spec, e_len);
+len += e_len;
+