/* * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.h" void PrintValue(const void *key, const void *value, void *context) { int key_len, value_len; const CFStringRef kStr = key; const CFTypeRef kVal = value; char *buf = NULL; int32_t val; char *intFmt = "%d\n"; if (CFGetTypeID(kStr) != CFStringGetTypeID()) { warnx("PrintDictionary: key type is not a string"); return; } if (CFStringCompare(kStr, CFSTR("owner-mode"), 0) == kCFCompareEqualTo) { intFmt = "0%o\n"; } else if (!gVerbose && (CFStringCompare(kStr, CFSTR("Base"), 0) == kCFCompareEqualTo || CFStringCompare(kStr, CFSTR("Size"), 0) == kCFCompareEqualTo)) { return; } key_len = CFStringGetLength(kStr); buf = malloc(key_len * 2); if (!buf) { warnx("PrintDictionary: unable to allocate buffer for key"); goto out; } if (!CFStringGetCString(kStr, buf, key_len * 2, kCFStringEncodingASCII)) { warnx("PrintDictionary: unable to get key as C string"); goto out; } printf("\t%s = ", buf); free(buf); buf = NULL; if (CFGetTypeID(kVal) == CFStringGetTypeID()) { value_len = CFStringGetLength(kVal); buf = malloc(value_len * 2); if (buf == NULL) { warnx("PrintDictionary: unable to allocate buffer for value"); printf("* * * ERROR * * *\n"); goto out; } if (!CFStringGetCString(kVal, buf, value_len * 2, kCFStringEncodingASCII)) { warnx("PrintDictionary: unable to get value as C String"); printf("* * * ERROR * * *\n"); goto out; } printf("\"%s\"\n", buf); free(buf); buf = NULL; } else if (CFGetTypeID(kVal) == CFNumberGetTypeID()) { if (!CFNumberGetValue(kVal, kCFNumberSInt32Type, &val)) { warnx("PrintDictionary: unable to get value as 32-bit number"); printf("* * * ERROR * * *\n"); goto out; } printf(intFmt, val); } out: if (buf) free(buf); return; } void doProps(const char *dev, char **args) { CFMutableDictionaryRef md = nil; CFDictionaryRef old; CFStringRef cfStr = nil; CFNumberRef cfNum = nil; int changes = 0; int i; old = ReadMetadata(dev); if (old == nil) { warnx("doProps: cannot get metadata for device %s", dev); goto out; } md = CFDictionaryCreateMutableCopy(nil, 0, old); if (md == nil) { warnx("cannot create dictionary in doProps"); goto out; } if (args[0] == NULL) { CFDictionaryApplyFunction(old, &PrintValue, NULL); goto out; } for (i = 0; args[i]; i++) { char *arg = args[i]; CFTypeRef v; CFStringRef k; if (parseProperty(arg, &k, &v) > 0) { if (v == nil) { /* No value, so just print it out */ v = CFDictionaryGetValue(old, k); if (v == nil) { warnx("Property `%s' does not exist in metadata", arg); } else { PrintValue(k, v, NULL); CFRelease(v); } CFRelease(k); continue; } // We have a key and a value, so we set them CFDictionarySetValue(md, k, v); printf("\tProperty %s\n", arg); CFRelease(k); CFRelease(v); changes++; } } if (gDebug) { CFDataRef data; int len; char *cp; data = CFPropertyListCreateXMLData(nil, (CFPropertyListRef)md); len = CFDataGetLength(data); cp = (char*)CFDataGetBytePtr(data); write (2, cp, len); CFRelease(data); } if (changes) { if (WriteMetadata(dev, md) != 1) { errx(3, "doProps: cannot write metadata"); } } out: if (old) CFRelease(old); if (md) CFRelease(md); if (cfStr) CFRelease(cfStr); if (cfNum) CFRelease(cfNum); return; }