xref: /netbsd-src/external/gpl2/gmake/dist/vmsify.c (revision 69606e3f5c9388e52aed8c120ad63c049ca45d8f)
1*69606e3fSchristos /* vmsify.c -- Module for vms <-> unix file name conversion
2*69606e3fSchristos Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3*69606e3fSchristos 2006 Free Software Foundation, Inc.
4*69606e3fSchristos This file is part of GNU Make.
5*69606e3fSchristos 
6*69606e3fSchristos GNU Make is free software; you can redistribute it and/or modify it under the
7*69606e3fSchristos terms of the GNU General Public License as published by the Free Software
8*69606e3fSchristos Foundation; either version 2, or (at your option) any later version.
9*69606e3fSchristos 
10*69606e3fSchristos GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11*69606e3fSchristos WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12*69606e3fSchristos A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13*69606e3fSchristos 
14*69606e3fSchristos You should have received a copy of the GNU General Public License along with
15*69606e3fSchristos GNU Make; see the file COPYING.  If not, write to the Free Software
16*69606e3fSchristos Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
17*69606e3fSchristos 
18*69606e3fSchristos /* Written by Klaus K�mpf (kkaempf@progis.de)
19*69606e3fSchristos    of proGIS Software, Aachen, Germany */
20*69606e3fSchristos 
21*69606e3fSchristos 
22*69606e3fSchristos #include <stdio.h>
23*69606e3fSchristos #include <string.h>
24*69606e3fSchristos #include <ctype.h>
25*69606e3fSchristos 
26*69606e3fSchristos #if VMS
27*69606e3fSchristos #include <unixlib.h>
28*69606e3fSchristos #include <stdlib.h>
29*69606e3fSchristos #include <jpidef.h>
30*69606e3fSchristos #include <descrip.h>
31*69606e3fSchristos #include <uaidef.h>
32*69606e3fSchristos #include <ssdef.h>
33*69606e3fSchristos #include <starlet.h>
34*69606e3fSchristos #include <lib$routines.h>
35*69606e3fSchristos /* Initialize a string descriptor (struct dsc$descriptor_s) for an
36*69606e3fSchristos    arbitrary string.   ADDR is a pointer to the first character
37*69606e3fSchristos    of the string, and LEN is the length of the string. */
38*69606e3fSchristos 
39*69606e3fSchristos #define INIT_DSC_S(dsc, addr, len) do { \
40*69606e3fSchristos   (dsc).dsc$b_dtype = DSC$K_DTYPE_T;    \
41*69606e3fSchristos   (dsc).dsc$b_class = DSC$K_CLASS_S;    \
42*69606e3fSchristos   (dsc).dsc$w_length = (len);           \
43*69606e3fSchristos   (dsc).dsc$a_pointer = (addr);         \
44*69606e3fSchristos } while (0)
45*69606e3fSchristos 
46*69606e3fSchristos /* Initialize a string descriptor (struct dsc$descriptor_s) for a
47*69606e3fSchristos    NUL-terminated string.  S is a pointer to the string; the length
48*69606e3fSchristos    is determined by calling strlen(). */
49*69606e3fSchristos 
50*69606e3fSchristos #define INIT_DSC_CSTRING(dsc, s) INIT_DSC_S(dsc, s, strlen(s))
51*69606e3fSchristos #endif
52*69606e3fSchristos 
53*69606e3fSchristos /*
54*69606e3fSchristos   copy 'from' to 'to' up to but not including 'upto'
55*69606e3fSchristos   return 0 if eos on from
56*69606e3fSchristos   return 1 if upto found
57*69606e3fSchristos 
58*69606e3fSchristos   return 'to' at last char + 1
59*69606e3fSchristos   return 'from' at match + 1 or eos if no match
60*69606e3fSchristos 
61*69606e3fSchristos   if as_dir == 1, change all '.' to '_'
62*69606e3fSchristos   else change all '.' but the last to '_'
63*69606e3fSchristos */
64*69606e3fSchristos 
65*69606e3fSchristos static int
copyto(char ** to,char ** from,char upto,int as_dir)66*69606e3fSchristos copyto (char **to, char **from, char upto, int as_dir)
67*69606e3fSchristos {
68*69606e3fSchristos   char *s;
69*69606e3fSchristos 
70*69606e3fSchristos   s = strrchr (*from, '.');
71*69606e3fSchristos 
72*69606e3fSchristos   while (**from)
73*69606e3fSchristos     {
74*69606e3fSchristos       if (**from == upto)
75*69606e3fSchristos 	{
76*69606e3fSchristos 	  do
77*69606e3fSchristos 	    {
78*69606e3fSchristos 	      (*from)++;
79*69606e3fSchristos 	    }
80*69606e3fSchristos 	  while (**from == upto);
81*69606e3fSchristos 	  return 1;
82*69606e3fSchristos 	}
83*69606e3fSchristos       if (**from == '.')
84*69606e3fSchristos 	{
85*69606e3fSchristos 	  if ((as_dir == 1)
86*69606e3fSchristos 	      || (*from != s))
87*69606e3fSchristos 	    **to = '_';
88*69606e3fSchristos 	  else
89*69606e3fSchristos 	    **to = '.';
90*69606e3fSchristos 	}
91*69606e3fSchristos       else
92*69606e3fSchristos 	{
93*69606e3fSchristos #ifdef HAVE_CASE_INSENSITIVE_FS
94*69606e3fSchristos 	  if (isupper ((unsigned char)**from))
95*69606e3fSchristos 	    **to = tolower ((unsigned char)**from);
96*69606e3fSchristos 	  else
97*69606e3fSchristos #endif
98*69606e3fSchristos 	    **to = **from;
99*69606e3fSchristos 	}
100*69606e3fSchristos       (*to)++;
101*69606e3fSchristos       (*from)++;
102*69606e3fSchristos     }
103*69606e3fSchristos 
104*69606e3fSchristos   return 0;
105*69606e3fSchristos }
106*69606e3fSchristos 
107*69606e3fSchristos 
108*69606e3fSchristos /*
109*69606e3fSchristos   get translation of logical name
110*69606e3fSchristos 
111*69606e3fSchristos */
112*69606e3fSchristos 
113*69606e3fSchristos static char *
trnlog(char * name)114*69606e3fSchristos trnlog (char *name)
115*69606e3fSchristos {
116*69606e3fSchristos   int stat;
117*69606e3fSchristos   static char reslt[1024];
118*69606e3fSchristos   $DESCRIPTOR (reslt_dsc, reslt);
119*69606e3fSchristos   short resltlen;
120*69606e3fSchristos   struct dsc$descriptor_s name_dsc;
121*69606e3fSchristos   char *s;
122*69606e3fSchristos 
123*69606e3fSchristos   INIT_DSC_CSTRING (name_dsc, name);
124*69606e3fSchristos 
125*69606e3fSchristos   stat = lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc);
126*69606e3fSchristos 
127*69606e3fSchristos   if ((stat&1) == 0)
128*69606e3fSchristos     {
129*69606e3fSchristos       return "";
130*69606e3fSchristos     }
131*69606e3fSchristos   if (stat == SS$_NOTRAN)
132*69606e3fSchristos     {
133*69606e3fSchristos       return "";
134*69606e3fSchristos     }
135*69606e3fSchristos   reslt[resltlen] = '\0';
136*69606e3fSchristos 
137*69606e3fSchristos   s = (char *)malloc (resltlen+1);
138*69606e3fSchristos   if (s == 0)
139*69606e3fSchristos     return "";
140*69606e3fSchristos   strcpy (s, reslt);
141*69606e3fSchristos   return s;
142*69606e3fSchristos }
143*69606e3fSchristos 
144*69606e3fSchristos static char *
showall(char * s)145*69606e3fSchristos showall (char *s)
146*69606e3fSchristos {
147*69606e3fSchristos   static char t[512];
148*69606e3fSchristos   char *pt;
149*69606e3fSchristos 
150*69606e3fSchristos   pt = t;
151*69606e3fSchristos   if (strchr (s, '\\') == 0)
152*69606e3fSchristos     return s;
153*69606e3fSchristos   while (*s)
154*69606e3fSchristos     {
155*69606e3fSchristos       if (*s == '\\')
156*69606e3fSchristos 	{
157*69606e3fSchristos 	  *pt++ = *s;
158*69606e3fSchristos 	}
159*69606e3fSchristos       *pt++ = *s++;
160*69606e3fSchristos     }
161*69606e3fSchristos   return pt;
162*69606e3fSchristos }
163*69606e3fSchristos 
164*69606e3fSchristos 
165*69606e3fSchristos enum namestate { N_START, N_DEVICE, N_OPEN, N_DOT, N_CLOSED, N_DONE };
166*69606e3fSchristos 
167*69606e3fSchristos /*
168*69606e3fSchristos   convert unix style name to vms style
169*69606e3fSchristos   type = 0 -> name is a full name (directory and filename part)
170*69606e3fSchristos   type = 1 -> name is a directory
171*69606e3fSchristos   type = 2 -> name is a filename without directory
172*69606e3fSchristos 
173*69606e3fSchristos   The following conversions are applied
174*69606e3fSchristos 			(0)		(1)			(2)
175*69606e3fSchristos 	input		full name	dir name		file name
176*69606e3fSchristos 
177*69606e3fSchristos 1	./		<cwd>		[]			<current directory>.dir
178*69606e3fSchristos 2	../		<home of cwd>	<home of cwd>		<home of cwd>.dir
179*69606e3fSchristos 
180*69606e3fSchristos 3	//		<dev of cwd>:	<dev of cwd>:[000000]	<dev of cwd>:000000.dir
181*69606e3fSchristos 4	//a		a:		a:			a:
182*69606e3fSchristos 5	//a/		a:		a:			a:000000.dir
183*69606e3fSchristos 
184*69606e3fSchristos 9	/		[000000]	[000000]		000000.dir
185*69606e3fSchristos 10	/a		[000000]a	[a]			[000000]a
186*69606e3fSchristos 11	/a/		[a]		[a]			[000000]a.dir
187*69606e3fSchristos 12	/a/b		[a]b		[a.b]			[a]b
188*69606e3fSchristos 13	/a/b/		[a.b]		[a.b]			[a]b.dir
189*69606e3fSchristos 14	/a/b/c		[a.b]c		[a.b.c]			[a.b]c
190*69606e3fSchristos 15	/a/b/c/		[a.b.c]		[a.b.c]			[a.b]c.dir
191*69606e3fSchristos 
192*69606e3fSchristos 16	a		a		[.a]			a
193*69606e3fSchristos 17	a/		[.a]		[.a]			a.dir
194*69606e3fSchristos 18	a/b		[.a]b		[.a.b]			[.a]b
195*69606e3fSchristos 19	a/b/		[.a.b]		[.a.b]			[.a]b.dir
196*69606e3fSchristos 20	a/b/c		[.a.b]c		[.a.b.c]		[.a.b]c
197*69606e3fSchristos 21	a/b/c/		[.a.b.c]	[.a.b.c]		[.a.b]c.dir
198*69606e3fSchristos 
199*69606e3fSchristos 22	a.b.c		a_b.c		[.a_b_c]		a_b_c.dir
200*69606e3fSchristos 
201*69606e3fSchristos 23	[x][y]z		[x.y]z		[x.y]z			[x.y]z
202*69606e3fSchristos 24	[x][.y]z	[x.y]z		[x.y]z			[x.y]z
203*69606e3fSchristos 
204*69606e3fSchristos 25  filenames with '$'  are left unchanged if they contain no '/'
205*69606e3fSchristos 25  filenames with ':' are left unchanged
206*69606e3fSchristos 26  filenames with a single pair of '[' ']' are left unchanged
207*69606e3fSchristos 
208*69606e3fSchristos   the input string is not written to
209*69606e3fSchristos */
210*69606e3fSchristos 
211*69606e3fSchristos char *
vmsify(char * name,int type)212*69606e3fSchristos vmsify (char *name, int type)
213*69606e3fSchristos {
214*69606e3fSchristos /* max 255 device
215*69606e3fSchristos    max 39 directory
216*69606e3fSchristos    max 39 filename
217*69606e3fSchristos    max 39 filetype
218*69606e3fSchristos    max 5 version
219*69606e3fSchristos */
220*69606e3fSchristos #define MAXPATHLEN 512
221*69606e3fSchristos 
222*69606e3fSchristos   enum namestate nstate;
223*69606e3fSchristos   static char vmsname[MAXPATHLEN+1];
224*69606e3fSchristos   char *fptr;
225*69606e3fSchristos   char *vptr;
226*69606e3fSchristos   char *s,*s1;
227*69606e3fSchristos   int as_dir;
228*69606e3fSchristos   int count;
229*69606e3fSchristos 
230*69606e3fSchristos   if (name == 0)
231*69606e3fSchristos     return 0;
232*69606e3fSchristos   fptr = name;
233*69606e3fSchristos   vptr = vmsname;
234*69606e3fSchristos   nstate = N_START;
235*69606e3fSchristos 
236*69606e3fSchristos   /* case 25a */
237*69606e3fSchristos 
238*69606e3fSchristos   s = strpbrk (name, "$:");
239*69606e3fSchristos   if (s != 0)
240*69606e3fSchristos     {
241*69606e3fSchristos       char *s1;
242*69606e3fSchristos       char *s2;
243*69606e3fSchristos 
244*69606e3fSchristos       if (type == 1)
245*69606e3fSchristos 	{
246*69606e3fSchristos 	  s1 = strchr (s+1, '[');
247*69606e3fSchristos 	  s2 = strchr (s+1, ']');
248*69606e3fSchristos 	}
249*69606e3fSchristos 
250*69606e3fSchristos       if (*s == '$')
251*69606e3fSchristos 	{
252*69606e3fSchristos 	  if (strchr (name, '/') == 0)
253*69606e3fSchristos 	    {
254*69606e3fSchristos 	      if ((type == 1) && (s1 != 0) && (s2 == 0))
255*69606e3fSchristos 		{
256*69606e3fSchristos 		  strcpy (vmsname, name);
257*69606e3fSchristos 		  strcat (vmsname, "]");
258*69606e3fSchristos 		  return vmsname;
259*69606e3fSchristos 		}
260*69606e3fSchristos 	      else
261*69606e3fSchristos 		return name;
262*69606e3fSchristos 	    }
263*69606e3fSchristos 	}
264*69606e3fSchristos       else
265*69606e3fSchristos 	{
266*69606e3fSchristos 	  if ((type == 1) && (s1 != 0) && (s2 == 0))
267*69606e3fSchristos 	    {
268*69606e3fSchristos 	      strcpy (vmsname, name);
269*69606e3fSchristos 	      strcat (vmsname, "]");
270*69606e3fSchristos 	      return vmsname;
271*69606e3fSchristos 	    }
272*69606e3fSchristos 	  else
273*69606e3fSchristos 	    return name;
274*69606e3fSchristos 	}
275*69606e3fSchristos     }
276*69606e3fSchristos 
277*69606e3fSchristos   /* case 26 */
278*69606e3fSchristos 
279*69606e3fSchristos   s = strchr (name, '[');
280*69606e3fSchristos 
281*69606e3fSchristos   if (s != 0)
282*69606e3fSchristos     {
283*69606e3fSchristos       s1 = strchr (s+1, '[');
284*69606e3fSchristos       if (s1 == 0)
285*69606e3fSchristos 	{
286*69606e3fSchristos 	  if ((type == 1)
287*69606e3fSchristos 	       && (strchr (s+1, ']') == 0))
288*69606e3fSchristos 	    {
289*69606e3fSchristos 	      strcpy (vmsname, name);
290*69606e3fSchristos 	      strcat (vmsname, "]");
291*69606e3fSchristos 	      return vmsname;
292*69606e3fSchristos 	    }
293*69606e3fSchristos 	  else
294*69606e3fSchristos 	    return name;			/* single [, keep unchanged */
295*69606e3fSchristos 	}
296*69606e3fSchristos       s1--;
297*69606e3fSchristos       if (*s1 != ']')
298*69606e3fSchristos 	{
299*69606e3fSchristos 	  return name;			/* not ][, keep unchanged */
300*69606e3fSchristos 	}
301*69606e3fSchristos 
302*69606e3fSchristos       /* we have ][ */
303*69606e3fSchristos 
304*69606e3fSchristos       s = name;
305*69606e3fSchristos 
306*69606e3fSchristos       /* s  -> starting char
307*69606e3fSchristos 	 s1 -> ending ']'  */
308*69606e3fSchristos 
309*69606e3fSchristos       do
310*69606e3fSchristos 	{
311*69606e3fSchristos 	  strncpy (vptr, s, s1-s);	/* copy up to but not including ']' */
312*69606e3fSchristos 	  vptr += s1-s;
313*69606e3fSchristos 	  if (*s1 == 0)
314*69606e3fSchristos 	    break;
315*69606e3fSchristos 	  s = s1 + 1;			/* s -> char behind ']' */
316*69606e3fSchristos 	  if (*s != '[')		/* was '][' ? */
317*69606e3fSchristos 	    break;			/* no, last ] found, exit */
318*69606e3fSchristos 	  s++;
319*69606e3fSchristos 	  if (*s != '.')
320*69606e3fSchristos 	    *vptr++ = '.';
321*69606e3fSchristos 	  s1 = strchr (s, ']');
322*69606e3fSchristos 	  if (s1 == 0)			/* no closing ] */
323*69606e3fSchristos 	    s1 = s + strlen (s);
324*69606e3fSchristos 	}
325*69606e3fSchristos       while (1);
326*69606e3fSchristos 
327*69606e3fSchristos       *vptr++ = ']';
328*69606e3fSchristos 
329*69606e3fSchristos       fptr = s;
330*69606e3fSchristos 
331*69606e3fSchristos     }
332*69606e3fSchristos 
333*69606e3fSchristos   else		/* no [ in name */
334*69606e3fSchristos 
335*69606e3fSchristos     {
336*69606e3fSchristos 
337*69606e3fSchristos       int state;
338*69606e3fSchristos       int rooted = 1;	/* flag if logical is rooted, else insert [000000] */
339*69606e3fSchristos 
340*69606e3fSchristos       state = 0;
341*69606e3fSchristos 
342*69606e3fSchristos       do
343*69606e3fSchristos 	{
344*69606e3fSchristos 
345*69606e3fSchristos       switch (state)
346*69606e3fSchristos 	{
347*69606e3fSchristos 	  case 0:				/* start of loop */
348*69606e3fSchristos 	    if (*fptr == '/')
349*69606e3fSchristos 	      {
350*69606e3fSchristos 		fptr++;
351*69606e3fSchristos 		state = 1;
352*69606e3fSchristos 	      }
353*69606e3fSchristos 	    else if (*fptr == '.')
354*69606e3fSchristos 	      {
355*69606e3fSchristos 		fptr++;
356*69606e3fSchristos 		state = 10;
357*69606e3fSchristos 	      }
358*69606e3fSchristos 	    else
359*69606e3fSchristos 	      state = 2;
360*69606e3fSchristos 	    break;
361*69606e3fSchristos 
362*69606e3fSchristos 	  case 1:				/* '/' at start */
363*69606e3fSchristos 	    if (*fptr == '/')
364*69606e3fSchristos 	      {
365*69606e3fSchristos 		fptr++;
366*69606e3fSchristos 		state = 3;
367*69606e3fSchristos 	      }
368*69606e3fSchristos 	    else
369*69606e3fSchristos 	      state = 4;
370*69606e3fSchristos 	    break;
371*69606e3fSchristos 
372*69606e3fSchristos 	  case 2:				/* no '/' at start */
373*69606e3fSchristos 	    s = strchr (fptr, '/');
374*69606e3fSchristos 	    if (s == 0)			/* no '/' (16) */
375*69606e3fSchristos 	      {
376*69606e3fSchristos 		if (type == 1)
377*69606e3fSchristos 		  {
378*69606e3fSchristos 		    strcpy (vptr, "[.");
379*69606e3fSchristos 		    vptr += 2;
380*69606e3fSchristos 		  }
381*69606e3fSchristos 		copyto (&vptr, &fptr, 0, (type==1));
382*69606e3fSchristos 		if (type == 1)
383*69606e3fSchristos 		  *vptr++ = ']';
384*69606e3fSchristos 		state = -1;
385*69606e3fSchristos 	      }
386*69606e3fSchristos 	    else			/* found '/' (17..21) */
387*69606e3fSchristos 	      {
388*69606e3fSchristos 		if ((type == 2)
389*69606e3fSchristos 		    && (*(s+1) == 0))	/* 17(2) */
390*69606e3fSchristos 		  {
391*69606e3fSchristos 		    copyto (&vptr, &fptr, '/', 1);
392*69606e3fSchristos 		    state = 7;
393*69606e3fSchristos 		  }
394*69606e3fSchristos 		else
395*69606e3fSchristos 		  {
396*69606e3fSchristos 		    strcpy (vptr, "[.");
397*69606e3fSchristos 		    vptr += 2;
398*69606e3fSchristos 		    copyto (&vptr, &fptr, '/', 1);
399*69606e3fSchristos 		    nstate = N_OPEN;
400*69606e3fSchristos 		    state = 9;
401*69606e3fSchristos 		  }
402*69606e3fSchristos 	      }
403*69606e3fSchristos 	    break;
404*69606e3fSchristos 
405*69606e3fSchristos 	  case 3:				/* '//' at start */
406*69606e3fSchristos 	    while (*fptr == '/')	/* collapse all '/' */
407*69606e3fSchristos 	      fptr++;
408*69606e3fSchristos 	    if (*fptr == 0)		/* just // */
409*69606e3fSchristos 	      {
410*69606e3fSchristos 		char cwdbuf[MAXPATHLEN+1];
411*69606e3fSchristos 
412*69606e3fSchristos 		s1 = getcwd(cwdbuf, MAXPATHLEN);
413*69606e3fSchristos 		if (s1 == 0)
414*69606e3fSchristos 		  {
415*69606e3fSchristos 		    return "";		/* FIXME, err getcwd */
416*69606e3fSchristos 		  }
417*69606e3fSchristos 		s = strchr (s1, ':');
418*69606e3fSchristos 		if (s == 0)
419*69606e3fSchristos 		  {
420*69606e3fSchristos 		    return "";		/* FIXME, err no device */
421*69606e3fSchristos 		  }
422*69606e3fSchristos 		strncpy (vptr, s1, s-s1+1);
423*69606e3fSchristos 		vptr += s-s1+1;
424*69606e3fSchristos 		state = -1;
425*69606e3fSchristos 		break;
426*69606e3fSchristos 	      }
427*69606e3fSchristos 
428*69606e3fSchristos 	    s = vptr;
429*69606e3fSchristos 
430*69606e3fSchristos 	    if (copyto (&vptr, &fptr, '/', 1) == 0)	/* copy device part */
431*69606e3fSchristos 	      {
432*69606e3fSchristos 		*vptr++ = ':';
433*69606e3fSchristos 		state = -1;
434*69606e3fSchristos 		break;
435*69606e3fSchristos 	      }
436*69606e3fSchristos 	    *vptr = ':';
437*69606e3fSchristos 	    nstate = N_DEVICE;
438*69606e3fSchristos 	    if (*fptr == 0)	/* just '//a/' */
439*69606e3fSchristos 	      {
440*69606e3fSchristos 		strcpy (vptr+1, "[000000]");
441*69606e3fSchristos 		vptr += 9;
442*69606e3fSchristos 		state = -1;
443*69606e3fSchristos 		break;
444*69606e3fSchristos 	      }
445*69606e3fSchristos 	    *vptr = 0;
446*69606e3fSchristos 				/* check logical for [000000] insertion */
447*69606e3fSchristos 	    s1 = trnlog (s);
448*69606e3fSchristos 	    if (*s1 != 0)
449*69606e3fSchristos 	      {			/* found translation */
450*69606e3fSchristos 		char *s2;
451*69606e3fSchristos 		for (;;)	/* loop over all nested logicals */
452*69606e3fSchristos 		  {
453*69606e3fSchristos 		    s2 = s1 + strlen (s1) - 1;
454*69606e3fSchristos 		    if (*s2 == ':')	/* translation ends in ':' */
455*69606e3fSchristos 		      {
456*69606e3fSchristos 			s2 = trnlog (s1);
457*69606e3fSchristos 			free (s1);
458*69606e3fSchristos 			if (*s2 == 0)
459*69606e3fSchristos 			  {
460*69606e3fSchristos 			    rooted = 0;
461*69606e3fSchristos 			    break;
462*69606e3fSchristos 			  }
463*69606e3fSchristos 			s1 = s2;
464*69606e3fSchristos 			continue;	/* next iteration */
465*69606e3fSchristos 		      }
466*69606e3fSchristos 		    if (*s2 == ']')	/* translation ends in ']' */
467*69606e3fSchristos 		      {
468*69606e3fSchristos 			if (*(s2-1) == '.')	/* ends in '.]' */
469*69606e3fSchristos 			  {
470*69606e3fSchristos 			    if (strncmp (fptr, "000000", 6) != 0)
471*69606e3fSchristos 			      rooted = 0;
472*69606e3fSchristos 			  }
473*69606e3fSchristos 			else
474*69606e3fSchristos 			  {
475*69606e3fSchristos 			    strcpy (vmsname, s1);
476*69606e3fSchristos 			    s = strchr (vmsname, ']');
477*69606e3fSchristos 			    *s = '.';
478*69606e3fSchristos 			    nstate = N_DOT;
479*69606e3fSchristos 			    vptr = s;
480*69606e3fSchristos 			  }
481*69606e3fSchristos 		      }
482*69606e3fSchristos 		    break;
483*69606e3fSchristos 		  }
484*69606e3fSchristos 		free (s1);
485*69606e3fSchristos 	      }
486*69606e3fSchristos 	    else
487*69606e3fSchristos 	      rooted = 0;
488*69606e3fSchristos 
489*69606e3fSchristos 	    if (*vptr == 0)
490*69606e3fSchristos 	      {
491*69606e3fSchristos 		nstate = N_DEVICE;
492*69606e3fSchristos 	        *vptr++ = ':';
493*69606e3fSchristos 	      }
494*69606e3fSchristos 	    else
495*69606e3fSchristos 	      vptr++;
496*69606e3fSchristos 
497*69606e3fSchristos 	    if (rooted == 0)
498*69606e3fSchristos 	      {
499*69606e3fSchristos 	        strcpy (vptr, "[000000.");
500*69606e3fSchristos 		vptr += 8;
501*69606e3fSchristos 		s1 = vptr-1;
502*69606e3fSchristos 		nstate = N_DOT;
503*69606e3fSchristos 	      }
504*69606e3fSchristos 	    else
505*69606e3fSchristos 	      s1 = 0;
506*69606e3fSchristos 
507*69606e3fSchristos 	/* s1-> '.' after 000000 or NULL */
508*69606e3fSchristos 
509*69606e3fSchristos 	    s = strchr (fptr, '/');
510*69606e3fSchristos 	    if (s == 0)
511*69606e3fSchristos 	      {				/* no next '/' */
512*69606e3fSchristos 		if (*(vptr-1) == '.')
513*69606e3fSchristos 		  *(vptr-1) = ']';
514*69606e3fSchristos 		else if (rooted == 0)
515*69606e3fSchristos 		  *vptr++ = ']';
516*69606e3fSchristos 		copyto (&vptr, &fptr, 0, (type == 1));
517*69606e3fSchristos 		state = -1;
518*69606e3fSchristos 		break;
519*69606e3fSchristos 	      }
520*69606e3fSchristos 	    else
521*69606e3fSchristos 	      {
522*69606e3fSchristos 		while (*(s+1) == '/')	/* skip multiple '/' */
523*69606e3fSchristos 		  s++;
524*69606e3fSchristos 	      }
525*69606e3fSchristos 
526*69606e3fSchristos 	    if ((rooted != 0)
527*69606e3fSchristos 	        && (*(vptr-1) != '.'))
528*69606e3fSchristos 	      {
529*69606e3fSchristos 		*vptr++ = '[';
530*69606e3fSchristos 		nstate = N_DOT;
531*69606e3fSchristos 	      }
532*69606e3fSchristos 	    else
533*69606e3fSchristos 	      if ((nstate == N_DOT)
534*69606e3fSchristos 		 && (s1 != 0)
535*69606e3fSchristos 		 && (*(s+1) == 0))
536*69606e3fSchristos 		{
537*69606e3fSchristos 		  if (type == 2)
538*69606e3fSchristos 		    {
539*69606e3fSchristos 		      *s1 = ']';
540*69606e3fSchristos 		      nstate = N_CLOSED;
541*69606e3fSchristos 		    }
542*69606e3fSchristos 		}
543*69606e3fSchristos 	    state = 9;
544*69606e3fSchristos 	    break;
545*69606e3fSchristos 
546*69606e3fSchristos 	  case 4:				/* single '/' at start (9..15) */
547*69606e3fSchristos 	    if (*fptr == 0)
548*69606e3fSchristos 	      state = 5;
549*69606e3fSchristos 	    else
550*69606e3fSchristos 	      state = 6;
551*69606e3fSchristos 	    break;
552*69606e3fSchristos 
553*69606e3fSchristos 	  case 5:				/* just '/' at start (9) */
554*69606e3fSchristos 	    if (type != 2)
555*69606e3fSchristos 	      {
556*69606e3fSchristos 	        *vptr++ = '[';
557*69606e3fSchristos 		nstate = N_OPEN;
558*69606e3fSchristos 	      }
559*69606e3fSchristos 	    strcpy (vptr, "000000");
560*69606e3fSchristos 	    vptr += 6;
561*69606e3fSchristos 	    if (type == 2)
562*69606e3fSchristos 	      state = 7;
563*69606e3fSchristos 	    else
564*69606e3fSchristos 	      state = 8;
565*69606e3fSchristos 	    break;
566*69606e3fSchristos 
567*69606e3fSchristos 	  case 6:				/* chars following '/' at start 10..15 */
568*69606e3fSchristos 	    *vptr++ = '[';
569*69606e3fSchristos 	    nstate = N_OPEN;
570*69606e3fSchristos 	    s = strchr (fptr, '/');
571*69606e3fSchristos 	    if (s == 0)			/* 10 */
572*69606e3fSchristos 	      {
573*69606e3fSchristos 		if (type != 1)
574*69606e3fSchristos 		  {
575*69606e3fSchristos 		    strcpy (vptr, "000000]");
576*69606e3fSchristos 		    vptr += 7;
577*69606e3fSchristos 		  }
578*69606e3fSchristos 		copyto (&vptr, &fptr, 0, (type == 1));
579*69606e3fSchristos 		if (type == 1)
580*69606e3fSchristos 		  {
581*69606e3fSchristos 		    *vptr++ = ']';
582*69606e3fSchristos 		  }
583*69606e3fSchristos 		state = -1;
584*69606e3fSchristos 	      }
585*69606e3fSchristos 	    else			/* 11..15 */
586*69606e3fSchristos 	      {
587*69606e3fSchristos 		if ( (type == 2)
588*69606e3fSchristos 		   && (*(s+1) == 0))	/* 11(2) */
589*69606e3fSchristos 		  {
590*69606e3fSchristos 		    strcpy (vptr, "000000]");
591*69606e3fSchristos 		    nstate = N_CLOSED;
592*69606e3fSchristos 		    vptr += 7;
593*69606e3fSchristos 		  }
594*69606e3fSchristos 		copyto (&vptr, &fptr, '/', (*(vptr-1) != ']'));
595*69606e3fSchristos 		state = 9;
596*69606e3fSchristos 	      }
597*69606e3fSchristos 	    break;
598*69606e3fSchristos 
599*69606e3fSchristos 	  case 7:				/* add '.dir' and exit */
600*69606e3fSchristos 	    if ((nstate == N_OPEN)
601*69606e3fSchristos 		|| (nstate == N_DOT))
602*69606e3fSchristos 	      {
603*69606e3fSchristos 		s = vptr-1;
604*69606e3fSchristos 		while (s > vmsname)
605*69606e3fSchristos 		  {
606*69606e3fSchristos 		    if (*s == ']')
607*69606e3fSchristos 		      {
608*69606e3fSchristos 			break;
609*69606e3fSchristos 		      }
610*69606e3fSchristos 		    if (*s == '.')
611*69606e3fSchristos 		      {
612*69606e3fSchristos 			*s = ']';
613*69606e3fSchristos 			break;
614*69606e3fSchristos 		      }
615*69606e3fSchristos 		    s--;
616*69606e3fSchristos 		  }
617*69606e3fSchristos 	      }
618*69606e3fSchristos 	    strcpy (vptr, ".dir");
619*69606e3fSchristos 	    vptr += 4;
620*69606e3fSchristos 	    state = -1;
621*69606e3fSchristos 	    break;
622*69606e3fSchristos 
623*69606e3fSchristos 	  case 8:				/* add ']' and exit */
624*69606e3fSchristos 	    *vptr++ = ']';
625*69606e3fSchristos 	    state = -1;
626*69606e3fSchristos 	    break;
627*69606e3fSchristos 
628*69606e3fSchristos 	  case 9:				/* 17..21, fptr -> 1st '/' + 1 */
629*69606e3fSchristos 	    if (*fptr == 0)
630*69606e3fSchristos 	      {
631*69606e3fSchristos 		if (type == 2)
632*69606e3fSchristos 		  {
633*69606e3fSchristos 		    state = 7;
634*69606e3fSchristos 		  }
635*69606e3fSchristos 		else
636*69606e3fSchristos 		  state = 8;
637*69606e3fSchristos 		break;
638*69606e3fSchristos 	      }
639*69606e3fSchristos 	    s = strchr (fptr, '/');
640*69606e3fSchristos 	    if (s == 0)
641*69606e3fSchristos 	      {
642*69606e3fSchristos 		if (type != 1)
643*69606e3fSchristos 		  {
644*69606e3fSchristos 		    if (nstate == N_OPEN)
645*69606e3fSchristos 		      {
646*69606e3fSchristos 			*vptr++ = ']';
647*69606e3fSchristos 			nstate = N_CLOSED;
648*69606e3fSchristos 		      }
649*69606e3fSchristos 		    as_dir = 0;
650*69606e3fSchristos 		  }
651*69606e3fSchristos 		else
652*69606e3fSchristos 		  {
653*69606e3fSchristos 		    if (nstate == N_OPEN)
654*69606e3fSchristos 		      {
655*69606e3fSchristos 			*vptr++ = '.';
656*69606e3fSchristos 			nstate = N_DOT;
657*69606e3fSchristos 		      }
658*69606e3fSchristos 		    as_dir = 1;
659*69606e3fSchristos 		  }
660*69606e3fSchristos 	      }
661*69606e3fSchristos 	    else
662*69606e3fSchristos 	      {
663*69606e3fSchristos 		while (*(s+1) == '/')
664*69606e3fSchristos 		  s++;
665*69606e3fSchristos 		if ( (type == 2)
666*69606e3fSchristos 		    && (*(s+1) == 0))		/* 19(2), 21(2)*/
667*69606e3fSchristos 		  {
668*69606e3fSchristos 		    if (nstate != N_CLOSED)
669*69606e3fSchristos 		      {
670*69606e3fSchristos 			*vptr++ = ']';
671*69606e3fSchristos 			nstate = N_CLOSED;
672*69606e3fSchristos 		      }
673*69606e3fSchristos 		    as_dir = 1;
674*69606e3fSchristos 		  }
675*69606e3fSchristos 		else
676*69606e3fSchristos 		  {
677*69606e3fSchristos 		    if (nstate == N_OPEN)
678*69606e3fSchristos 		      {
679*69606e3fSchristos 			*vptr++ = '.';
680*69606e3fSchristos 			nstate = N_DOT;
681*69606e3fSchristos 		      }
682*69606e3fSchristos 		    as_dir = 1;
683*69606e3fSchristos 		  }
684*69606e3fSchristos 	      }
685*69606e3fSchristos 	    if ( (*fptr == '.')			/* check for '..' or '../' */
686*69606e3fSchristos 		&& (*(fptr+1) == '.')
687*69606e3fSchristos 		&& ((*(fptr+2) == '/')
688*69606e3fSchristos 		    || (*(fptr+2) == 0)) )
689*69606e3fSchristos 	      {
690*69606e3fSchristos 		fptr += 2;
691*69606e3fSchristos 		if (*fptr == '/')
692*69606e3fSchristos 		  {
693*69606e3fSchristos 		    do
694*69606e3fSchristos 		      {
695*69606e3fSchristos 			fptr++;
696*69606e3fSchristos 		      }
697*69606e3fSchristos 		    while (*fptr == '/');
698*69606e3fSchristos 		  }
699*69606e3fSchristos 		else if (*fptr == 0)
700*69606e3fSchristos 		  type = 1;
701*69606e3fSchristos 		vptr--;				/* vptr -> '.' or ']' */
702*69606e3fSchristos 		s1 = vptr;
703*69606e3fSchristos 		for (;;)
704*69606e3fSchristos 		  {
705*69606e3fSchristos 		    s1--;
706*69606e3fSchristos 		    if (*s1 == '.')		/* one back */
707*69606e3fSchristos 		      {
708*69606e3fSchristos 			vptr = s1;
709*69606e3fSchristos 			nstate = N_OPEN;
710*69606e3fSchristos 			break;
711*69606e3fSchristos 		      }
712*69606e3fSchristos 		    if (*s1 == '[')		/* top level reached */
713*69606e3fSchristos 		      {
714*69606e3fSchristos 			if (*fptr == 0)
715*69606e3fSchristos 			  {
716*69606e3fSchristos 			    strcpy (s1, "[000000]");
717*69606e3fSchristos 			    vptr = s1 + 8;
718*69606e3fSchristos 			    nstate = N_CLOSED;
719*69606e3fSchristos 			    s = 0;
720*69606e3fSchristos 			    break;
721*69606e3fSchristos 			  }
722*69606e3fSchristos 			else
723*69606e3fSchristos 			  {
724*69606e3fSchristos 			    vptr = s1+1;
725*69606e3fSchristos 			    nstate = N_OPEN;
726*69606e3fSchristos 			    break;
727*69606e3fSchristos 			  }
728*69606e3fSchristos 		      }
729*69606e3fSchristos 		  }
730*69606e3fSchristos 	      }
731*69606e3fSchristos 	    else
732*69606e3fSchristos 	      {
733*69606e3fSchristos 		copyto (&vptr, &fptr, '/', as_dir);
734*69606e3fSchristos 		if (nstate == N_DOT)
735*69606e3fSchristos 		  nstate = N_OPEN;
736*69606e3fSchristos 	      }
737*69606e3fSchristos 	    if (s == 0)
738*69606e3fSchristos 	      {					/* 18,20 */
739*69606e3fSchristos 		if (type == 1)
740*69606e3fSchristos 		  *vptr++ = ']';
741*69606e3fSchristos 		state = -1;
742*69606e3fSchristos 	      }
743*69606e3fSchristos 	    else
744*69606e3fSchristos 	      {
745*69606e3fSchristos 		if (*(s+1) == 0)
746*69606e3fSchristos 		  {
747*69606e3fSchristos 		    if (type == 2)		/* 19,21 */
748*69606e3fSchristos 		      {
749*69606e3fSchristos 		        state = 7;
750*69606e3fSchristos 		      }
751*69606e3fSchristos 		    else
752*69606e3fSchristos 		      {
753*69606e3fSchristos 			*vptr++ = ']';
754*69606e3fSchristos 			state = -1;
755*69606e3fSchristos 		      }
756*69606e3fSchristos 		  }
757*69606e3fSchristos 	      }
758*69606e3fSchristos 	    break;
759*69606e3fSchristos 
760*69606e3fSchristos 	  case 10:				/* 1,2 first is '.' */
761*69606e3fSchristos 	    if (*fptr == '.')
762*69606e3fSchristos 	      {
763*69606e3fSchristos 		fptr++;
764*69606e3fSchristos 		state = 11;
765*69606e3fSchristos 	      }
766*69606e3fSchristos 	    else
767*69606e3fSchristos 	      state = 12;
768*69606e3fSchristos 	    break;
769*69606e3fSchristos 
770*69606e3fSchristos 	  case 11:				/* 2, '..' at start */
771*69606e3fSchristos 	    count = 1;
772*69606e3fSchristos 	    if (*fptr != 0)
773*69606e3fSchristos 	      {
774*69606e3fSchristos 		if (*fptr != '/')		/* got ..xxx */
775*69606e3fSchristos 		  {
776*69606e3fSchristos 		    return name;
777*69606e3fSchristos 		  }
778*69606e3fSchristos 		do				/* got ../ */
779*69606e3fSchristos 		  {
780*69606e3fSchristos 		    fptr++;
781*69606e3fSchristos 		    while (*fptr == '/') fptr++;
782*69606e3fSchristos 		    if (*fptr != '.')
783*69606e3fSchristos 		      break;
784*69606e3fSchristos 		    if (*(fptr+1) != '.')
785*69606e3fSchristos 		      break;
786*69606e3fSchristos 		    fptr += 2;
787*69606e3fSchristos 		    if ((*fptr == 0)
788*69606e3fSchristos 			|| (*fptr == '/'))
789*69606e3fSchristos 		      count++;
790*69606e3fSchristos 		  }
791*69606e3fSchristos 		while (*fptr == '/');
792*69606e3fSchristos 	      }
793*69606e3fSchristos 	    {					/* got '..' or '../' */
794*69606e3fSchristos 	      char cwdbuf[MAXPATHLEN+1];
795*69606e3fSchristos 
796*69606e3fSchristos 	      s1 = getcwd(cwdbuf, MAXPATHLEN);
797*69606e3fSchristos 	      if (s1 == 0)
798*69606e3fSchristos 		{
799*69606e3fSchristos 		  return "";	    /* FIXME, err getcwd */
800*69606e3fSchristos 		}
801*69606e3fSchristos 	      strcpy (vptr, s1);
802*69606e3fSchristos 	      s = strchr (vptr, ']');
803*69606e3fSchristos 	      if (s != 0)
804*69606e3fSchristos 		{
805*69606e3fSchristos 		  nstate = N_OPEN;
806*69606e3fSchristos 		  while (s > vptr)
807*69606e3fSchristos 		    {
808*69606e3fSchristos 		      s--;
809*69606e3fSchristos 		      if (*s == '[')
810*69606e3fSchristos 			{
811*69606e3fSchristos 			  s++;
812*69606e3fSchristos 			  strcpy (s, "000000]");
813*69606e3fSchristos 			  state = -1;
814*69606e3fSchristos 			  break;
815*69606e3fSchristos 			}
816*69606e3fSchristos 		      else if (*s == '.')
817*69606e3fSchristos 			{
818*69606e3fSchristos 			  if (--count == 0)
819*69606e3fSchristos 			    {
820*69606e3fSchristos 			      if (*fptr == 0)	/* had '..' or '../' */
821*69606e3fSchristos 				{
822*69606e3fSchristos 				  *s++ = ']';
823*69606e3fSchristos 				  state = -1;
824*69606e3fSchristos 				}
825*69606e3fSchristos 			      else			/* had '../xxx' */
826*69606e3fSchristos 				{
827*69606e3fSchristos 				  state = 9;
828*69606e3fSchristos 				}
829*69606e3fSchristos 			      *s = 0;
830*69606e3fSchristos 			      break;
831*69606e3fSchristos 			    }
832*69606e3fSchristos 			}
833*69606e3fSchristos 		    }
834*69606e3fSchristos 		}
835*69606e3fSchristos 	      vptr += strlen (vptr);
836*69606e3fSchristos 	    }
837*69606e3fSchristos 	    break;
838*69606e3fSchristos 
839*69606e3fSchristos 	  case 12:				/* 1, '.' at start */
840*69606e3fSchristos 	    if (*fptr != 0)
841*69606e3fSchristos 	      {
842*69606e3fSchristos 		if (*fptr != '/')
843*69606e3fSchristos 		  {
844*69606e3fSchristos 		    return name;
845*69606e3fSchristos 		  }
846*69606e3fSchristos 		while (*fptr == '/')
847*69606e3fSchristos 		  fptr++;
848*69606e3fSchristos 	      }
849*69606e3fSchristos 
850*69606e3fSchristos 	    {
851*69606e3fSchristos 	      char cwdbuf[MAXPATHLEN+1];
852*69606e3fSchristos 
853*69606e3fSchristos 	      s1 = getcwd(cwdbuf, MAXPATHLEN);
854*69606e3fSchristos 	      if (s1 == 0)
855*69606e3fSchristos 		{
856*69606e3fSchristos 		  return "";	    /*FIXME, err getcwd */
857*69606e3fSchristos 		}
858*69606e3fSchristos 	      strcpy (vptr, s1);
859*69606e3fSchristos 	      if (*fptr == 0)
860*69606e3fSchristos 		{
861*69606e3fSchristos 		  state = -1;
862*69606e3fSchristos 		  break;
863*69606e3fSchristos 		}
864*69606e3fSchristos 	      else
865*69606e3fSchristos 		{
866*69606e3fSchristos 		  s = strchr (vptr, ']');
867*69606e3fSchristos 		  if (s == 0)
868*69606e3fSchristos 		    {
869*69606e3fSchristos 		      state = -1;
870*69606e3fSchristos 		      break;
871*69606e3fSchristos 		    }
872*69606e3fSchristos 		  *s = 0;
873*69606e3fSchristos 		  nstate = N_OPEN;
874*69606e3fSchristos 		  vptr += strlen (vptr);
875*69606e3fSchristos 		  state = 9;
876*69606e3fSchristos 		}
877*69606e3fSchristos 	    }
878*69606e3fSchristos 	    break;
879*69606e3fSchristos 	}
880*69606e3fSchristos 
881*69606e3fSchristos 	}
882*69606e3fSchristos       while (state > 0);
883*69606e3fSchristos 
884*69606e3fSchristos 
885*69606e3fSchristos     }
886*69606e3fSchristos 
887*69606e3fSchristos 
888*69606e3fSchristos   /* directory conversion done
889*69606e3fSchristos      fptr -> filename part of input string
890*69606e3fSchristos      vptr -> free space in vmsname
891*69606e3fSchristos   */
892*69606e3fSchristos 
893*69606e3fSchristos   *vptr++ = 0;
894*69606e3fSchristos 
895*69606e3fSchristos   return vmsname;
896*69606e3fSchristos }
897*69606e3fSchristos 
898*69606e3fSchristos 
899*69606e3fSchristos 
900*69606e3fSchristos /*
901*69606e3fSchristos   convert from vms-style to unix-style
902*69606e3fSchristos 
903*69606e3fSchristos   dev:[dir1.dir2]	//dev/dir1/dir2/
904*69606e3fSchristos */
905*69606e3fSchristos 
906*69606e3fSchristos char *
unixify(char * name)907*69606e3fSchristos unixify (char *name)
908*69606e3fSchristos {
909*69606e3fSchristos   static char piece[512];
910*69606e3fSchristos   char *s, *p;
911*69606e3fSchristos 
912*69606e3fSchristos   if (strchr (name, '/') != 0)		/* already in unix style */
913*69606e3fSchristos     return name;
914*69606e3fSchristos 
915*69606e3fSchristos   p = piece;
916*69606e3fSchristos   *p = 0;
917*69606e3fSchristos 
918*69606e3fSchristos   /* device part */
919*69606e3fSchristos 
920*69606e3fSchristos   s = strchr (name, ':');
921*69606e3fSchristos 
922*69606e3fSchristos   if (s != 0)
923*69606e3fSchristos     {
924*69606e3fSchristos       *s = 0;
925*69606e3fSchristos       *p++ = '/';
926*69606e3fSchristos       *p++ = '/';
927*69606e3fSchristos       strcpy (p, name);
928*69606e3fSchristos       p += strlen (p);
929*69606e3fSchristos       *s = ':';
930*69606e3fSchristos     }
931*69606e3fSchristos 
932*69606e3fSchristos   /* directory part */
933*69606e3fSchristos 
934*69606e3fSchristos   *p++ = '/';
935*69606e3fSchristos   s = strchr (name, '[');
936*69606e3fSchristos 
937*69606e3fSchristos   if (s != 0)
938*69606e3fSchristos     {
939*69606e3fSchristos       s++;
940*69606e3fSchristos       switch (*s)
941*69606e3fSchristos         {
942*69606e3fSchristos 	  case ']':		/* [] */
943*69606e3fSchristos 	    strcat (p, "./");
944*69606e3fSchristos 	    break;
945*69606e3fSchristos 	  case '-':		/* [- */
946*69606e3fSchristos 	    strcat (p, "../");
947*69606e3fSchristos 	    break;
948*69606e3fSchristos 	  case '.':
949*69606e3fSchristos 	    strcat (p, "./");	/* [. */
950*69606e3fSchristos 	    break;
951*69606e3fSchristos 	  default:
952*69606e3fSchristos 	    s--;
953*69606e3fSchristos 	    break;
954*69606e3fSchristos         }
955*69606e3fSchristos       s++;
956*69606e3fSchristos       while (*s)
957*69606e3fSchristos         {
958*69606e3fSchristos 	  if (*s == '.')
959*69606e3fSchristos 	    *p++ = '/';
960*69606e3fSchristos 	  else
961*69606e3fSchristos 	    *p++ = *s;
962*69606e3fSchristos 	  s++;
963*69606e3fSchristos 	  if (*s == ']')
964*69606e3fSchristos 	    {
965*69606e3fSchristos 	      s++;
966*69606e3fSchristos 	      break;
967*69606e3fSchristos 	    }
968*69606e3fSchristos         }
969*69606e3fSchristos       if (*s != 0)		/* more after ']' ?? */
970*69606e3fSchristos         {
971*69606e3fSchristos 	  if (*(p-1) != '/')
972*69606e3fSchristos 	    *p++ = '/';
973*69606e3fSchristos 	  strcpy (p, s);		/* copy it anyway */
974*69606e3fSchristos         }
975*69606e3fSchristos     }
976*69606e3fSchristos 
977*69606e3fSchristos   else		/* no '[' anywhere */
978*69606e3fSchristos 
979*69606e3fSchristos     {
980*69606e3fSchristos       *p++ = 0;
981*69606e3fSchristos     }
982*69606e3fSchristos 
983*69606e3fSchristos   /* force end with '/' */
984*69606e3fSchristos 
985*69606e3fSchristos   if (*(p-1) != '/')
986*69606e3fSchristos     *p++ = '/';
987*69606e3fSchristos   *p = 0;
988*69606e3fSchristos 
989*69606e3fSchristos   return piece;
990*69606e3fSchristos }
991*69606e3fSchristos 
992*69606e3fSchristos /* EOF */
993