1/* 2 * Copyright (c) 2001-2007 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * handleDevice.c 25 * bless 26 * 27 * Created by Shantonu Sen <ssen@apple.com> on Thu Dec 6 2001. 28 * Copyright (c) 2001-2007 Apple Inc. All Rights Reserved. 29 * 30 * $Id: handleDevice.c,v 1.54 2006/07/19 00:15:36 ssen Exp $ 31 * 32 * 33 */ 34 35#include <stdlib.h> 36#include <stdio.h> 37#include <unistd.h> 38#include <sys/stat.h> 39#include <sys/mount.h> 40#include <sys/paths.h> 41#include <string.h> 42 43#include "enums.h" 44#include "structs.h" 45 46#include "bless.h" 47#include "bless_private.h" 48#include "protos.h" 49 50int modeDevice(BLContextPtr context, struct clarg actargs[klast]) { 51 int ret = 0; 52 CFDataRef labeldata = NULL; 53 CFDataRef labeldata2 = NULL; 54 CFDataRef bootXdata = NULL; 55 56 BLPreBootEnvType preboot; 57 58 if(!(geteuid() == 0)) { 59 blesscontextprintf(context, kBLLogLevelError, "Not run as root\n" ); 60 return 1; 61 } 62 63 ret = BLGetPreBootEnvironmentType(context, &preboot); 64 if(ret) { 65 blesscontextprintf(context, kBLLogLevelError, "Could not determine preboot environment\n"); 66 return 1; 67 } 68 69 70 71 /* try to grovel the HFS+ catalog and update a label if present */ 72 if(actargs[klabelfile].present) { 73 ret = BLLoadFile(context, actargs[klabelfile].argument, 0, &labeldata); 74 if(ret) { 75 blesscontextprintf(context, kBLLogLevelError, "Can't load label '%s'\n", 76 actargs[klabelfile].argument); 77 return 2; 78 } 79 } else if(actargs[klabel].present) { 80 ret = BLGenerateLabelData(context, actargs[klabel].argument, kBitmapScale_1x, &labeldata); 81 if(ret) { 82 blesscontextprintf(context, kBLLogLevelError, "Can't render scale 1 label '%s'\n", 83 actargs[klabel].argument); 84 return 3; 85 } 86 ret = BLGenerateLabelData(context, actargs[klabel].argument, kBitmapScale_2x, &labeldata2); 87 if(ret) { 88 blesscontextprintf(context, kBLLogLevelError, "Can't render scale 2 label '%s'\n", 89 actargs[klabel].argument); 90 return 3; 91 } 92 } 93 94 if(actargs[kbootinfo].present) { 95 if(!actargs[kbootinfo].hasArg) { 96 blesscontextprintf(context, kBLLogLevelError, 97 "BootX file must be specified in Device Mode\n"); 98 return 4; 99 } 100 101 ret = BLLoadFile(context, actargs[kbootinfo].argument, 0, &bootXdata); 102 if(ret) { 103 blesscontextprintf(context, kBLLogLevelError, "Could not load BootX data from %s\n", 104 actargs[kbootinfo].argument); 105 } 106 } 107 108 /* Set Open Firmware to boot off the specified volume*/ 109 if(actargs[ksetboot].present) { 110 if(preboot == kBLPreBootEnvType_EFI) { 111 112 ret = setefidevice(context, actargs[kdevice].argument + strlen("/dev/"), 113 actargs[knextonly].present, 114 actargs[klegacy].present, 115 actargs[klegacydrivehint].present ? actargs[klegacydrivehint].argument : NULL, 116 actargs[koptions].present ? actargs[koptions].argument : NULL, 117 actargs[kshortform].present ? true : false); 118 } else { 119 ret = setboot(context, actargs[kdevice].argument, bootXdata, labeldata); 120 } 121 122 if(ret) { 123 return 3; 124 } 125 } else if (labeldata) { 126 ret = BLSetDiskLabelForDevice(context, actargs[kdevice].argument, labeldata, 1); 127 if(ret) { 128 blesscontextprintf(context, kBLLogLevelError, "Error while setting scale 1 label for %s\n", actargs[kdevice].argument ); 129 return 3; 130 } 131 if (labeldata2) { 132 ret = BLSetDiskLabelForDevice(context, actargs[kdevice].argument, labeldata2, 2); 133 if(ret) { 134 blesscontextprintf(context, kBLLogLevelError, "Error while setting scale 2 label for %s\n", actargs[kdevice].argument ); 135 return 3; 136 } 137 } 138 } 139 140 if (labeldata) CFRelease(labeldata); 141 if (labeldata2) CFRelease(labeldata2); 142 if (bootXdata) CFRelease(bootXdata); 143 144 return 0; 145} 146