int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) { Q_Q(QDBusInterface); if (c == QMetaObject::InvokeMetaMethod) { int offset = metaObject->methodOffset(); QMetaMethod mm = metaObject->method(id + offset); if (mm.methodType() == QMetaMethod::Signal) { // signal relay from D-Bus world to Qt world QMetaObject::activate(q, metaObject, id, argv); } else if (mm.methodType() == QMetaMethod::Slot || mm.methodType() == QMetaMethod::Method) { // method call relay from Qt world to D-Bus world // get D-Bus equivalent signature QString methodName = QString::fromLatin1(mm.name()); const int *inputTypes = metaObject->inputTypesForMethod(id); int inputTypesCount = *inputTypes; // we will assume that the input arguments were passed correctly QVariantList args; args.reserve(inputTypesCount); int i = 1; for ( ; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); // make the call QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args); if (reply.type() == QDBusMessage::ReplyMessage) { // attempt to demarshall the return values args = reply.arguments(); QVariantList::ConstIterator it = args.constBegin(); const int *outputTypes = metaObject->outputTypesForMethod(id); int outputTypesCount = *outputTypes++; if (mm.returnType() != QMetaType::UnknownType && mm.returnType() != QMetaType::Void) { // this method has a return type if (argv[0] && it != args.constEnd()) copyArgument(argv[0], *outputTypes++, *it); // skip this argument even if we didn't copy it --outputTypesCount; ++it; } for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) { copyArgument(argv[i], outputTypes[j], *it); } } // done lastError = QDBusError(reply); return -1; } } return id; }
// // Returns TRUE if an argument was copied, FALSE otherwise bool processBootArgument( const char *argName, // The argument to search for const char *userString, // Typed-in boot arguments const char *kernelFlags, // Kernel flags from config table const char *configTable, char **argP, // Output value int *cntRemainingP, // Output count char *foundVal // found value ) { const char *val; int cnt; bool found = false; if (getValueForBootKey(userString, argName, &val, &cnt)) { // Don't copy; these values will be copied at the end of argument processing. found = true; } else if (getValueForBootKey(kernelFlags, argName, &val, &cnt)) { // Don't copy; these values will be copied at the end of argument processing. found = true; } else if (getValueForKey(argName, &val, &cnt, &bootInfo->bootConfig)) { copyArgument(argName, val, cnt, argP, cntRemainingP); found = true; } if (found && foundVal) { strlcpy(foundVal, val, cnt+1); } return found; }
/*! Copies the given user function with the given body, minimum and maximum arguments, and arguments list @param fun the tap function to copy @return the new tap function */ tap_fun* copyTapFunction (tap_fun* fun) { if (fun == NULL) { return NULL; } else { int numargs; if (fun->maxargs == ARGLEN_INF) { numargs = fun->minargs; } else { numargs = fun->maxargs; } argument** args = allocate(sizeof(argument*) * numargs); int i; for (i = 0; i < numargs; ++i) { args[i] = copyArgument(fun->args[i]); } return newTapFunction(args, fun->minargs, fun->maxargs, copyExpression(fun->body)); } }
int processBootOptions() { const char * cp = gBootArgs; const char * val = 0; const char * kernel; int cnt; int userCnt; int cntRemaining; char * argP; char uuidStr[64]; bool uuidSet = false; char * configKernelFlags; char * valueBuffer; valueBuffer = malloc(VALUE_SIZE); skipblanks( &cp ); // Update the unit and partition number. if ( gBootVolume ) { if (!( gBootVolume->flags & kBVFlagNativeBoot )) { readBootSector( gBootVolume->biosdev, gBootVolume->part_boff, (void *) 0x7c00 ); // // Setup edx, and signal intention to chain load the // foreign booter. // chainbootdev = gBootVolume->biosdev; chainbootflag = 1; return 1; } setRootVolume(gBootVolume); } // If no boot volume fail immediately because we're just going to fail // trying to load the config file anyway. else return -1; // Load config table specified by the user, or use the default. if (!getValueForBootKey(cp, "config", &val, &cnt)) { val = 0; cnt = 0; } // Load com.apple.Boot.plist from the selected volume // and use its contents to override default bootConfig. // This is not a mandatory operation anymore. loadOverrideConfig(&bootInfo->overrideConfig); // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying // a non-default kernel name in the config file counts as // overriding the kernel, which causes the kernelcache not // to be used. gOverrideKernel = false; if (( kernel = extractKernelName((char **)&cp) )) { strcpy( bootInfo->bootFile, kernel ); gOverrideKernel = true; } else { if ( getValueForKey( kKernelNameKey, &val, &cnt, &bootInfo->bootConfig ) ) { strlcpy( bootInfo->bootFile, val, cnt+1 ); if (strcmp( bootInfo->bootFile, kDefaultKernel ) != 0) { gOverrideKernel = true; } } else { strcpy( bootInfo->bootFile, kDefaultKernel ); } } cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; // Get config table kernel flags, if not ignored. if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) || !getValueForKey( kKernelFlagsKey, &val, &cnt, &bootInfo->bootConfig )) { val = ""; cnt = 0; } configKernelFlags = malloc(cnt + 1); strlcpy(configKernelFlags, val, cnt + 1); if (processBootArgument(kBootUUIDKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, 0)) { // boot-uuid was set either on the command-line // or in the config file. uuidSet = true; } else { // // Try an alternate method for getting the root UUID on boot helper partitions. // if (gBootVolume->flags & kBVFlagBooter) { if((loadHelperConfig(&bootInfo->helperConfig) == 0) && getValueForKey(kHelperRootUUIDKey, &val, &cnt, &bootInfo->helperConfig) ) { getValueForKey(kHelperRootUUIDKey, &val, &cnt, &bootInfo->helperConfig); copyArgument(kBootUUIDKey, val, cnt, &argP, &cntRemaining); uuidSet = true; } } if (!uuidSet && gBootVolume->fs_getuuid && gBootVolume->fs_getuuid (gBootVolume, uuidStr) == 0) { verbose("Setting boot-uuid to: %s\n", uuidStr); copyArgument(kBootUUIDKey, uuidStr, strlen(uuidStr), &argP, &cntRemaining); uuidSet = true; } } if (!processBootArgument(kRootDeviceKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gRootDevice)) { cnt = 0; if ( getValueForKey( kBootDeviceKey, &val, &cnt, &bootInfo->bootConfig)) { valueBuffer[0] = '*'; cnt++; strlcpy(valueBuffer + 1, val, cnt); val = valueBuffer; } else { if (uuidSet) { val = "*uuid"; cnt = 5; } else { // Don't set "rd=.." if there is no boot device key // and no UUID. val = ""; cnt = 0; } } if (cnt > 0) { copyArgument( kRootDeviceKey, val, cnt, &argP, &cntRemaining); } strlcpy( gRootDevice, val, (cnt + 1)); } /* * Removed. We don't need this anymore. * if (!processBootArgument(kPlatformKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gPlatformName)) { getPlatformName(gPlatformName); copyArgument(kPlatformKey, gPlatformName, strlen(gPlatformName), &argP, &cntRemaining); } */ if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && !getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt)) { if (gBootMode & kBootModeSafe) { copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &cntRemaining); } } // Store the merged kernel flags and boot args. cnt = strlen(configKernelFlags); if (cnt) { if (cnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); cnt = cntRemaining; } strncpy(argP, configKernelFlags, cnt); argP[cnt++] = ' '; cntRemaining -= cnt; } userCnt = strlen(cp); if (userCnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); userCnt = cntRemaining; } strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; if(!shouldboot) { gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->bootConfig ) || getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->bootConfig ); gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) ? kBootModeSafe : kBootModeNormal; if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, &bootInfo->bootConfig ) ) { gBootMode = kBootModeSafe; } } if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) ) { strlcpy(gMKextName, val, cnt + 1); } free(configKernelFlags); free(valueBuffer); return 0; }
int processBootOptions() { const char *cp = gBootArgs; const char *val = 0; const char *kernel; int cnt; int userCnt; int cntRemaining; char *argP; char *configKernelFlags; char *valueBuffer; valueBuffer = malloc(VALUE_SIZE); skipblanks( &cp ); // Update the unit and partition number. if ( gBootVolume ) { if (!( gBootVolume->flags & kBVFlagNativeBoot )) { readBootSector( gBootVolume->biosdev, gBootVolume->part_boff, (void *) 0x7c00 ); // // Setup edx, and signal intention to chain load the // foreign booter. // chainbootdev = gBootVolume->biosdev; chainbootflag = 1; return 1; } setRootVolume(gBootVolume); } // If no boot volume fail immediately because we're just going to fail // trying to load the config file anyway. else { return -1; } // Find out which version mac os we're booting. strncpy(gMacOSVersion, gBootVolume->OSVersion, sizeof(gMacOSVersion)); // Load config table specified by the user, or use the default. if (!getValueForBootKey(cp, "config", &val, &cnt)) { val = 0; cnt = 0; } // Load com.apple.Boot.plist from the selected volume // and use its contents to override default bootConfig. loadSystemConfig(&bootInfo->bootConfig); loadChameleonConfig(&bootInfo->chameleonConfig, NULL); // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying // a non-default kernel name in the config file counts as // overriding the kernel, which causes the kernelcache not // to be used. gOverrideKernel = false; if (( kernel = extractKernelName((char **)&cp) )) { strlcpy( bootInfo->bootFile, kernel, sizeof(bootInfo->bootFile) ); } else { if ( getValueForKey( kKernelNameKey, &val, &cnt, &bootInfo->bootConfig ) ) { strlcpy( bootInfo->bootFile, val, cnt+1 ); } else { if( YOSEMITE ) // is 10.10 { strlcpy( bootInfo->bootFile, kOSXKernel, sizeof(bootInfo->bootFile) ); //printf(HEADER "/System/Library/Kernels/%s\n", bootInfo->bootFile); } else { // OSX is not 10.10 strlcpy( bootInfo->bootFile, kDefaultKernel, sizeof(bootInfo->bootFile) ); //printf(HEADER "/%s\n", bootInfo->bootFile); } } } if (!YOSEMITE) // not 10.10 so 10.9 and previus { if (strcmp( bootInfo->bootFile, kDefaultKernel ) != 0) { //printf(HEADER "org.chameleon.Boot.plist found path for custom '%s' found!\n", bootInfo->bootFile); gOverrideKernel = true; } } else { // OSX is 10.10 if (strcmp( bootInfo->bootFile, kOSXKernel ) != 0) { //printf(HEADER "org.chameleon.Boot.plist found path for custom '%s' found!\n", bootInfo->bootFile); gOverrideKernel = true; } } // Ermac : Inject "kext-dev-mode=1" if OS X 10.10 is detected if( YOSEMITE ) // is 10.10 { addBootArg("kext-dev-mode=1"); } cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; // Get config kernel flags, if not ignored. if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) || !getValueForKey( kKernelFlagsKey, &val, &cnt, &bootInfo->bootConfig )) { val = ""; cnt = 0; } configKernelFlags = malloc(cnt + 1); strlcpy(configKernelFlags, val, cnt + 1); // boot-uuid can be set either on the command-line or in the config file if (!processBootArgument(kBootUUIDKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gBootUUIDString, sizeof(gBootUUIDString))) { // // Try an alternate method for getting the root UUID on boot helper partitions. // if (gBootVolume->flags & kBVFlagBooter) { // Load the configuration store in the boot helper partition if (loadHelperConfig(&bootInfo->helperConfig) == 0) { val = getStringForKey(kHelperRootUUIDKey, &bootInfo->helperConfig); if (val != NULL) { strlcpy(gBootUUIDString, val, sizeof(gBootUUIDString)); } } } /* // Try to get the volume uuid string if (!strlen(gBootUUIDString) && gBootVolume->fs_getuuid) { gBootVolume->fs_getuuid(gBootVolume, gBootUUIDString); } */ // If we have the volume uuid add it to the commandline arguments if (strlen(gBootUUIDString)) { copyArgument(kBootUUIDKey, gBootUUIDString, strlen(gBootUUIDString), &argP, &cntRemaining); } // Try to get the volume uuid string if (!strlen(gBootUUIDString) && gBootVolume->fs_getuuid) { gBootVolume->fs_getuuid(gBootVolume, gBootUUIDString); DBG("boot-uuid: %s\n", gBootUUIDString); } } if (!processBootArgument(kRootDeviceKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gRootDevice, ROOT_DEVICE_SIZE)) { cnt = 0; if ( getValueForKey( kBootDeviceKey, &val, &cnt, &bootInfo->chameleonConfig)) { valueBuffer[0] = '*'; cnt++; strlcpy(valueBuffer + 1, val, cnt); val = valueBuffer; } else { /* if (strlen(gBootUUIDString)) { val = "*uuid"; cnt = 5; } else { */ // Don't set "rd=.." if there is no boot device key // and no UUID. val = ""; cnt = 0; /* } */ } if (cnt > 0) { copyArgument( kRootDeviceKey, val, cnt, &argP, &cntRemaining); } strlcpy( gRootDevice, val, (cnt + 1)); } /* * Removed. We don't need this anymore. * if (!processBootArgument(kPlatformKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gPlatformName, sizeof(gCacheNameAdler))) { getPlatformName(gPlatformName); copyArgument(kPlatformKey, gPlatformName, strlen(gPlatformName), &argP, &cntRemaining); } */ if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && !getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt)) { if (gBootMode & kBootModeSafe) { copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &cntRemaining); } } // Store the merged kernel flags and boot args. cnt = strlen(configKernelFlags); if (cnt) { if (cnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); cnt = cntRemaining; } strncpy(argP, configKernelFlags, cnt); argP[cnt++] = ' '; cntRemaining -= cnt; } userCnt = strlen(cp); if (userCnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); userCnt = cntRemaining; } strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; if(!shouldboot) { gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->chameleonConfig ) || getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->chameleonConfig ); gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->chameleonConfig ) ) ? kBootModeSafe : kBootModeNormal; if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, &bootInfo->chameleonConfig ) ) { gBootMode = kBootModeSafe; } } if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) ) { strlcpy(gMKextName, val, cnt + 1); } else { gMKextName[0]=0; } free(configKernelFlags); free(valueBuffer); return 0; }
DESCRIBE(newArgument, "argument* newArgument (string* name, typelist* types, expression* initial)") IT("Creates a new argument") expression* expr = newExpressionNil(); argument* arg = newArgument(newString(strDup("arg")), newTypelist(TYPE_NIL), expr); SHOULD_EQUAL(strcmp(arg->name->content, "arg"), 0) SHOULD_EQUAL(arg->types->type, TYPE_NIL) SHOULD_EQUAL(arg->initial, expr) freeArg(arg); END_IT END_DESCRIBE DESCRIBE(copyArgument, "argument* copyArgument (argument* arg)") IT("Copies the given argument and its content") expression* expr = newExpressionInt(1); argument* arg1 = newArgument(newString(strDup("name")), newTypelist(TYPE_INT), expr); argument* arg2 = copyArgument(arg1); SHOULD_NOT_EQUAL(arg1, arg2) SHOULD_EQUAL(strcmp(arg1->name->content, arg2->name->content), 0) SHOULD_NOT_EQUAL(arg1->types, arg2->types) SHOULD_EQUAL(arg1->types->type, arg2->types->type) SHOULD_NOT_EQUAL(arg1->initial, arg2->initial) SHOULD_EQUAL(arg1->initial->ev.intval, arg2->initial->ev.intval) freeArg(arg1); freeArg(arg2); END_IT END_DESCRIBE DESCRIBE(newTypelist, "typelist* newTypelist (datatype type)") IT("Creates a new list of types of length 1") typelist* tl = newTypelist(TYPE_INT); SHOULD_EQUAL(tl->type, TYPE_INT)
int processBootOptions(void) { char *cp_cache = (char*)(uint32_t)get_env(envgBootArgs); if (cp_cache) { bzero(gBootArgs,sizeof(gBootArgs)); strlcpy(gBootArgs, cp_cache,sizeof(gBootArgs)); } const char * cp = gBootArgs; const char * val = 0; const char * kernel; int cnt; int userCnt; char * argP; char * configKernelFlags; int ArgCntRemaining; skipblanks( &cp ); // Update the unit and partition number. if ( ((BVRef)(uint32_t)get_env(envgBootVolume)) ) { #ifndef NO_MULTIBOOT_SUPPORT if (!( ((BVRef)(uint32_t)get_env(envgBootVolume))->flags & kBVFlagNativeBoot )) { readBootSector( ((BVRef)(uint32_t)get_env(envgBootVolume))->biosdev, ((BVRef)(uint32_t)get_env(envgBootVolume))->part_boff, (void *) 0x7c00 ); // // Setup edx, and signal intention to chain load the // foreign booter. // extern unsigned char chainbootdev; extern unsigned char chainbootflag; chainbootdev = ((BVRef)(uint32_t)get_env(envgBootVolume))->biosdev; chainbootflag = 1; return 1; } #endif setRootVolume(((BVRef)(uint32_t)get_env(envgBootVolume))); } // If no boot volume fail immediately because we're just going to fail // trying to load the config file anyway. else return -1; // Load config table specified by the user, or use the default. if (!getValueForBootKey(cp, "config", &val, &cnt)) { val = 0; cnt = 0; } // Load com.apple.Boot.plist from the selected volume // and use its contents to override default bootConfig. // This is not a mandatory opeartion anymore. loadOverrideConfig(); // Load System com.apple.boot.plist config file loadSystemConfig(); #if virtualM || PCI_FIX // we can simply make an option for this fix addBootArg("npci=0x2000"); #endif #if verbose addBootArg("-v"); #endif // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying // a non-default kernel name in the config file counts as // overriding the kernel, which causes the kernelcache not // to be used. safe_set_env(envgOverrideKernel,false); if (( kernel = extractKernelName((char **)&cp) )) { strlcpy( bootInfo->bootFile, kernel, sizeof(bootInfo->bootFile) ); safe_set_env(envgOverrideKernel,true); } else { if ( getValueForKey( kKernelNameKey, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { strlcpy( bootInfo->bootFile, val, sizeof(bootInfo->bootFile) ); if (strncmp( bootInfo->bootFile, kDefaultKernel, sizeof(kDefaultKernel) ) != 0) { safe_set_env(envgOverrideKernel,true); } } else if (((BVRef)(uint32_t)get_env(envgBootVolume))->kernelfound == true) { strlcpy( bootInfo->bootFile, kDefaultKernel, sizeof(bootInfo->bootFile) ); } else { printf("No kernel found on this volume : hd(%d,%d)\n", BIOS_DEV_UNIT(((BVRef)(uint32_t)get_env(envgBootVolume))), ((BVRef)(uint32_t)get_env(envgBootVolume))->part_no); sleep(1); return -1; } } ArgCntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; // Get config table kernel flags, if not ignored. if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) || !getValueForKey( kKernelFlagsKey, &val, &cnt, DEFAULT_BOOT_CONFIG )) { val = ""; cnt = 0; } configKernelFlags = newString(val); { bool isSafeMode = false; if (configKernelFlags) { isSafeMode = getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt); } if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && (isSafeMode == false)) { if (get_env(envgBootMode) & kBootModeSafe) { copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &ArgCntRemaining); } } } if (configKernelFlags) { // Store the merged kernel flags and boot args. cnt = strlen(configKernelFlags); if (cnt) { if (cnt > ArgCntRemaining) { printf("Warning: boot arguments too long, truncating\n"); cnt = ArgCntRemaining; } strncpy(argP, configKernelFlags, cnt); argP[cnt++] = ' '; ArgCntRemaining -= cnt; } } userCnt = strlen(cp); if (userCnt > ArgCntRemaining) { printf("Warning: boot arguments too long, truncating\n"); userCnt = ArgCntRemaining; } strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; if(!get_env(envShouldboot)) { bool gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ) || getValueForKey( kSingleUserModeFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ); safe_set_env(envgVerboseMode, gVerboseMode); long gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) ? kBootModeSafe : kBootModeNormal; safe_set_env(envgBootMode,gBootMode); if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { gBootMode = kBootModeSafe; safe_set_env(envgBootMode,gBootMode); } } if ( getValueForKey( kMKextCacheKey, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { char * MKextName = (char*)(uint32_t)get_env(envMKextName); strlcpy(MKextName,val,Cache_len_name); } if (configKernelFlags) { free(configKernelFlags); } safe_set_env(envArgCntRemaining,ArgCntRemaining); return 0; }
int processBootOptions() { const char * cp = gBootArgs; const char * val = 0; const char * kernel; int cnt; int userCnt; int cntRemaining; char * argP; char uuidStr[64]; BOOL uuidSet = NO; char * configKernelFlags; char * valueBuffer; valueBuffer = (char *)malloc(VALUE_SIZE); skipblanks( &cp ); // Update the unit and partition number. if ( gBootVolume ) { if ( gBootVolume->flags & kBVFlagForeignBoot ) { readBootSector( gBootVolume->biosdev, gBootVolume->part_boff, (void *) 0x7c00 ); // // Setup edx, and signal intention to chain load the // foreign booter. // chainbootdev = gBootVolume->biosdev; chainbootflag = 1; return 1; } bootInfo->kernDev &= ~((B_UNITMASK << B_UNITSHIFT ) | (B_PARTITIONMASK << B_PARTITIONSHIFT)); bootInfo->kernDev |= MAKEKERNDEV( 0, /* unit */ BIOS_DEV_UNIT(gBootVolume), /* partition */ gBootVolume->part_no ); } // Load config table specified by the user, or use the default. if (getValueForBootKey( cp, "config", &val, &cnt ) == FALSE) { val = 0; cnt = 0; } loadSystemConfig(val, cnt); if ( !sysConfigValid ) return -1; // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying // a non-default kernel name in the config file counts as // overriding the kernel, which causes the kernelcache not // to be used. gOverrideKernel = NO; if (( kernel = extractKernelName((char **)&cp) )) { strcpy( bootInfo->bootFile, kernel ); gOverrideKernel = YES; } else { if ( getValueForKey( kKernelNameKey, &val, &cnt ) ) { strlcpy( bootInfo->bootFile, val, cnt+1 ); if (strcmp( bootInfo->bootFile, kDefaultKernel ) != 0) { gOverrideKernel = YES; } } else { strcpy( bootInfo->bootFile, kDefaultKernel ); } } cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; // Get config table kernel flags, if not ignored. if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) == TRUE || getValueForKey( kKernelFlagsKey, &val, &cnt ) == FALSE) { val = ""; cnt = 0; } configKernelFlags = (char *)malloc(cnt + 1); strlcpy(configKernelFlags, val, cnt + 1); if (processBootArgument(kBootUUIDKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, 0)) { // boot-uuid was set either on the command-line // or in the config file. uuidSet = YES; } else { if (GetFSUUID(bootInfo->bootFile, uuidStr) == 0) { verbose("Setting boot-uuid to: %s\n", uuidStr); copyArgument(kBootUUIDKey, uuidStr, strlen(uuidStr), &argP, &cntRemaining); uuidSet = YES; } } if (!processBootArgument(kRootDeviceKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gRootDevice)) { cnt = 0; if ( getValueForKey( kBootDeviceKey, &val, &cnt)) { valueBuffer[0] = '*'; cnt++; strlcpy(valueBuffer + 1, val, cnt); val = valueBuffer; } else { if (uuidSet) { val = "*uuid"; cnt = 5; } else { // Don't set "rd=.." if there is no boot device key // and no UUID. val = ""; cnt = 0; } } if (cnt > 0) { copyArgument( kRootDeviceKey, val, cnt, &argP, &cntRemaining); } strlcpy( gRootDevice, val, (cnt + 1)); } if (!processBootArgument(kPlatformKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gPlatformName)) { getPlatformName(gPlatformName); copyArgument(kPlatformKey, gPlatformName, strlen(gPlatformName), &argP, &cntRemaining); } if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && !getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt)) { if (gBootMode & kBootModeSafe) { copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &cntRemaining); } } // Store the merged kernel flags and boot args. cnt = strlen(configKernelFlags); if (cnt) { if (cnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); cnt = cntRemaining; } strncpy(argP, configKernelFlags, cnt); argP[cnt++] = ' '; cntRemaining -= cnt; } userCnt = strlen(cp); if (userCnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); userCnt = cntRemaining; } strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt ) || getValueForKey( kSingleUserModeFlag, &val, &cnt ); gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt ) ) ? kBootModeSafe : kBootModeNormal; if ( getValueForKey( kOldSafeModeFlag, &val, &cnt ) ) { gBootMode = kBootModeSafe; } if ( getValueForKey( kMKextCacheKey, &val, &cnt ) ) { strlcpy(gMKextName, val, cnt + 1); } free(configKernelFlags); free(valueBuffer); return 0; }
void getAndProcessBootArguments(char * configKernelFlags) { bool truncated = false; const char * cp = gBootArgs; char * argP = bootArgs->CommandLine; int key; int pressedKey = 0; int cntRemaining = BOOT_STRING_LEN - 2; // (1024 -2) int kernelFlagsLength = strlen(configKernelFlags); int index = 1; int bootModes[6] = { -1, kBootModeNormal, kBootModeNormal, -1, kBootModeSafe, kBootModeNormal }; const char * bootFlags[6] = { "", kVerboseModeFlag, kSingleUserModeFlag, "", kSafeModeFlag, kIgnoreCachesFlag }; skipblanks(&cp); while (readKeyboardStatus()) { key = (bgetc() & 0xff); switch (key |= 0x20) { case 'v': // Verbose booting. printf("V\n"); pressedKey |= 1; break; case 's': // Single user mode. printf("S\n"); pressedKey |= 2; break; case 'x': // Safe mode. printf("X\n"); pressedKey |= 4; break; case 'f': // Skip MKext. printf("F\n"); pressedKey |= 8; break; } } if ((pressedKey & 1) || (pressedKey & 2)) { // Mandatory mode change before entering single user mode, // which is optional for normal and safe booting modes. gVerboseMode = true; // ((pressedKey & 1) || (pressedKey & 2)); } for (index = 1; index < 6; index++) { int currentMode = bootModes[index]; // printf("currentMode: %d\n", currentMode); // sleep(2); if (currentMode >= 0 && (pressedKey & index) == index) { // printf("And action...\n"); if (gBootArgsPtr + 3 < gBootArgsEnd) { gBootMode = currentMode; copyArgument(0, bootFlags[index], 3, &argP, &cntRemaining); } pressedKey -= index; } } // Reworked copy from processBootOptions() which is no more. if (kernelFlagsLength) { if (kernelFlagsLength > cntRemaining) { truncated = true; kernelFlagsLength = cntRemaining; } // Store kernel flags. strncpy(argP, configKernelFlags, kernelFlagsLength); argP[kernelFlagsLength++] = ' '; cntRemaining -= kernelFlagsLength; } int bootArgsLength = strlen(cp); if (bootArgsLength > cntRemaining) { truncated = true; bootArgsLength = cntRemaining; } if (truncated) { error("Warning: boot arguments too long, truncating\n"); } // Store boot args. strncpy(&argP[kernelFlagsLength], cp, bootArgsLength); argP[kernelFlagsLength + bootArgsLength] = '\0'; if (configKernelFlags) { // Free the earlier allocated (in boot.c) / passed on Kernel Flags. free(configKernelFlags); } }