re-mark 1.29b-2 as not yet uploaded (merge madness!)
[debian/tar] / gnu / linkat.c
1 /* Create a hard link relative to open directories.
2    Copyright (C) 2009-2015 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* written by Eric Blake */
18
19 #include <config.h>
20
21 #include <unistd.h>
22
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <limits.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29
30 #include "areadlink.h"
31 #include "dirname.h"
32 #include "filenamecat.h"
33 #include "openat-priv.h"
34
35 #if HAVE_SYS_PARAM_H
36 # include <sys/param.h>
37 #endif
38 #ifndef MAXSYMLINKS
39 # ifdef SYMLOOP_MAX
40 #  define MAXSYMLINKS SYMLOOP_MAX
41 # else
42 #  define MAXSYMLINKS 20
43 # endif
44 #endif
45
46 #if !HAVE_LINKAT || LINKAT_SYMLINK_NOTSUP
47
48 /* Create a link.  If FILE1 is a symlink, either create a hardlink to
49    that symlink, or fake it by creating an identical symlink.  */
50 # if LINK_FOLLOWS_SYMLINKS == 0
51 #  define link_immediate link
52 # else
53 static int
54 link_immediate (char const *file1, char const *file2)
55 {
56   char *target = areadlink (file1);
57   if (target)
58     {
59       /* A symlink cannot be modified in-place.  Therefore, creating
60          an identical symlink behaves like a hard link to a symlink,
61          except for incorrect st_ino and st_nlink.  However, we must
62          be careful of EXDEV.  */
63       struct stat st1;
64       struct stat st2;
65       char *dir = mdir_name (file2);
66       if (!dir)
67         {
68           free (target);
69           errno = ENOMEM;
70           return -1;
71         }
72       if (lstat (file1, &st1) == 0 && stat (dir, &st2) == 0)
73         {
74           if (st1.st_dev == st2.st_dev)
75             {
76               int result = symlink (target, file2);
77               int saved_errno = errno;
78               free (target);
79               free (dir);
80               errno = saved_errno;
81               return result;
82             }
83           free (target);
84           free (dir);
85           errno = EXDEV;
86           return -1;
87         }
88       free (target);
89       free (dir);
90     }
91   if (errno == ENOMEM)
92     return -1;
93   return link (file1, file2);
94 }
95 # endif /* LINK_FOLLOWS_SYMLINKS == 0 */
96
97 /* Create a link.  If FILE1 is a symlink, create a hardlink to the
98    canonicalized file.  */
99 # if 0 < LINK_FOLLOWS_SYMLINKS
100 #  define link_follow link
101 # else
102 static int
103 link_follow (char const *file1, char const *file2)
104 {
105   char *name = (char *) file1;
106   char *target;
107   int result;
108   int i = MAXSYMLINKS;
109
110   /* Using realpath or canonicalize_file_name is too heavy-handed: we
111      don't need an absolute name, and we don't need to resolve
112      intermediate symlinks, just the basename of each iteration.  */
113   while (i-- && (target = areadlink (name)))
114     {
115       if (IS_ABSOLUTE_FILE_NAME (target))
116         {
117           if (name != file1)
118             free (name);
119           name = target;
120         }
121       else
122         {
123           char *dir = mdir_name (name);
124           if (name != file1)
125             free (name);
126           if (!dir)
127             {
128               free (target);
129               errno = ENOMEM;
130               return -1;
131             }
132           name = mfile_name_concat (dir, target, NULL);
133           free (dir);
134           free (target);
135           if (!name)
136             {
137               errno = ENOMEM;
138               return -1;
139             }
140         }
141     }
142   if (i < 0)
143     {
144       target = NULL;
145       errno = ELOOP;
146     }
147   if (!target && errno != EINVAL)
148     {
149       if (name != file1)
150         {
151           int saved_errno = errno;
152           free (name);
153           errno = saved_errno;
154         }
155       return -1;
156     }
157   result = link (name, file2);
158   if (name != file1)
159     {
160       int saved_errno = errno;
161       free (name);
162       errno = saved_errno;
163     }
164   return result;
165 }
166 # endif /* 0 < LINK_FOLLOWS_SYMLINKS */
167
168 /* On Solaris, link() doesn't follow symlinks by default, but does so as soon
169    as a library or executable takes part in the program that has been compiled
170    with "c99" or "cc -xc99=all" or "cc ... /usr/lib/values-xpg4.o ...".  */
171 # if LINK_FOLLOWS_SYMLINKS == -1
172
173 /* Reduce the penalty of link_immediate and link_follow by incorporating the
174    knowledge that link()'s behaviour depends on the __xpg4 variable.  */
175 extern int __xpg4;
176
177 static int
178 solaris_optimized_link_immediate (char const *file1, char const *file2)
179 {
180   if (__xpg4 == 0)
181     return link (file1, file2);
182   return link_immediate (file1, file2);
183 }
184
185 static int
186 solaris_optimized_link_follow (char const *file1, char const *file2)
187 {
188   if (__xpg4 != 0)
189     return link (file1, file2);
190   return link_follow (file1, file2);
191 }
192
193 #  define link_immediate solaris_optimized_link_immediate
194 #  define link_follow solaris_optimized_link_follow
195
196 # endif
197
198 #endif /* !HAVE_LINKAT || LINKAT_SYMLINK_NOTSUP  */
199
200 #if !HAVE_LINKAT
201
202 /* Create a link to FILE1, in the directory open on descriptor FD1, to FILE2,
203    in the directory open on descriptor FD2.  If FILE1 is a symlink, FLAG
204    controls whether to dereference FILE1 first.  If possible, do it without
205    changing the working directory.  Otherwise, resort to using
206    save_cwd/fchdir, then rename/restore_cwd.  If either the save_cwd or
207    the restore_cwd fails, then give a diagnostic and exit nonzero.  */
208
209 int
210 linkat (int fd1, char const *file1, int fd2, char const *file2, int flag)
211 {
212   if (flag & ~AT_SYMLINK_FOLLOW)
213     {
214       errno = EINVAL;
215       return -1;
216     }
217   return at_func2 (fd1, file1, fd2, file2,
218                    flag ? link_follow : link_immediate);
219 }
220
221 #else /* HAVE_LINKAT */
222
223 # undef linkat
224
225 /* Create a link.  If FILE1 is a symlink, create a hardlink to the
226    canonicalized file.  */
227
228 static int
229 linkat_follow (int fd1, char const *file1, int fd2, char const *file2)
230 {
231   char *name = (char *) file1;
232   char *target;
233   int result;
234   int i = MAXSYMLINKS;
235
236   /* There is no realpathat.  */
237   while (i-- && (target = areadlinkat (fd1, name)))
238     {
239       if (IS_ABSOLUTE_FILE_NAME (target))
240         {
241           if (name != file1)
242             free (name);
243           name = target;
244         }
245       else
246         {
247           char *dir = mdir_name (name);
248           if (name != file1)
249             free (name);
250           if (!dir)
251             {
252               free (target);
253               errno = ENOMEM;
254               return -1;
255             }
256           name = mfile_name_concat (dir, target, NULL);
257           free (dir);
258           free (target);
259           if (!name)
260             {
261               errno = ENOMEM;
262               return -1;
263             }
264         }
265     }
266   if (i < 0)
267     {
268       target = NULL;
269       errno = ELOOP;
270     }
271   if (!target && errno != EINVAL)
272     {
273       if (name != file1)
274         {
275           int saved_errno = errno;
276           free (name);
277           errno = saved_errno;
278         }
279       return -1;
280     }
281   result = linkat (fd1, name, fd2, file2, 0);
282   if (name != file1)
283     {
284       int saved_errno = errno;
285       free (name);
286       errno = saved_errno;
287     }
288   return result;
289 }
290
291
292 /* Like linkat, but guarantee that AT_SYMLINK_FOLLOW works even on
293    older Linux kernels.  */
294
295 int
296 rpl_linkat (int fd1, char const *file1, int fd2, char const *file2, int flag)
297 {
298   if (flag & ~AT_SYMLINK_FOLLOW)
299     {
300       errno = EINVAL;
301       return -1;
302     }
303
304 # if LINKAT_TRAILING_SLASH_BUG
305   /* Reject trailing slashes on non-directories.  */
306   {
307     size_t len1 = strlen (file1);
308     size_t len2 = strlen (file2);
309     if ((len1 && file1[len1 - 1] == '/')
310         || (len2 && file2[len2 - 1] == '/'))
311       {
312         /* Let linkat() decide whether hard-linking directories is legal.
313            If fstatat() fails, then linkat() should fail for the same reason;
314            if fstatat() succeeds, require a directory.  */
315         struct stat st;
316         if (fstatat (fd1, file1, &st, flag ? 0 : AT_SYMLINK_NOFOLLOW))
317           return -1;
318         if (!S_ISDIR (st.st_mode))
319           {
320             errno = ENOTDIR;
321             return -1;
322           }
323       }
324   }
325 # endif
326
327   if (!flag)
328     {
329       int result = linkat (fd1, file1, fd2, file2, flag);
330 # if LINKAT_SYMLINK_NOTSUP
331       /* OS X 10.10 has linkat() but it doesn't support
332          hardlinks to symlinks.  Fallback to our emulation
333          in that case.  */
334       if (result == -1 && (errno == ENOTSUP || errno == EOPNOTSUPP))
335         return at_func2 (fd1, file1, fd2, file2, link_immediate);
336 # endif
337       return result;
338     }
339
340   /* Cache the information on whether the system call really works.  */
341   {
342     static int have_follow_really; /* 0 = unknown, 1 = yes, -1 = no */
343     if (0 <= have_follow_really)
344     {
345       int result = linkat (fd1, file1, fd2, file2, flag);
346       if (!(result == -1 && errno == EINVAL))
347         {
348           have_follow_really = 1;
349           return result;
350         }
351       have_follow_really = -1;
352     }
353   }
354   return linkat_follow (fd1, file1, fd2, file2);
355 }
356
357 #endif /* HAVE_LINKAT */