diff options
author | gcc <gcc@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2006-08-17 01:18:26 +0000 |
---|---|---|
committer | gcc <gcc@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2006-08-17 01:18:26 +0000 |
commit | 15f34685e7a9b5caf761af2ebf6afa20438d440b (patch) | |
tree | dc04ce3cdf040f198743c15b64557824de174680 /libc/elf/sln.c | |
parent | 1e848e0e775a36f6359161f5deb890942ef42ff3 (diff) | |
download | eglibc2-15f34685e7a9b5caf761af2ebf6afa20438d440b.tar.gz |
Import glibc-mainline for 2006-08-16
git-svn-id: svn://svn.eglibc.org/fsf/trunk@4 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/elf/sln.c')
-rw-r--r-- | libc/elf/sln.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/libc/elf/sln.c b/libc/elf/sln.c new file mode 100644 index 000000000..8e66510bb --- /dev/null +++ b/libc/elf/sln.c @@ -0,0 +1,189 @@ +/* `sln' program to create symbolic links between files. + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <error.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> + +#if !defined S_ISDIR && defined S_IFDIR +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +static int makesymlink (const char *src, const char *dest); +static int makesymlinks (const char *file); + +int +main (int argc, char **argv) +{ + switch (argc) + { + case 2: + return makesymlinks (argv [1]); + break; + + case 3: + return makesymlink (argv [1], argv [2]); + break; + + default: + printf ("Usage: %s src dest|file\n", argv [0]); + return 1; + break; + } +} + +static int +makesymlinks (file) + const char *file; +{ +#ifndef PATH_MAX +#define PATH_MAX 4095 +#endif + char *buffer = NULL; + size_t bufferlen = 0; + int ret; + int lineno; + FILE *fp; + + if (strcmp (file, "-") == 0) + fp = stdin; + else + { + fp = fopen (file, "r"); + if (fp == NULL) + { + fprintf (stderr, "%s: file open error: %m\n", file); + return 1; + } + } + + ret = 0; + lineno = 0; + while (!feof_unlocked (fp)) + { + ssize_t n = getline (&buffer, &bufferlen, fp); + char *src; + char *dest; + char *cp = buffer; + + if (n < 0) + break; + if (buffer[n - 1] == '\n') + buffer[n - 1] = '\0'; + + ++lineno; + while (isspace (*cp)) + ++cp; + if (*cp == '\0') + /* Ignore empty lines. */ + continue; + src = cp; + + do + ++cp; + while (*cp != '\0' && ! isspace (*cp)); + if (*cp != '\0') + *cp++ = '\0'; + + while (isspace (*cp)) + ++cp; + if (*cp == '\0') + { + fprintf (stderr, "No target in line %d\n", lineno); + ret = 1; + continue; + } + dest = cp; + + do + ++cp; + while (*cp != '\0' && ! isspace (*cp)); + if (*cp != '\0') + *cp++ = '\0'; + + ret |= makesymlink (src, dest); + } + fclose (fp); + + return ret; +} + +static int +makesymlink (src, dest) + const char *src; + const char *dest; +{ + struct stat stats; + const char *error; + + /* Destination must not be a directory. */ + if (lstat (dest, &stats) == 0) + { + if (S_ISDIR (stats.st_mode)) + { + fprintf (stderr, "%s: destination must not be a directory\n", + dest); + return 1; + } + else if (unlink (dest) && errno != ENOENT) + { + fprintf (stderr, "%s: failed to remove the old destination\n", + dest); + return 1; + } + } + else if (errno != ENOENT) + { + error = strerror (errno); + fprintf (stderr, "%s: invalid destination: %s\n", dest, error); + return -1; + } + +#ifdef S_ISLNK + if (symlink (src, dest) == 0) +#else + if (link (src, dest) == 0) +#endif + { + /* Destination must exist by now. */ + if (access (dest, F_OK)) + { + error = strerror (errno); + unlink (dest); + fprintf (stderr, "Invalid link from \"%s\" to \"%s\": %s\n", + src, dest, error); + return 1; + } + return 0; + } + else + { + error = strerror (errno); + fprintf (stderr, "Invalid link from \"%s\" to \"%s\": %s\n", + src, dest, error); + return 1; + } +} |