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;
+