]> git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/rename.c
textual: gettextize several overlooked messages
[thirdparty/util-linux.git] / misc-utils / rename.c
1 /*
2 * rename.c - aeb 2000-01-01
3 *
4 --------------------------------------------------------------
5 #!/bin/sh
6 if [ $# -le 2 ]; then echo call: rename from to files; exit; fi
7 FROM="$1"
8 TO="$2"
9 shift
10 shift
11 for i in $@; do N=`echo "$i" | sed "s/$FROM/$TO/g"`; mv "$i" "$N"; done
12 --------------------------------------------------------------
13 * This shell script will do renames of files, but may fail
14 * in cases involving special characters. Here a C version.
15 */
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <getopt.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include "nls.h"
26 #include "xalloc.h"
27 #include "c.h"
28 #include "closestream.h"
29
30 static int do_rename(char *from, char *to, char *s, int verbose, int symtarget)
31 {
32 char *newname, *where, *p, *q, *target;
33 int flen, tlen, slen;
34 struct stat sb;
35
36 if (symtarget) {
37 if (lstat(s, &sb) == -1)
38 err(EXIT_FAILURE, _("%s: lstat failed"), s);
39
40 if (!S_ISLNK(sb.st_mode))
41 errx(EXIT_FAILURE, _("%s: not a symbolic link"), s);
42
43 target = xmalloc(sb.st_size + 1);
44 if (readlink(s, target, sb.st_size + 1) < 0)
45 err(EXIT_FAILURE, _("%s: readlink failed"), s);
46
47 target[sb.st_size] = '\0';
48 where = strstr(target, from);
49 } else
50 where = strstr(s, from);
51
52 if (where == NULL)
53 return 0;
54
55 flen = strlen(from);
56 tlen = strlen(to);
57 if (symtarget) {
58 slen = strlen(target);
59 p = target;
60 } else {
61 slen = strlen(s);
62 p = s;
63 }
64 newname = xmalloc(tlen + slen + 1);
65
66 q = newname;
67 while (p < where)
68 *q++ = *p++;
69 p = to;
70 while (*p)
71 *q++ = *p++;
72 p = where + flen;
73 while (*p)
74 *q++ = *p++;
75 *q = 0;
76
77 if (symtarget) {
78 if (0 > unlink(s))
79 err(EXIT_FAILURE, _("%s: unlink failed"), s);
80 if (symlink(newname, s) != 0)
81 err(EXIT_FAILURE, _("%s: symlinking to %s failed"), s, newname);
82 if (verbose)
83 printf("%s: `%s' -> `%s'\n", s, target, newname);
84 } else {
85 if (rename(s, newname) != 0)
86 err(EXIT_FAILURE, _("%s: rename to %s failed"), s, newname);
87 if (verbose)
88 printf("`%s' -> `%s'\n", s, newname);
89 }
90
91 free(newname);
92 return 1;
93 }
94
95 static void __attribute__ ((__noreturn__)) usage(FILE * out)
96 {
97 fputs(_("\nUsage:\n"), out);
98 fprintf(out,
99 _(" %s [options] expression replacement file...\n"),
100 program_invocation_short_name);
101
102 fputs(_("\nOptions:\n"), out);
103 fputs(_(" -v, --verbose explain what is being done\n"
104 " -V, --version output version information and exit\n"
105 " -s, --symlink act on symlink target\n"
106 " -h, --help display this help and exit\n\n"), out);
107
108 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
109 }
110
111 int main(int argc, char **argv)
112 {
113 char *from, *to;
114 int i, c, symtarget=0, verbose = 0;
115
116 static const struct option longopts[] = {
117 {"verbose", no_argument, NULL, 'v'},
118 {"version", no_argument, NULL, 'V'},
119 {"help", no_argument, NULL, 'h'},
120 {"symlink", no_argument, NULL, 's'},
121 {NULL, 0, NULL, 0}
122 };
123
124 setlocale(LC_ALL, "");
125 bindtextdomain(PACKAGE, LOCALEDIR);
126 textdomain(PACKAGE);
127 atexit(close_stdout);
128
129 while ((c = getopt_long(argc, argv, "vsVh", longopts, NULL)) != -1)
130 switch (c) {
131 case 'v':
132 verbose = 1;
133 break;
134 case 's':
135 symtarget = 1;
136 break;
137 case 'V':
138 printf(UTIL_LINUX_VERSION);
139 return EXIT_SUCCESS;
140 case 'h':
141 usage(stdout);
142 default:
143 usage(stderr);
144 }
145
146 argc -= optind;
147 argv += optind;
148
149 if (argc < 3) {
150 warnx(_("not enough arguments"));
151 usage(stderr);
152 }
153
154 from = argv[0];
155 to = argv[1];
156
157 for (i = 2; i < argc; i++)
158 do_rename(from, to, argv[i], verbose, symtarget);
159
160 return EXIT_SUCCESS;
161 }