--- ctm/ctm_pass3.c.orig 2018-10-27 15:56:22 UTC +++ ctm/ctm_pass3.c @@ -31,14 +31,22 @@ settime(const char *name, const struct timeval *times) } int +setmodefromchar(const char *name, const u_char *mode) +{ + return chmod(name, strtol(mode, NULL, 8)); +} + +int Pass3(FILE *fd) { u_char *p,*q,buf[BUFSIZ]; MD5_CTX ctx; - int i,j,sep,cnt; + int i,j,sep; + intmax_t cnt,rel; + char *svn_command = NULL; u_char *md5=0,*md5before=0,*trash=0,*name=0,*uid=0,*gid=0,*mode=0; struct CTM_Syntax *sp; - FILE *ed=0; + FILE *ed=0, *fd_to; struct stat st; char md5_1[33]; int match=0; @@ -131,7 +139,7 @@ Pass3(FILE *fd) WRONG found: for(i=0;(j = sp->List[i]);i++) { - if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes) + if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Forward) sep = ' '; else sep = '\n'; @@ -149,53 +157,99 @@ Pass3(FILE *fd) break; case CTM_F_Count: GETBYTECNT(cnt,sep); break; case CTM_F_Bytes: GETDATA(trash,cnt); break; + case CTM_F_Release: GETBYTECNT(rel,sep); break; + case CTM_F_Forward: + if ((j & CTM_Q_MASK) == CTM_Q_Forward_Tar) { + if (Verbose > 0) + fd_to = popen("tar xvf -","w"); + else + fd_to = popen("tar xvf - >/dev/null 2>&1","w"); + } else if ((j & CTM_Q_MASK) == CTM_Q_Forward_SVN) { + svn_command = alloca(strlen(name)+128); + if (Verbose > 0) + snprintf(svn_command,strlen(name)+127,"svnadmin load %s\n", name); + else + snprintf(svn_command,strlen(name)+127,"svnadmin load %s > /dev/null 2>&1\n", name); + fd_to = popen(svn_command,"w"); + } else WRONG + if (fd_to == NULL) { + fprintf(stderr,"Cannot forward\n"); + WRONG + } + if (Verbose > 0) { + if (!strcmp(sp->Key,"TR")) + fprintf(stderr,"> %s\n",sp->Key); + else + fprintf(stderr,"> %s %s\n",sp->Key,name); + } + GETFORWARD(cnt,fd_to); + if (pclose(fd_to)) { + if ((j & CTM_Q_MASK) == CTM_Q_Forward_Tar) + fprintf(stderr,"Tar failed to close properly\n"); + else if ((j & CTM_Q_MASK) == CTM_Q_Forward_SVN) + fprintf(stderr,"Svnadmin failed to close properly\n"); + WRONG + } + if ((j & CTM_Q_MASK) == CTM_Q_Forward_SVN) { + snprintf(svn_command,strlen(name)+127,"svnadmin pack %s\n", name); + if (system(svn_command)) { + fprintf(stderr,"\"%s\" didn't work.", svn_command); + WRONG + } + } + break; default: WRONG } } - /* XXX This should go away. Disallow trailing '/' */ - j = strlen(name)-1; - if(name[j] == '/') name[j] = '\0'; - /* - * 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. - */ + if (name) { + /* XXX This should go away. Disallow trailing '/' */ + j = strlen(name)-1; + if(name[j] == '/') name[j] = '\0'; - 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 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 (CTM_FILTER_DISABLE == match) /* skip file if disabled */ + continue; - if (Verbose > 0) + if (Verbose > 0 && strcmp(sp->Key,"SV") && strcmp(sp->Key,"TR")) fprintf(stderr,"> %s %s\n",sp->Key,name); - if(!strcmp(sp->Key,"FM") || !strcmp(sp->Key, "FS")) { - i = open(name,O_WRONLY|O_CREAT|O_TRUNC,0666); - if(i < 0) { - warn("%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) { + warn("%s", name); + WRONG + } + if(cnt != write(i,trash,cnt)) { + warn("%s", name); + WRONG + } + close(i); + if(strcmp(md5,MD5File(name,md5_1))) { + fprintf(stderr," %s %s MD5 didn't come out right\n", + sp->Key,name); + WRONG + } + if (settime(name,times)) WRONG + if (setmodefromchar(name,mode)) WRONG + continue; } - if(cnt != write(i,trash,cnt)) { - warn("%s", name); - WRONG - } - close(i); - if(strcmp(md5,MD5File(name,md5_1))) { - fprintf(stderr," %s %s MD5 didn't come out right\n", - sp->Key,name); - WRONG - } - if (settime(name,times)) WRONG - continue; } + if(!strcmp(sp->Key,"FE")) { ed = popen("ed","w"); if(!ed) { @@ -218,6 +272,7 @@ Pass3(FILE *fd) WRONG } if (settime(name,times)) WRONG + if (setmodefromchar(name,mode)) WRONG continue; } if(!strcmp(sp->Key,"FN")) { @@ -237,6 +292,7 @@ Pass3(FILE *fd) if (rename(buf,name) == -1) WRONG if (settime(name,times)) WRONG + if (setmodefromchar(name,mode)) WRONG continue; } if(!strcmp(sp->Key,"DM")) { @@ -249,6 +305,7 @@ Pass3(FILE *fd) WRONG } if (settime(name,times)) WRONG + if (setmodefromchar(name,mode)) WRONG continue; } if(!strcmp(sp->Key,"FR")) { @@ -278,6 +335,8 @@ Pass3(FILE *fd) } continue; } + if(!strcmp(sp->Key,"TR") || !strcmp(sp->Key,"SV")) + continue; WRONG }