/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This 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 OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Modification History * * July 17, 2000 Allan Nathanson * - initial revision */ #include #include #include #include #include "cfManager.h" /* * Opens a configuration file and returns a CFArrayRef consisting * of a CFStringRef for each line. */ CFArrayRef configRead(const char *path) { int fd; struct stat statBuf; CFMutableDataRef data; CFStringRef str; CFArrayRef config = NULL; fd = open(path, O_RDONLY, 0644); if (fd < 0) { goto done; } if (fstat(fd, &statBuf) < 0) { goto done; } if ((statBuf.st_mode & S_IFMT) != S_IFREG) { goto done; } data = CFDataCreateMutable(NULL, statBuf.st_size); CFDataSetLength(data, statBuf.st_size); if(read(fd, (void *)CFDataGetMutableBytePtr(data), statBuf.st_size) != statBuf.st_size) { CFRelease(data); goto done; } str = CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingMacRoman); CFRelease(data); config = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR("\n")); CFRelease(str); done: if (fd >= 0) { close(fd); } if (config == NULL) { CFMutableArrayRef emptyConfig; /* pretend that we found an empty file */ emptyConfig = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(emptyConfig, CFSTR("")); config = (CFArrayRef)emptyConfig; } return config; } /* * Writes a new configuration file with the contents of a CFArrayRef. Each * element of the array is a CFStringRef. */ void configWrite(const char *path, CFArrayRef config) { CFStringRef str; CFDataRef data; int fd = -1; int len; str = CFStringCreateByCombiningStrings(NULL, config, CFSTR("\n")); data = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingMacRoman, '.'); CFRelease(str); fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd < 0) { goto done; } len = CFDataGetLength(data); if (len) { (void)write(fd, CFDataGetBytePtr(data), len); } done: if (fd >= 0) close(fd); CFRelease(data); return; } void configSet(CFMutableArrayRef config, CFStringRef key, CFStringRef value) { CFMutableStringRef pref; CFIndex configLen = CFArrayGetCount(config); CFIndex i; CFMutableStringRef newValue; CFRange range; CFStringRef specialChars = CFSTR(" \"'$!|\\><{}[]"); boolean_t mustQuote = FALSE; /* create search prefix */ pref = CFStringCreateMutableCopy(NULL, 0, key); CFStringAppend(pref, CFSTR("=")); /* * create new / replacement value * * Note: Since the configuration file may be processed by a * shell script we need to ensure that, if needed, the * string is properly quoted. */ newValue = CFStringCreateMutableCopy(NULL, 0, value); for (i=0; i= 0) { const CFRange *range; range = CFArrayGetValueAtIndex(matches, j); CFStringInsert(newValue, range->location, CFSTR("\\")); } CFRelease(matches); } } CFStringInsert(newValue, 0, CFSTR("\"")); CFStringAppend(newValue, CFSTR("\"")); } /* locate existing key */ for (i=0; i