source: trunk/athena/etc/synctree/rules.c @ 10717

Revision 10717, 9.4 KB checked in by ghudson, 27 years ago (diff)
Ditch alloca for malloc.
Line 
1/* Copyright (C) 1988  Tim Shepard   All rights reserved. */
2
3#include "synctree.h"
4#include <string.h>
5#include <stdio.h>
6
7extern char *date_db_name;
8extern rule rules[];
9extern unsigned int lastrule;
10extern unsigned int rflag;
11
12extern bool nosrcrules;
13extern bool nodstrules;
14
15extern char *src_rule_file;
16extern char *dst_rule_file;
17
18extern int verbosef;
19
20char srcpath;
21char dstpath;
22
23void compute_ifs();
24
25int findrule(pathname,rtype,ftype,srcpath)
26     enum rule_type rtype;
27     char *pathname, *srcpath;
28{
29    int i;
30    char *p;
31
32    if (verbosef>2) {
33        printf("findrule of |%s| rtype = %d\n", pathname, rtype);
34    }
35
36    /* First we catch the special file names which we never want to be
37     * updated.  They are "." and "..".  If pathname refers to one of
38     * these files, we return rule 0 which should always be a "map *".
39     * We also map ".reconcile_dates*" files (date_db_name) to nowhere
40     * (by using rule 0).
41     */
42
43    if (p = strrchr(pathname,'/'))
44        p++;
45    else
46        p = pathname;
47
48    if ((strcmp(p,".") == 0) || (strcmp(p,"..") == 0) ||
49        (strncmp(p,date_db_name,strlen(date_db_name)) == 0))
50        return
51            (rtype == R_MAP)? 0 :
52    (rtype == R_ACTION)? 1 :
53    panic("findrule: rtype is unexpected rule type for special case");
54 
55    /* now search the normal rules */
56    for (i = lastrule ; i >= 0 ; i--) {
57        switch (rules[i].type) {
58        case R_MAP:
59            if ((rtype == R_MAP) &&
60                hastype(rules[i].u.u_map.file_types,ftype) &&
61                glob_match(rules[i].u.u_map.globexp,pathname))
62                return i;
63            break;
64        case R_CHASE:
65            if ((rtype == R_CHASE) &&
66                (ftype == TYPE_L) &&
67                glob_match(rules[i].u.u_chase.globexp,pathname))
68                return i;
69            break;
70        case R_ACTION:
71            if (verbosef > 2) {
72                printf("Checking for a match with rule %d:\n",i);
73                printf("\tFile types: 0x%02.2x\t(source type: 0x%02.2x)\n",
74                       rules[i].u.u_action.file_types, ftype);
75                printf("\tAction type: %d\n",
76                       rules[i].u.u_action.type);
77            }   
78            if ((rtype == R_ACTION) &&
79                glob_match(rules[i].u.u_action.globexp,pathname))
80                {
81                    if (verbosef > 2) {
82                        printf("Rule %d - regexp passed\n", i);
83                    }
84                   
85                    /*
86                     * A "virtual" file (one that exists only in the target)
87                     * can only have one of a couple actions performed on it:
88                     * "delete" and "ignore"
89                     */
90                    if (hastype(ftype,TYPE_V) &&
91                        rules[i].u.u_action.type != ACTION_DELETE &&
92                        rules[i].u.u_action.type != ACTION_IGNORE)
93                        break;
94
95                    /*
96                     * Don't waste time checking for executables if there is
97                     * already a match...
98                     */
99                    if (hastype(rules[i].u.u_action.file_types,ftype)) {
100                        if (verbosef>2) {
101                            printf("findrule %s - matches general mask; rule %d\n", pathname, i);
102                        }
103                        return i;
104                    }
105         
106                    /*
107                     * We have been unable to establish a match; check if this
108                     * rule applies to executables and if the file in question
109                     * is an executable.
110                     */
111                    if (hastype(rules[i].u.u_action.file_types,TYPE_X) &&
112                        !hastype(rules[i].u.u_action.file_types,TYPE_R) &&
113                        (ftype == TYPE_R))
114                        {
115                            /*
116                             * At this point, we know:
117                             * 1. The pathname matches the pattern supplied.
118                             * 2. The pathname should be an executable.
119                             */
120
121                            int fd, nbytes;
122                            unsigned long       magic;
123                            unsigned short      *smagic =
124                                (unsigned short *)&magic;
125
126#define swabs(a) (((a&0xff00) >> 8) | ((a&0xff) << 8))
127#define swabl(a) ((a>>24)&0xff | (((a>>16)&0xff)<<8) | \
128                  (((a>>8)&0xff)<<16) | ((a&0xff)<<24))
129   
130                            if ((fd=open(srcpath,0,0)) < 0)
131                                break;
132                            nbytes = read(fd,&magic,sizeof(magic));
133                            close(fd);
134
135                            if (nbytes != sizeof(magic))
136                                break;
137
138#ifdef ZMAGIC
139#define xxx(a) case(a): case(swabl(a)):
140                            switch(magic) {
141                            xxx(ZMAGIC);
142                            xxx(NMAGIC);
143                            xxx(OMAGIC);
144#ifdef Z0MAGIC
145                            xxx(Z0MAGIC);
146#endif
147                                if (verbosef>2) {
148                                    printf("findrule %s - matches (COFF executable); rule %d\n", pathname, i);
149                                }
150                                return i;
151
152                            default:
153                                break;  /* Not an a.out executable */
154                            }
155#undef xxx
156#endif /* ZMAGIC */
157
158#ifdef F_EXEC
159#define xxx(a) \
160        if (*smagic == (a) || *smagic == (swabs(a))) { \
161            if (verbosef>2) { \
162                printf("findrule %s - matches (COFF executable); rule %d\n", \
163                       pathname, i); \
164            } \
165            return i; \
166        }
167
168#ifdef B16MAGIC
169                            /* Basic-16 */
170                            xxx(B16MAGIC);
171                            xxx(BTVMAGIC);
172#endif
173#ifdef X86MAGIC
174                            /* x86 */
175                            xxx(X86MAGIC);
176                            xxx(XTVMAGIC);
177#endif
178#ifdef I286SMAGIC
179                            xxx(I286SMAGIC);
180                            xxx(I286LMAGIC);
181#endif
182#ifdef N3BMAGIC
183                            /* n3b */
184                            xxx(N3BMAGIC);
185                            xxx(NTVMAGIC);
186#endif
187#ifdef FBOMAGIC
188                            /* MAC-32, 3b-5 */
189                            xxx(FBOMAGIC);
190                            xxx(RBOMAGIC);
191                            xxx(MTVMAGIC);
192#endif
193#ifdef VAXWRMAGIC
194                            /* VAX 11/780 and VAX 11/750 */
195                            xxx(VAXWRMAGIC);
196                            xxx(VAXROMAGIC);
197#endif
198#ifdef MC68MAGIC
199                            /* Motorola 68000 */
200                            xxx(MC68MAGIC);
201                            xxx(MC68TVMAGIC);
202                            xxx(M68MAGIC);
203                            xxx(M68TVMAGIC);
204#endif
205#ifdef M68NSMAGIC
206                            /* UniSoft additions for 68000 */
207                            xxx(M68NSMAGIC);
208#endif
209#ifdef AMDWRMAGIC
210                            /* Amdahl 470/580 */
211                            xxx(AMDWRMAGIC);
212                            xxx(AMDROMAGIC);
213#endif
214#ifdef U370WRMAGIC
215                            /* IBM 370 */
216                            xxx(U370WRMAGIC);
217                            xxx(U370ROMAGIC);
218#endif
219#ifdef U800WRMAGIC
220                            /* IBM RT */
221                            xxx(U800WRMAGIC);
222                            xxx(U800ROMAGIC);
223                            xxx(U800TOCMAGIC);
224#endif
225#ifdef U802WRMAGIC
226                            /* IBM R2 */
227                            xxx(U802WRMAGIC);
228                            xxx(U802ROMAGIC);
229                            xxx(U802TOCMAGIC);
230#endif
231#ifdef MIPSEBMAGIC
232                            /* DEC Mips */
233                            xxx(MIPSEBMAGIC);
234                            xxx(MIPSELMAGIC);
235                            xxx(SMIPSEBMAGIC);
236                            xxx(SMIPSELMAGIC);
237                            xxx(MIPSEBUMAGIC);
238                            xxx(MIPSELUMAGIC);
239#endif
240
241#undef xxx
242#endif /* F_EXEC */
243                            break;      /* Not an executable */
244                        }
245                }
246            break;
247        case R_WHEN:
248            if ((rtype == R_WHEN) &&
249                hastype(rules[i].u.u_when.file_types,ftype) &&
250                glob_match(rules[i].u.u_when.globexp,pathname))
251                return i;
252            break;
253        case R_IF:
254            if (rules[i].u.u_if.inactive) {
255                i = rules[i].u.u_if.first; /* will be decremented in a moment... */
256                continue;
257            }
258            break;
259        case R_IF_ELSE:
260            if (rules[i].u.u_if.inactive) {
261                /* do nothing (we do the else clause and then hit the skip) */
262            } else {
263                i = rules[i].u.u_if.first; /* will be decremented in a moment... */
264                continue;
265            }
266            break;
267        case R_SKIP:
268            i = rules[i].u.u_skip.first;
269            continue;
270        case R_FRAMEMARKER:
271            break;
272        default:
273            panic("findrule: unknown rule type");
274        }
275    }
276 
277    /* we did not find a rule */
278    switch(rtype) {
279    case R_CHASE:
280    case R_WHEN:
281        /* the code that looks for these types of rules can deal with
282         *          this error return value */
283        return -1;
284    default:
285        panic("findrule: did not find rule");
286    }
287}
288
289
290void getrules(src,dst)
291     char *src;
292     char *dst;
293{
294  char *srcrules,*dstrules;
295  static firstread = 0;
296  extern int aflag;
297  extern char *afile;
298
299  newrule();
300  lstrule.type = R_FRAMEMARKER;
301
302  vtable_push();
303 
304  srcrules = (char *) malloc(strlen(src) + strlen(src_rule_file) + 2);
305  (void) strcpy(srcrules,src);
306  (void) strcat(srcrules,"/");
307  (void) strcat(srcrules,src_rule_file);
308 
309  dstrules = (char *) malloc(strlen(dst) + strlen(dst_rule_file) + 2);
310  (void) strcpy(dstrules,dst);
311  (void) strcat(dstrules,"/");
312  (void) strcat(dstrules,dst_rule_file);
313
314  if (nosrcrules == FALSE)
315    if (readrules(srcrules,src,dst) != 0)
316      { fprintf(stderr,"Error while reading %s\n", srcrules);
317        panic("Syntax error in conf file.");
318      }
319
320  if (nodstrules == FALSE)
321    if (readrules(dstrules,src,dst) != 0)
322      { fprintf(stderr,"Error while reading %s\n",dstrules);
323        panic("Syntax error in conf file.");
324      }
325
326  if (!(firstread++) && aflag && readrules(afile,src,dst) != 0)
327    { fprintf(stderr,"Error while reading %s\n",afile);
328      panic("Syntax error in conf file.");
329    }
330 
331  compute_ifs();  /* see below */
332  free(dstrules);
333  free(srcrules);
334}
335
336
337void poprules()
338{
339  vtable_pop();
340
341  for(;;lastrule--) {
342    switch(lstrule.type) {
343    case R_MAP:
344      sfree(lstrule.u.u_map.globexp);
345      svecfree(lstrule.u.u_map.dests);
346      continue;
347    case R_CHASE:
348      sfree(lstrule.u.u_chase.globexp);
349      continue;
350    case R_ACTION:
351      sfree(lstrule.u.u_action.globexp);
352      continue;
353    case R_WHEN:
354      sfree(lstrule.u.u_when.globexp);
355      svecfree(lstrule.u.u_when.cmds);
356      continue;
357    case R_IF:
358    case R_IF_ELSE:
359      bool_free(lstrule.u.u_if.boolexp);
360      continue;
361    case R_FRAMEMARKER:
362      break;
363    default:
364       panic("poprules: unknown rule type");
365    }
366    lastrule--;
367    break;
368  }
369
370#ifdef notdef
371  /* This doesn't need to be done here because, reconcile will not call */
372  /* findrule after calling this without first calling getrules. If */
373  /* this ever changes, this will have to be turned on again. */
374  compute_ifs();  /* defined below */
375#endif notdef
376}
377
378static void compute_ifs()
379{
380  int i;
381
382  rflag &= ~RFLAG_SCAN_TARGET;
383 
384  for(i = lastrule; i >= 0; i--) {
385    switch(rules[i].type) {
386    case R_IF:
387    case R_IF_ELSE:
388      rules[i].u.u_if.inactive = (bool) ! bool_eval(rules[i].u.u_if.boolexp);
389      break;
390    case R_CHASE:
391    case R_MAP:
392    case R_WHEN:
393    case R_FRAMEMARKER:
394      break;
395    case R_ACTION:
396      if (rules[i].u.u_action.type == ACTION_DELETE)
397          rflag |= RFLAG_SCAN_TARGET;
398      break;
399    default:
400      panic("compute_ifs: unknown rule type");
401    }
402  }
403}
404
405
406void newrule()
407{
408    if (++lastrule >= MAXNRULES)
409        panic("newrule: too many rules");
410    if (verbosef > 2)
411        printf("newrule: lastrule = %d\n",lastrule);
412}
413   
414 
Note: See TracBrowser for help on using the repository browser.