#include <CoreFoundation/CoreFoundation.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "enums.h"
#include "structs.h"
#include "bless.h"
#define kIsInvisible 0x4000
int modeFolder(BLContext context, struct clopt commandlineopts[klast], struct clarg actargs[klast]) {
int err;
int isHFS;
u_int32_t folderXid = 0; u_int32_t folder9id = 0;
if(!(geteuid() == 0)) {
contextprintf(context, kBLLogLevelError, "Not run as root\n" );
return 1;
}
if(actargs[kbootinfo].present) {
if(actargs[kfolder].present) {
CFDataRef bootXdata = NULL;
err = BLLoadFile(context, actargs[kbootinfo].argument, 0, (void **)&bootXdata);
if(err) {
contextprintf(context, kBLLogLevelError, "Could not load BootX data from %s\n", actargs[kbootinfo].argument);
} else {
err = BLCreateFile(context, (void *)bootXdata, actargs[kfolder].argument, "BootX", 0, 'tbxi', 'chrp');
if(err) {
contextprintf(context, kBLLogLevelError, "Could not create BootX in %s\n", actargs[kfolder].argument );
} else {
contextprintf(context, kBLLogLevelVerbose, "BootX created successfully in %s\n", actargs[kfolder].argument );
}
}
} else {
contextprintf(context, kBLLogLevelVerbose, "Could not create BootX, no X folder specified\n" );
}
} else {
contextprintf(context, kBLLogLevelVerbose, "No BootX creation requested\n" );
}
if(actargs[ksystemfile].present) {
if(actargs[kfolder9].present) {
CFDataRef systemdata = NULL;
err = BLLoadFile(context, actargs[ksystemfile].argument, 0, (void **)&systemdata);
if(err) {
contextprintf(context, kBLLogLevelError, "Could not load system file data from %s\n", actargs[ksystemfile].argument);
} else {
err = BLCreateFile(context, (void *)systemdata, actargs[kfolder9].argument,
"System", 1, 'zsys', 'MACS');
if(err) {
contextprintf(context, kBLLogLevelError, "Could not create System in %s\n", actargs[kfolder9].argument );
} else {
contextprintf(context, kBLLogLevelVerbose, "System created successfully in %s\n", actargs[kfolder9].argument );
}
}
} else {
contextprintf(context, kBLLogLevelError, "Could not create system file, no 9 folder specified\n" );
}
}
if(actargs[kmount].present) {
err = BLGetCommonMountPoint(context, actargs[kmount].argument, "", actargs[kmount].argument);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't determine mount point of '%s'\n", actargs[kmount].argument );
} else {
contextprintf(context, kBLLogLevelVerbose, "Mount point is '%s'\n", actargs[kmount].argument );
}
actargs[ksave9].present = 1;
actargs[ksaveX].present = 1;
} else {
err = BLGetCommonMountPoint(context, actargs[kfolder].argument, actargs[kfolder9].argument, actargs[kmount].argument);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't determine mount point of '%s' and '%s'\n", actargs[kfolder].argument,
actargs[kfolder9].argument);
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Common mount point of '%s' and '%s' is %s\n",
actargs[kfolder].argument,
actargs[kfolder9].argument, actargs[kmount].argument );
}
}
err = BLIsMountHFS(context, actargs[kmount].argument, &isHFS);
if(err) {
contextprintf(context, kBLLogLevelError, "Could not determine filesystem of %s\n", actargs[kmount].argument );
return 1;
}
if(isHFS && (actargs[kfolder].present || actargs[kfolder9].present)) {
u_int32_t oldwords[8];
int useX = 1;
err = BLGetVolumeFinderInfo(context, actargs[kmount].argument, oldwords);
if(err) {
contextprintf(context, kBLLogLevelError, "Error getting old Finder info words for %s\n", actargs[kmount].argument );
return 1;
}
if(actargs[ksave9].present) {
folder9id = oldwords[3];
contextprintf(context, kBLLogLevelVerbose, "Saved folder 9\n" );
}
if(actargs[ksaveX].present) {
folderXid = oldwords[5];
contextprintf(context, kBLLogLevelVerbose, "Saved folder X\n" );
}
if(actargs[kfolder].present) {
err = BLGetFileID(context, actargs[kfolder].argument, &folderXid);
if(err) {
contextprintf(context, kBLLogLevelError, "Error while get directory ID of %s\n", actargs[kfolder].argument );
} else {
contextprintf(context, kBLLogLevelVerbose, "Got directory ID of %u for %s\n", folderXid, actargs[kfolder].argument );
}
}
if(actargs[kfolder9].present) {
err = BLGetFileID(context, actargs[kfolder9].argument, &folder9id);
if(err) {
contextprintf(context, kBLLogLevelError, "Error while get directory ID of %s\n", actargs[kfolder9].argument );
} else {
contextprintf(context, kBLLogLevelVerbose, "Got directory ID of %u for %s\n", folder9id, actargs[kfolder9].argument );
}
}
if(actargs[kuse9].present) {
useX = 0;
}
err = BLBlessDir(context, actargs[kmount].argument, folderXid, folder9id, useX);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't bless directories\n" );
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Volume at %s blessed successfully\n", actargs[kmount].argument );
}
if(actargs[kbootblocks].present || actargs[kbootblockfile].present) {
unsigned char bBlocks[1024];
if(actargs[kbootblockfile].present) {
err = BLGetBootBlocksFromDataForkFile(context, actargs[kbootblockfile].argument, bBlocks);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't get boot blocks from data-fork file %s\n",
actargs[kbootblockfile].argument);
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Boot blocks read from %s\n", actargs[kbootblockfile].argument );
}
} else if(folder9id) {
err = BLGetBootBlocksFromFolder(context, actargs[kmount].argument, folder9id, bBlocks);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't get boot blocks from system file\n" );
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Boot blocks read from %s\n", actargs[ksystem].argument );
}
} else {
contextprintf(context, kBLLogLevelError, "Don't know how to get boot blocks\n" );
return 1;
}
err = BLSetBootBlocks(context, actargs[kmount].argument, bBlocks);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't set boot blocks for %s\n", actargs[kmount].argument );
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Boot blocks set successfully\n" );
}
}
}
if(actargs[ksetOF].present) {
err = BLSetOpenFirmwareBootDeviceForMountPoint(context, actargs[kmount].argument);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't set Open Firmware\n" );
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Open Firmware set successfully\n" );
}
}
if(actargs[klabel].present && isHFS) {
CFDataRef labeldata = NULL;
err = BLGenerateOFLabel(context, actargs[klabel].argument, (void **)&labeldata);
if(err) {
contextprintf(context, kBLLogLevelError, "Can't render label '%s'\n",
actargs[klabel].argument);
} else {
u_int32_t oldwords2[8];
unsigned char sysfolder[MAXPATHLEN];
err = BLGetVolumeFinderInfo(context, actargs[kmount].argument, oldwords2);
if(err) {
contextprintf(context, kBLLogLevelError, "Don't know where to generate bitmap\n" );
return 1;
}
err = BLLookupFileIDOnMount(context, actargs[kmount].argument, oldwords2[0], sysfolder);
if(err) {
return 2;
}
contextprintf(context, kBLLogLevelVerbose, "Putting label bitmap in %s/%s\n", sysfolder, "Volume Name Icon" );
if(err) {
return 2;
}
err = BLCreateFile(context, (void *)labeldata,
sysfolder,
"Volume Name Icon",
0, 'tbxj', 'chrp');
if(err) {
contextprintf(context, kBLLogLevelError, "Could not write bitmap label file\n" );
CFRelease(labeldata);
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "OF label written\n");
}
CFRelease(labeldata);
strcat(sysfolder, "/Volume Name Icon");
err = BLSetFinderFlag(context, sysfolder, 0x0400, 1);
if(err) {
contextprintf(context, kBLLogLevelError, "Could not set invisibility for %s\n", sysfolder );
return 1;
} else {
contextprintf(context, kBLLogLevelVerbose, "Invisibility set for %s\n", sysfolder );
}
}
}
return 0;
}