From: nagamatu@sm.sony.co.jp (Tatsuo Nagamatu)
Newsgroups: fj.lang.c
Subject: Re: How to get program's full path ?
Date: 13 Sep 92 09:26:48 GMT
	<1992Sep12.182715.16513@nntp.csl.sony.co.jp>
Distribution: fj
Organization: Sony Corporation, Tokyo, JAPAN


In article <1992Sep12.182715.16513@nntp.csl.sony.co.jp> kono@csl.sony.co.jp (Shinji Kono) writes:

>> $B<B9T%U%!%$%k$HF1$8%Q%9$K$"$k(B$B=i4|2=%U%!%$%k$rFI$a$k$h$&$K$b$d$j(B
>> $B$?$+$C$?$N$G$9$,!"$d$C$Q$j!"M_D%(B$B$j2a$.$G$7$g$&$+!)(B
>
> $B$@$C$?$i(Bpath$B$r$_$F<+J,$GC5$;$P(B? $BCY$$$G$7$g$&$1$I(B$B!#(B

$B$A$g$3$C$H:n$C$F$_$^$7$?!#4D6-JQ?t(B PATH$B$+$i<B9T2DG=$J$b$N$rA\$7=P$7(B$B$^$9!#(B
$B<B9T$G$-$k$+$I$&$+$r(B test(1)$B$r;H$C$FD4$Y$k$?$a!"$+$J$jCY$$$G$9!#(B$B<+J,$G(B
$B=q$1$P!"Aa$/$J$k$G$7$g$&!#$=$l$h$j!"(B

> shell script$B$r$O$5$s$G(B
>     #!/bin/sh
>     echo $0
> $B$H$$$&7A$G$H$C$FMh$k$H$$$&<j$b$"$j$^$9!#(B

$B$3$NJ}K!(B$B$N$[$&$,4qNo$@$M!#(B

--
$B$J$,$^$D(B


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	fullpath.c
# This archive created: Sun Sep 13 17:53:53 1992
export PATH; PATH=/bin:$PATH
if test -f 'fullpath.c'
then
	echo shar: will not over-write existing file "'fullpath.c'"
else
cat << \SHAR_EOF > 'fullpath.c'
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>

/*
 * Remove dot from a path
 *        returns non-zero if the next field is dot dot
 */ 

int
rmdot(char *s)
{
    char *p;

    if ((p = index(s, '/')) != NULL) {
	if (rmdot(++p) || *s == '.') {
	    int rval = (*(s + 1) == '.');
	    bcopy(p, s, strlen(p) + 1);
	    return (rval);
	}
    }
    return (0);
}


#define CMD "/bin/test -x "

int
executable(char *file)
{
    char *cmd;
    int found;

    if ((cmd = (char *)malloc(strlen(CMD) + strlen(file) + 1)) == NULL) {
	perror("malloc");
	exit(-1);
    }
    
    sprintf(cmd, "%s%s", CMD, file);
    
    /* This check routine is very slooow */
    found = system(cmd);

    free(cmd);

    return (!found);
}


/*
 * Returns full path name of the first executable
 */

char *
check_path(char *s, char *path)
{
    char *p, *file;

    if (path == NULL)
	return (NULL);

    if ((p = index(path, ':')) != NULL)
	*p = '\0';

    if (*path == '.' && *(path + 1) == '\0')
	path = getcwd(NULL, BUFSIZ);
    
    if ((file = (char *)malloc(strlen(s) + strlen(path) + 2)) == NULL) {
	perror("malloc");
	exit(-1);
    }

    sprintf(file, "%s/%s", path, s);

    if (executable(file))
	return (file);

    free(file);

    return ((p != NULL)? check_path(s, p + 1): NULL);
}


/*
 * Returns full path name of this executable file name
 */

char *
fullpath(char *s)
{
    /* Is thie full path name ? */
    if (*s == '/') {
	(void)rmdot(s);
	return (s);
    }

    /* Is this absolute path name ? */
    if (index(s, '/')) {
	char *cwd;
	char *ss;
	
	if ((cwd = getcwd((char *)NULL, BUFSIZ)) == NULL) {
	    perror("getcwd");
	    exit(-1);
	}
	
	if ((ss = (char *)malloc(strlen(cwd) + strlen(s) + 2)) == NULL) {
	    perror("malloc");
	    exit(-1);
	}
	
	sprintf(ss, "%s/%s", cwd, s);
	
	(void)rmdot(ss);
	return (ss);
    }

    /* We must check PATH entries */

    return (check_path(s, getenv("PATH")));
}

int
main(int argc, char *argv[])
{
    printf("%s\n", fullpath(argv[0]));
    exit(0);
}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0