1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
27 * return in path the full path name of the probe(1)
28 * information for lang and tool using proc
29 * if attr != 0 then path attribute assignments placed here
31 * if path==0 then the space is malloc'd
35 * -3 return non-writable path name with no generation
36 * -2 return path name with no generation
37 * -1 return no $HOME path name with no generation
41 * 0 returned if the info does not exist and cannot be generated
53 #if defined(ST_RDONLY) || defined(ST_NOSUID)
56 * return non-0 if path is in a readonly or non-setuid fs
60 rofs(const char* path
)
65 if (!statvfs(path
, &vfs
))
67 #if defined(ST_RDONLY)
68 if (vfs
.f_flag
& ST_RDONLY
)
71 #if defined(ST_NOSUID)
72 if ((vfs
.f_flag
& ST_NOSUID
) && (stat(path
, &st
) || st
.st_uid
!= getuid() && st
.st_uid
!= geteuid()))
86 pathprobe(char* path
, char* attr
, const char* lang
, const char* tool
, const char* aproc
, int op
)
88 char* proc
= (char*)aproc
;
119 if (p
= strchr(proc
, ' '))
121 strncopy(buf
, proc
, p
- proc
+ 1);
124 if (!(proc
= pathpath(cmd
, proc
, NiL
, PATH_ABSOLUTE
|PATH_REGULAR
|PATH_EXECUTE
)))
129 strncopy(proc
+ n
, p
, PATH_MAX
- n
- 1);
135 x
= lib
+ sizeof(lib
) - 1;
136 k
= lib
+ sfsprintf(lib
, x
- lib
, "lib/%s/", probe
);
137 p
= k
+ sfsprintf(k
, x
- k
, "%s/%s/", lang
, tool
);
138 pathkey(key
, attr
, lang
, tool
, proc
);
141 strncopy(p
, key
, x
- p
);
142 if (pathpath(path
, lib
, "", PATH_ABSOLUTE
) && !stat(path
, &st
) && (st
.st_mode
& S_IWUSR
))
143 return path
== buf
? strdup(path
) : path
;
145 e
= strncopy(p
, probe
, x
- p
);
146 if (!pathpath(path
, lib
, "", PATH_ABSOLUTE
|PATH_EXECUTE
) || stat(path
, &ps
))
152 if (n
< (PATH_MAX
- 5))
154 strcpy(path
+ n
, ".ini");
155 if (!stat(path
, &st
) && st
.st_size
&& ptime
< (unsigned long)st
.st_mtime
)
159 np
= path
+ n
- (e
- k
);
160 nx
= path
+ PATH_MAX
- 1;
161 strncopy(np
, probe
, nx
- np
);
162 if (!stat(path
, &st
))
166 * yes lib/probe/<lang>/<proc>/probe
169 * do a manual pathaccess() to find a dir with both
172 sfsprintf(exe
, sizeof(exe
), "lib/%s/%s", probe
, probe
);
178 dirs
= pathcat(path
, dir
, ':', "..", exe
);
180 if (*path
== '/' && pathexists(path
, PATH_REGULAR
|PATH_EXECUTE
))
182 pathcat(path
, dir
, ':', "..", lib
);
184 if (*path
== '/' && pathexists(path
, PATH_REGULAR
|PATH_EXECUTE
) && !stat(path
, &ps
))
189 strncopy(p
, key
, x
- p
);
193 if (op
>= -1 && (!(st
.st_mode
& S_ISUID
) && ps
.st_uid
!= geteuid() || rofs(path
)))
195 if (!(p
= getenv("HOME")))
197 p
= path
+ sfsprintf(path
, PATH_MAX
- 1, "%s/.%s/%s/", p
, probe
, HOSTTYPE
);
199 strncopy(p
, k
, x
- p
);
201 if (op
>= 0 && !stat(path
, &st
))
203 if (ptime
<= (unsigned long)st
.st_mtime
|| ptime
<= (unsigned long)st
.st_ctime
)
206 * verify (<sep><name><sep><option><sep><value>)* header
209 if (sp
= sfopen(NiL
, path
, "r"))
211 if (x
= sfgetr(sp
, '\n', 1))
213 while (*x
&& *x
!= ' ')
220 for (k
= x
; *x
&& *x
!= n
; x
++);
224 for (p
= x
; *x
&& *x
!= n
; x
++);
228 for (e
= x
; *x
&& *x
!= n
; x
++);
232 if (streq(k
, "VERSION"))
238 ops
[0] = PROC_FD_DUP(1, 2, 0);
240 if (pp
= procopen(proc
, arg
, NiL
, ops
, PROC_READ
))
242 if ((v
= x
- e
) >= sizeof(ver
))
244 for (k
= p
= ver
;; k
++)
248 if (v
<= 0 || (r
= read(pp
->rfd
, k
, v
)) <= 0)
253 if (*k
== '\n' || *k
== '\r')
262 error(0, "probe processor %s version \"%s\" changed -- expected \"%s\"", proc
, ver
, e
);
275 if (op
>= 0 && (st
.st_mode
& S_IWUSR
))
278 error(0, "%s probe information for %s language processor %s must be manually regenerated", tool
, lang
, proc
);
295 if (procrun(exe
, arg
, 0))
297 if (eaccess(path
, R_OK
))
300 return path
== buf
? strdup(path
) : path
;