1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
23da2e3ebdSchin /*
2434f9b3eeSRoland Mainz  * Glenn Fowler
2534f9b3eeSRoland Mainz  * AT&T Research
2634f9b3eeSRoland Mainz  *
2734f9b3eeSRoland Mainz  * return the full path of the current program in path
2834f9b3eeSRoland Mainz  * command!=0 is used as a default
29da2e3ebdSchin  */
30da2e3ebdSchin 
3134f9b3eeSRoland Mainz #include <ast.h>
32da2e3ebdSchin 
3334f9b3eeSRoland Mainz #if _WINIX
3434f9b3eeSRoland Mainz #include <ast_windows.h>
3534f9b3eeSRoland Mainz #include <ctype.h>
3634f9b3eeSRoland Mainz #endif
37da2e3ebdSchin 
3834f9b3eeSRoland Mainz #include "FEATURE/prog"
39da2e3ebdSchin 
40*b30d1939SAndy Fiddaman #if _hdr_macho_o_dyld && _lib__NSGetExecutablePath
41*b30d1939SAndy Fiddaman #include <mach-o/dyld.h>
42*b30d1939SAndy Fiddaman #else
43*b30d1939SAndy Fiddaman #undef	_lib__NSGetExecutablePath
44*b30d1939SAndy Fiddaman #endif
45*b30d1939SAndy Fiddaman 
4634f9b3eeSRoland Mainz static size_t
prog(const char * command,char * path,size_t size)4734f9b3eeSRoland Mainz prog(const char* command, char* path, size_t size)
48da2e3ebdSchin {
4934f9b3eeSRoland Mainz 	ssize_t		n;
5034f9b3eeSRoland Mainz 	char*		s;
5134f9b3eeSRoland Mainz #if _WINIX
5234f9b3eeSRoland Mainz 	char*		t;
5334f9b3eeSRoland Mainz 	char*		e;
5434f9b3eeSRoland Mainz 	int		c;
5534f9b3eeSRoland Mainz 	int		q;
5634f9b3eeSRoland Mainz #endif
57*b30d1939SAndy Fiddaman #if _lib__NSGetExecutablePath
58*b30d1939SAndy Fiddaman 	uint32_t	z;
59*b30d1939SAndy Fiddaman #endif
60da2e3ebdSchin 
6134f9b3eeSRoland Mainz #ifdef _PROC_PROG
62*b30d1939SAndy Fiddaman 	if ((n = readlink(_PROC_PROG, path, size)) > 0 && *path == '/')
63da2e3ebdSchin 	{
6434f9b3eeSRoland Mainz 		if (n < size)
6534f9b3eeSRoland Mainz 			path[n] = 0;
6634f9b3eeSRoland Mainz 		return n;
67da2e3ebdSchin 	}
6834f9b3eeSRoland Mainz #endif
6934f9b3eeSRoland Mainz #if _lib_getexecname
70*b30d1939SAndy Fiddaman 	if ((s = (char*)getexecname()) && *s == '/')
71*b30d1939SAndy Fiddaman 		goto found;
72*b30d1939SAndy Fiddaman #endif
73*b30d1939SAndy Fiddaman #if _lib__NSGetExecutablePath
74*b30d1939SAndy Fiddaman 	z = size;
75*b30d1939SAndy Fiddaman 	if (!_NSGetExecutablePath(path, &z) && *path == '/')
76*b30d1939SAndy Fiddaman 		return strlen(path);
7734f9b3eeSRoland Mainz #endif
7834f9b3eeSRoland Mainz #if _WINIX
7934f9b3eeSRoland Mainz 	if (s = GetCommandLine())
8034f9b3eeSRoland Mainz 	{
8134f9b3eeSRoland Mainz 		n = 0;
8234f9b3eeSRoland Mainz 		q = 0;
8334f9b3eeSRoland Mainz 		t = path;
8434f9b3eeSRoland Mainz 		e = path + size - 1;
8534f9b3eeSRoland Mainz 		while (c = *s++)
8634f9b3eeSRoland Mainz 		{
8734f9b3eeSRoland Mainz 			if (c == q)
8834f9b3eeSRoland Mainz 				q = 0;
8934f9b3eeSRoland Mainz 			else if (!q && c == '"')
9034f9b3eeSRoland Mainz 				q = c;
9134f9b3eeSRoland Mainz 			else if (!q && isspace(c))
9234f9b3eeSRoland Mainz 				break;
9334f9b3eeSRoland Mainz 			else if (t < e)
9434f9b3eeSRoland Mainz 				*t++ = c == '\\' ? '/' : c;
9534f9b3eeSRoland Mainz 			else
9634f9b3eeSRoland Mainz 				n++;
9734f9b3eeSRoland Mainz 		}
9834f9b3eeSRoland Mainz 		if (t < e)
9934f9b3eeSRoland Mainz 			*t = 0;
10034f9b3eeSRoland Mainz 		return (t - path) + n;
10134f9b3eeSRoland Mainz 	}
10234f9b3eeSRoland Mainz #endif
10334f9b3eeSRoland Mainz 	if (command)
10434f9b3eeSRoland Mainz 	{
105*b30d1939SAndy Fiddaman 		s = (char*)command;
106*b30d1939SAndy Fiddaman 		goto found;
10734f9b3eeSRoland Mainz 	}
10834f9b3eeSRoland Mainz 	return 0;
109*b30d1939SAndy Fiddaman  found:
110*b30d1939SAndy Fiddaman 	n = strlen(s);
111*b30d1939SAndy Fiddaman 	if (n < size)
112*b30d1939SAndy Fiddaman 		memcpy(path, s, n + 1);
113*b30d1939SAndy Fiddaman 	return n;
114da2e3ebdSchin }
115da2e3ebdSchin 
11634f9b3eeSRoland Mainz size_t
pathprog(const char * command,char * path,size_t size)11734f9b3eeSRoland Mainz pathprog(const char* command, char* path, size_t size)
118da2e3ebdSchin {
119*b30d1939SAndy Fiddaman 	char*		rel;
12034f9b3eeSRoland Mainz 	ssize_t		n;
121da2e3ebdSchin 
122*b30d1939SAndy Fiddaman 	if ((n = prog(command, path, size)) > 0 && n < size && *path != '/' && (rel = strdup(path)))
12334f9b3eeSRoland Mainz 	{
124*b30d1939SAndy Fiddaman 		n = pathpath(rel, NiL, PATH_REGULAR|PATH_EXECUTE, path, size) ? strlen(path) : 0;
125*b30d1939SAndy Fiddaman 		free(rel);
12634f9b3eeSRoland Mainz 	}
12734f9b3eeSRoland Mainz 	return n;
128da2e3ebdSchin }
129