$OpenBSD: patch-ctm_ctm_ctm_pass3_c,v 1.2 2007/10/31 23:14:46 ajacoutot Exp $ --- ctm/ctm/ctm_pass3.c.orig Wed Oct 31 23:06:34 2007 +++ ctm/ctm/ctm_pass3.c Wed Oct 31 23:06:34 2007 @@ -22,7 +22,7 @@ settime(const char *name, const struct timeval *times) { if (SetTime) if (utimes(name,times)) { - fprintf(stderr, " utimes(): %s: %s\n", name, strerror(errno)); + warn("utimes(): %s", name); return -1; } return 0; @@ -39,8 +39,9 @@ Pass3(FILE *fd) FILE *ed=0; struct stat st; char md5_1[33]; + int match=0; struct timeval times[2]; - + struct CTM_Filter *filter = NULL; if(Verbose>3) printf("Pass3 -- Applying the CTM-patch\n"); MD5Init (&ctx); @@ -139,10 +140,11 @@ Pass3(FILE *fd) case CTM_F_Gid: GETFIELDCOPY(gid,sep); break; case CTM_F_Mode: GETFIELDCOPY(mode,sep); break; case CTM_F_MD5: - if(j & CTM_Q_MD5_Before) + if(j & CTM_Q_MD5_Before) { GETFIELDCOPY(md5before,sep); - else + } else { GETFIELDCOPY(md5,sep); + } break; case CTM_F_Count: GETBYTECNT(cnt,sep); break; case CTM_F_Bytes: GETDATA(trash,cnt); break; @@ -153,15 +155,55 @@ Pass3(FILE *fd) j = strlen(name)-1; if(name[j] == '/') name[j] = '\0'; - fprintf(stderr,"> %s %s\n",sp->Key,name); + /* + * If a filter list is specified, run thru the filter list and + * match `name' against filters. If the name matches, set the + * required action to that specified in the filter. + * The default action if no filterlist is given is to match + * everything. + */ + + match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE); + for (filter = FilterList; filter; filter = filter->Next) { + if (0 == regexec(&filter->CompiledRegex, name, + 0, 0, 0)) { + match = filter->Action; + } + } + + if (CTM_FILTER_DISABLE == match) /* skip file if disabled */ + continue; + + if (Verbose > 0) + fprintf(stderr,"> %s %s\n",sp->Key,name); + if ((strcmp(sp->Key, "FS") == 0 || + strcmp(sp->Key, "FN") == 0 || + strcmp(sp->Key, "FE") == 0) && -1 == access(name, W_OK)) { + if (Verbose > 1) + fprintf(stderr, " %s: chmod u+w %s\n", + sp->Key, name); + if (!Force) { + warn("%s", name); + WRONG + } + if (-1 == stat(name, &st)) { + warn("stat: %s", name); + WRONG + } + if (-1 == chmod(name, st.st_mode | S_IWUSR)) { + warn("chmod: %s", name); + WRONG + } + } + if(!strcmp(sp->Key,"FM") || !strcmp(sp->Key, "FS")) { i = open(name,O_WRONLY|O_CREAT|O_TRUNC,0666); if(i < 0) { - perror(name); + warn("%s", name); WRONG } if(cnt != write(i,trash,cnt)) { - perror(name); + warn("%s", name); WRONG } close(i); @@ -180,13 +222,13 @@ Pass3(FILE *fd) } fprintf(ed,"e %s\n",name); if(cnt != fwrite(trash,1,cnt,ed)) { - perror(name); + warn("%s", name); pclose(ed); WRONG } fprintf(ed,"w %s\n",name); if(pclose(ed)) { - perror("ed"); + warn("ed"); WRONG } if(strcmp(md5,MD5File(name,md5_1))) { @@ -206,12 +248,13 @@ Pass3(FILE *fd) sp->Key,name,i); WRONG } - rename(buf,name); - if(strcmp(md5,MD5File(name,md5_1))) { + if(strcmp(md5,MD5File(buf,md5_1))) { fprintf(stderr," %s %s Edit failed MD5 check.\n", sp->Key,name); WRONG } + if (rename(buf,name) == -1) + WRONG if (settime(name,times)) WRONG continue; } @@ -228,7 +271,11 @@ Pass3(FILE *fd) continue; } if(!strcmp(sp->Key,"FR")) { - if (0 != unlink(name)) { + if (KeepIt) { + if (Verbose > 1) + printf("<%s> not removed\n", name); + } + else if (0 != unlink(name)) { fprintf(stderr,"<%s> unlink failed\n",name); if (!Force) WRONG @@ -240,8 +287,14 @@ Pass3(FILE *fd) * We cannot use rmdir() because we do not get the directories * in '-depth' order (cvs-cur.0018.gz for examples) */ - sprintf(buf,"rm -rf %s",name); - system(buf); + if (KeepIt) { + if (Verbose > 1) { + printf("<%s> not removed\n", name); + } + } else { + sprintf(buf,"rm -rf %s",name); + system(buf); + } continue; } WRONG