1/* 2 * Copyright (c) 2003-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 * You can do a pretty grueling self-test with: 25 * find -x /System -print0 | xargs -0 -n 1 ./build/testgetfileid | grep -v ^Success: 26 */ 27 28#define DEBUG 1 29 30#include <libc.h> 31#include <stdint.h> 32#include <inttypes.h> 33#include <bless.h> 34#include <AssertMacros.h> 35 36void usage() { 37 fprintf(stderr, "Usage: %s [ mountpoint cnid | path ]\n", getprogname()); 38 exit(1); 39} 40 41int main(int argc, char *argv[]) { 42 43 if(argc < 2 || argc > 3) { 44 usage(); 45 } 46 47 if(argc == 2) { 48 char *path = argv[1]; 49 int isHFS = 0; 50 struct stat sb; 51 struct statfs sf; 52 uint32_t fileID = 0; 53 char newpath[MAXPATHLEN]; 54 55 require_noerr(lstat(path, &sb), cantStat); 56 if(S_ISLNK(sb.st_mode)) { 57 printf("Success: %s is a symlink\b", path); 58 return 0; 59 } 60 61 require_noerr(statfs(path, &sf), cantStat); 62 require_noerr(BLIsMountHFS(NULL, path, &isHFS), notHFS); 63 require(isHFS == 1, notHFS); 64 65 require_noerr(BLGetFileID(NULL, path, &fileID), error); 66 require(fileID == sb.st_ino, error); 67 68 require_noerr(BLLookupFileIDOnMount(NULL, 69 sf.f_mntonname, 70 fileID, 71 newpath), error); 72 73 require(strcmp(newpath, path) == 0, cantstrcmp); 74 75 printf("Success: %s\n", newpath); 76 77 return 0; 78 79 error: 80 printf("Error: %s\n", path); 81 return 1; 82 cantstrcmp: 83 printf("%s != %s\n", newpath, path); 84 return 1; 85cantStat: 86 printf("%s: %s\n",path, strerror(errno)); 87 return 1; 88notHFS: 89 printf("%s not on an HFS+ filesystem\n", path); 90 return 1; 91 } else if(argc == 3) { 92 char *path = argv[1]; 93 int isHFS = 0; 94 struct statfs sf; 95 uint32_t fileID = 0; 96 char newpath[MAXPATHLEN]; 97 98 fileID = strtoul(argv[2], NULL, 0); 99 require(fileID > 0, error2); 100 101 require_noerr(statfs(path, &sf), cantStat2); 102 require_noerr(BLIsMountHFS(NULL, path, &isHFS), notHFS2); 103 require(isHFS == 1, notHFS2); 104 105 require_noerr(BLLookupFileIDOnMount(NULL, 106 sf.f_mntonname, 107 fileID, 108 newpath), error2); 109 110 printf("Success: %s\n", newpath); 111 112 return 0; 113 114error2: 115 return 1; 116cantStat2: 117 printf("%s: %s\n",path, strerror(errno)); 118 return 1; 119notHFS2: 120 printf("%s not on an HFS+ filesystem\n", path); 121 return 1; 122 } 123 124 125 126 return 0; 127} 128 129