1 /* `ln' program to create links between files.
2 Copyright (C) 86, 89, 90, 91, 95, 1996 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Written by Mike Parker and David MacKenzie. */
26 #include <sys/types.h>
30 #include "backupfile.h"
33 int link (); /* Some systems don't declare this anywhere. */
40 # define SYMBOLIC_SPACE_STRING symbolic_link ? _("symbolic ") : ""
42 # define SYMBOLIC_SPACE_STRING ""
45 /* Construct a string NEW_DEST by concatenating DEST, a slash, and
46 basename(SOURCE) in alloca'd memory. Don't modify DEST or SOURCE. */
48 #define PATH_BASENAME_CONCAT(new_dest, dest, source) \
54 tmp_source = (char *) alloca (strlen ((source)) + 1); \
55 strcpy (tmp_source, (source)); \
56 strip_trailing_slashes (tmp_source); \
57 source_base = basename (tmp_source); \
59 (new_dest) = (char *) alloca (strlen ((dest)) + 1 \
60 + strlen (source_base) + 1); \
61 stpcpy (stpcpy (stpcpy ((new_dest), (dest)), "/"), source_base);\
66 enum backup_type
get_version ();
69 void strip_trailing_slashes ();
72 /* The name by which the program was run, for error messages. */
75 /* A pointer to the function used to make links. This will point to either
76 `link' or `symlink'. */
77 static int (*linkfunc
) ();
79 /* If nonzero, make symbolic links; otherwise, make hard links. */
80 static int symbolic_link
;
82 /* If nonzero, ask the user before removing existing files. */
83 static int interactive
;
85 /* If nonzero, remove existing files unconditionally. */
86 static int remove_existing_files
;
88 /* If nonzero, list each file as it is moved. */
91 /* If nonzero, allow the superuser to make hard links to directories. */
92 static int hard_dir_link
;
94 /* If nonzero, and the specified destination is a symbolic link to a
95 directory, treat it just as if it were a directory. Otherwise, the
96 command `ln --force --no-dereference file symlink-to-dir' deletes
97 symlink-to-dir before creating the new link. */
98 static int dereference_dest_dir_symlinks
= 1;
100 /* If nonzero, display usage information and exit. */
101 static int show_help
;
103 /* If nonzero, print the version on standard output and exit. */
104 static int show_version
;
106 static struct option
const long_options
[] =
108 {"backup", no_argument
, NULL
, 'b'},
109 {"directory", no_argument
, &hard_dir_link
, 1},
110 {"no-dereference", no_argument
, NULL
, 'n'},
111 {"force", no_argument
, NULL
, 'f'},
112 {"interactive", no_argument
, NULL
, 'i'},
113 {"suffix", required_argument
, NULL
, 'S'},
114 {"symbolic", no_argument
, &symbolic_link
, 1},
115 {"verbose", no_argument
, &verbose
, 1},
116 {"version-control", required_argument
, NULL
, 'V'},
117 {"help", no_argument
, &show_help
, 1},
118 {"version", no_argument
, &show_version
, 1},
122 /* Make a link DEST to the (usually) existing file SOURCE.
123 Symbolic links to nonexistent files are allowed.
124 If DEST is a directory, put the link to SOURCE in that directory.
125 Return 1 if there is an error, otherwise 0. */
128 do_link (const char *source
, const char *dest
)
130 struct stat source_stats
;
131 struct stat dest_stats
;
132 char *dest_backup
= NULL
;
135 /* Use stat here instead of lstat.
136 On SVR4, link does not follow symlinks, so this check disallows
137 making hard links to symlinks that point to directories. Big deal.
138 On other systems, link follows symlinks, so this check is right. */
141 if (stat (source
, &source_stats
) != 0)
143 error (0, errno
, "%s", source
);
146 if (!hard_dir_link
&& S_ISDIR (source_stats
.st_mode
))
148 error (0, 0, _("%s: hard link not allowed for directory"), source
);
153 lstat_status
= lstat (dest
, &dest_stats
);
155 if (lstat_status
!= 0 && errno
!= ENOENT
)
157 error (0, errno
, "%s", dest
);
161 /* If --force (-f) has been specified, before making a link ln must
162 remove the destination file if it exists. But if the source and
163 destination are the same, don't remove anything and fail right here. */
164 if (remove_existing_files
166 && (!symlink
|| stat (source
, &source_stats
) == 0)
167 && source_stats
.st_dev
== dest_stats
.st_dev
168 && source_stats
.st_ino
== dest_stats
.st_ino
)
170 error (0, 0, _("`%s' and `%s' are the same file"), source
, dest
);
174 /* If the destination is a directory or (it is a symlink to a directory
175 and the user has not specified --no-dereference), then form the
176 actual destination name by appending basename (source) to the
177 specified destination directory. */
178 if ((lstat_status
== 0
179 && S_ISDIR (dest_stats
.st_mode
))
181 || (dereference_dest_dir_symlinks
182 && (S_ISLNK (dest_stats
.st_mode
)
187 /* Target is a directory; build the full filename. */
189 PATH_BASENAME_CONCAT (new_dest
, dest
, source
);
191 /* Set this to nonzero to force another call to lstat
192 with the new destination. */
196 if (lstat_status
== 0 || lstat (dest
, &dest_stats
) == 0)
198 if (S_ISDIR (dest_stats
.st_mode
))
200 error (0, 0, _("%s: cannot overwrite directory"), dest
);
205 fprintf (stderr
, _("%s: replace `%s'? "), program_name
, dest
);
209 else if (!remove_existing_files
)
211 error (0, 0, _("%s: File exists"), dest
);
215 if (backup_type
!= none
)
217 char *tmp_backup
= find_backup_file_name (dest
);
218 if (tmp_backup
== NULL
)
219 error (1, 0, _("virtual memory exhausted"));
220 dest_backup
= (char *) alloca (strlen (tmp_backup
) + 1);
221 strcpy (dest_backup
, tmp_backup
);
223 if (rename (dest
, dest_backup
))
227 error (0, errno
, _("cannot backup `%s'"), dest
);
234 else if (unlink (dest
) && errno
!= ENOENT
)
236 error (0, errno
, _("cannot remove `%s'"), dest
);
240 else if (errno
!= ENOENT
)
242 error (0, errno
, "%s", dest
);
247 printf (_("create %slink %s to %s\n"), SYMBOLIC_SPACE_STRING
,
250 if ((*linkfunc
) (source
, dest
) == 0)
255 error (0, errno
, _("cannot %slink `%s' to `%s'"), SYMBOLIC_SPACE_STRING
,
260 if (rename (dest_backup
, dest
))
261 error (0, errno
, _("cannot un-backup `%s'"), dest
);
270 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
275 Usage: %s [OPTION]... SOURCE [DEST]\n\
276 or: %s [OPTION]... SOURCE... DIRECTORY\n\
278 program_name
, program_name
);
280 Link SOURCE to DEST (. by default), or multiple SOURCE(s) to DIRECTORY.\n\
281 Makes hard links by default, symbolic links with -s.\n\
283 -b, --backup make backups for removed files\n\
284 -d, -F, --directory hard link directories (super-user only)\n\
285 -f, --force remove existing destinations\n\
286 -n, --no-dereference treat destination that is a symlink to a\n\
287 directory as if it were a normal file\n\
288 -i, --interactive prompt whether to remove destinations\n\
289 -s, --symbolic make symbolic links instead of hard links\n\
290 -v, --verbose print name of each file before linking\n\
291 -S, --suffix=SUFFIX override the usual backup suffix\n\
292 -V, --version-control=WORD override the usual version control\n\
293 --help display this help and exit\n\
294 --version output version information and exit\n\
296 The backup suffix is ~, unless set with SIMPLE_BACKUP_SUFFIX. The\n\
297 version control may be set with VERSION_CONTROL, values are:\n\
299 t, numbered make numbered backups\n\
300 nil, existing numbered if numbered backups exist, simple otherwise\n\
301 never, simple always make simple backups\n"));
307 main (int argc
, char **argv
)
311 int make_backups
= 0;
314 program_name
= argv
[0];
315 setlocale (LC_ALL
, "");
316 bindtextdomain (PACKAGE
, LOCALEDIR
);
317 textdomain (PACKAGE
);
319 version
= getenv ("SIMPLE_BACKUP_SUFFIX");
321 simple_backup_suffix
= version
;
322 version
= getenv ("VERSION_CONTROL");
325 symbolic_link
= remove_existing_files
= interactive
= verbose
329 while ((c
= getopt_long (argc
, argv
,
330 "bdfinsvFS:V:", long_options
, (int *) 0))
335 case 0: /* Long-named option. */
345 remove_existing_files
= 1;
349 remove_existing_files
= 0;
353 dereference_dest_dir_symlinks
= 0;
359 error (1, 0, _("symbolic links are not supported on this system"));
366 simple_backup_suffix
= optarg
;
379 printf ("ln - %s\n", PACKAGE_VERSION
);
388 error (0, 0, _("missing file argument"));
393 backup_type
= get_version (version
);
400 if (optind
== argc
- 1)
401 errors
= do_link (argv
[optind
], ".");
402 else if (optind
== argc
- 2)
404 struct stat source_stats
;
409 source
= argv
[optind
];
410 dest
= argv
[optind
+ 1];
412 /* When the destination is specified with a trailing slash and the
413 source exists but is not a directory, convert the user's command
414 `ln source dest/' to `ln source dest/basename(source)'. */
416 if (dest
[strlen (dest
) - 1] == '/'
417 && lstat (source
, &source_stats
) == 0
418 && !S_ISDIR (source_stats
.st_mode
))
420 PATH_BASENAME_CONCAT (new_dest
, dest
, source
);
427 errors
= do_link (source
, new_dest
);
435 error (1, 0, _("when making multiple links, last argument must be a directory"));
436 for (; optind
< argc
- 1; ++optind
)
437 errors
+= do_link (argv
[optind
], to
);