char * zt_progpath(char *prog) { if(prog && *prog != '\0') { memset(_progpath, '\0', PATH_MAX); zt_cstr_dirname(_progpath, PATH_MAX, prog); if(_progpath[0] == '\0') { /* the passed in path did not include a path */ char * path; size_t offt = 0; ssize_t base = 0; size_t len; char * tpath; struct stat sbuf; path = getenv("PATH"); if (!path) { /* no way to determine the path */ return _progpath; } len = strlen(path); while(offt < len) { ssize_t sofft; if ((sofft = zt_cstr_any(path, offt, -1, ENV_SEPERATOR)) < 0) { break; } offt = (size_t)sofft; tpath = zt_cstr_catv(path, base, offt-1, PATH_SEPERATOR, 0, -1, prog, 0, -1, NULL); errno = 0; if((stat(tpath, &sbuf) == 0)) { zt_cstr_copy(tpath, 0, -1, _progpath, PATH_MAX); XFREE(tpath); return _progpath; } XFREE(tpath); base = offt+1; offt++; } } else { /* the passed in path did include a path * determine if it is relative */ char cwd[PATH_MAX+1]; if(getcwd(cwd, PATH_MAX) != NULL) { zt_cstr_copy(cwd, 0, -1, _progpath, PATH_MAX); } } } return _progpath; }
char * zt_progpath(char *prog) { /* If prog is !NULL then try to calculate the correct path. * Otherwise just return the current path setting. */ if(prog && *prog != '\0') { /* if the passed in path is not NULL */ memset(_progpath, '\0', PATH_MAX); zt_cstr_dirname(_progpath, PATH_MAX, prog); if(_progpath[0] == '\0' || strcmp(_progpath, ".") == 0) { /* the passed in prog did not include a path */ char * path; size_t offt = 0; ssize_t base = 0; size_t len; char * tpath; struct stat sbuf; path = getenv("PATH"); if (!path) { /* try to use system specific methods to get the path */ char * pp; if ((pp = zt_os_progpath()) == NULL) { return _progpath; } zt_cstr_dirname(_progpath, PATH_MAX, pp); zt_free(pp); return _progpath; } len = strlen(path); while(offt < len) { ssize_t sofft; if ((sofft = zt_cstr_any(path, offt, -1, ENV_SEPERATOR)) < 0) { break; } offt = (size_t)sofft; tpath = zt_cstr_catv(path, base, offt-1, PATH_SEPERATOR, 0, -1, prog, 0, -1, NULL); errno = 0; if((stat(tpath, &sbuf) == 0)) { zt_cstr_dirname(_progpath, PATH_MAX, tpath); zt_free(tpath); return _progpath; } zt_free(tpath); base = offt+1; offt++; } /* if still no path */ if (strcmp(_progpath, ".") == 0) { /* just return the cwd */ char cwd[PATH_MAX+1]; if (getcwd(cwd, PATH_MAX) != NULL) { zt_cstr_copy(cwd, 0, -1, _progpath, PATH_MAX); } } } else { /* the passed in path did include a path * determine if it is relative */ char cwd[PATH_MAX+1]; if(getcwd(cwd, PATH_MAX) != NULL) { if (_progpath[0] != '/') { /* path is relative append and remove prog */ char * tpath; char * pp = _progpath; if(_progpath[0] == '.' && _progpath[1] == '/') { /* if it starts with ./ then remove it */ pp += 2; } tpath = zt_cstr_path_append(cwd, pp); zt_cstr_copy(tpath, 0, -1, _progpath, PATH_MAX); zt_free(tpath); } } } } return _progpath; }