home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / apps / posix / source / PAX / REPLACE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-17  |  7.3 KB  |  329 lines

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