void Del (const char *dir1, const char *dir2, const char *name, struct dirent *de) { damage++; change++; if (de->d_type == DT_DIR) { char *p = alloca(strlen(name)+strlen(de->d_name)+2); strcpy(p, name); strcat(p, de->d_name); strcat(p, "/"); DoDir(dir1, dir2, p); printf("CTMDR %s%s\n", name, de->d_name); fprintf(logf, "CTMDR %s%s\n", name, de->d_name); if (verbose > 1) { fprintf(stderr, "CTMDR %s%s\n", name, de->d_name); } s_del_dirs++; } else if (de->d_type == DT_REG) { char *buf1 = alloca(strlen(dir1) + strlen(name) + strlen(de->d_name) + 3); char *m1, md5_1[33]; strcpy(buf1, dir1); strcat(buf1, "/"); strcat(buf1, name); strcat(buf1, "/"); strcat(buf1, de->d_name); m1 = MD5File(buf1, md5_1); printf("CTMFR %s%s %s\n", name, de->d_name, m1); fprintf(logf, "CTMFR %s%s %s\n", name, de->d_name, m1); if (verbose > 1) { fprintf(stderr, "CTMFR %s%s\n", name, de->d_name); } s_del_files++; s_del_bytes += StatFile(buf1)->st_size; } }
bool XmlView::Key(dword key, int) { if(key == K_ENTER) { DoDir(); return true; } return false; }
void Add(const char *dir1, const char *dir2, const char *name, struct dirent *de) { change++; if (de->d_type == DT_DIR) { char *p = alloca(strlen(name)+strlen(de->d_name)+2); strcpy(p, name); strcat(p, de->d_name); strcat(p, "/"); name_stat("CTMDM", dir2, name, de); putchar('\n'); s_new_dirs++; DoDir(dir1, dir2, p); } else if (de->d_type == DT_REG) { char *buf2 = alloca(strlen(dir2) + strlen(name) + strlen(de->d_name) + 3); char *m2, md5_2[33]; u_char *p1; struct stat st; int fd1; strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, name); strcat(buf2, "/"); strcat(buf2, de->d_name); 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); } 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); putchar('\n'); munmap(p1, st.st_size); s_new_files++; s_new_bytes += st.st_size; } }
static rc_t Start (KDirectory * cwd, const char * src, const char * dst) { KPathType dtype; KPathType stype; char dpath [MY_MAX_PATH]; char spath [MY_MAX_PATH]; rc_t rc; bool using_stdin, using_stdout, try_rename; /* limited anti oops checks */ try_rename = (dst == NULL); if (!try_rename) { /* try to prevent file to file clash */ if (strcmp (src,dst) == 0) dst = NULL; /* try to prevent file to dir clash */ else { size_t s,d; s = string_size (src); d = string_size (dst); if (s > d) { if (string_cmp (src, s, dst, d, d) == 0) { if ((strchr (src+d+1, '/') == NULL) && ((src[d] == '/') || (src[d-1] == '/'))) { try_rename = true; dst = NULL; } } } } } /* * This is a quick fix "hack" * A fully built out VFS should replace the KFS in use and eliminate this */ using_stdin = (strcmp (src, "/dev/stdin") == 0); if (using_stdin) { if (dst == NULL) { rc = RC (rcExe, rcArgv, rcParsing, rcParam, rcNull); LOGERR (klogErr, rc, "Unable to handle stdin in place"); return rc; } stype = kptFile; strcpy (spath, src); UseStdin = true; STSMSG (1, ("reading console / stdin as input")); goto stdin_shortcut; } rc = KDirectoryResolvePath (cwd, false, spath, sizeof spath, "%s", src); if (rc) { LOGERR (klogErr, rc, "can't resolve source"); return rc; } stype = KDirectoryPathType (cwd, spath); switch (stype) { case kptNotFound: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcNotFound); break; default: case kptBadPath: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcInvalid); break; case kptCharDev: case kptBlockDev: case kptFIFO: case kptZombieFile: case kptDataset: case kptDatatype: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); break; case kptFile: case kptDir: break; } if (rc) { PLOGERR (klogErr, (klogErr, rc, "can not use source '$(S)'", "S=%s", src)); return rc; } /* * In Place Operation */ if (dst == NULL) { /* * Input is a file */ if (stype == kptFile) { KDirectory * ndir; char * pc; pc = strrchr (spath, '/'); if (pc == NULL) { pc = spath; ndir = cwd; rc = KDirectoryAddRef (cwd); } else if (pc == spath) { ++pc; ndir = cwd; rc = KDirectoryAddRef (cwd); } else { *pc++ = '\0'; rc = KDirectoryOpenDirUpdate (cwd, &ndir, false, spath); } if (rc == 0) { rc = FileInPlace (ndir, pc, try_rename); KDirectoryRelease (ndir); } } /* * Input is a directory */ else { KDirectory * ndir; rc = KDirectoryOpenDirUpdate (cwd, &ndir, false, spath); if (rc) ; else { STSMSG (1, ("%scrypting directory %s", De, spath)); rc = DoDir (ndir, ndir); STSMSG (1, ("done with directory %s", spath)); KDirectoryRelease (ndir); } } } /* * 'Copy' Operation */ else { stdin_shortcut: using_stdout = (strcmp (dst, "/dev/stdout") == 0); if (using_stdout == true) { dtype = kptFile; strcpy (dpath, dst); UseStdout = true; STSMSG (1, ("writing console / stdout as output")); goto do_file; } rc = KDirectoryResolvePath (cwd, false, dpath, sizeof dpath, "%s", dst); if (rc) { LOGERR (klogErr, rc, "can't resolve destination"); return rc; } dtype = KDirectoryPathType (cwd, dpath); switch (dtype) { default: case kptBadPath: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcInvalid); PLOGERR (klogErr, (klogErr, rc, "can not use destination '$(S)'", "S=%s", dst)); break; case kptCharDev: case kptBlockDev: case kptFIFO: case kptZombieFile: case kptDataset: case kptDatatype: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); PLOGERR (klogErr, (klogErr, rc, "can not use destination parameter '$(S)'", "S=%s", dst)); break; case kptNotFound: { size_t z; z = strlen (dst) - 1; if ((dst[z] == '/') || (stype == kptDir)) goto do_dir; else goto do_file; } case kptFile: if (!ForceFlag) { rc = RC (rcExe, rcArgv, rcParsing, rcFile, rcExists); PLOGERR (klogErr, (klogErr, rc, "can not over-write '$(F)' without --force", "F=%s", dpath)); break; } do_file: if (stype == kptFile) { rc = FileToFile (cwd, spath, cwd, dpath, try_rename, NULL); } else { rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); LOGERR (klogErr, rc, "Can't do directory to file"); } break; do_dir: case kptDir: /* * Input is a directory */ if (stype == kptDir) { #if DIRECTORY_TO_DIRECTORY_SUPPORTED const KDirectory * sdir; KDirectory * ddir; rc = KDirectoryOpenDirRead (cwd, &sdir, false, spath); if (rc) ; else { if (dtype == kptNotFound) { STSMSG (1, ("creating output directory %s", dpath)); rc = KDirectoryCreateDir (cwd, 0775, kcmCreate|kcmParents, "%s", dpath); } if (rc == 0) { rc = KDirectoryOpenDirUpdate (cwd, &ddir, false, dpath); if (rc) ; else { STSMSG (1, ("%scrypting directory %s to %s", De, spath, dpath)); rc = DoDir (sdir, ddir); STSMSG (1, ("done with directory %s to %s", spath, dpath)); KDirectoryRelease (ddir); } } KDirectoryRelease (sdir); } #else rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); LOGERR (klogErr, rc, "Can't do directory to directory"); #endif } /* * Input is a file */ else { KDirectory * ndir; const char * pc; if (dtype == kptNotFound) { STSMSG (1, ("creating output directory %s", dpath)); rc = KDirectoryCreateDir (cwd, 0775, kcmCreate|kcmParents, "%s", dpath); } if (rc == 0) { STSMSG (1, ("opening output directory %s", dpath)); rc = KDirectoryOpenDirUpdate (cwd, &ndir, false, dpath); if (rc) ; else { pc = strrchr (spath, '/'); if (pc == NULL) pc = spath; else ++pc; rc = FileToFile (cwd, spath, ndir, pc, true, dpath); KDirectoryRelease (ndir); } } } break; } } return rc; }
static rc_t DoDir (const KDirectory * sd, KDirectory * dd) { KNamelist * names; rc_t rc; rc = KDirectoryList (sd, &names, NULL, NULL, "."); if (rc) ; else { uint32_t count; rc = KNamelistCount (names, &count); if (rc) ; else { uint32_t idx; for (idx = 0; idx < count; ++idx) { const char * name; rc = KNamelistGet (names, idx, &name); if (rc) ; else { const KDirectory * nsd; KDirectory * ndd; KPathType kpt; kpt = KDirectoryPathType (sd, name); switch (kpt) { default: break; case kptFile: if (sd == dd) rc = FileInPlace (dd, name, true); else rc = FileToFile (sd, name, dd, name, true, NULL); break; case kptDir: if (sd == dd) { rc = KDirectoryOpenDirUpdate (dd, &ndd, false, "%s", name); if (rc) ; else { /* RECURSION */ STSMSG (1, ("%scrypting directory %s", De, name)); rc = DoDir (ndd, ndd); STSMSG (1, ("done with directory %s", name)); KDirectoryRelease (ndd); } } else { rc = KDirectoryOpenDirRead (sd, &nsd, false, name); if (rc) ; else { rc = KDirectoryCreateDir (dd, 0600, kcmOpen, "%s", name); if (rc) ; else { rc = KDirectoryOpenDirUpdate (dd, &ndd, false, "%s", name); if (rc) ; else { /* RECURSION */ STSMSG (1, ("%scrypting directory %s", De, name)); rc = DoDir (nsd, ndd); STSMSG (1, ("done with directory %s", name)); KDirectoryRelease (ndd); } } KDirectoryRelease (nsd); } } break; } } } } KNamelistRelease (names); } return rc; }
int main(int argc, char **argv) { int i; setbuf(stderr, NULL); #if 0 if (regcomp(®_bogus, DEFAULT_BOGUS, REG_EXTENDED | REG_NEWLINE)) /* XXX use regerror to explain it */ errx(1, "default regular expression argument to -B is botched"); flag_bogus = 1; if (regcomp(®_ignore, DEFAULT_IGNORE, REG_EXTENDED | REG_NEWLINE)) /* XXX use regerror to explain it */ errx(1, "default regular expression argument to -I is botched"); flag_ignore = 1; #endif while ((i = getopt(argc, argv, "D:I:B:l:qv")) != -1) switch (i) { case 'D': damage_limit = strtol(optarg, 0, 0); if (damage_limit < 0) errx(1, "damage limit must be positive"); break; case 'I': if (flag_ignore) regfree(®_ignore); flag_ignore = 0; if (!*optarg) break; if (regcomp(®_ignore, optarg, REG_EXTENDED | REG_NEWLINE)) /* XXX use regerror to explain it */ errx(1, "regular expression argument to -I is botched"); flag_ignore = 1; break; case 'B': if (flag_bogus) regfree(®_bogus); flag_bogus = 0; if (!*optarg) break; if (regcomp(®_bogus, optarg, REG_EXTENDED | REG_NEWLINE)) /* XXX use regerror to explain it */ errx(1, "regular expression argument to -B is botched"); flag_bogus = 1; break; case 'l': logf = fopen(optarg, "w"); if (!logf) err(1, "%s", optarg); setlinebuf(logf); break; case 'q': verbose--; break; case 'v': verbose++; break; case '?': default: Usage(); return (1); } argc -= optind; argv += optind; if (!logf) logf = fopen(_PATH_DEVNULL, "w"); setbuf(stdout, 0); if (argc != 6) { Usage(); return (1); } signal(SIGINFO, stat_info); fprintf(stderr, "CTM_BEGIN 2.0 %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]); fprintf(logf, "CTM_BEGIN 2.0 %s %s %s %s\n", 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 (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) { errx(4, "no changes"); } else { printf("CTM_END "); fprintf(logf, "CTM_END\n"); print_stat(stderr, "END: "); } exit(0); }
void Equ(const char *dir1, const char *dir2, const char *name, struct dirent *de) { if (de->d_type == DT_DIR) { char *p = alloca(strlen(name)+strlen(de->d_name)+2); strcpy(p, name); strcat(p, de->d_name); strcat(p, "/"); DoDir(dir1, dir2, p); s_same_dirs++; } else { char *buf1 = alloca(strlen(dir1) + strlen(name) + strlen(de->d_name) + 3); char *buf2 = alloca(strlen(dir2) + strlen(name) + strlen(de->d_name) + 3); char *m1, md5_1[33], *m2, md5_2[33]; u_char *p1, *p2; int fd1, fd2; struct stat s1, s2; strcpy(buf1, dir1); strcat(buf1, "/"); strcat(buf1, name); strcat(buf1, "/"); strcat(buf1, de->d_name); fd1 = open(buf1, O_RDONLY); if(fd1 < 0) { err(3, "%s", buf1); } fstat(fd1, &s1); strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, name); strcat(buf2, "/"); strcat(buf2, de->d_name); fd2 = open(buf2, O_RDONLY); if(fd2 < 0) { err(3, "%s", buf2); } fstat(fd2, &s2); #if 0 /* XXX if we could just trust the size to change... */ if (s1.st_size == s2.st_size) { s_same_files++; s_same_bytes += s1.st_size; close(fd1); close(fd2); 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); } close(fd1); 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. */ if((s1.st_size == s2.st_size) && !memcmp(p1, p2, s1.st_size)) { s_same_files++; s_same_bytes += s1.st_size; goto finish; } s_files_chg++; change++; if (s1.st_size > s2.st_size) s_bytes_del += (s1.st_size - s2.st_size); else s_bytes_add += (s2.st_size - s1.st_size); m1 = MD5Data(p1, s1.st_size, md5_1); m2 = MD5Data(p2, s2.st_size, md5_2); /* Just a curiosity... */ if(!strcmp(m1, m2)) { if (s1.st_size != s2.st_size) fprintf(stderr, "Notice: MD5 same for files of diffent size:\n\t%s\n\t%s\n", buf1, buf2); goto finish; } { u_long l = s2.st_size + 2; u_char *cmd = alloca(strlen(buf1)+strlen(buf2)+100); u_char *ob = malloc(l), *p; int j; FILE *F; if (s1.st_size && p1[s1.st_size-1] != '\n') { if (verbose > 0) fprintf(stderr, "last char != \\n in %s\n", buf1); goto subst; } if (s2.st_size && p2[s2.st_size-1] != '\n') { if (verbose > 0) fprintf(stderr, "last char != \\n in %s\n", buf2); goto subst; } for (p=p1; p<p1+s1.st_size; p++) if (!*p) { if (verbose > 0) fprintf(stderr, "NULL char in %s\n", buf1); goto subst; } for (p=p2; p<p2+s2.st_size; p++) if (!*p) { if (verbose > 0) fprintf(stderr, "NULL char in %s\n", buf2); goto subst; } strcpy(cmd, "diff -n "); strcat(cmd, buf1); strcat(cmd, " "); strcat(cmd, buf2); F = popen(cmd, "r"); for (j = 1, l = 0; l < s2.st_size; ) { j = fread(ob+l, 1, s2.st_size - l, F); if (j < 1) break; l += j; continue; } if (j) { l = 0; while (EOF != fgetc(F)) continue; } pclose(F); if (l && l < s2.st_size) { name_stat("CTMFN", dir2, name, de); printf(" %s %s %d\n", m1, m2, (unsigned)l); fwrite(ob, 1, l, stdout); putchar('\n'); s_edit_files++; s_edit_bytes += l; s_edit_saves += (s2.st_size - l); } else { subst: name_stat("CTMFS", dir2, name, de); printf(" %s %s %u\n", m1, m2, (unsigned)s2.st_size); fwrite(p2, 1, s2.st_size, stdout); putchar('\n'); s_sub_files++; s_sub_bytes += s2.st_size; } free(ob); } finish: munmap(p1, s1.st_size); munmap(p2, s2.st_size); } }