00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 static const char RCSbrlcad_path[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/brlcad_path.c,v 14.29 2006/08/31 23:16:38 lbutler Exp $ (BRL)";
00037
00038 #include "common.h"
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #ifdef HAVE_STRING_H
00043 # include <string.h>
00044 #else
00045 # include <strings.h>
00046 #endif
00047 #ifdef HAVE_SYS_PARAM_H
00048 # include <sys/param.h>
00049 #endif
00050
00051 #include "machine.h"
00052 #include "bu.h"
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static const char *
00063 bu_ipwd()
00064 {
00065 static const char *pwd = NULL;
00066
00067 if (pwd) {
00068 return pwd;
00069 }
00070
00071 #ifdef HAVE_GETENV
00072 pwd = getenv("PWD");
00073 #else
00074 pwd = (char *)NULL;
00075 #endif
00076
00077 return pwd;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 static const char *
00089 bu_argv0(const char *path)
00090 {
00091 static const char *argv0 = NULL;
00092
00093
00094 (void)bu_ipwd();
00095
00096 if (path) {
00097 argv0 = path;
00098 }
00099
00100 if (argv0) {
00101 return (argv0);
00102 }
00103
00104
00105
00106
00107 #ifdef HAVE_GETPROGNAME
00108 argv0 = getprogname();
00109 #endif
00110
00111 return argv0;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121 const char *
00122 bu_getprogname(void) {
00123 return bu_argv0(NULL);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 void
00135 bu_setprogname(const char *progname) {
00136 #ifdef HAVE_SETPROGNAME
00137 setprogname(progname);
00138 #endif
00139 (void)bu_argv0(progname);
00140 return;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 static void
00150 bu_root_missing(const char *paths)
00151 {
00152 bu_log("\
00153 Unable to locate where BRL-CAD %s is installed while searching:\n\
00154 %s\n\
00155 This version of BRL-CAD was compiled to be installed at:\n\
00156 %s\n\n", BRLCAD_VERSION, paths, BRLCAD_ROOT);
00157
00158 #ifndef _WIN32
00159 bu_log("\
00160 You may specify where to locate BRL-CAD by setting the BRLCAD_ROOT\n\
00161 environment variable. For example:\n\
00162 \n\
00163 for csh/tcsh users:\n\
00164 setenv BRLCAD_ROOT /path/to/brlcad\n\
00165 for sh/bash users:\n\
00166 BRLCAD_ROOT=/path/to/brlcad ; export BRLCAD_ROOT\n\n");
00167 #endif
00168
00169 return;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178 static void
00179 bu_data_missing(const char *paths)
00180 {
00181 bu_log("\
00182 Unable to locate where BRL-CAD %s data resources are installed\n\
00183 while searching:\n\
00184 %s\n\
00185 This release of BRL-CAD expects data resources to be at:\n\
00186 %s\n\n", BRLCAD_VERSION, paths, BRLCAD_DATA);
00187
00188 #ifndef _WIN32
00189 bu_log("\
00190 You may specify where to locate BRL-CAD data resources by setting\n\
00191 the BRLCAD_DATA environment variable. For example:\n\
00192 \n\
00193 for csh/tcsh users:\n\
00194 setenv BRLCAD_DATA /path/to/brlcad/data\n\
00195 for sh/bash users:\n\
00196 BRLCAD_DATA=/path/to/brlcad/data ; export BRLCAD_DATA\n\n");
00197 #endif
00198
00199 return;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209 static int
00210 bu_find_path(char result[MAXPATHLEN], const char *lhs, const char *rhs, struct bu_vls *searched, const char *where)
00211 {
00212 int llen,rlen;
00213 static const char *currdir=".";
00214
00215
00216
00217
00218 if (lhs == NULL && rhs != NULL) {
00219 lhs = rhs;
00220 rhs = NULL;
00221 }
00222
00223 if (lhs == NULL) {
00224 if (searched && where) {
00225 bu_vls_strcat(searched, where);
00226 }
00227 return 0;
00228 }
00229
00230 rlen = llen = 0;
00231 if (rhs) {
00232 rlen = strlen(rhs);
00233 }
00234
00235
00236 if (rlen + 2 > MAXPATHLEN) {
00237 bu_log("Warning: path is way too long (%d characters > %d)\n", rlen+2, MAXPATHLEN);
00238 if (searched && where) {
00239 bu_vls_strcat(searched, where);
00240 }
00241 return 0;
00242 }
00243
00244
00245 if (lhs[0] == '\0') {
00246 lhs = currdir;
00247 }
00248
00249
00250 if (!bu_file_exists(lhs)) {
00251 if (searched && where) {
00252 bu_vls_strcat(searched, where);
00253 }
00254 return 0;
00255 }
00256
00257
00258 memset(result, 0, MAXPATHLEN);
00259 strncpy(result, lhs, MAXPATHLEN);
00260
00261
00262 if (!rhs || (rlen == 0)) {
00263 return 1;
00264 }
00265
00266
00267 llen = strlen(result);
00268 if (llen + rlen + 3 > MAXPATHLEN) {
00269 bu_log("Warning: path is way too long (%d characters > %d)\n", llen+rlen+3, MAXPATHLEN);
00270 if (searched && where) {
00271 bu_vls_strcat(searched, where);
00272 }
00273 return 0;
00274 }
00275
00276 if ( (*(result+llen-1) != BU_DIR_SEPARATOR) && (rhs[0] != BU_DIR_SEPARATOR) ) {
00277
00278 *(result+llen) = BU_DIR_SEPARATOR;
00279 llen++;
00280 } else if ( (*(result+llen-1) == BU_DIR_SEPARATOR) && (rhs[0] == BU_DIR_SEPARATOR) ) {
00281
00282 rhs++;
00283 rlen--;
00284 }
00285
00286
00287 strncpy(result+llen, rhs, MAXPATHLEN - llen);
00288 if (bu_file_exists(result)) {
00289 return 1;
00290 }
00291
00292
00293 if (searched && where) {
00294 bu_vls_strcat(searched, where);
00295 }
00296 return 0;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 char *
00320 bu_brlcad_root(const char *rhs, int fail_quietly)
00321 {
00322 static char result[MAXPATHLEN] = {0};
00323 const char *lhs;
00324 struct bu_vls searched;
00325 char where[MAXPATHLEN + 64] = {0};
00326
00327
00328
00329 bu_vls_init(&searched);
00330
00331 if (bu_debug) {
00332 bu_log("bu_brlcad_root: searching for [%s]\n", rhs);
00333 }
00334
00335
00336 lhs = getenv("BRLCAD_ROOT");
00337 if (lhs) {
00338 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT environment variable [%s]\n", lhs);
00339 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00340 if (bu_debug) {
00341 bu_log("Found: BRLCAD_ROOT environment variable [%s]\n", result);
00342 }
00343 return result;
00344 }
00345 } else {
00346 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT environment variable\n");
00347 bu_vls_strcat(&searched, where);
00348 }
00349
00350
00351 lhs = BRLCAD_ROOT;
00352 if (lhs) {
00353 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT compile-time path [%s]\n", lhs);
00354 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00355 if (bu_debug) {
00356 bu_log("Found: BRLCAD_ROOT compile-time path [%s]\n", result);
00357 }
00358 return result;
00359 }
00360 } else {
00361 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT compile-time path [UNKNOWN]\n");
00362 bu_vls_strcat(&searched, where);
00363 }
00364
00365
00366 lhs = bu_getprogname();
00367 if (lhs) {
00368 char argv0[MAXPATHLEN + 64] = {0};
00369 int len = strlen(lhs);
00370 snprintf(argv0, MAXPATHLEN + 64, "%s", lhs);
00371
00372
00373 while (len-1 > 0) {
00374 if (argv0[len-1] == BU_DIR_SEPARATOR) {
00375 argv0[len] = '.';
00376 argv0[len+1] = '.';
00377 argv0[len+2] = '\0';
00378 break;
00379 }
00380 len--;
00381 }
00382
00383 snprintf(where, MAXPATHLEN + 64, "\trun-time path identification [%s]\n", argv0);
00384 if (bu_find_path(result, argv0, rhs, &searched, where)) {
00385 if (bu_debug) {
00386 bu_log("Found: Run-time path identification [%s]\n", result);
00387 }
00388 return result;
00389 }
00390 } else {
00391 snprintf(where, MAXPATHLEN + 64, "\trun-time path identification [UNKNOWN]\n");
00392 bu_vls_strcat(&searched, where);
00393 }
00394
00395
00396 if (strncmp("/usr/brlcad", BRLCAD_ROOT, 12) != 0) {
00397 if (bu_find_path(result, "/usr/brlcad", rhs, &searched, "\t/usr/brlcad default path\n")) {
00398 if (bu_debug) {
00399 bu_log("Found: /usr/brlcad default path [%s]\n", result);
00400 }
00401 return result;
00402 }
00403 }
00404
00405
00406 if (bu_find_path(result, ".", rhs, &searched, "\tcurrent directory\n")) {
00407 if (bu_debug) {
00408 bu_log("Found: current directory [%s]\n", result);
00409 }
00410 return result;
00411 }
00412
00413 if (!fail_quietly) {
00414 bu_root_missing(bu_vls_addr(&searched));
00415 if (rhs) {
00416 bu_log("Unable to find '%s' within the BRL-CAD software installation.\nThis copy of BRL-CAD may not be properly installed.\n\n", rhs);
00417 } else {
00418 bu_log("Unable to find the BRL-CAD software installation.\nThis copy of BRL-CAD may not be properly installed.\n\n");
00419 }
00420 }
00421 return NULL;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 char *
00446 bu_brlcad_data(const char *rhs, int fail_quietly)
00447 {
00448 static char result[MAXPATHLEN] = {0};
00449 const char *lhs;
00450 struct bu_vls searched;
00451 char where[MAXPATHLEN + 64] = {0};
00452 char path[64] = {0};
00453
00454
00455
00456 bu_vls_init(&searched);
00457
00458 if (bu_debug) {
00459 bu_log("bu_brlcad_data: looking for [%s]\n", rhs);
00460 }
00461
00462
00463 lhs = getenv("BRLCAD_DATA");
00464 if (lhs) {
00465 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_DATA environment variable [%s]\n", lhs);
00466 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00467 if (bu_debug) {
00468 bu_log("Found: BRLCAD_DATA environment variable [%s]\n", result);
00469 }
00470 return result;
00471 }
00472 } else {
00473 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_DATA environment variable\n");
00474 bu_vls_strcat(&searched, where);
00475 }
00476
00477
00478 lhs = BRLCAD_DATA;
00479 if (lhs) {
00480 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_DATA compile-time path [%s]\n", lhs);
00481 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00482 if (bu_debug) {
00483 bu_log("Found: BRLCAD_DATA compile-time path [%s]\n", result);
00484 }
00485 return result;
00486 }
00487 } else {
00488 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_DATA compile-time path [UNKNOWN]\n");
00489 bu_vls_strcat(&searched, where);
00490 }
00491
00492
00493 snprintf(path, MAXPATHLEN, "share/brlcad/%s", BRLCAD_VERSION);
00494 lhs = bu_brlcad_root(path, 1);
00495 if (lhs) {
00496 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT common data path [%s]\n", path);
00497 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00498 if (bu_debug) {
00499 bu_log("Found: BRLCAD_ROOT common data path [%s]\n", result);
00500 }
00501 return result;
00502 }
00503 }
00504
00505
00506 lhs = bu_brlcad_root("share/brlcad", 1);
00507 if (lhs) {
00508 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT common data path [%s]\n", lhs);
00509 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00510 if (bu_debug) {
00511 bu_log("Found: BRLCAD_ROOT common data path [%s]\n", result);
00512 }
00513 return result;
00514 }
00515 }
00516
00517
00518 lhs = bu_brlcad_root("share", 1);
00519 if (lhs) {
00520 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT common data path [%s]\n", lhs);
00521 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00522 if (bu_debug) {
00523 bu_log("Found: BRLCAD_ROOT common data path [%s]\n", result);
00524 }
00525 return result;
00526 }
00527 }
00528
00529
00530 lhs = bu_brlcad_root("", 1);
00531 if (lhs) {
00532 snprintf(where, MAXPATHLEN + 64, "\tBRLCAD_ROOT common data path [%s]\n", lhs);
00533 if (bu_find_path(result, lhs, rhs, &searched, where)) {
00534 if (bu_debug) {
00535 bu_log("Found: BRLCAD_ROOT common data path [%s]\n", result);
00536 }
00537 return result;
00538 }
00539 }
00540
00541
00542 if (bu_find_path(result, ".", rhs, &searched, "\tcurrent directory\n")) {
00543 if (bu_debug) {
00544 bu_log("Found: current directory [%s]\n", result);
00545 }
00546 return result;
00547 }
00548
00549 if (!fail_quietly) {
00550 bu_data_missing(bu_vls_addr(&searched));
00551 if (rhs) {
00552 bu_log("Unable to find '%s' within the BRL-CAD software installation.\nThis copy of BRL-CAD may not be properly installed.\n\n", rhs);
00553 } else {
00554 bu_log("Unable to find the BRL-CAD software installation.\nThis copy of BRL-CAD may not be properly installed.\n\n");
00555 }
00556 }
00557 return NULL;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 char *
00573 bu_brlcad_path(const char *rhs, int fail_quietly)
00574 {
00575 bu_log("\
00576 WARNING: bu_brlcad_path is deprecated and will likely disappear in\n\
00577 a future release of BRL-CAD. Programs and scripts should utilize\n\
00578 bu_brlcad_root and bu_brlcad_data instead.\n\
00579 \n\
00580 Use bu_brlcad_root for the path of applications and libraries.\n\
00581 Use bu_brlcad_data for the path to the data resources.\n\n");
00582
00583 return bu_brlcad_root(rhs, fail_quietly);
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594