1/* vi: set sw=4 ts=4: */ 2/* 3 * Mini ln implementation for busybox 4 * 5 * Copyright (C) 1999,2000,2001 by Lineo, inc. 6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 7 * 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 24#include <stdio.h> 25#include <dirent.h> 26#include <string.h> 27#include <stdlib.h> 28#include <errno.h> 29#include <unistd.h> 30#include "busybox.h" 31 32 33static const int LN_SYMLINK = 1; 34static const int LN_FORCE = 2; 35static const int LN_NODEREFERENCE = 4; 36 37/* 38 * linkDestName is where the link points to, 39 * linkSrcName is the name of the link to be created. 40 */ 41static int fs_link(const char *link_destname, const char *link_srcname, 42 const int flag) 43{ 44 int status; 45 int src_is_dir; 46 char *src_name; 47 48 if (link_destname==NULL) 49 return(FALSE); 50 51 src_name = (char *) xmalloc(strlen(link_srcname)+strlen(link_destname)+1); 52 53 if (link_srcname==NULL) 54 strcpy(src_name, link_destname); 55 else 56 strcpy(src_name, link_srcname); 57 58 if (flag&LN_NODEREFERENCE) 59 src_is_dir = is_directory(src_name, TRUE, NULL); 60 else 61 src_is_dir = is_directory(src_name, FALSE, NULL); 62 63 if ((src_is_dir==TRUE)&&((flag&LN_NODEREFERENCE)==0)) { 64 char* srcdir_name; 65 66 srcdir_name = xstrdup(link_destname); 67 strcat(src_name, "/"); 68 strcat(src_name, get_last_path_component(srcdir_name)); 69 free(srcdir_name); 70 } 71 72 if (flag&LN_FORCE) 73 unlink(src_name); 74 75 if (flag&LN_SYMLINK) 76 status = symlink(link_destname, src_name); 77 else 78 status = link(link_destname, src_name); 79 80 if (status != 0) { 81 perror_msg(src_name); 82 return(FALSE); 83 } 84 return(TRUE); 85} 86 87extern int ln_main(int argc, char **argv) 88{ 89 int status = EXIT_SUCCESS; 90 int flag = 0; 91 int opt; 92 93 /* Parse any options */ 94 while ((opt=getopt(argc, argv, "sfn")) != -1) { 95 switch(opt) { 96 case 's': 97 flag |= LN_SYMLINK; 98 break; 99 case 'f': 100 flag |= LN_FORCE; 101 break; 102 case 'n': 103 flag |= LN_NODEREFERENCE; 104 break; 105 default: 106 show_usage(); 107 } 108 } 109 if (optind > (argc-1)) { 110 show_usage(); 111 } 112 if (optind == (argc-1)) { 113 if (fs_link(argv[optind], 114 get_last_path_component(argv[optind]), flag)==FALSE) 115 status = EXIT_FAILURE; 116 } 117 while(optind<(argc-1)) { 118 if (fs_link(argv[optind], argv[argc-1], flag)==FALSE) 119 status = EXIT_FAILURE; 120 optind++; 121 } 122 exit(status); 123} 124 125/* 126Local Variables: 127c-file-style: "linux" 128c-basic-offset: 4 129tab-width: 4 130End: 131*/ 132