Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
6.8 KiB

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