1 /* $Source: /u/mark/src/pax/RCS/replace.c,v $
2 *
3 * $Revision: 1.2 $
4 *
5 * replace.c - regular expression pattern replacement functions
6 *
7 * DESCRIPTION
8 *
9 * These routines provide for regular expression file name replacement
10 * as required by pax.
11 *
12 * AUTHORS
13 *
14 * Mark H. Colburn, NAPS International
15 *
16 * Sponsored by The USENIX Association for public distribution.
17 *
18 * Copyright (c) 1989 Mark H. Colburn.
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms are permitted
22 * provided that the above copyright notice is duplicated in all such
23 * forms and that any documentation, advertising materials, and other
24 * materials related to such distribution and use acknowledge that the
25 * software was developed * by Mark H. Colburn and sponsored by The
26 * USENIX Association.
27 *
28 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31 *
32 * $Log: replace.c,v $
33 * Revision 1.2 89/02/12 10:05:59 mark
34 * 1.2 release fixes
35 *
36 * Revision 1.1 88/12/23 18:02:36 mark
37 * Initial revision
38 *
39 */
40
41 #ifndef lint
42 static char *ident = "$Id: replace.c,v 1.2 89/02/12 10:05:59 mark Exp $";
43 static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
44 #endif /* not lint */
45
46 /* Headers */
47
48 #include "pax.h"
49
50
51 /* add_replstr - add a replacement string to the replacement string list
52 *
53 * DESCRIPTION
54 *
55 * Add_replstr adds a replacement string to the replacement string
56 * list which is applied each time a file is about to be processed.
57 *
58 * PARAMETERS
59 *
60 * char *pattern - A regular expression which is to be parsed
61 */
62
63 #ifdef __STDC__
64
add_replstr(char * pattern)65 void add_replstr(char *pattern)
66
67 #else
68
69 void add_replstr(pattern)
70 char *pattern;
71
72 #endif
73 {
74 char *p;
75 char sep;
76 Replstr *rptr;
77 int len;
78
79 if ((len = strlen(pattern)) < 4) {
80 warn("Replacement string not added",
81 "Malformed substitution syntax");
82 return;
83 }
84 if ((rptr = (Replstr *) malloc(sizeof(Replstr))) == (Replstr *)NULL) {
85 warn("Replacement string not added", "No space");
86 return;
87 }
88
89 /* First character is the delimeter... */
90 sep = *pattern;
91
92 /* Get trailing g and/or p */
93 p = pattern + len - 1;
94 while (*p != sep) {
95 if (*p == 'g') {
96 rptr->global = 1;
97 } else if (*p == 'p') {
98 rptr->print = 1;
99 } else {
100 warn(p, "Invalid RE modifier");
101 }
102 p--;
103 }
104
105 if (*p != sep) {
106 warn("Replacement string not added", "Bad delimeters");
107 free(rptr);
108 return;
109 }
110 /* strip off leading and trailing delimeter */
111 *p = '\0';
112 pattern++;
113
114 /* find the separating '/' in the pattern */
115 p = pattern;
116 while (*p) {
117 if (*p == sep) {
118 break;
119 }
120 if (*p == '\\' && *(p + 1) != '\0') {
121 p++;
122 }
123 p++;
124 }
125 if (*p != sep) {
126 warn("Replacement string not added", "Bad delimeters");
127 free(rptr);
128 return;
129 }
130 *p++ = '\0';
131
132 /*
133 * Now pattern points to 'old' and p points to 'new' and both are '\0'
134 * terminated
135 */
136 if ((rptr->comp = regcomp(pattern)) == (regexp *)NULL) {
137 warn("Replacement string not added", "Invalid RE");
138 free(rptr);
139 return;
140 }
141 rptr->replace = p;
142 rptr->next = (Replstr *)NULL;
143 if (rplhead == (Replstr *)NULL) {
144 rplhead = rptr;
145 rpltail = rptr;
146 } else {
147 rpltail->next = rptr;
148 rpltail = rptr;
149 }
150 }
151
152
153
154 /* rpl_name - possibly replace a name with a regular expression
155 *
156 * DESCRIPTION
157 *
158 * The string name is searched for in the list of regular expression
159 * substituions. If the string matches any of the regular expressions
160 * then the string is modified as specified by the user.
161 *
162 * PARAMETERS
163 *
164 * char *name - name to search for and possibly modify
165 */
166
167 #ifdef __STDC__
168
rpl_name(char * name)169 void rpl_name(char *name)
170
171 #else
172
173 void rpl_name(name)
174 char *name;
175
176 #endif
177 {
178 int found = 0;
179 int ret;
180 Replstr *rptr;
181 char buff[PATH_MAX + 1];
182 char buff1[PATH_MAX + 1];
183 char buff2[PATH_MAX + 1];
184 char *p;
185 char *b;
186
187 strcpy(buff, name);
188 for (rptr = rplhead; !found && rptr != (Replstr *)NULL; rptr = rptr->next) {
189 do {
190 if ((ret = regexec(rptr->comp, buff)) != 0) {
191 p = buff;
192 b = buff1;
193 while (p < rptr->comp->startp[0]) {
194 *b++ = *p++;
195 }
196 p = rptr->replace;
197 while (*p) {
198 *b++ = *p++;
199 }
200 strcpy(b, rptr->comp->endp[0]);
201 found = 1;
202 regsub(rptr->comp, buff1, buff2);
203 strcpy(buff, buff2);
204 }
205 } while (ret && rptr->global);
206 if (found) {
207 if (rptr->print) {
208 fprintf(stderr, "%s >> %s\n", name, buff);
209 }
210 strcpy(name, buff);
211 }
212 }
213 }
214
215
216 /* get_disposition - get a file disposition
217 *
218 * DESCRIPTION
219 *
220 * Get a file disposition from the user. If the user enters 'y'
221 * the the file is processed, anything else and the file is ignored.
222 * If the user enters EOF, then the PAX exits with a non-zero return
223 * status.
224 *
225 * PARAMETERS
226 *
227 * char *mode - string signifying the action to be taken on file
228 * char *name - the name of the file
229 *
230 * RETURNS
231 *
232 * Returns 1 if the file should be processed, 0 if it should not.
233 */
234
235 #ifdef __STDC__
236
get_disposition(char * mode,char * name)237 int get_disposition(char *mode, char *name)
238
239 #else
240
241 int get_disposition(mode, name)
242 char *mode;
243 char *name;
244
245 #endif
246 {
247 char ans[2];
248 char buf[PATH_MAX + 10];
249
250 if (f_disposition) {
251 sprintf(buf, "%s %s? ", mode, name);
252 if (nextask(buf, ans, sizeof(ans)) == -1 || ans[0] == 'q') {
253 exit(0);
254 }
255 if (strlen(ans) == 0 || ans[0] != 'y') {
256 return(1);
257 }
258 }
259 return(0);
260 }
261
262
263 /* get_newname - prompt the user for a new filename
264 *
265 * DESCRIPTION
266 *
267 * The user is prompted with the name of the file which is currently
268 * being processed. The user may choose to rename the file by
269 * entering the new file name after the prompt; the user may press
270 * carriage-return/newline, which will skip the file or the user may
271 * type an 'EOF' character, which will cause the program to stop.
272 *
273 * PARAMETERS
274 *
275 * char *name - filename, possibly modified by user
276 * int size - size of allowable new filename
277 *
278 * RETURNS
279 *
280 * Returns 0 if successfull, or -1 if an error occurred.
281 *
282 */
283
284 #ifdef __STDC__
285
get_newname(char * name,int size)286 int get_newname(char *name, int size)
287
288 #else
289
290 int get_newname(name, size)
291 char *name;
292 int size;
293
294 #endif
295 {
296 char buf[PATH_MAX + 10];
297
298 if (f_interactive) {
299 sprintf(buf, "rename %s? ", name);
300 if (nextask(buf, name, size) == -1) {
301 exit(0);
302 }
303 if (strlen(name) == 0) {
304 return(1);
305 }
306 }
307 return(0);
308 }
309