Old match.c
  1 #include <stdio.h>
  2 #include <errno.h>
  3 #include <unistd.h>
  4 #include <string.h>
  5 #include <stdlib.h>
  6 #include <sys/signal.h>
  7 #include <sys/types.h>
  8 #include <sys/ioctl.h>
  9 #include <sys/stat.h>
 10 #include <pwd.h>
 11 #include <grp.h>
 12 #include "patchlevel.h"
 13 
 14 #ifdef HAVEFNMATCH
 15 
 16 #include <fnmatch.h>
 17 
 18 #else
 19 
 20 /* A limited fnmatch replacement. Only accepts patterns 
 21    in the form "ccccc" or "ccccc*". (These were the patterns accepted
 22    by older afio versions.)
 23 
 24 */
 25 
 26 int fnmatch(const char *p, const char *s, int flag)
 27 {
 28   if(p[strlen(p)-1]=='*')
 29       return strncmp(p,s,strlen(p)-1);
 30   else
 31       return strcmp(p,s);
 32 }
 33 
 34 #endif
 35 
 36 #ifdef linux
 37 #include <utime.h>
 38 #endif
 39 
 40 #include "afio.h"
 41 
 42 STATIC int ignoreslash=1;
 43 
 44 /*
 45  * Pathnames to (or not to) be processed.
 46  */
 47 typedef struct pattern
 48 {
 49   struct pattern *p_forw;       /* Forward chain */
 50   char *p_str;                  /* String */
 51   int p_len;                    /* Length of string */
 52   int p_not;                    /* Reverse logic */
 53 } Pattern;
 54 
 55 STATIC Pattern *pattern;        /* Pathname matching patterns */
 56 
 57 /*
 58  * nameadd()
 59  *
 60  * Add a name to the pattern list.
 61  */
 62 STATIC void
 63 nameadd (name, not)
 64      reg char *name;
 65      int not;
 66 {
 67   reg Pattern *px;
 68 
 69   px = (Pattern *) memget (sizeof (Pattern));
 70   px->p_forw = pattern;
 71   px->p_str = strdup(name);
 72    if(px->p_str==NULL) fatal(name,"out of memory.");
 73   px->p_len = strlen (name);
 74   px->p_not = not;
 75   pattern = px;
 76 
 77   /* fprintf(stderr,"--%s added\n",name); */
 78 }
 79 
 80 /*
 81  * nameaddfile()
 82  *
 83  * Add a file of patterns to the pattern list.
 84  * Returns 0 on failure, 1 on success.
 85 */
 86 
 87 STATIC int
 88 nameaddfile(fname,not)
 89      char *fname;
 90      int not;
 91 {
 92  FILE *infile;
 93  char pat[1001];
 94 
 95  infile=fopen(fname,"r");
 96  if(infile==0) return 0;
 97 
 98  while(fgets(pat,1000,infile)!=NULL)
 99    {
100     /* remove \n */
101      pat[strlen(pat)-1]='\0';
102 
103      if(pat[strlen(pat)-1]==' ')
104         warn(pat,"warning: trailing space in this pattern.");
105 
106      nameadd(pat,not);
107    }
108 
109  fclose(infile);
110  return 1;
111 }
112 
113 
114 /*
115  * namecmp()
116  *
117  * Compare a pathname with the pattern list. Returns 0 for
118  * a match, -1 otherwise.
119  * 
120  * This new version uses the GCC library function fnmatch()
121  * to provide real pattern matching.
122  *
123  * Also, this implementation assures that if a file matches a pattern
124  * in the `not to process' list, it is never processed.
125  * In the old version, this depended on several implementation details
126  * and the names in the `to process' list.
127  *
128  * Control files always match.
129  */
130 STATIC int
131 namecmp (name, asb)
132      reg char *name;
133      Stat *asb;
134 {
135   reg Pattern *px;
136   int existpospat; /* there are `to process' patterns in the list */
137   char *namedot,*p,*n;
138   char namec[PATHSIZE];
139 
140   /* fprintf(stderr,"name:\"%s\" rdev:%d\n",name,
141      asb->sb_rdev);
142   */
143 
144   if(asb && ISCONTROL(asb)) return 0;
145 
146   strcpy(namec,name);
147   namedot = strrchr (namec, '.');
148   if (Zflag && asb && (asb->sb_mode & S_IFMT) == S_IFREG
149       && asb->sb_rdev == 0
150       && namedot && namedot[1] == 'z' && !namedot[2]
151      )
152       *namedot = '\0';
153     else
154       namedot = 0;
155 
156   n=namec;
157   if(ignoreslash && (n[0]=='/')) n++;
158 
159   for(px=pattern; px; px=px->p_forw)
160    if(px->p_not)
161      {
162        p=px->p_str;
163        if(ignoreslash && (p[0]=='/')) p++;
164 
165        if(fnmatch(p,n,0)==0) return -1;
166      }
167 
168   existpospat=0;
169 
170   for(px=pattern; px; px=px->p_forw)
171    if(!(px->p_not))
172      {
173        existpospat=1;
174 
175        p=px->p_str;
176        if(ignoreslash && (p[0]=='/')) p++;
177 
178        if(fnmatch(p,n,0)==0) return 0;
179      }
180 
181   if(!existpospat) return 0; else return -1;
182 
183 }
184 
185