1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1989-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Eduardo Krell <ekrell@adexus.cl>                   *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 
24 #include "3d.h"
25 
26 int
symlink3d(const char * path,const char * target)27 symlink3d(const char* path, const char* target)
28 {
29 	register char*	sp;
30 	register char*	tp;
31 	register int	r;
32 	char*		t;
33 	int		oerrno;
34 	char		buf[PATH_MAX + 1];
35 #if FS
36 	char		tmp[PATH_MAX + 1];
37 	Mount_t*	mp;
38 
39 	if (!fscall(NiL, MSG_symlink, 0, path, target))
40 		return(state.ret);
41 #endif
42 	if (!state.safe) sp = (char*)path;
43 	else if (!(sp = pathreal(path, P_PATHONLY|P_SAFE, NiL))) return(-1);
44 	else sp = strncpy(buf, sp, PATH_MAX);
45 #if FS
46 	mp = monitored();
47 #endif
48 	if (!(tp = pathreal(target, P_PATHONLY|P_NOOPAQUE, NiL)))
49 		return(-1);
50 	oerrno = errno;
51 	if ((r = SYMLINK(sp, tp)) && errno == ENOENT && (t = strrchr(tp, '/')))
52 	{
53 		*t = 0;
54 		r = fs3d_mkdir(tp, S_IRWXU|S_IRWXG|S_IRWXO);
55 		*t = '/';
56 		if (!r)
57 		{
58 			errno = oerrno;
59 			r = SYMLINK(sp, tp);
60 		}
61 	}
62 #if FS
63 	if (!r)
64 	{
65 		if (mp)
66 		{
67 			if (tp != tmp)
68 			{
69 				if (!(tp = pathreal(target, P_PATHONLY|P_NOOPAQUE|P_ABSOLUTE, NiL)))
70 					return(r);
71 				tp = strncpy(tmp, tp, PATH_MAX);
72 			}
73 			fscall(mp, MSG_symlink, 0, sp, tp);
74 		}
75 		for (mp = state.global; mp; mp = mp->global)
76 			if (fssys(mp, MSG_symlink))
77 			{
78 				if (tp != tmp)
79 				{
80 					if (!(tp = pathreal(target, P_PATHONLY|P_NOOPAQUE|P_ABSOLUTE, NiL)))
81 						return(r);
82 					tp = strncpy(tmp, tp, PATH_MAX);
83 				}
84 				fscall(mp, MSG_symlink, 0, sp, tp);
85 			}
86 	}
87 #endif
88 	return(r);
89 }
90