diff -ur /usr/src/usr.sbin/ctm/mkCTM/mkctm.c mkCTM/mkctm.c --- /usr/src/usr.sbin/ctm/mkCTM/mkctm.c 2010-04-24 17:19:38.000000000 -0500 +++ mkCTM/mkctm.c 2011-12-24 22:42:37.000000000 -0600 @@ -493,6 +493,134 @@ free(nl2); } +void +Do_ctm_status(const char *dir1, const char *dir2) +{ + char *name = ""; + int i1, i2, n1, n2, i; + struct dirent **nl1, **nl2; + char *buf1 = alloca(strlen(dir1) + strlen(name) + 4); + char *buf2 = alloca(strlen(dir2) + strlen(name) + 4); + + strcpy(buf1, dir1); strcat(buf1, "/"); strcat(buf1, name); + strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, name); + n1 = scandir(buf1, &nl1, dirselect, alphasort); + n2 = scandir(buf2, &nl2, dirselect, alphasort); + i1 = i2 = -1; + GetNext(&i1, &n1, nl1, dir1, name, &s1_ignored, &s1_bogus, &s1_wrong); + GetNext(&i2, &n2, nl2, dir2, name, &s2_ignored, &s2_bogus, &s2_wrong); + for (;i1 < n1 || i2 < n2;) { + + if (damage_limit && damage > damage_limit) + break; + + /* Get next item from list 1 */ + if (i1 < n1 && !nl1[i1]) + GetNext(&i1, &n1, nl1, dir1, name, + &s1_ignored, &s1_bogus, &s1_wrong); + + /* Get next item from list 2 */ + if (i2 < n2 && !nl2[i2]) + GetNext(&i2, &n2, nl2, dir2, name, + &s2_ignored, &s2_bogus, &s2_wrong); + + if (i1 >= n1 && i2 >= n2) { + /* Done */ + break; + } else if (i1 >= n1 && i2 < n2) { + /* end of list 1 */ + if (strcmp(nl2[i2]->d_name,".ctm_status")==0) + Add(dir1, dir2, name, nl2[i2]); + free(nl2[i2]); nl2[i2] = 0; + } else if (i1 < n1 && i2 >= n2) { + /* end of list 2 */ + free(nl1[i1]); nl1[i1] = 0; + } else if (!(i = strcmp(nl1[i1]->d_name, nl2[i2]->d_name))) { + /* Identical names */ + if (nl1[i1]->d_type == nl2[i2]->d_type && strcmp(nl1[i1]->d_name,".ctm_status")==0) { + /* same type and .ctm_status */ + Equ(dir1, dir2, name, nl1[i1]); + } + free(nl1[i1]); nl1[i1] = 0; + free(nl2[i2]); nl2[i2] = 0; + } else if (i < 0) { + /* Something extra in list 1, delete it */ + free(nl1[i1]); nl1[i1] = 0; + } else { + /* Something extra in list 2, add it */ + free(nl2[i2]); nl2[i2] = 0; + } + } + if (n1 >= 0) + free(nl1); + if (n2 >= 0) + free(nl2); +} + +void +DoSvn(const char *dir1, const char *dir2) +{ + char current_file[] = "base/db/current"; + char *buf1 = alloca(strlen(dir1) + strlen(current_file) + 4); + char *buf2 = alloca(strlen(dir2) + strlen(current_file) + 4); + char *tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL) + tmpdir = strdup(_PATH_TMP); + char tmpfilebase[] = "/CTMserver.XXXXXXXXXX"; + char *tmpfilename = alloca(strlen(tmpdir)+strlen(tmpfilebase)+4); + int command_size = strlen(dir2) + strlen(tmpdir)+strlen(tmpfilebase) + 128; + char *command = alloca(command_size+1); + long int release1, release2; + FILE *current1, *current2; + int ret_val; + + Do_ctm_status(dir1, dir2); + + strcpy(buf1, dir1); strcat(buf1, "/"); strcat(buf1, current_file); + strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, current_file); + strcpy(tmpfilename, tmpdir); strcat(tmpfilename, tmpfilebase); + mktemp(tmpfilename); + + current1 = fopen(buf1,"r"); + current2 = fopen(buf2,"r"); + + if (current1 != NULL) { + fscanf(current1,"%ld",&release1); + fclose(current1); + } else + release1 = -1; + if (current2 != NULL) { + fscanf(current2,"%ld",&release2); + fclose(current2); + } else + release2 = -1; + + if (release1 == -1) { + snprintf(command,command_size,"tar -C %s -cvf %s base 2>&%d\n",dir2,tmpfilename,fileno(logf)); + fflush(logf); + ret_val = system(command); + if (ret_val!=0) errx(1,"The command \"%s\" failed with return value %d",command,ret_val); + printf("CTMTR "); + change++; + } else if (release2 > release1) { + snprintf(command,command_size,"svnadmin dump %s/base -r %ld:%ld --incremental --deltas 2>&%d > %s\n",dir2,release1+1,release2,fileno(logf),tmpfilename); + fflush(logf); + ret_val = system(command); + if (ret_val!=0) errx(1,"The command \"%s\" failed with return value %d",command,ret_val); + printf("CTMSV %ld ",release1); + change++; + } + + if (change >= 2) { + StatFile(tmpfilename); + printf("%jd\n", st.st_size); + snprintf(command,command_size,"cat %s; rm -f %s\n",tmpfilename,tmpfilename); + ret_val = system(command); + if (ret_val!=0) errx(1,"The command \"%s\" failed with return value %d",command,ret_val); + putchar('\n'); + } +} + int main(int argc, char **argv) { @@ -581,7 +709,10 @@ argv[0], argv[1], argv[2], argv[3]); printf("CTM_BEGIN 2.0 %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]); - DoDir(argv[4], argv[5], ""); + if (strncmp(argv[0],"svn",3) == 0) + DoSvn(argv[4], argv[5]); + else + DoDir(argv[4], argv[5], ""); if (damage_limit && damage > damage_limit) { print_stat(stderr, "DAMAGE: "); errx(1, "damage of %d would exceed %d files", @@ -591,7 +722,8 @@ } else { printf("CTM_END "); fprintf(logf, "CTM_END\n"); - print_stat(stderr, "END: "); + if (strncmp(argv[0],"svn",3) != 0) + print_stat(stderr, "END: "); } exit(0); }