1 /* 2 * finddir.c - 3 * (c) 2002, Sebastian Nozzi <sebnozzi@gmx.net> 4 * 08/24/2004 - Francois Revol - added -l option. 5 */ 6 7 #include <FindDirectory.h> 8 #include <fs_info.h> 9 10 #include <stdio.h> 11 #include <string.h> 12 13 14 #define NO_ERRORS 0 15 #define ARGUMENT_MISSING 1 16 #define WRONG_DIR_TYPE 2 17 18 typedef struct { 19 const char *key; 20 directory_which value; 21 } directoryType; 22 23 #define KEYVALUE_PAIR(key) {#key,key} 24 25 directoryType directoryTypes[] = { 26 KEYVALUE_PAIR(B_DESKTOP_DIRECTORY), 27 KEYVALUE_PAIR(B_TRASH_DIRECTORY), 28 KEYVALUE_PAIR(B_APPS_DIRECTORY), 29 KEYVALUE_PAIR(B_PREFERENCES_DIRECTORY), 30 KEYVALUE_PAIR(B_BEOS_DIRECTORY), 31 KEYVALUE_PAIR(B_BEOS_SYSTEM_DIRECTORY), 32 KEYVALUE_PAIR(B_BEOS_ADDONS_DIRECTORY), 33 KEYVALUE_PAIR(B_BEOS_BOOT_DIRECTORY), 34 KEYVALUE_PAIR(B_BEOS_FONTS_DIRECTORY), 35 KEYVALUE_PAIR(B_BEOS_LIB_DIRECTORY), 36 KEYVALUE_PAIR(B_BEOS_SERVERS_DIRECTORY), 37 KEYVALUE_PAIR(B_BEOS_APPS_DIRECTORY), 38 KEYVALUE_PAIR(B_BEOS_BIN_DIRECTORY), 39 KEYVALUE_PAIR(B_BEOS_ETC_DIRECTORY), 40 KEYVALUE_PAIR(B_BEOS_DOCUMENTATION_DIRECTORY), 41 KEYVALUE_PAIR(B_BEOS_PREFERENCES_DIRECTORY), 42 KEYVALUE_PAIR(B_COMMON_DIRECTORY), 43 KEYVALUE_PAIR(B_COMMON_SYSTEM_DIRECTORY), 44 KEYVALUE_PAIR(B_COMMON_ADDONS_DIRECTORY), 45 KEYVALUE_PAIR(B_COMMON_BOOT_DIRECTORY), 46 KEYVALUE_PAIR(B_COMMON_FONTS_DIRECTORY), 47 KEYVALUE_PAIR(B_COMMON_LIB_DIRECTORY), 48 KEYVALUE_PAIR(B_COMMON_SERVERS_DIRECTORY), 49 KEYVALUE_PAIR(B_COMMON_BIN_DIRECTORY), 50 KEYVALUE_PAIR(B_COMMON_ETC_DIRECTORY), 51 KEYVALUE_PAIR(B_COMMON_DOCUMENTATION_DIRECTORY), 52 KEYVALUE_PAIR(B_COMMON_SETTINGS_DIRECTORY), 53 KEYVALUE_PAIR(B_COMMON_DEVELOP_DIRECTORY), 54 KEYVALUE_PAIR(B_COMMON_LOG_DIRECTORY), 55 KEYVALUE_PAIR(B_COMMON_SPOOL_DIRECTORY), 56 KEYVALUE_PAIR(B_COMMON_TEMP_DIRECTORY), 57 KEYVALUE_PAIR(B_COMMON_VAR_DIRECTORY), 58 KEYVALUE_PAIR(B_USER_DIRECTORY), 59 KEYVALUE_PAIR(B_USER_CONFIG_DIRECTORY), 60 KEYVALUE_PAIR(B_USER_ADDONS_DIRECTORY), 61 KEYVALUE_PAIR(B_USER_BOOT_DIRECTORY), 62 KEYVALUE_PAIR(B_USER_FONTS_DIRECTORY), 63 KEYVALUE_PAIR(B_USER_LIB_DIRECTORY), 64 KEYVALUE_PAIR(B_USER_SETTINGS_DIRECTORY), 65 KEYVALUE_PAIR(B_USER_DESKBAR_DIRECTORY), 66 /* some more */ 67 KEYVALUE_PAIR(B_BEOS_MEDIA_NODES_DIRECTORY), 68 KEYVALUE_PAIR(B_BEOS_SOUNDS_DIRECTORY), 69 KEYVALUE_PAIR(B_BEOS_TRANSLATORS_DIRECTORY), 70 KEYVALUE_PAIR(B_COMMON_MEDIA_NODES_DIRECTORY), 71 KEYVALUE_PAIR(B_COMMON_SOUNDS_DIRECTORY), 72 KEYVALUE_PAIR(B_COMMON_TRANSLATORS_DIRECTORY), 73 KEYVALUE_PAIR(B_USER_MEDIA_NODES_DIRECTORY), 74 KEYVALUE_PAIR(B_USER_PRINTERS_DIRECTORY), 75 KEYVALUE_PAIR(B_USER_SOUNDS_DIRECTORY), 76 KEYVALUE_PAIR(B_USER_TRANSLATORS_DIRECTORY), 77 KEYVALUE_PAIR(B_UTILITIES_DIRECTORY), 78 #ifdef B_BEOS_VERSION_DANO 79 /* Dano specific */ 80 KEYVALUE_PAIR(B_ROOT_DIRECTORY), 81 #endif /* B_BEOS_VERSION_DANO */ 82 {NULL,B_USER_DESKBAR_DIRECTORY} 83 }; 84 85 86 static void 87 listDirectoryWhich(void) 88 { 89 int i; 90 91 for (i = 0; directoryTypes[i].key; i++) { 92 printf("%s\n", directoryTypes[i].key); 93 } 94 } 95 96 97 static bool 98 retrieveDirValue(directoryType *list, const char *key, directory_which *value_out) 99 { 100 unsigned i = 0; 101 102 while (list[i].key != NULL) { 103 if (strcmp(list[i].key, key) == 0) { 104 *value_out = list[i].value; 105 return true; 106 } 107 108 i++; 109 } 110 111 return false; 112 } 113 114 115 static void 116 usageMsg() 117 { 118 printf("usage: /bin/finddir -l | [ -v volume ] directory_which\n"); 119 printf("\t-l\t list valid which constants to use\n"); 120 printf("\t-v <file> use the specified volume for directory\n"); 121 printf("\t\t constants that are volume-specific.\n"); 122 printf("\t\t <file> can be any file on that volume.\n"); 123 printf("\t\t defaults to the boot volume.\n"); 124 printf(" For a description of recognized directory_which constants,\n"); 125 printf(" see the find_directory(...) documentation in the Be Book.\n"); 126 } 127 128 129 int 130 main(int argc, char *argv[]) 131 { 132 int directoryArgNr; 133 int status; 134 dev_t volume; 135 directory_which dirType; 136 int returnCode; 137 138 status = NO_ERRORS; 139 directoryArgNr = 1; 140 returnCode = 0; 141 142 dirType = B_BEOS_DIRECTORY; /* so that it compiles */ 143 144 /* By default use boot volume*/ 145 volume = dev_for_path("/boot"); 146 147 if (argc <= 1) { 148 status = ARGUMENT_MISSING; 149 } else { 150 if (strcmp(argv[1], "-l") == 0 ) { 151 listDirectoryWhich(); 152 return 0; 153 } 154 if (strcmp(argv[1], "-v") == 0 ) { 155 if (argc >= 3) { 156 dev_t temp_volume; 157 /* get volume from second arg */ 158 temp_volume = dev_for_path(argv[2]); 159 160 /* Keep default value in case of error */ 161 if (temp_volume >= 0) 162 volume = temp_volume; 163 164 /* two arguments were used for volume */ 165 directoryArgNr+=2; 166 } else { 167 /* set status to argument missing */ 168 status = ARGUMENT_MISSING; 169 } 170 } 171 } 172 173 if (status == NO_ERRORS && argc > directoryArgNr) { 174 /* get directory constant from next argument */ 175 176 if (retrieveDirValue(directoryTypes, argv[directoryArgNr], &dirType) == false) { 177 status = WRONG_DIR_TYPE; 178 } 179 180 } else { 181 status = ARGUMENT_MISSING; 182 } 183 184 /* Do the actual directoy finding */ 185 186 if (status == NO_ERRORS) { 187 /* Question: would B_PATH_NAME_LENGTH alone have been enough? */ 188 char buffer[B_PATH_NAME_LENGTH+B_FILE_NAME_LENGTH]; 189 status_t result; 190 191 result = find_directory (dirType, volume, /*create it*/ false, buffer, sizeof(buffer)); 192 193 if (result == B_OK) { 194 printf("%s\n", buffer); 195 } else { 196 /* else what? */ 197 /* this can not happen! */ 198 printf("Serious internal error; contact support\n"); 199 } 200 } 201 202 /* Error messages and return code setting */ 203 204 if (status == WRONG_DIR_TYPE) { 205 printf("%s: unrecognized directory_which constant \'%s\'\n", argv[0], argv[directoryArgNr]); 206 returnCode = 252; 207 } 208 209 if (status == ARGUMENT_MISSING) { 210 usageMsg(); 211 returnCode = 255; 212 } 213 214 return returnCode; 215 } 216 217