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