/* * NAME: do_format() * DESCRIPTION: call hfs_format() with necessary privileges */ static hfsvol *do_format(const char *path, int partno, const char *vname) { hfsvol *vol = 0; suid_enable(); if (hfs_format(path, partno, vname, 0, 0) != -1) vol = hfs_mount(path, partno, HFS_MODE_ANY); suid_disable(); return vol; }
void * FuseHFS_init(struct fuse_conn_info *conn) { struct fuse_context *cntx=fuse_get_context(); struct fusehfs_options *options = cntx->private_data; #if (__FreeBSD__ >= 10) FUSE_ENABLE_SETVOLNAME(conn); // this actually doesn't do anything FUSE_ENABLE_XTIMES(conn); // and apparently this doesn't either #endif #ifdef DEBUG //char logfn[128]; //sprintf(logfn, "/fusefs_hfs/FuseHFS.%d.log", getpid()); //stderr = freopen(logfn, "a", stderr); log_to_file(); fprintf(stderr, "FuseHFS_init\n"); fflush(stderr); #endif // create iconv iconv_to_utf8 = iconv_open("UTF-8", options->encoding); if (iconv_to_utf8 == (iconv_t)-1) { perror("iconv_open"); exit(1); } iconv_to_mac = iconv_open(options->encoding, "UTF-8"); if (iconv_to_mac == (iconv_t)-1) { perror("iconv_open"); exit(1); } // mount volume int mode = options->readonly?HFS_MODE_RDONLY:HFS_MODE_ANY; if (NULL == hfs_mount(options->path, 0, mode)) { perror("hfs_mount"); exit(1); } // initialize some globals _readonly = options->readonly; hfsvolent vstat; hfs_vstat(NULL, &vstat); strcpy(_volname, vstat.name); return NULL; }
short int FS_MOUNT(unsigned short flag, struct vpfsi *pvpfsi, struct vpfsd *pvpfsd, unsigned short hVPB, unsigned short vol_descr, unsigned char *pBoot) { unsigned short oldVPB; unsigned long len_parm; unsigned char label[CCHMAXPATH], maclabel[HFS_MAX_VLEN+1]; hfsvolent volent; #ifdef DEBUG printf("Mount, flag = %hu, hVPB = %hu\n", flag, hVPB); #endif switch(flag) { case MOUNT_MOUNT: /* The cache uses hVPB as part of the key, so we flush it here. */ flush_cache(); /* Check for duplicate VPB */ oldVPB = hVPB; if( do_FSCtl(NULL, 0, NULL, &oldVPB, sizeof(unsigned short), &len_parm, FSCTL_FUNC_FINDDUPHVPB) == NO_ERROR ) { /* We should read the vol info and bitmap again here for the old VPB, as the volume may have been written while it was removed. */ /* Mark the VPB as duplicate */ set_vol_status(hVPB, pvpfsi->vpi_drive, MTSTAT_DUPLICATE); /* If necessary, mark the old VPB as mounted */ if(get_mount_status(oldVPB)==MTSTAT_REMOVED) set_vol_status(oldVPB, pvpfsi->vpi_drive, MTSTAT_MOUNTED); return NO_ERROR; } /* Mount the volume */ pvpfsd->vol = hfs_mount(hVPB, 1, pvpfsi->vpi_bsize, 0); if(pvpfsd->vol == NULL) { #ifdef DEBUG printf("hfs_mount failed!\n"); #endif return ERROR_VOLUME_NOT_MOUNTED; } if(hfs_vstat(pvpfsd->vol, &volent) < 0) { #ifdef DEBUG printf("hfs_vstat failed!\n"); #endif return ERROR_VOLUME_NOT_MOUNTED; } /* Fill vpfsi fields */ /* Use creation timestamp as ID */ pvpfsi->vpi_vid = volent.crdate; strcpy(maclabel, pvpfsd->vol->mdb.drVN); mac_to_os2_label(maclabel, label); strncpy(pvpfsi->vpi_text, label, 12); pvpfsi->vpi_text[11]=0; set_vol_status(hVPB, pvpfsi->vpi_drive, MTSTAT_MOUNTED); if(is_readonly(hVPB, pvpfsd->vol)) pvpfsd->vol->flags |= HFS_READONLY; #ifdef DEBUG printf("Got HFS volume\n"); #endif return NO_ERROR; case MOUNT_VOL_REMOVED: flush_cache(); /* If the disk was removed, forget about flushing. We should do a setvolume() here if volume is dirty, but it does not work. */ pvpfsd->vol->flags |= HFS_READONLY; return NO_ERROR; case MOUNT_RELEASE: switch(get_mount_status(hVPB)) { case MTSTAT_REMOVED: case MTSTAT_MOUNTED: hfs_umount(pvpfsd->vol); break; case MTSTAT_DUPLICATE: #ifdef DEBUG printf("Trying to unmount non-mounted volume!\n"); #endif break; } flush_cache(); set_vol_status(hVPB, 0, MTSTAT_FREE); return NO_ERROR; case MOUNT_ACCEPT: return ERROR_NOT_SUPPORTED; default: return ERROR_NOT_SUPPORTED; } }
int main(int argc, char* argv[], char* env[]) { int ret = 0; int device = 0; struct stat status; console = open("/dev/console", O_WRONLY); dup2(console, 1); dup2(console, 2); envp = env; puts("Searching for disk...\n"); while (stat("/dev/disk0s1", &status) != 0) { sleep(1); } puts("\n\n\n\n\n"); puts("Pois0nDisk - by Chronic-Dev Team\n"); puts("Mounting filesystem...\n"); if (hfs_mount("/dev/disk0s1", "/mnt", MNT_ROOTFS | MNT_RDONLY) != 0) { if (hfs_mount("/dev/disk0s1s1", "/mnt", MNT_ROOTFS | MNT_RDONLY) != 0) { puts("Unable to mount filesystem!\n"); return -1; } else { device = DEVICE_ATV; } } puts("Filesystem mounted\n"); puts("Mounting devices...\n"); if (mount("devfs", "/mnt/dev", 0, NULL) != 0) { puts("Unable to mount devices!\n"); unmount("/mnt", 0); return -1; } puts("Devices mounted\n"); puts("Checking root filesystem...\n"); if(device == DEVICE_ATV) { ret = fsexec(fsck_hfs_atv, env); } else { ret = fsexec(fsck_hfs, env); } if (ret != 0) { puts("Unable to check root filesystem!\n"); unmount("/mnt/dev", 0); unmount("/mnt", 0); return -1; } puts("Root filesystem checked\n"); puts("Checking user filesystem...\n"); if(device == DEVICE_ATV) { fsexec(fsck_hfs_user_atv, env); } else { fsexec(fsck_hfs_user, env); fsexec(fsck_hfs_user_old, env); } puts("User filesystem checked\n"); puts("Updating filesystem...\n"); if(device == DEVICE_ATV) { ret = hfs_mount("/dev/disk0s1s1", "/mnt", MNT_ROOTFS | MNT_UPDATE); } else { ret = hfs_mount("/dev/disk0s1", "/mnt", MNT_ROOTFS | MNT_UPDATE); } if (ret != 0) { puts("Unable to update filesystem!\n"); unmount("/mnt/dev", 0); unmount("/mnt", 0); return -1; } puts("Filesystem updated\n"); puts("Mounting user filesystem...\n"); mkdir("/mnt/private/var2", 0755); if(device == DEVICE_ATV) { if (hfs_mount("/dev/disk0s1s2", "/mnt/private/var2", 0) != 0) { puts("Unable to mount user filesystem!\n"); return -1; } } else { if (hfs_mount("/dev/disk0s2s1", "/mnt/private/var2", 0) != 0) { if (hfs_mount("/dev/disk0s2", "/mnt/private/var2", 0) != 0) { puts("Unable to mount user filesystem!\n"); return -1; } else { device = DEVICE_OLD; } } else { device = DEVICE_NEW; } } puts("User filesystem mounted\n"); puts("Installing files...\n"); if (install_files(device) != 0) { puts("Failed to install files!\n"); unmount("/mnt/private/var2", 0); rmdir("/mnt/private/var2"); unmount("/mnt/dev", 0); unmount("/mnt", 0); return -1; } puts("Installation complete\n"); sync(); puts("Unmounting disks...\n"); rmdir("/mnt/private/var2"); unmount("/mnt/private/var2", 0); unmount("/mnt/dev", 0); unmount("/mnt", 0); puts("Flushing buffers...\n"); sync(); puts("Rebooting device...\n"); close(console); reboot(1); return 0; }
/* ** make_mac_volume: "create" an HFS volume using the ISO data ** ** The HFS volume structures are set up (but no data is written yet). ** ** ISO volumes have a allocation size of 2048 bytes - regardless ** of the size of the volume. HFS allocation size is depends on volume ** size, so we may have to update the ISO structures to add in any ** padding. */ int FDECL2(make_mac_volume, struct directory *, dpnt, int, start_extent) { char vol_name[HFS_MAX_VLEN+1]; /* Mac volume name */ hfsvol *vol; /* Mac volume */ int vlen, vblen; /* vol length (bytes, blocks) */ int Csize, lastCsize; /* allocation sizes */ int ret = 0; /* return value */ int loop = 1; /* umount volume if we have had a previous attempt */ if (vol_save) if (hfs_umount(vol_save, 0) < 0) return (-1); /* set the default clump size to the ISO block size */ lastCsize = SECTOR_SIZE; if (verbose > 1) fprintf(stderr, "Creating HFS Volume info\n"); /* name or copy ISO volume name to Mac Volume name */ strncpy(vol_name, hfs_volume_id ? hfs_volume_id : volume_id, HFS_MAX_VLEN); vol_name[HFS_MAX_VLEN] = '\0'; /* get initial size of HFS volume (size of ISO volume) */ vblen = last_extent * BLK_CONV; /* add on size of extents/catalog file, but this may mean the allocation size will change, so loop round until the allocation size doesn't change */ while (loop) { hce->XTCsize = XClpSiz(vblen); vblen = get_vol_size(vblen); Csize = AlcSiz(vblen); if (Csize == lastCsize) { /* allocation size hasn't changed, so carry on */ loop = 0; } else { /* allocation size has changed, so update ISO volume size */ if ((vlen = get_adj_size(Csize)) < 0) { snprintf(hce->error, ERROR_SIZE, "too many files for HFS volume"); return (-1); } vlen += V_ROUND_UP(start_extent * SECTOR_SIZE, Csize); vblen = vlen / HFS_BLOCKSZ; lastCsize = Csize; } } /* set vlen to size in bytes */ /* vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ; */ /* take off the label/map size */ vblen -= hce->hfs_map_size; vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ; /* set the default allocation size for libhfs */ hce->Csize = Csize; /* format and mount the "volume" */ if (hfs_format(hce, 0, vol_name) < 0) { snprintf(hce->error, ERROR_SIZE, "can't HFS format %s",vol_name); return(-1); } /* update the ISO structures with new start extents and any padding required */ if (Csize != SECTOR_SIZE) { last_extent = adj_size(Csize, start_extent, hce->hfs_hdr_size + hce->hfs_map_size); adj_size_other(dpnt); } if ((vol = hfs_mount(hce, 0, 0)) == 0) { snprintf(hce->error, ERROR_SIZE, "can't HFS mount %s",vol_name); return(-1); } /* save the volume for possible later use */ vol_save = vol; /* Recursively "copy" the files to the volume - we need to know the first allocation block in the volume as starting blocks of files are relative to this. */ ret = copy_to_mac_vol(vol, dpnt); if (ret < 0) return(ret); /* make the Desktop files - I *think* this stops the Mac rebuilding the desktop when the CD is mounted on a Mac These will be ignored if they already exist */ if (create_dt) ret = make_desktop(vol, last_extent*BLK_CONV); if (ret < 0) return(ret); /* close the volume */ if (hfs_flush(vol) < 0) return(-1); /* unmount and set the start blocks for the catalog/extents files */ if (hfs_umount(vol, last_extent*BLK_CONV) < 0) return(-1); return(Csize); }