Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / lib / util / tt_ldpath.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
24 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
25 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
26 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
27 //%%  $TOG: tt_ldpath.C /main/7 1999/10/14 18:42:03 mgreess $                                                   
28 /*
29  *
30  * tt_ldpath.cc
31  *
32  * Copyright (c) 1990 by Sun Microsystems, Inc.
33  */
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <errno.h>
39 #include "util/tt_string.h"
40 #include "util/tt_port.h"
41 #include <stdio.h>
42 #include <string.h>     
43
44 /* Included after "util/tt_string.h" to avoid index/strchr conflicts. */
45 #define X_INCLUDE_DIRENT_H
46 #define XOS_USE_NO_LOCKING
47 #include <X11/Xos_r.h>
48
49 static int
50 find_lib(_Tt_string &cpath, _Tt_string &libname, _Tt_string &fullpath)
51 {
52         class stat      st;
53         int             result;
54         DIR             *cdir;
55         dirent          *dentry;
56         _Tt_string      cname;
57         _Tt_string      prefix;
58         _Tt_string      vinfo;
59         int             vmajor, vminor;
60         int             max_vmajor, max_vminor;
61         _Tt_string      best_version;
62         int             dlen, llen;
63         _Xreaddirparams dir_buf;
64
65
66         memset((char*) &dir_buf, 0, sizeof(_Xreaddirparams));
67         result = 0;
68         fullpath = cpath.cat("/").cat(libname);
69         if (stat((char *)fullpath, &st) == 0) {
70                 result = 1;
71         } else if (!(cdir = opendir((char *)cpath))) {
72                 // need to find a version in cpath if possible
73                 max_vmajor = -1;
74                 max_vminor = -1;
75                 llen = libname.len();
76                 while ((dentry = _XReaddir(cdir, dir_buf)) != (dirent *)0) {
77                         dlen = strlen(dentry->d_name);
78                         if (dlen >= llen) {
79                                 cname = dentry->d_name;
80                                 prefix = cname.left(llen);
81                                 if (libname == prefix) {
82                                         vinfo = cname.mid(llen + 1,
83                                                           cname.len());
84                                         sscanf((char *)vinfo,"%d.%d",
85                                                &vmajor, &vminor);
86                                         if (vmajor >= max_vmajor &&
87                                             vminor > max_vminor) {
88                                                 max_vmajor = vmajor;
89                                                 max_vminor = vminor;
90                                                 best_version = cname;
91                                         }
92                                 }
93                         }
94                 }
95                 closedir(cdir);
96                 if (max_vmajor == -1) {
97                         result = 0;
98                 } else {
99                         fullpath = cpath.cat("/").cat(best_version);
100                         result = 1;
101                 }
102         }
103         return result;
104 }
105
106 // Returns:
107 //      1       success
108 //      0       failure; diagnostic logged
109 int
110 tt_ldpath(_Tt_string libname, _Tt_string &path)
111 {
112         // iterate through the directories specified in
113         // LD_LIBRARY_PATH with the addition of the hardcoded
114         // directories /lib, /usr/lib, and /usr/local/lib to find a
115         // version of libname. For each directory we try find libname
116         // first. If that fails then we stat the directory and find
117         // all the instances of libname plus major and minor versions.
118         _Tt_string      cpath;
119         _Tt_string      rpath;
120         _Tt_string      ldpath;
121         _Tt_string      tried;
122
123         if (getenv("LD_LIBRARY_PATH") != (char *)0) {
124                 ldpath = getenv("LD_LIBRARY_PATH");
125                 ldpath = ldpath.cat(":/lib:/usr/lib:/usr/local/lib");
126         } else {
127                 ldpath = "/lib:/usr/lib:/usr/local/lib";
128         }
129         tried = ldpath;
130         while (ldpath.len()) {
131                 rpath = ldpath.split(':', cpath);
132                 if (cpath.len() == 0) {
133                         cpath = rpath;
134                 }
135                 if (find_lib(cpath, libname, path)) {
136                         return(1);
137                 }
138                 if (ldpath == rpath) {
139                         break;
140                 }
141                 ldpath = rpath;
142         }
143         _tt_syslog( 0, LOG_ERR,
144                     "%s: %s ($LD_LIBRARY_PATH: %s)",
145                     libname.operator const char *(), strerror(ENOENT),
146                     tried.operator const char *() );
147         return(0);
148 }
149
150
151 #ifdef TEST_MAIN
152 main(int argc, char **argv)
153 {
154         _Tt_string      lib = argv[1];
155         _Tt_string      path;
156         
157         if (_tt_ldpath(lib, path)) {
158                 printf("full_ldpath: %s\n", (char *)path);
159         }
160 }
161 #endif                          // TEST_MAIN