virgo_error_t* virgo__versions_latest_file(virgo_t *v, const char *path, is_file_cmp file_compare, char *buffer, size_t buffer_len) { char *latest = NULL; char *ptr; int rc, i; uv_fs_t readdir_req; virgo_error_t *err; rc = uv_fs_readdir(uv_default_loop(), &readdir_req, path, 0, NULL); if (rc <= 0) { return virgo_error_createf(-1, "readdir returned %u", rc); } ptr = readdir_req.ptr; for (i=0; i < rc; i++) { int comparison; /* Verify this is a bundle filename */ if (!file_compare(ptr)) { goto next; } /* Initial pass */ if (!latest) { latest = ptr; goto next; } /* Perform the comparison */ err = compare_files(ptr, latest, &comparison); if (err) { virgo_error_clear(err); goto next; } /* If comparison returns 1, then the versions are greater */ if (comparison == 1) { latest = ptr; } next: ptr = ptr + strlen(ptr) + 1; } if (!latest) { uv_fs_req_cleanup(&readdir_req); return virgo_error_create(VIRGO_ENOFILE, "zero files"); } /* Save off the path */ snprintf(buffer, buffer_len, "%s%s%s", path, SEP, latest); uv_fs_req_cleanup(&readdir_req); return VIRGO_SUCCESS; }
static int hlink_compare(struct file_struct *f1, struct file_struct *f2) { if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode)) return 0; if (!S_ISREG(f1->mode)) return -1; if (!S_ISREG(f2->mode)) return 1; if (f1->dev != f2->dev) return (int) (f1->dev > f2->dev ? 1 : -1); if (f1->inode != f2->inode) return (int) (f1->inode > f2->inode ? 1 : -1); return file_compare(&f1, &f2); }
// find out if the file is duplicated and store the data as needed. void check_equals(work_package_t &work_package, const fs::path& path) { auto crc32 = file_crc32(work_package.file_cmp_options, path); auto range = work_package.crc32_to_path.equal_range(crc32); bool need_to_add = true; for (auto it = range.first; it != range.second; ++it) { auto cmp_path = it->second; if (file_compare(work_package.file_cmp_options, cmp_path, path)) { need_to_add = false; auto equal_it = work_package.equals.find(cmp_path); if (equal_it == work_package.equals.end()) { work_package.equals[cmp_path].push_back(cmp_path); } work_package.equals[cmp_path].push_back(path); } } if (need_to_add) { work_package.crc32_to_path.insert(std::make_pair(crc32, path)); } }
int main() { char* disk = "fdimage"; int program_count = 2; char* program[] = { "my_showblock", "kc_showblock.bin" }; char* outfile[] = { "my_outfile" , "kc_outfile" }; // List of files used for testing char* pathname[] = { "tiny", "big.dat", "X/tiny", "Y/bigfile", "Z/hugefile", "dontExist", NULL }; int i = 0; while(pathname[i]) { int j; int pid; int status; int result; int* err_line1 = (int*)malloc(sizeof(int)); int* err_line2 = (int*)malloc(sizeof(int)); printf("\n----------------------------------------------\n\n"); for(j = 0; j < program_count; j++) { // Remove outfile so it guaranteed to be empty remove(outfile[j]); // Fork Process if((pid = fork()) < 0) perror("main(): forking child process"); if(pid) { // Parent // Wait for immediate child process to die waitpid(pid, &status, 0); } else { // Child int child_pid; child_pid = run_showblock(program[j], disk, pathname[i], outfile[j]); // Wait for children processes to die waitpid(child_pid, &status, 0); exit(0); } putchar('\n'); } result = file_compare(outfile[0], outfile[1], err_line1, err_line2); if(result > 0) { printf("\n*********************\n"); printf("FAILED:\n"); printf("Disk: %s\n", disk); printf("Pathname: %s\n", pathname[i]); printf("Differences: %d\n", result); printf("\nFirst Error\n"); printf("%s line %d\n", outfile[0], *err_line1); printf("%s line %d\n", outfile[1], *err_line2); } else printf("PASSED\n"); free(err_line1); free(err_line2); i++; } printf("\n----------------------------------------------\n\n"); return 0; }
/* * On OSX we can set the icon to an Open ZFS specific one, just to be extra * shiny */ static void zfs_mount_seticon(const char *mountpoint) { /* For a root file system, add a volume icon. */ ssize_t attrsize; uint16_t finderinfo[16]; struct stat sbuf; char *path; FILE *dstfp, *srcfp; unsigned char buf[1024]; unsigned int red; boolean_t hasicon = 0; if (asprintf(&path, "%s/%s", mountpoint, MOUNT_POINT_CUSTOM_ICON) == -1) return; if ((stat(path, &sbuf) == 0 && sbuf.st_size > 0)) hasicon = 1; /* check if we can read in the default ZFS icon */ srcfp = fopen(CUSTOM_ICON_PATH, "r"); /* No source icon */ if (!srcfp) { free(path); if (hasicon) goto setfinderinfo; else return; } if (hasicon) { /* Open the output icon for reading */ dstfp = fopen(path, "r"); if (!dstfp) { fclose(srcfp); free(path); goto setfinderinfo; } if (file_compare(srcfp, dstfp) == 0) { fclose(srcfp); fclose(dstfp); free(path); goto setfinderinfo; } else { fclose(dstfp); } } /* Open the output icon for writing */ dstfp = fopen(path, "w"); if (!dstfp) { fclose(srcfp); free(path); goto setfinderinfo; } /* Copy icon */ while ((red = fread(buf, 1, sizeof(buf), srcfp)) > 0) (void) fwrite(buf, 1, red, dstfp); fclose(dstfp); fclose(srcfp); free(path); setfinderinfo: /* Tag the root directory as having a custom icon. */ attrsize = getxattr(mountpoint, XATTR_FINDERINFO_NAME, &finderinfo, sizeof (finderinfo), 0, 0); if (attrsize != sizeof (finderinfo)) (void) memset(&finderinfo, 0, sizeof(finderinfo)); if ((finderinfo[4] & BE_16(0x0400)) == 0) { finderinfo[4] |= BE_16(0x0400); (void) setxattr(mountpoint, XATTR_FINDERINFO_NAME, &finderinfo, sizeof (finderinfo), 0, 0); } }