replace.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. #ifndef lint
  41. static char *ident = "$Id: replace.c,v 1.2 89/02/12 10:05:59 mark Exp $";
  42. static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  43. #endif /* not lint */
  44. /* Headers */
  45. #include "pax.h"
  46. /* add_replstr - add a replacement string to the replacement string list
  47. *
  48. * DESCRIPTION
  49. *
  50. * Add_replstr adds a replacement string to the replacement string
  51. * list which is applied each time a file is about to be processed.
  52. *
  53. * PARAMETERS
  54. *
  55. * char *pattern - A regular expression which is to be parsed
  56. */
  57. #ifdef __STDC__
  58. void add_replstr(char *pattern)
  59. #else
  60. void add_replstr(pattern)
  61. char *pattern;
  62. #endif
  63. {
  64. char *p;
  65. char sep;
  66. Replstr *rptr;
  67. int len;
  68. if ((len = strlen(pattern)) < 4) {
  69. warn("Replacement string not added",
  70. "Malformed substitution syntax");
  71. return;
  72. }
  73. if ((rptr = (Replstr *) malloc(sizeof(Replstr))) == (Replstr *)NULL) {
  74. warn("Replacement string not added", "No space");
  75. return;
  76. }
  77. /* First character is the delimeter... */
  78. sep = *pattern;
  79. /* Get trailing g and/or p */
  80. p = pattern + len - 1;
  81. while (*p != sep) {
  82. if (*p == 'g') {
  83. rptr->global = 1;
  84. } else if (*p == 'p') {
  85. rptr->print = 1;
  86. } else {
  87. warn(p, "Invalid RE modifier");
  88. }
  89. p--;
  90. }
  91. if (*p != sep) {
  92. warn("Replacement string not added", "Bad delimeters");
  93. free(rptr);
  94. return;
  95. }
  96. /* strip off leading and trailing delimeter */
  97. *p = '\0';
  98. pattern++;
  99. /* find the separating '/' in the pattern */
  100. p = pattern;
  101. while (*p) {
  102. if (*p == sep) {
  103. break;
  104. }
  105. if (*p == '\\' && *(p + 1) != '\0') {
  106. p++;
  107. }
  108. p++;
  109. }
  110. if (*p != sep) {
  111. warn("Replacement string not added", "Bad delimeters");
  112. free(rptr);
  113. return;
  114. }
  115. *p++ = '\0';
  116. /*
  117. * Now pattern points to 'old' and p points to 'new' and both are '\0'
  118. * terminated
  119. */
  120. if ((rptr->comp = regcomp(pattern)) == (regexp *)NULL) {
  121. warn("Replacement string not added", "Invalid RE");
  122. free(rptr);
  123. return;
  124. }
  125. rptr->replace = p;
  126. rptr->next = (Replstr *)NULL;
  127. if (rplhead == (Replstr *)NULL) {
  128. rplhead = rptr;
  129. rpltail = rptr;
  130. } else {
  131. rpltail->next = rptr;
  132. rpltail = rptr;
  133. }
  134. }
  135. /* rpl_name - possibly replace a name with a regular expression
  136. *
  137. * DESCRIPTION
  138. *
  139. * The string name is searched for in the list of regular expression
  140. * substituions. If the string matches any of the regular expressions
  141. * then the string is modified as specified by the user.
  142. *
  143. * PARAMETERS
  144. *
  145. * char *name - name to search for and possibly modify
  146. */
  147. #ifdef __STDC__
  148. void rpl_name(char *name)
  149. #else
  150. void rpl_name(name)
  151. char *name;
  152. #endif
  153. {
  154. int found = 0;
  155. int ret;
  156. Replstr *rptr;
  157. char buff[PATH_MAX + 1];
  158. char buff1[PATH_MAX + 1];
  159. char buff2[PATH_MAX + 1];
  160. char *p;
  161. char *b;
  162. strcpy(buff, name);
  163. for (rptr = rplhead; !found && rptr != (Replstr *)NULL; rptr = rptr->next) {
  164. do {
  165. if ((ret = regexec(rptr->comp, buff)) != 0) {
  166. p = buff;
  167. b = buff1;
  168. while (p < rptr->comp->startp[0]) {
  169. *b++ = *p++;
  170. }
  171. p = rptr->replace;
  172. while (*p) {
  173. *b++ = *p++;
  174. }
  175. strcpy(b, rptr->comp->endp[0]);
  176. found = 1;
  177. regsub(rptr->comp, buff1, buff2);
  178. strcpy(buff, buff2);
  179. }
  180. } while (ret && rptr->global);
  181. if (found) {
  182. if (rptr->print) {
  183. fprintf(stderr, "%s >> %s\n", name, buff);
  184. }
  185. strcpy(name, buff);
  186. }
  187. }
  188. }
  189. /* get_disposition - get a file disposition
  190. *
  191. * DESCRIPTION
  192. *
  193. * Get a file disposition from the user. If the user enters 'y'
  194. * the the file is processed, anything else and the file is ignored.
  195. * If the user enters EOF, then the PAX exits with a non-zero return
  196. * status.
  197. *
  198. * PARAMETERS
  199. *
  200. * char *mode - string signifying the action to be taken on file
  201. * char *name - the name of the file
  202. *
  203. * RETURNS
  204. *
  205. * Returns 1 if the file should be processed, 0 if it should not.
  206. */
  207. #ifdef __STDC__
  208. int get_disposition(char *mode, char *name)
  209. #else
  210. int get_disposition(mode, name)
  211. char *mode;
  212. char *name;
  213. #endif
  214. {
  215. char ans[2];
  216. char buf[PATH_MAX + 10];
  217. if (f_disposition) {
  218. sprintf(buf, "%s %s? ", mode, name);
  219. if (nextask(buf, ans, sizeof(ans)) == -1 || ans[0] == 'q') {
  220. exit(0);
  221. }
  222. if (strlen(ans) == 0 || ans[0] != 'y') {
  223. return(1);
  224. }
  225. }
  226. return(0);
  227. }
  228. /* get_newname - prompt the user for a new filename
  229. *
  230. * DESCRIPTION
  231. *
  232. * The user is prompted with the name of the file which is currently
  233. * being processed. The user may choose to rename the file by
  234. * entering the new file name after the prompt; the user may press
  235. * carriage-return/newline, which will skip the file or the user may
  236. * type an 'EOF' character, which will cause the program to stop.
  237. *
  238. * PARAMETERS
  239. *
  240. * char *name - filename, possibly modified by user
  241. * int size - size of allowable new filename
  242. *
  243. * RETURNS
  244. *
  245. * Returns 0 if successfull, or -1 if an error occurred.
  246. *
  247. */
  248. #ifdef __STDC__
  249. int get_newname(char *name, int size)
  250. #else
  251. int get_newname(name, size)
  252. char *name;
  253. int size;
  254. #endif
  255. {
  256. char buf[PATH_MAX + 10];
  257. if (f_interactive) {
  258. sprintf(buf, "rename %s? ", name);
  259. if (nextask(buf, name, size) == -1) {
  260. exit(0);
  261. }
  262. if (strlen(name) == 0) {
  263. return(1);
  264. }
  265. }
  266. return(0);
  267. }