1 /* `ln' program to create links between files.
2 Copyright (C) 86, 89, 90, 91, 1995-2005 Free Software Foundation, Inc.
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 2, or (at your option)
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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 /* Written by Mike Parker and David MacKenzie. */
22 #include <sys/types.h>
27 #include "backupfile.h"
33 /* The official name of this program (e.g., no `g' prefix). */
34 #define PROGRAM_NAME "ln"
36 #define AUTHORS "Mike Parker", "David MacKenzie"
38 #ifndef ENABLE_HARD_LINK_TO_SYMLINK_WARNING
39 # define ENABLE_HARD_LINK_TO_SYMLINK_WARNING 0
42 /* In being careful not even to try to make hard links to directories,
43 we have to know whether link(2) follows symlinks. If it does, then
44 we have to *stat* the `source' to see if the resulting link would be
45 to a directory. Otherwise, we have to use *lstat* so that we allow
46 users to make hard links to symlinks-that-point-to-directories. */
48 #if LINK_FOLLOWS_SYMLINKS
49 # define STAT_LIKE_LINK(File, Stat_buf) \
52 # define STAT_LIKE_LINK(File, Stat_buf) \
53 lstat (File, Stat_buf)
56 /* Construct a string NEW_DEST by concatenating DEST, a slash, and
57 basename(SOURCE) in alloca'd memory. Don't modify DEST or SOURCE. */
59 #define FILE_BASENAME_CONCAT(new_dest, dest, source) \
62 const char *source_base; \
64 size_t buf_len = strlen (source) + 1; \
66 tmp_source = alloca (buf_len); \
67 memcpy (tmp_source, (source), buf_len); \
68 strip_trailing_slashes (tmp_source); \
69 source_base = base_name (tmp_source); \
71 (new_dest) = alloca (strlen ((dest)) + 1 \
72 + strlen (source_base) + 1); \
73 stpcpy (stpcpy (stpcpy ((new_dest), (dest)), "/"), source_base);\
77 /* The name by which the program was run, for error messages. */
81 static enum backup_type backup_type;
83 /* A pointer to the function used to make links. This will point to either
84 `link' or `symlink'. */
85 static int (*linkfunc) ();
87 /* If true, make symbolic links; otherwise, make hard links. */
88 static bool symbolic_link;
90 /* If true, ask the user before removing existing files. */
91 static bool interactive;
93 /* If true, remove existing files unconditionally. */
94 static bool remove_existing_files;
96 /* If true, list each file as it is moved. */
99 /* If true, allow the superuser to *attempt* to make hard links
100 to directories. However, it appears that this option is not useful
101 in practice, since even the superuser is prohibited from hard-linking
102 directories on most (all?) existing systems. */
103 static bool hard_dir_link;
105 /* If nonzero, and the specified destination is a symbolic link to a
106 directory, treat it just as if it were a directory. Otherwise, the
107 command `ln --force --no-dereference file symlink-to-dir' deletes
108 symlink-to-dir before creating the new link. */
109 static bool dereference_dest_dir_symlinks = true;
111 static struct option const long_options[] =
113 {"backup", optional_argument, NULL, 'b'},
114 {"directory", no_argument, NULL, 'F'},
115 {"no-dereference", no_argument, NULL, 'n'},
116 {"no-target-directory", no_argument, NULL, 'T'},
117 {"force", no_argument, NULL, 'f'},
118 {"interactive", no_argument, NULL, 'i'},
119 {"suffix", required_argument, NULL, 'S'},
120 {"target-directory", required_argument, NULL, 't'},
121 {"symbolic", no_argument, NULL, 's'},
122 {"verbose", no_argument, NULL, 'v'},
123 {GETOPT_HELP_OPTION_DECL},
124 {GETOPT_VERSION_OPTION_DECL},
128 /* FILE is the last operand of this command. Return true if FILE is a
129 directory. But report an error there is a problem accessing FILE,
130 or if FILE does not exist but would have to refer to an existing
131 directory if it referred to anything at all. */
134 target_directory_operand (char const *file)
136 char const *b = base_name (file);
137 size_t blen = strlen (b);
138 bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
140 int err = ((dereference_dest_dir_symlinks ? stat : lstat) (file, &st) == 0
142 bool is_a_dir = !err && S_ISDIR (st.st_mode);
143 if (err && err != ENOENT)
144 error (EXIT_FAILURE, err, _("accessing %s"), quote (file));
145 if (is_a_dir < looks_like_a_dir)
146 error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file));
150 /* Make a link DEST to the (usually) existing file SOURCE.
151 Symbolic links to nonexistent files are allowed.
152 If DEST_IS_DIR, put the link to SOURCE in the DEST directory.
153 Return true if successful. */
156 do_link (const char *source, const char *dest, bool dest_is_dir)
158 struct stat source_stats;
159 struct stat dest_stats;
160 char *dest_backup = NULL;
161 bool lstat_ok = false;
163 /* Use stat here instead of lstat.
164 On SVR4, link does not follow symlinks, so this check disallows
165 making hard links to symlinks that point to directories. Big deal.
166 On other systems, link follows symlinks, so this check is right. */
169 if (STAT_LIKE_LINK (source, &source_stats) != 0)
171 error (0, errno, _("accessing %s"), quote (source));
175 if (ENABLE_HARD_LINK_TO_SYMLINK_WARNING
176 && S_ISLNK (source_stats.st_mode))
178 error (0, 0, _("%s: warning: making a hard link to a symbolic link\
183 if (!hard_dir_link && S_ISDIR (source_stats.st_mode))
185 error (0, 0, _("%s: hard link not allowed for directory"),
193 /* Treat DEST as a directory; build the full filename. */
195 FILE_BASENAME_CONCAT (new_dest, dest, source);
199 if (remove_existing_files || interactive || backup_type != no_backups)
201 lstat_ok = (lstat (dest, &dest_stats) == 0);
202 if (!lstat_ok && errno != ENOENT)
204 error (0, errno, _("accessing %s"), quote (dest));
209 /* If --force (-f) has been specified without --backup, then before
210 making a link ln must remove the destination file if it exists.
211 (with --backup, it just renames any existing destination file)
212 But if the source and destination are the same, don't remove
213 anything and fail right here. */
214 if (remove_existing_files
216 /* Allow `ln -sf --backup k k' to succeed in creating the
217 self-referential symlink, but don't allow the hard-linking
218 equivalent: `ln -f k k' (with or without --backup) to get
219 beyond this point, because the error message you'd get is
221 && (backup_type == no_backups || !symbolic_link)
222 && (!symbolic_link || stat (source, &source_stats) == 0)
223 && SAME_INODE (source_stats, dest_stats)
224 /* The following detects whether removing DEST will also remove
225 SOURCE. If the file has only one link then both are surely
226 the same link. Otherwise check whether they point to the same
227 name in the same directory. */
228 && (source_stats.st_nlink == 1 || same_name (source, dest)))
230 error (0, 0, _("%s and %s are the same file"),
231 quote_n (0, source), quote_n (1, dest));
237 if (S_ISDIR (dest_stats.st_mode))
239 error (0, 0, _("%s: cannot overwrite directory"), quote (dest));
244 fprintf (stderr, _("%s: replace %s? "), program_name, quote (dest));
249 if (backup_type != no_backups)
251 char *tmp_backup = find_backup_file_name (dest, backup_type);
252 size_t buf_len = strlen (tmp_backup) + 1;
253 dest_backup = alloca (buf_len);
254 memcpy (dest_backup, tmp_backup, buf_len);
256 if (rename (dest, dest_backup))
260 error (0, errno, _("cannot backup %s"), quote (dest));
271 printf ((symbolic_link
272 ? _("create symbolic link %s to %s")
273 : _("create hard link %s to %s")),
274 quote_n (0, dest), quote_n (1, source));
276 printf (_(" (backup: %s)"), quote (dest_backup));
280 if ((*linkfunc) (source, dest) == 0)
283 /* If the attempt to create a link failed and we are removing or
284 backing up destinations, unlink the destination and try again.
286 POSIX 1003.1-2004 requires that ln -f A B must unlink B even on
287 failure (e.g., when A does not exist). This is counterintuitive,
288 and we submitted a defect report
289 <http://www.opengroup.org/sophocles/show_mail.tpl?source=L&listname=austin-review-l&id=1795>
290 (2004-06-24). If the committee does not fix the standard we'll
291 have to change the behavior of ln -f, at least if POSIXLY_CORRECT
292 is set. In the meantime ln -f A B will not unlink B unless the
293 attempt to link A to B failed because B already existed.
295 Try to unlink DEST even if we may have backed it up successfully.
296 In some unusual cases (when DEST and DEST_BACKUP are hard-links
297 that refer to the same file), rename succeeds and DEST remains.
298 If we didn't remove DEST in that case, the subsequent LINKFUNC
301 if (errno == EEXIST && (remove_existing_files || dest_backup))
303 if (unlink (dest) != 0)
305 error (0, errno, _("cannot remove %s"), quote (dest));
309 if (linkfunc (source, dest) == 0)
315 ? _("creating symbolic link %s to %s")
316 : _("creating hard link %s to %s")),
317 quote_n (0, dest), quote_n (1, source));
321 if (rename (dest_backup, dest))
322 error (0, errno, _("cannot un-backup %s"), quote (dest));
330 if (status != EXIT_SUCCESS)
331 fprintf (stderr, _("Try `%s --help' for more information.\n"),
336 Usage: %s [OPTION]... [-T] TARGET LINK_NAME (1st form)\n\
337 or: %s [OPTION]... TARGET (2nd form)\n\
338 or: %s [OPTION]... TARGET... DIRECTORY (3rd form)\n\
339 or: %s [OPTION]... -t DIRECTORY TARGET... (4th form)\n\
341 program_name, program_name, program_name, program_name);
343 In the 1st form, create a link to TARGET with the name LINK_NAME.\n\
344 In the 2nd form, create a link to TARGET in the current directory.\n\
345 In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.\n\
346 Create hard links by default, symbolic links with --symbolic.\n\
347 When creating hard links, each TARGET must exist.\n\
351 Mandatory arguments to long options are mandatory for short options too.\n\
354 --backup[=CONTROL] make a backup of each existing destination file\n\
355 -b like --backup but does not accept an argument\n\
356 -d, -F, --directory allow the superuser to attempt to hard link\n\
357 directories (note: will probably fail due to\n\
358 system restrictions, even for the superuser)\n\
359 -f, --force remove existing destination files\n\
362 -n, --no-dereference treat destination that is a symlink to a\n\
363 directory as if it were a normal file\n\
364 -i, --interactive prompt whether to remove destinations\n\
365 -s, --symbolic make symbolic links instead of hard links\n\
368 -S, --suffix=SUFFIX override the usual backup suffix\n\
369 -t, --target-directory=DIRECTORY specify the DIRECTORY in which to create\n\
371 -T, --no-target-directory treat LINK_NAME as a normal file\n\
372 -v, --verbose print name of each file before linking\n\
374 fputs (HELP_OPTION_DESCRIPTION, stdout);
375 fputs (VERSION_OPTION_DESCRIPTION, stdout);
378 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
379 The version control method may be selected via the --backup option or through\n\
380 the VERSION_CONTROL environment variable. Here are the values:\n\
384 none, off never make backups (even if --backup is given)\n\
385 numbered, t make numbered backups\n\
386 existing, nil numbered if numbered backups exist, simple otherwise\n\
387 simple, never always make simple backups\n\
389 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
395 main (int argc, char **argv)
399 bool make_backups = false;
400 char *backup_suffix_string;
401 char *version_control_string = NULL;
402 char *target_directory = NULL;
403 bool no_target_directory = false;
407 initialize_main (&argc, &argv);
408 program_name = argv[0];
409 setlocale (LC_ALL, "");
410 bindtextdomain (PACKAGE, LOCALEDIR);
411 textdomain (PACKAGE);
413 atexit (close_stdout);
415 /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
416 we'll actually use backup_suffix_string. */
417 backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
419 symbolic_link = remove_existing_files = interactive = verbose
420 = hard_dir_link = false;
422 while ((c = getopt_long (argc, argv, "bdfinst:vFS:T", long_options, NULL))
430 version_control_string = optarg;
434 hard_dir_link = true;
437 remove_existing_files = true;
441 remove_existing_files = false;
445 dereference_dest_dir_symlinks = false;
449 symbolic_link = true;
451 error (EXIT_FAILURE, 0,
452 _("symbolic links are not supported on this system"));
456 if (target_directory)
457 error (EXIT_FAILURE, 0, _("multiple target directories specified"));
461 if (stat (optarg, &st) != 0)
462 error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
463 if (! S_ISDIR (st.st_mode))
464 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
467 target_directory = optarg;
470 no_target_directory = true;
477 backup_suffix_string = optarg;
479 case_GETOPT_HELP_CHAR;
480 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
482 usage (EXIT_FAILURE);
487 n_files = argc - optind;
488 file = argv + optind;
492 error (0, 0, _("missing file operand"));
493 usage (EXIT_FAILURE);
496 if (no_target_directory)
498 if (target_directory)
499 error (EXIT_FAILURE, 0,
500 _("Cannot combine --target-directory "
501 "and --no-target-directory"));
506 _("missing destination file operand after %s"),
509 error (0, 0, _("extra operand %s"), quote (file[2]));
510 usage (EXIT_FAILURE);
513 else if (!target_directory)
516 target_directory = ".";
517 else if (2 <= n_files && target_directory_operand (file[n_files - 1]))
518 target_directory = file[--n_files];
519 else if (2 < n_files)
520 error (EXIT_FAILURE, 0, _("target %s is not a directory"),
521 quote (file[n_files - 1]));
529 if (backup_suffix_string)
530 simple_backup_suffix = xstrdup (backup_suffix_string);
532 backup_type = (make_backups
533 ? xget_version (_("backup type"), version_control_string)
536 if (target_directory)
540 for (i = 0; i < n_files; ++i)
541 ok &= do_link (file[i], target_directory, true);
544 ok = do_link (file[0], file[1], false);
546 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);