blob: 8ef8d05decaf69fe543dd62d03bbbafa125c92a0 [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 *
Erik Andersen61677fe2000-04-13 01:18:56 +00005 * Copyright (C) 1999,2000 by Lineo, inc.
Eric Andersenc4996011999-10-20 22:08:37 +00006 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
Eric Andersenf6be9441999-10-13 21:12:06 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
Eric Andersen3570a342000-09-25 21:45:58 +000024#include "busybox.h"
Erik Andersenfac10d72000-02-07 05:29:42 +000025#define BB_DECLARE_EXTERN
Erik Andersenfac10d72000-02-07 05:29:42 +000026#define bb_need_not_a_directory
27#include "messages.c"
28
Eric Andersencc8ed391999-10-05 16:24:54 +000029#include <stdio.h>
Eric Andersenf6be9441999-10-13 21:12:06 +000030#include <dirent.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000031#include <errno.h>
32
Eric Andersenf6be9441999-10-13 21:12:06 +000033static int symlinkFlag = FALSE;
34static int removeoldFlag = FALSE;
Erik Andersenfac10d72000-02-07 05:29:42 +000035static int followLinks = TRUE;
Eric Andersenf6be9441999-10-13 21:12:06 +000036
37extern int ln_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000038{
Eric Andersen9b2297a2000-07-10 20:08:44 +000039 char *linkName, *dirName=NULL;
Erik Andersene49d5ec2000-02-08 19:58:47 +000040 int linkIntoDirFlag;
Pavel Roskin2e965232000-06-15 18:04:40 +000041 int stopIt = FALSE;
Eric Andersencc8ed391999-10-05 16:24:54 +000042
Eric Andersenf6be9441999-10-13 21:12:06 +000043 argc--;
44 argv++;
Eric Andersenf6be9441999-10-13 21:12:06 +000045
Erik Andersene49d5ec2000-02-08 19:58:47 +000046 /* Parse any options */
Pavel Roskin2e965232000-06-15 18:04:40 +000047 while (argc > 0 && stopIt == FALSE) {
48 if (**argv == '-') {
Eric Andersen815e9042000-06-06 16:15:23 +000049 while (*++(*argv))
50 switch (**argv) {
51 case 's':
52 symlinkFlag = TRUE;
53 break;
54 case 'f':
55 removeoldFlag = TRUE;
56 break;
57 case 'n':
58 followLinks = FALSE;
59 break;
Pavel Roskin2e965232000-06-15 18:04:40 +000060 case '-':
61 stopIt = TRUE;
62 break;
Eric Andersen815e9042000-06-06 16:15:23 +000063 default:
64 usage(ln_usage);
65 }
Pavel Roskin2e965232000-06-15 18:04:40 +000066 argc--;
67 argv++;
Eric Andersen815e9042000-06-06 16:15:23 +000068 }
Pavel Roskin2e965232000-06-15 18:04:40 +000069 else
70 break;
Erik Andersenfac10d72000-02-07 05:29:42 +000071 }
72
Pavel Roskin2e965232000-06-15 18:04:40 +000073 if (argc < 2) {
74 usage(ln_usage);
Eric Andersen815e9042000-06-06 16:15:23 +000075 }
76
Erik Andersene49d5ec2000-02-08 19:58:47 +000077 linkName = argv[argc - 1];
Erik Andersenfac10d72000-02-07 05:29:42 +000078
Eric Andersen195fa152000-07-11 17:35:32 +000079 linkIntoDirFlag = isDirectory(linkName, followLinks, NULL);
Pavel Roskin110fc0c2000-06-18 00:02:24 +000080 if ((argc >= 3) && linkIntoDirFlag == FALSE) {
Matt Kraaid537a952000-07-14 01:51:25 +000081 errorMsg(not_a_directory, linkName);
Erik Andersene49d5ec2000-02-08 19:58:47 +000082 exit FALSE;
Eric Andersenf6be9441999-10-13 21:12:06 +000083 }
Erik Andersene49d5ec2000-02-08 19:58:47 +000084
Eric Andersen0b4551f2000-07-10 16:44:03 +000085 if (linkIntoDirFlag == TRUE)
86 dirName = linkName;
87
Erik Andersene49d5ec2000-02-08 19:58:47 +000088 while (argc-- >= 2) {
Eric Andersen6f9985e2000-06-22 00:02:56 +000089 int status;
Erik Andersene49d5ec2000-02-08 19:58:47 +000090
Eric Andersen0b4551f2000-07-10 16:44:03 +000091 if (linkIntoDirFlag == TRUE) {
92 char *baseName = get_last_path_component(*argv);
Matt Kraai322ae932000-09-13 02:46:14 +000093 linkName = (char *)xmalloc(strlen(dirName)+strlen(baseName)+2);
Eric Andersen0b4551f2000-07-10 16:44:03 +000094 strcpy(linkName, dirName);
95 if(dirName[strlen(dirName)-1] != '/')
96 strcat(linkName, "/");
97 strcat(linkName,baseName);
98 }
Erik Andersene49d5ec2000-02-08 19:58:47 +000099
100 if (removeoldFlag == TRUE) {
101 status = (unlink(linkName) && errno != ENOENT);
102 if (status != 0) {
103 perror(linkName);
104 exit FALSE;
105 }
106 }
107
108 if (symlinkFlag == TRUE)
109 status = symlink(*argv, linkName);
110 else
111 status = link(*argv, linkName);
112 if (status != 0) {
113 perror(linkName);
114 exit FALSE;
115 }
Eric Andersen0b4551f2000-07-10 16:44:03 +0000116
Eric Andersen195fa152000-07-11 17:35:32 +0000117 if (linkIntoDirFlag == TRUE)
Eric Andersen0b4551f2000-07-10 16:44:03 +0000118 free(linkName);
119
120 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000121 }
Eric Andersenb6106152000-06-19 17:25:40 +0000122 return( TRUE);
Eric Andersencc8ed391999-10-05 16:24:54 +0000123}
Erik Andersen029011b2000-03-04 21:19:32 +0000124
125/*
126Local Variables:
127c-file-style: "linux"
128c-basic-offset: 4
129tab-width: 4
130End:
131*/