blob: 7c282b0013ec6e8449500aecd52d07dda2dfb74d [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersenf6be9441999-10-13 21:12:06 +00002/*
3 * Mini ln implementation for busybox
4 *
Eric Andersencb81e642003-07-14 21:21:08 +00005 * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
Eric Andersenf6be9441999-10-13 21:12:06 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
Manuel Novoa III cad53642003-03-19 09:13:01 +000023/* BB_AUDIT SUSv3 compliant */
24/* BB_AUDIT GNU options missing: -b, -d, -F, -i, -S, and -v. */
25/* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
26
27/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
28 *
29 * Fixed bug involving -n option. Essentially, -n was always in effect.
30 */
31
Eric Andersened3ef502001-01-27 08:24:39 +000032#include <stdlib.h>
Eric Andersened3ef502001-01-27 08:24:39 +000033#include <unistd.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000034#include "busybox.h"
Eric Andersencbe31da2001-02-20 06:14:08 +000035
Manuel Novoa III cad53642003-03-19 09:13:01 +000036#define LN_SYMLINK 1
37#define LN_FORCE 2
38#define LN_NODEREFERENCE 4
Eric Andersenf6be9441999-10-13 21:12:06 +000039
40extern int ln_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000041{
Eric Andersen13241df2000-10-04 16:02:53 +000042 int status = EXIT_SUCCESS;
Manuel Novoa III cad53642003-03-19 09:13:01 +000043 int flag;
44 char *last;
45 char *src_name;
Glenn L McGrathcfc0ad42003-12-31 23:10:44 +000046 char *src;
47 struct stat statbuf;
Manuel Novoa III cad53642003-03-19 09:13:01 +000048 int (*link_func)(const char *, const char *);
49
50 flag = bb_getopt_ulflags(argc, argv, "sfn");
51
52 if (argc == optind) {
53 bb_show_usage();
54 }
55
56 last = argv[argc - 1];
57 argv += optind;
58
59 if (argc == optind + 1) {
60 *--argv = last;
61 last = bb_get_last_path_component(bb_xstrdup(last));
62 }
63
64 do {
Glenn L McGrathcfc0ad42003-12-31 23:10:44 +000065 src_name = NULL;
Manuel Novoa III cad53642003-03-19 09:13:01 +000066 src = last;
67
68 if (is_directory(src,
69 (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE,
70 NULL)) {
71 src_name = bb_xstrdup(*argv);
72 src = concat_path_file(src, bb_get_last_path_component(src_name));
73 free(src_name);
Glenn L McGrathcfc0ad42003-12-31 23:10:44 +000074 src_name = src;
75 }
Glenn L McGrath95f75a32004-01-08 10:51:09 +000076 if (!(flag & LN_SYMLINK) && stat(*argv, &statbuf)) {
Glenn L McGrathcfc0ad42003-12-31 23:10:44 +000077 bb_perror_msg(*argv);
78 status = EXIT_FAILURE;
79 free(src_name);
80 continue;
Eric Andersen815e9042000-06-06 16:15:23 +000081 }
Manuel Novoa III cad53642003-03-19 09:13:01 +000082
83 if (flag & LN_FORCE) {
84 unlink(src);
85 }
86
87 link_func = link;
88 if (flag & LN_SYMLINK) {
89 link_func = symlink;
90 }
91
92 if (link_func(*argv, src) != 0) {
93 bb_perror_msg(src);
Glenn L McGrathcfc0ad42003-12-31 23:10:44 +000094 status = EXIT_FAILURE;
Manuel Novoa III cad53642003-03-19 09:13:01 +000095 }
96
97 free(src_name);
98
99 } while ((++argv)[1]);
100
Eric Andersenfcffa2c2002-04-06 05:17:57 +0000101 return status;
Eric Andersencc8ed391999-10-05 16:24:54 +0000102}