home *** CD-ROM | disk | FTP | other *** search
- /* WhereAmI
- *
- * A category of Application that provides methods for finding the
- * application executable and executable directory.
- *
- * Copyright 1991, 1992 Scott Hess. This source code may be
- * redistributed and modified without restriction. Well, one
- * restriction - do not claim that you wrote it.
- *
- * Scott Hess
- * 12901 Upton Avenue South, #326
- * Burnsville, MN 55337
- * (612) 895-1208
- * scott@gac.edu
- * shess@ssesco.com
- */
- #import "WhereAmI.h"
- #import <appkit/defaults.h>
- #import <sys/param.h>
- #import <libc.h>
- #import <strings.h>
-
- @implementation Application (WhereAmI)
- int whereAmIReference=0;
- -(NXAtom)whoAmI
- {
- static NXAtom whoAmI=NULL;
- static BOOL beenHere;
-
- if( !beenHere) {
- char buf[ MAXPATHLEN+1]="";
- char linkbuf[ MAXPATHLEN+1];
- int len, links;
-
- /* First, trace the file that is in NXArgv[ 0].
- * If it starts with '/', it's an absolute pathname and thus truth.
- * Else, check to see if it is relative to the working directory.
- * Else, look on the path for it.
- */
- if( NXArgv[ 0][ 0]=='/') {
- strcpy( buf, NXArgv[ 0]);
- } else if( access( NXArgv[ 0], F_OK)==0) {
- if( getwd( buf)) {
- strcat( buf, "/");
- strcat( buf, NXArgv[ 0]);
- }
- } else {
- const char *pathList=getenv( "PATH");
- if( pathList) {
- while( *pathList) {
- const char *colon=index( pathList, ':');
- if( colon) {
- strncpy( buf, pathList, colon-pathList);
- buf[ colon-pathList]=0;
- pathList=colon+1;
- } else {
- strcpy( buf, pathList);
- pathList+=strlen( pathList);
- }
- strcat( buf, "/");
- strcat( buf, NXArgv[ 0]);
- if( access( buf, F_OK)==0) {
- break;
- }
- }
- }
- if( !pathList || *pathList==0) {
- buf[ 0]='\0';
- }
- }
-
- /* Now, trace the file through symbolic links to where it _really_ is.
- * Note that symbolic links can be multiple.
- * Give up after tracing through 8 links (assume a cycle).
- */
- for( links=0; links<8 && (len=readlink( buf, linkbuf, MAXPATHLEN))!=-1; links++) {
- linkbuf[ len]='\0';
- if( linkbuf[ 0]=='/') {
- strcpy( buf, linkbuf);
- } else {
- char *p=linkbuf;
- for( ;;) {
- char *s=rindex( buf, '/');
- if( s) {
- *s='\0';
- }
- if( strncmp( p, "../", 3)) {
- break;
- }
- p+=3;
- }
- strcat( buf, "/");
- strcat( buf, p);
- }
- }
- if( links==8) {
- buf[ 0]='\0';
- }
-
- if( !access( buf, X_OK)) {
- whoAmI=NXUniqueString( buf);
- }
- beenHere=YES;
- }
- return whoAmI;
- }
- -(NXAtom)whereAmI
- {
- static NXAtom whereAmI=NULL;
- static BOOL beenHere=NO;
-
- if( !beenHere) {
- /* Just get the executable path, and then strip off the
- * executable's name.
- */
- NXAtom who=[self whoAmI];
- if( who) {
- char buf[ MAXPATHLEN+1]="";
- char *i;
- strcpy( buf, who);
- i=rindex( buf, '/');
- if( i) {
- *i='\0';
- }
- if( buf[ 0]) {
- whereAmI=NXUniqueString( buf);
- } else {
- whereAmI="";
- }
- }
-
- beenHere=YES;
- }
- return whereAmI;
- }
- -(const char *)whereIs:(const char *)file path:(char *)result
- {
- /* Get the directory the application resides in.
- * Append the file part.
- * Attempt to verify the file's existance.
- */
- if( result) {
- NXAtom where=[self whereAmI];
- if( where) {
- strcpy( result, where);
- strcat( result, "/");
- if( file) {
- strcat( result, file);
- }
- if( !access( result, F_OK)) {
- return result;
- }
- return NULL;
- }
- }
- *result='\0';
- return NULL;
- }
- @end
-