$OpenBSD: patch-ctm_ctm_ctm_pass1_c,v 1.2 2007/10/31 23:14:46 ajacoutot Exp $ --- ctm/ctm/ctm_pass1.c.orig Wed Oct 31 23:06:34 2007 +++ ctm/ctm/ctm_pass1.c Wed Oct 31 23:06:34 2007 @@ -23,9 +23,9 @@ Pass1(FILE *fd, unsigned applied) u_char *p,*q; MD5_CTX ctx; int i,j,sep,cnt; - u_char *md5=0,*trash=0; + u_char *md5=0,*name=0,*trash=0; struct CTM_Syntax *sp; - int slashwarn=0; + int slashwarn=0, match=0, total_matches=0; unsigned current; char md5_1[33]; @@ -55,8 +55,10 @@ Pass1(FILE *fd, unsigned applied) GETFIELDCOPY(Prefix,'\n'); /* */ sscanf(Nbr, "%u", ¤t); + if (FilterList || ListIt) + current = 0; /* ignore if -l or if filters are present */ if(current && current <= applied) { - if(Verbose) + if(Verbose > 0) fprintf(stderr,"Delta number %u is already applied; ignoring.\n", current); return Exit_Version; @@ -64,8 +66,14 @@ Pass1(FILE *fd, unsigned applied) for(;;) { Delete(md5); + Delete(name); Delete(trash); cnt = -1; + /* if a filter list is defined we assume that all pathnames require + an action opposite to that requested by the first filter in the + list. + If no filter is defined, all pathnames are assumed to match. */ + match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE); GETFIELD(p,' '); /* CTM_something */ @@ -92,31 +100,61 @@ Pass1(FILE *fd, unsigned applied) sep = ' '; else sep = '\n'; - if(Verbose > 5) - fprintf(stderr," %x(%d)",sp->List[i],sep); + if(Verbose > 5) + fprintf(stderr," %x(%d)",sp->List[i],sep); + switch (j & CTM_F_MASK) { case CTM_F_Name: /* XXX check for garbage and .. */ - GETFIELD(p,sep); - j = strlen(p); - if(p[j-1] == '/' && !slashwarn) { + GETFIELDCOPY(name,sep); + j = strlen(name); + if(name[j-1] == '/' && !slashwarn) { fprintf(stderr,"Warning: contains trailing slash\n"); slashwarn++; } - if (p[0] == '/') { + if (name[0] == '/') { Fatal("Absolute paths are illegal."); return Exit_Mess; } + q = name; for (;;) { - if (p[0] == '.' && p[1] == '.') - if (p[2] == '/' || p[2] == '\0') { + if (q[0] == '.' && q[1] == '.') + if (q[2] == '/' || q[2] == '\0') { Fatal("Paths containing '..' are illegal."); return Exit_Mess; } - if ((p = strchr(p, '/')) == NULL) + if ((q = strchr(q, '/')) == NULL) break; - p++; + q++; } + + /* if we have been asked to `keep' files then skip + removes; i.e. we don't match these entries at + all. */ + if (KeepIt && + (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) { + match = CTM_FILTER_DISABLE; + break; + } + + /* If filter expression have been defined, match the + path name against the expression list. */ + + if (FilterList) { + struct CTM_Filter *filter; + + for (filter = FilterList; filter; + filter = filter->Next) { + if (0 == regexec(&filter->CompiledRegex, name, + 0, 0, 0)) + /* if the name matches, adopt the + action */ + match = filter->Action; + } + } + + /* Add up the total number of matches */ + total_matches += match; break; case CTM_F_Uid: GETFIELD(p,sep); @@ -170,22 +208,22 @@ Pass1(FILE *fd, unsigned applied) p = MD5Data(trash,cnt,md5_1); if(md5 && strcmp(md5,p)) { Fatal("Internal MD5 failed."); - return 1; + return Exit_Garbage; default: fprintf(stderr,"List = 0x%x\n",j); Fatal("List had garbage."); - return 1; - + return Exit_Garbage; } - - } } + } if(Verbose > 5) putc('\n',stderr); - continue; + if(ListIt && match) + printf("> %s %s\n", sp->Key, name); } Delete(md5); + Delete(name); Delete(trash); q = MD5End (&ctx,md5_1); @@ -198,7 +236,7 @@ Pass1(FILE *fd, unsigned applied) Fatal("MD5 sum doesn't match."); fprintf(stderr,"\tI have:<%s>\n",q); fprintf(stderr,"\tShould have been:<%s>\n",p); - return 1; + return Exit_Garbage; } if (-1 != getc(fd)) { if(!Force) { @@ -206,5 +244,7 @@ Pass1(FILE *fd, unsigned applied) return 16; } } - return 0; + if ((Verbose > 1) && (0 == total_matches)) + printf("No matches in \"%s\"\n", FileName); + return (total_matches ? Exit_OK : Exit_NoMatch); }