diff options
Diffstat (limited to 'misc/ctm/files/patch-mkCTM_mkctm.c')
-rw-r--r-- | misc/ctm/files/patch-mkCTM_mkctm.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/misc/ctm/files/patch-mkCTM_mkctm.c b/misc/ctm/files/patch-mkCTM_mkctm.c new file mode 100644 index 000000000000..8a7952f0a6e1 --- /dev/null +++ b/misc/ctm/files/patch-mkCTM_mkctm.c @@ -0,0 +1,269 @@ +--- mkCTM/mkctm.c.orig 2018-10-27 15:56:22 UTC ++++ mkCTM/mkctm.c +@@ -181,12 +181,16 @@ Equ(const char *dir1, const char *dir2, const char *na + goto finish; + } + #endif +- p1=mmap(0, s1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); +- if (p1 == (u_char *)MAP_FAILED) { err(3, "%s", buf1); } ++ if (s1.st_size) { ++ p1=mmap(0, s1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); ++ if (p1 == (u_char *)MAP_FAILED) { err(3, "%s", buf1); } ++ } + close(fd1); + +- p2=mmap(0, s2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); +- if (p2 == (u_char *)MAP_FAILED) { err(3, "%s", buf2); } ++ if (s2.st_size) { ++ p2=mmap(0, s2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); ++ if (p2 == (u_char *)MAP_FAILED) { err(3, "%s", buf2); } ++ } + close(fd2); + + /* If identical, we're done. */ +@@ -222,6 +226,9 @@ Equ(const char *dir1, const char *dir2, const char *na + int j; + FILE *F; + ++ if (!s1.st_size || !s2.st_size) ++ goto subst; ++ + if (s1.st_size && p1[s1.st_size-1] != '\n') { + if (verbose > 0) + fprintf(stderr, +@@ -295,8 +302,10 @@ Equ(const char *dir1, const char *dir2, const char *na + free(ob); + } + finish: +- munmap(p1, s1.st_size); +- munmap(p2, s2.st_size); ++ if (s1.st_size) ++ munmap(p1, s1.st_size); ++ if (s2.st_size) ++ munmap(p2, s2.st_size); + } + } + +@@ -325,15 +334,19 @@ Add(const char *dir1, const char *dir2, const char *na + fd1 = open(buf2, O_RDONLY); + if (fd1 < 0) { err(3, "%s", buf2); } + fstat(fd1, &st); +- p1=mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); +- if (p1 == (u_char *)MAP_FAILED) { err(3, "%s", buf2); } ++ if (st.st_size) { ++ p1=mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); ++ if (p1 == (u_char *)MAP_FAILED) { err(3, "%s", buf2); } ++ } + close(fd1); + m2 = MD5Data(p1, st.st_size, md5_2); + name_stat("CTMFM", dir2, name, de); + printf(" %s %u\n", m2, (unsigned)st.st_size); +- fwrite(p1, 1, st.st_size, stdout); ++ if (st.st_size) ++ fwrite(p1, 1, st.st_size, stdout); + putchar('\n'); +- munmap(p1, st.st_size); ++ if (st.st_size) ++ munmap(p1, st.st_size); + s_new_files++; + s_new_bytes += st.st_size; + } +@@ -493,6 +506,172 @@ DoDir(const char *dir1, const char *dir2, const char * + free(nl2); + } + ++void ++SvnAdd(const char *dir1, const char *dir2, struct dirent *de) ++{ ++ char current_file[] = "/db/current"; ++ char *buf2 = alloca(strlen(dir2) + strlen(current_file) + strlen(de->d_name) + 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) + strlen(de->d_name) + 128; ++ char *command = alloca(command_size+1); ++ int ret_val; ++ ++ strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, de->d_name); strcat(buf2, current_file); ++ strcpy(tmpfilename, tmpdir); strcat(tmpfilename, tmpfilebase); ++ mktemp(tmpfilename); ++ ++ snprintf(command,command_size,"tar -C %s -cvf %s %s 2>&%d\n",dir2,tmpfilename,de->d_name,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 += 2; /* Make sure change is big enough .*/ ++ ++ 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'); ++} ++ ++void ++SvnEqu(const char *dir1, const char *dir2, struct dirent *de) ++{ ++ char current_file[] = "/db/current"; ++ char *buf1 = alloca(strlen(dir1) + strlen(current_file) + strlen(de->d_name) + 4); ++ char *buf2 = alloca(strlen(dir2) + strlen(current_file) + strlen(de->d_name) + 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) + strlen(de->d_name) + 128; ++ char *command = alloca(command_size+1); ++ long int release1, release2; ++ FILE *current1, *current2; ++ int ret_val; ++ ++ strcpy(buf1, dir1); strcat(buf1, "/"); strcat(buf1, de->d_name); strcat(buf1, current_file); ++ strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, de->d_name); 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 ++ errx(1,"No db/release in %s",buf1); ++ if (current2 != NULL) { ++ fscanf(current2,"%ld",&release2); ++ fclose(current2); ++ } else ++ errx(1,"No db/release in %s",buf2); ++ ++ if (release2 > release1) { ++ snprintf(command,command_size,"svnadmin dump %s/%s -r %ld:%ld --incremental --deltas 2>&%d > %s\n",dir2,de->d_name,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 %s %ld ", de->d_name, release1); ++ change += 2; /* Make sure change is big enough .*/ ++ ++ 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'); ++ } ++} ++ ++void ++DoSvn(const char *dir1, const char *dir2) ++{ ++ int i1, i2, n1, n2, i; ++ struct dirent **nl1, **nl2; ++ char *buf1 = alloca(strlen(dir1) + 4); ++ char *buf2 = alloca(strlen(dir2) + 4); ++ ++ strcpy(buf1, dir1); strcat(buf1, "/"); ++ strcpy(buf2, dir2); strcat(buf2, "/"); ++ n1 = scandir(buf1, &nl1, dirselect, alphasort); ++ n2 = scandir(buf2, &nl2, dirselect, alphasort); ++ i1 = i2 = -1; ++ GetNext(&i1, &n1, nl1, dir1, "", &s1_ignored, &s1_bogus, &s1_wrong); ++ GetNext(&i2, &n2, nl2, dir2, "", &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, "", ++ &s1_ignored, &s1_bogus, &s1_wrong); ++ ++ /* Get next item from list 2 */ ++ if (i2 < n2 && !nl2[i2]) ++ GetNext(&i2, &n2, nl2, dir2, "", ++ &s2_ignored, &s2_bogus, &s2_wrong); ++ ++ if (i1 >= n1 && i2 >= n2) { ++ /* Done */ ++ break; ++ } else if (i1 >= n1 && i2 < n2) { ++ /* end of list 1, add anything left on list 2 */ ++ if (nl2[i2]->d_type == DT_REG) { ++ if (strcmp(nl2[i2]->d_name,".ctm_status")==0) ++ Add(dir1, dir2, "", nl2[i2]); ++ else ++ errx(1,"Improper file found in svn archive"); ++ } else ++ SvnAdd(dir1, dir2, nl2[i2]); ++ free(nl2[i2]); nl2[i2] = 0; ++ } else if (i1 < n1 && i2 >= n2) { ++ /* end of list 2, delete anything left on list 1 */ ++ Del(dir1, dir2, "", nl1[i1]); ++ free(nl1[i1]); nl1[i1] = 0; ++ } else if (!(i = strcmp(nl1[i1]->d_name, nl2[i2]->d_name))) { ++ /* Identical names */ ++ if (nl2[i1]->d_type == DT_REG && nl2[i2]->d_type == DT_REG && strcmp(nl2[i2]->d_name,".ctm_status")==0) ++ Equ(dir1, dir2, "", nl1[i1]); ++ else if (nl2[i1]->d_type == DT_DIR && nl2[i2]->d_type == DT_DIR) ++ SvnEqu(dir1, dir2, nl1[i1]); ++ else ++ ++ errx(1,"Improper file found in svn archive"); ++ free(nl1[i1]); nl1[i1] = 0; ++ free(nl2[i2]); nl2[i2] = 0; ++ } else if (i < 0) { ++ /* Something extra in list 1, delete it */ ++ Del(dir1, dir2, "", nl1[i1]); ++ free(nl1[i1]); nl1[i1] = 0; ++ } else { ++ /* Something extra in list 2, add it */ ++ if (nl2[i2]->d_type == DT_REG) { ++ if (strcmp(nl2[i2]->d_name,".ctm_status")==0) ++ Add(dir1, dir2, "", nl2[i2]); ++ else ++ errx(1,"Improper file found in svn archive"); ++ } else ++ SvnAdd(dir1, dir2, nl2[i2]); ++ free(nl2[i2]); nl2[i2] = 0; ++ } ++ } ++ if (n1 >= 0) ++ free(nl1); ++ if (n2 >= 0) ++ free(nl2); ++} ++ + int + main(int argc, char **argv) + { +@@ -581,17 +760,22 @@ main(int argc, char **argv) + 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", + damage, damage_limit); +- } else if (change < 2) { ++/* change <= 2 means no change because of .ctm_status and .svn_revision */ ++ } else if (change < 3) { + errx(4, "no changes"); + } 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); + } |