1 /* `ln' program to create links between files.
2 Copyright (C) 1986, 1989, 1990, 1991 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
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Written by Mike Parker and David MacKenzie. */
25 #if defined (CONFIG_BROKETS)
26 /* We use <config.h> instead of "config.h" so that a compilation
27 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
28 (which it would do because it found this file in $srcdir). */
36 #include <sys/types.h>
39 #include "backupfile.h"
42 int link (); /* Some systems don't declare this anywhere. */
48 /* Construct a string NEW_DEST by concatenating DEST, a slash, and
49 basename(SOURCE) in alloca'd memory. Don't modify DEST or SOURCE. */
51 #define PATH_BASENAME_CONCAT(new_dest, dest, source) \
57 tmp_source = (char *) alloca (strlen ((source)) + 1); \
58 strcpy (tmp_source, (source)); \
59 strip_trailing_slashes (tmp_source); \
60 source_base = basename (tmp_source); \
62 (new_dest) = (char *) alloca (strlen ((dest)) + 1 \
63 + strlen (source_base) + 1); \
64 stpcpy (stpcpy (stpcpy ((new_dest), (dest)), "/"), source_base);\
69 enum backup_type
get_version ();
73 void strip_trailing_slashes ();
77 static int do_link ();
79 /* The name by which the program was run, for error messages. */
82 /* A pointer to the function used to make links. This will point to either
83 `link' or `symlink'. */
84 static int (*linkfunc
) ();
86 /* If nonzero, make symbolic links; otherwise, make hard links. */
87 static int symbolic_link
;
89 /* If nonzero, ask the user before removing existing files. */
90 static int interactive
;
92 /* If nonzero, remove existing files unconditionally. */
93 static int remove_existing_files
;
95 /* If nonzero, list each file as it is moved. */
98 /* If nonzero, allow the superuser to make hard links to directories. */
99 static int hard_dir_link
;
101 /* If non-zero, display usage information and exit. */
102 static int show_help
;
104 /* If non-zero, print the version on standard output and exit. */
105 static int show_version
;
107 static struct option
const long_options
[] =
109 {"backup", no_argument
, NULL
, 'b'},
110 {"directory", no_argument
, &hard_dir_link
, 1},
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},
129 int make_backups
= 0;
132 version
= getenv ("SIMPLE_BACKUP_SUFFIX");
134 simple_backup_suffix
= version
;
135 version
= getenv ("VERSION_CONTROL");
136 program_name
= argv
[0];
138 symbolic_link
= remove_existing_files
= interactive
= verbose
142 while ((c
= getopt_long (argc
, argv
, "bdfisvFS:V:", long_options
, (int *) 0))
147 case 0: /* Long-named option. */
157 remove_existing_files
= 1;
161 remove_existing_files
= 0;
168 error (1, 0, "symbolic links are not supported on this system");
175 simple_backup_suffix
= optarg
;
188 printf ("%s\n", version_string
);
199 backup_type
= get_version (version
);
206 if (optind
== argc
- 1)
207 errors
= do_link (argv
[optind
], ".");
208 else if (optind
== argc
- 2)
210 struct stat source_stats
;
215 source
= argv
[optind
];
216 dest
= argv
[optind
+ 1];
218 /* When the destination is specified with a trailing slash and the
219 source exists but is not a directory, convert the user's command
220 `ln source dest/' to `ln source dest/basename(source)'. */
222 if (dest
[strlen (dest
) - 1] == '/'
223 && lstat (source
, &source_stats
) == 0
224 && !S_ISDIR (source_stats
.st_mode
))
226 PATH_BASENAME_CONCAT (new_dest
, dest
, source
);
233 errors
= do_link (source
, new_dest
);
241 error (1, 0, "when making multiple links, last argument must be a directory");
242 for (; optind
< argc
- 1; ++optind
)
243 errors
+= do_link (argv
[optind
], to
);
249 /* Make a link DEST to existing file SOURCE.
250 If DEST is a directory, put the link to SOURCE in that directory.
251 Return 1 if there is an error, otherwise 0. */
254 do_link (source
, dest
)
258 struct stat dest_stats
;
259 char *dest_backup
= NULL
;
261 /* isdir uses stat instead of lstat.
262 On SVR4, link does not follow symlinks, so this check disallows
263 making hard links to symlinks that point to directories. Big deal.
264 On other systems, link follows symlinks, so this check is right. */
265 if (!symbolic_link
&& !hard_dir_link
&& isdir (source
))
267 error (0, 0, "%s: hard link not allowed for directory", source
);
272 /* Target is a directory; build the full filename. */
274 PATH_BASENAME_CONCAT (new_dest
, dest
, source
);
278 if (lstat (dest
, &dest_stats
) == 0)
280 if (S_ISDIR (dest_stats
.st_mode
))
282 error (0, 0, "%s: cannot overwrite directory", dest
);
287 fprintf (stderr
, "%s: replace `%s'? ", program_name
, dest
);
291 else if (!remove_existing_files
)
293 error (0, 0, "%s: File exists", dest
);
297 if (backup_type
!= none
)
299 char *tmp_backup
= find_backup_file_name (dest
);
300 if (tmp_backup
== NULL
)
301 error (1, 0, "virtual memory exhausted");
302 dest_backup
= (char *) alloca (strlen (tmp_backup
) + 1);
303 strcpy (dest_backup
, tmp_backup
);
305 if (rename (dest
, dest_backup
))
309 error (0, errno
, "cannot backup `%s'", dest
);
316 else if (unlink (dest
) && errno
!= ENOENT
)
318 error (0, errno
, "cannot remove old link to `%s'", dest
);
322 else if (errno
!= ENOENT
)
324 error (0, errno
, "%s", dest
);
329 printf ("%s -> %s\n", source
, dest
);
331 if ((*linkfunc
) (source
, dest
) == 0)
336 error (0, errno
, "cannot %slink `%s' to `%s'",
338 linkfunc
== symlink
? "symbolic " : "",
346 if (rename (dest_backup
, dest
))
347 error (0, errno
, "cannot un-backup `%s'", dest
);
356 Usage: %s [options] source [dest]\n\
357 %s [options] source... directory\n\
359 [-bdfisvF] [-S backup-suffix] [-V {numbered,existing,simple}]\n\
360 [--version-control={numbered,existing,simple}] [--backup] [--directory]\n\
361 [--force] [--interactive] [--symbolic] [--verbose]\n\
362 [--suffix=backup-suffix] [--help] [--version]\n",
363 program_name
, program_name
);