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