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 * BLCreateFile.c 25 * bless 26 * 27 * Created by Shantonu Sen <ssen@apple.com> on Tue Apr 17 2001. 28 * Copyright (c) 2001-2007 Apple Inc. All Rights Reserved. 29 * 30 * $Id: BLCreateFile.c,v 1.26 2006/02/20 22:49:56 ssen Exp $ 31 * 32 */ 33 34#include <CoreFoundation/CoreFoundation.h> 35 36#include <stdlib.h> 37#include <unistd.h> 38#include <stdio.h> 39#include <sys/param.h> 40#include <sys/stat.h> 41#include <sys/fcntl.h> 42#include <sys/paths.h> 43#include <errno.h> 44 45#include "bless.h" 46#include "bless_private.h" 47#include "bless_private.h" 48 49 50int BLCreateFile(BLContextPtr context, const CFDataRef data, 51 const char * file, int setImmutable, 52 uint32_t type, uint32_t creator) { 53 54 55 int err; 56 int mainfd; 57 struct stat sb; 58 const char *rsrcpath = file; 59 60 61 err = lstat(rsrcpath, &sb); 62 if(err == 0) { 63 if(!S_ISREG(sb.st_mode)) { 64 contextprintf(context, kBLLogLevelError, "%s is not a regular file\n", 65 rsrcpath); 66 return 1; 67 } 68 69 if(sb.st_flags & UF_IMMUTABLE) { 70 uint32_t newflags = sb.st_flags & ~UF_IMMUTABLE; 71 72 contextprintf(context, kBLLogLevelVerbose, "Removing UF_IMMUTABLE from %s\n", 73 rsrcpath); 74 err = chflags(rsrcpath, newflags); 75 if(err) { 76 contextprintf(context, kBLLogLevelError, 77 "Can't remove UF_IMMUTABLE from %s: %s\n", rsrcpath, 78 strerror(errno)); 79 return 1; 80 } 81 82 } 83 84 85 contextprintf(context, kBLLogLevelVerbose, "Deleting old %s\n", 86 rsrcpath); 87 err = unlink(rsrcpath); 88 if(err) { 89 contextprintf(context, kBLLogLevelError, 90 "Can't delete %s: %s\n", rsrcpath, 91 strerror(errno)); 92 return 1; 93 } 94 95 } else if(errno != ENOENT) { 96 contextprintf(context, kBLLogLevelError, "Can't access %s: %s\n", rsrcpath, 97 strerror(errno)); 98 return 1; 99 } else { 100 // ENOENT is OK, we'll create the file now 101 } 102 103 mainfd = open(rsrcpath, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 104 if(mainfd < 0) { 105 contextprintf(context, kBLLogLevelError, "Could not touch %s\n", rsrcpath ); 106 return 2; 107 } 108 close(mainfd); 109 110 if(data != NULL) { 111 err = BLCopyFileFromCFData(context, data, rsrcpath, 1); 112 if(err) return 3; 113 } 114 115 if (type || creator) { 116 err = BLSetTypeAndCreator(context, rsrcpath, type, creator); 117 if(err) { 118 contextprintf(context, kBLLogLevelError, 119 "Error while setting type/creator for %s\n", rsrcpath ); 120 return 4; 121 } else { 122 char printType[5], printCreator[5]; 123 124 contextprintf(context, kBLLogLevelVerbose, "Type/creator set to %4.4s/%4.4s for %s\n", 125 blostype2string(type, printType), 126 blostype2string(creator, printCreator), rsrcpath ); 127 } 128 } 129 130 if(setImmutable) { 131 contextprintf(context, kBLLogLevelVerbose, "Setting UF_IMMUTABLE on %s\n", 132 rsrcpath); 133 err = chflags(rsrcpath, UF_IMMUTABLE); 134 if(err && errno != ENOTSUP) { 135 contextprintf(context, kBLLogLevelError, 136 "Can't set UF_IMMUTABLE on %s: %s\n", rsrcpath, 137 strerror(errno)); 138 return 5; 139 } 140 } 141 142 return 0; 143} 144