elf: Remove legacy hwcaps support from the dynamic loader
[glibc.git] / elf / sln.c
blob5347338e91671cadb4a1c666b5cf82f5761f86a5
1 /* `sln' program to create symbolic links between files.
2 Copyright (C) 1998-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <error.h>
20 #include <errno.h>
21 #include <libintl.h>
22 #include <locale.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <ctype.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <limits.h>
32 #include "../version.h"
34 #define PACKAGE _libc_intl_domainname
36 static int makesymlink (const char *src, const char *dest);
37 static int makesymlinks (const char *file);
38 static void usage (void);
40 int
41 main (int argc, char **argv)
43 /* Set locale via LC_ALL. */
44 setlocale (LC_ALL, "");
46 /* Set the text message domain. */
47 textdomain (PACKAGE);
49 switch (argc)
51 case 2:
52 if (strcmp (argv[1], "--version") == 0) {
53 printf ("sln %s%s\n", PKGVERSION, VERSION);
54 return 0;
55 } else if (strcmp (argv[1], "--help") == 0) {
56 usage ();
57 return 0;
59 return makesymlinks (argv [1]);
60 break;
62 case 3:
63 return makesymlink (argv [1], argv [2]);
64 break;
66 default:
67 usage ();
68 return 1;
69 break;
73 static void
74 usage (void)
76 printf (_("Usage: sln src dest|file\n\n"));
77 printf (_("For bug reporting instructions, please see:\n\
78 %s.\n"), REPORT_BUGS_TO);
81 static int
82 makesymlinks (const char *file)
84 char *buffer = NULL;
85 size_t bufferlen = 0;
86 int ret;
87 int lineno;
88 FILE *fp;
90 if (strcmp (file, "-") == 0)
91 fp = stdin;
92 else
94 fp = fopen (file, "r");
95 if (fp == NULL)
97 fprintf (stderr, _("%s: file open error: %m\n"), file);
98 return 1;
102 ret = 0;
103 lineno = 0;
104 while (!feof_unlocked (fp))
106 ssize_t n = getline (&buffer, &bufferlen, fp);
107 char *src;
108 char *dest;
109 char *cp = buffer;
111 if (n < 0)
112 break;
113 if (buffer[n - 1] == '\n')
114 buffer[n - 1] = '\0';
116 ++lineno;
117 while (isspace (*cp))
118 ++cp;
119 if (*cp == '\0')
120 /* Ignore empty lines. */
121 continue;
122 src = cp;
125 ++cp;
126 while (*cp != '\0' && ! isspace (*cp));
127 if (*cp != '\0')
128 *cp++ = '\0';
130 while (isspace (*cp))
131 ++cp;
132 if (*cp == '\0')
134 fprintf (stderr, _("No target in line %d\n"), lineno);
135 ret = 1;
136 continue;
138 dest = cp;
141 ++cp;
142 while (*cp != '\0' && ! isspace (*cp));
143 if (*cp != '\0')
144 *cp++ = '\0';
146 ret |= makesymlink (src, dest);
148 fclose (fp);
150 return ret;
153 static int
154 makesymlink (const char *src, const char *dest)
156 struct stat stats;
157 const char *error;
159 /* Destination must not be a directory. */
160 if (lstat (dest, &stats) == 0)
162 if (S_ISDIR (stats.st_mode))
164 fprintf (stderr, _("%s: destination must not be a directory\n"),
165 dest);
166 return 1;
168 else if (unlink (dest) && errno != ENOENT)
170 fprintf (stderr, _("%s: failed to remove the old destination\n"),
171 dest);
172 return 1;
175 else if (errno != ENOENT)
177 error = strerror (errno);
178 fprintf (stderr, _("%s: invalid destination: %s\n"), dest, error);
179 return -1;
182 if (symlink (src, dest) == 0)
184 /* Destination must exist by now. */
185 if (access (dest, F_OK))
187 error = strerror (errno);
188 unlink (dest);
189 fprintf (stderr, _("Invalid link from \"%s\" to \"%s\": %s\n"),
190 src, dest, error);
191 return 1;
193 return 0;
195 else
197 error = strerror (errno);
198 fprintf (stderr, _("Invalid link from \"%s\" to \"%s\": %s\n"),
199 src, dest, error);
200 return 1;