#include <stdio.h>
#include <string.h>
#include <ctype.h>
#if VMS
#include <unixlib.h>
#include <stdlib.h>
#include <jpidef.h>
#include <descrip.h>
#include <uaidef.h>
#include <ssdef.h>
#include <starlet.h>
#include <lib$routines.h>
#define INIT_DSC_S(dsc, addr, len) do { \
(dsc).dsc$b_dtype = DSC$K_DTYPE_T; \
(dsc).dsc$b_class = DSC$K_CLASS_S; \
(dsc).dsc$w_length = (len); \
(dsc).dsc$a_pointer = (addr); \
} while (0)
#define INIT_DSC_CSTRING(dsc, s) INIT_DSC_S(dsc, s, strlen(s))
#endif
static int
copyto (char **to, char **from, char upto, int as_dir)
{
char *s;
s = strrchr (*from, '.');
while (**from)
{
if (**from == upto)
{
do
{
(*from)++;
}
while (**from == upto);
return 1;
}
if (**from == '.')
{
if ((as_dir == 1)
|| (*from != s))
**to = '_';
else
**to = '.';
}
else
{
#ifdef HAVE_CASE_INSENSITIVE_FS
if (isupper ((unsigned char)**from))
**to = tolower ((unsigned char)**from);
else
#endif
**to = **from;
}
(*to)++;
(*from)++;
}
return 0;
}
static char *
trnlog (char *name)
{
int stat;
static char reslt[1024];
$DESCRIPTOR (reslt_dsc, reslt);
short resltlen;
struct dsc$descriptor_s name_dsc;
char *s;
INIT_DSC_CSTRING (name_dsc, name);
stat = lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc);
if ((stat&1) == 0)
{
return "";
}
if (stat == SS$_NOTRAN)
{
return "";
}
reslt[resltlen] = '\0';
s = (char *)malloc (resltlen+1);
if (s == 0)
return "";
strcpy (s, reslt);
return s;
}
static char *
showall (char *s)
{
static char t[512];
char *pt;
pt = t;
if (strchr (s, '\\') == 0)
return s;
while (*s)
{
if (*s == '\\')
{
*pt++ = *s;
}
*pt++ = *s++;
}
return pt;
}
enum namestate { N_START, N_DEVICE, N_OPEN, N_DOT, N_CLOSED, N_DONE };
char *
vmsify (char *name, int type)
{
#define MAXPATHLEN 512
enum namestate nstate;
static char vmsname[MAXPATHLEN+1];
char *fptr;
char *vptr;
char *s,*s1;
int as_dir;
int count;
if (name == 0)
return 0;
fptr = name;
vptr = vmsname;
nstate = N_START;
s = strpbrk (name, "$:");
if (s != 0)
{
char *s1;
char *s2;
if (type == 1)
{
s1 = strchr (s+1, '[');
s2 = strchr (s+1, ']');
}
if (*s == '$')
{
if (strchr (name, '/') == 0)
{
if ((type == 1) && (s1 != 0) && (s2 == 0))
{
strcpy (vmsname, name);
strcat (vmsname, "]");
return vmsname;
}
else
return name;
}
}
else
{
if ((type == 1) && (s1 != 0) && (s2 == 0))
{
strcpy (vmsname, name);
strcat (vmsname, "]");
return vmsname;
}
else
return name;
}
}
s = strchr (name, '[');
if (s != 0)
{
s1 = strchr (s+1, '[');
if (s1 == 0)
{
if ((type == 1)
&& (strchr (s+1, ']') == 0))
{
strcpy (vmsname, name);
strcat (vmsname, "]");
return vmsname;
}
else
return name;
}
s1--;
if (*s1 != ']')
{
return name;
}
s = name;
do
{
strncpy (vptr, s, s1-s);
vptr += s1-s;
if (*s1 == 0)
break;
s = s1 + 1;
if (*s != '[')
break;
s++;
if (*s != '.')
*vptr++ = '.';
s1 = strchr (s, ']');
if (s1 == 0)
s1 = s + strlen (s);
}
while (1);
*vptr++ = ']';
fptr = s;
}
else
{
int state;
int rooted = 1;
state = 0;
do
{
switch (state)
{
case 0:
if (*fptr == '/')
{
fptr++;
state = 1;
}
else if (*fptr == '.')
{
fptr++;
state = 10;
}
else
state = 2;
break;
case 1:
if (*fptr == '/')
{
fptr++;
state = 3;
}
else
state = 4;
break;
case 2:
s = strchr (fptr, '/');
if (s == 0)
{
if (type == 1)
{
strcpy (vptr, "[.");
vptr += 2;
}
copyto (&vptr, &fptr, 0, (type==1));
if (type == 1)
*vptr++ = ']';
state = -1;
}
else
{
if ((type == 2)
&& (*(s+1) == 0))
{
copyto (&vptr, &fptr, '/', 1);
state = 7;
}
else
{
strcpy (vptr, "[.");
vptr += 2;
copyto (&vptr, &fptr, '/', 1);
nstate = N_OPEN;
state = 9;
}
}
break;
case 3:
while (*fptr == '/')
fptr++;
if (*fptr == 0)
{
char cwdbuf[MAXPATHLEN+1];
s1 = getcwd(cwdbuf, MAXPATHLEN);
if (s1 == 0)
{
return "";
}
s = strchr (s1, ':');
if (s == 0)
{
return "";
}
strncpy (vptr, s1, s-s1+1);
vptr += s-s1+1;
state = -1;
break;
}
s = vptr;
if (copyto (&vptr, &fptr, '/', 1) == 0)
{
*vptr++ = ':';
state = -1;
break;
}
*vptr = ':';
nstate = N_DEVICE;
if (*fptr == 0)
{
strcpy (vptr+1, "[000000]");
vptr += 9;
state = -1;
break;
}
*vptr = 0;
s1 = trnlog (s);
if (*s1 != 0)
{
char *s2;
for (;;)
{
s2 = s1 + strlen (s1) - 1;
if (*s2 == ':')
{
s2 = trnlog (s1);
free (s1);
if (*s2 == 0)
{
rooted = 0;
break;
}
s1 = s2;
continue;
}
if (*s2 == ']')
{
if (*(s2-1) == '.')
{
if (strncmp (fptr, "000000", 6) != 0)
rooted = 0;
}
else
{
strcpy (vmsname, s1);
s = strchr (vmsname, ']');
*s = '.';
nstate = N_DOT;
vptr = s;
}
}
break;
}
free (s1);
}
else
rooted = 0;
if (*vptr == 0)
{
nstate = N_DEVICE;
*vptr++ = ':';
}
else
vptr++;
if (rooted == 0)
{
strcpy (vptr, "[000000.");
vptr += 8;
s1 = vptr-1;
nstate = N_DOT;
}
else
s1 = 0;
s = strchr (fptr, '/');
if (s == 0)
{
if (*(vptr-1) == '.')
*(vptr-1) = ']';
else if (rooted == 0)
*vptr++ = ']';
copyto (&vptr, &fptr, 0, (type == 1));
state = -1;
break;
}
else
{
while (*(s+1) == '/')
s++;
}
if ((rooted != 0)
&& (*(vptr-1) != '.'))
{
*vptr++ = '[';
nstate = N_DOT;
}
else
if ((nstate == N_DOT)
&& (s1 != 0)
&& (*(s+1) == 0))
{
if (type == 2)
{
*s1 = ']';
nstate = N_CLOSED;
}
}
state = 9;
break;
case 4:
if (*fptr == 0)
state = 5;
else
state = 6;
break;
case 5:
if (type != 2)
{
*vptr++ = '[';
nstate = N_OPEN;
}
strcpy (vptr, "000000");
vptr += 6;
if (type == 2)
state = 7;
else
state = 8;
break;
case 6:
*vptr++ = '[';
nstate = N_OPEN;
s = strchr (fptr, '/');
if (s == 0)
{
if (type != 1)
{
strcpy (vptr, "000000]");
vptr += 7;
}
copyto (&vptr, &fptr, 0, (type == 1));
if (type == 1)
{
*vptr++ = ']';
}
state = -1;
}
else
{
if ( (type == 2)
&& (*(s+1) == 0))
{
strcpy (vptr, "000000]");
nstate = N_CLOSED;
vptr += 7;
}
copyto (&vptr, &fptr, '/', (*(vptr-1) != ']'));
state = 9;
}
break;
case 7:
if ((nstate == N_OPEN)
|| (nstate == N_DOT))
{
s = vptr-1;
while (s > vmsname)
{
if (*s == ']')
{
break;
}
if (*s == '.')
{
*s = ']';
break;
}
s--;
}
}
strcpy (vptr, ".dir");
vptr += 4;
state = -1;
break;
case 8:
*vptr++ = ']';
state = -1;
break;
case 9:
if (*fptr == 0)
{
if (type == 2)
{
state = 7;
}
else
state = 8;
break;
}
s = strchr (fptr, '/');
if (s == 0)
{
if (type != 1)
{
if (nstate == N_OPEN)
{
*vptr++ = ']';
nstate = N_CLOSED;
}
as_dir = 0;
}
else
{
if (nstate == N_OPEN)
{
*vptr++ = '.';
nstate = N_DOT;
}
as_dir = 1;
}
}
else
{
while (*(s+1) == '/')
s++;
if ( (type == 2)
&& (*(s+1) == 0))
{
if (nstate != N_CLOSED)
{
*vptr++ = ']';
nstate = N_CLOSED;
}
as_dir = 1;
}
else
{
if (nstate == N_OPEN)
{
*vptr++ = '.';
nstate = N_DOT;
}
as_dir = 1;
}
}
if ( (*fptr == '.')
&& (*(fptr+1) == '.')
&& ((*(fptr+2) == '/')
|| (*(fptr+2) == 0)) )
{
fptr += 2;
if (*fptr == '/')
{
do
{
fptr++;
}
while (*fptr == '/');
}
else if (*fptr == 0)
type = 1;
vptr--;
s1 = vptr;
for (;;)
{
s1--;
if (*s1 == '.')
{
vptr = s1;
nstate = N_OPEN;
break;
}
if (*s1 == '[')
{
if (*fptr == 0)
{
strcpy (s1, "[000000]");
vptr = s1 + 8;
nstate = N_CLOSED;
s = 0;
break;
}
else
{
vptr = s1+1;
nstate = N_OPEN;
break;
}
}
}
}
else
{
copyto (&vptr, &fptr, '/', as_dir);
if (nstate == N_DOT)
nstate = N_OPEN;
}
if (s == 0)
{
if (type == 1)
*vptr++ = ']';
state = -1;
}
else
{
if (*(s+1) == 0)
{
if (type == 2)
{
state = 7;
}
else
{
*vptr++ = ']';
state = -1;
}
}
}
break;
case 10:
if (*fptr == '.')
{
fptr++;
state = 11;
}
else
state = 12;
break;
case 11:
count = 1;
if (*fptr != 0)
{
if (*fptr != '/')
{
return name;
}
do
{
fptr++;
while (*fptr == '/') fptr++;
if (*fptr != '.')
break;
if (*(fptr+1) != '.')
break;
fptr += 2;
if ((*fptr == 0)
|| (*fptr == '/'))
count++;
}
while (*fptr == '/');
}
{
char cwdbuf[MAXPATHLEN+1];
s1 = getcwd(cwdbuf, MAXPATHLEN);
if (s1 == 0)
{
return "";
}
strcpy (vptr, s1);
s = strchr (vptr, ']');
if (s != 0)
{
nstate = N_OPEN;
while (s > vptr)
{
s--;
if (*s == '[')
{
s++;
strcpy (s, "000000]");
state = -1;
break;
}
else if (*s == '.')
{
if (--count == 0)
{
if (*fptr == 0)
{
*s++ = ']';
state = -1;
}
else
{
state = 9;
}
*s = 0;
break;
}
}
}
}
vptr += strlen (vptr);
}
break;
case 12:
if (*fptr != 0)
{
if (*fptr != '/')
{
return name;
}
while (*fptr == '/')
fptr++;
}
{
char cwdbuf[MAXPATHLEN+1];
s1 = getcwd(cwdbuf, MAXPATHLEN);
if (s1 == 0)
{
return "";
}
strcpy (vptr, s1);
if (*fptr == 0)
{
state = -1;
break;
}
else
{
s = strchr (vptr, ']');
if (s == 0)
{
state = -1;
break;
}
*s = 0;
nstate = N_OPEN;
vptr += strlen (vptr);
state = 9;
}
}
break;
}
}
while (state > 0);
}
*vptr++ = 0;
return vmsname;
}
char *
unixify (char *name)
{
static char piece[512];
char *s, *p;
if (strchr (name, '/') != 0)
return name;
p = piece;
*p = 0;
s = strchr (name, ':');
if (s != 0)
{
*s = 0;
*p++ = '/';
*p++ = '/';
strcpy (p, name);
p += strlen (p);
*s = ':';
}
*p++ = '/';
s = strchr (name, '[');
if (s != 0)
{
s++;
switch (*s)
{
case ']':
strcat (p, "./");
break;
case '-':
strcat (p, "../");
break;
case '.':
strcat (p, "./");
break;
default:
s--;
break;
}
s++;
while (*s)
{
if (*s == '.')
*p++ = '/';
else
*p++ = *s;
s++;
if (*s == ']')
{
s++;
break;
}
}
if (*s != 0)
{
if (*(p-1) != '/')
*p++ = '/';
strcpy (p, s);
}
}
else
{
*p++ = 0;
}
if (*(p-1) != '/')
*p++ = '/';
*p = 0;
return piece;
}