da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return in path the full path name of the probe(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * information for lang and tool using proc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if attr != 0 then path attribute assignments placed here
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if path==0 then the space is malloc'd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * op:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -3 return non-writable path name with no generation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -2 return path name with no generation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -1 return no $HOME path name with no generation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 verbose probe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1 silent probe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 returned if the info does not exist and cannot be generated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ls.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <proc.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef PROBE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROBE "probe"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(ST_RDONLY) || defined(ST_NOSUID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return non-0 if path is in a readonly or non-setuid fs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrofs(const char* path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct statvfs vfs;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct stat st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!statvfs(path, &vfs))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(ST_RDONLY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (vfs.f_flag & ST_RDONLY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(ST_NOSUID)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((vfs.f_flag & ST_NOSUID) && (stat(path, &st) || st.st_uid != getuid() && st.st_uid != geteuid()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define rofs(p) 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpathprobe(char* path, char* attr, const char* lang, const char* tool, const char* aproc, int op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* proc = (char*)aproc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char** ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int force;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* nx;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* probe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* dirs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* dir;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Proc_t* pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char cmd[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char exe[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char lib[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char ver[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char key[16];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* arg[8];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ops[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long ptime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat ps;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*proc != '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = strchr(proc, ' '))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncopy(buf, proc, p - proc + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proc = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(proc = pathpath(cmd, proc, NiL, PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proc = (char*)aproc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(proc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncopy(proc + n, p, PATH_MAX - n - 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin probe = PROBE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = lib + sizeof(lib) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = lib + sfsprintf(lib, x - lib, "lib/%s/", probe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = k + sfsprintf(k, x - k, "%s/%s/", lang, tool);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathkey(key, attr, lang, tool, proc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op >= -2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncopy(p, key, x - p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pathpath(path, lib, "", PATH_ABSOLUTE) && !stat(path, &st) && (st.st_mode & S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return path == buf ? strdup(path) : path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = strncopy(p, probe, x - p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pathpath(path, lib, "", PATH_ABSOLUTE|PATH_EXECUTE) || stat(path, &ps))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ptime = ps.st_mtime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < (PATH_MAX - 5))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(path + n, ".ini");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!stat(path, &st) && st.st_size && ptime < (unsigned long)st.st_mtime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ptime = st.st_mtime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = path + n - (e - k);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nx = path + PATH_MAX - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncopy(np, probe, nx - np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!stat(path, &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * yes lib/probe/<lang>/<proc>/probe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * no lib/probe/probe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * do a manual pathaccess() to find a dir with both
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(exe, sizeof(exe), "lib/%s/%s", probe, probe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dirs = pathbin();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(dir = dirs))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dirs = pathcat(path, dir, ':', "..", exe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcanon(path, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*path == '/' && pathexists(path, PATH_REGULAR|PATH_EXECUTE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcat(path, dir, ':', "..", lib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcanon(path, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*path == '/' && pathexists(path, PATH_REGULAR|PATH_EXECUTE) && !stat(path, &ps))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncopy(p, key, x - p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = nx;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(exe, path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op >= -1 && (!(st.st_mode & S_ISUID) && ps.st_uid != geteuid() || rofs(path)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = getenv("HOME")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = path + sfsprintf(path, PATH_MAX - 1, "%s/.%s/%s/", p, probe, HOSTTYPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncopy(p, k, x - p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin force = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op >= 0 && !stat(path, &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ptime <= (unsigned long)st.st_mtime || ptime <= (unsigned long)st.st_ctime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * verify (<sep><name><sep><option><sep><value>)* header
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp = sfopen(NiL, path, "r"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x = sfgetr(sp, '\n', 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*x && *x != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*x == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n = *x++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = x; *x && *x != n; x++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *x++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p = x; *x && *x != n; x++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *x++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (e = x; *x && *x != n; x++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *x++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(k, "VERSION"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = proc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ops[0] = PROC_FD_DUP(1, 2, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ops[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp = procopen(proc, arg, NiL, ops, PROC_READ))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((v = x - e) >= sizeof(ver))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = sizeof(ver) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = p = ver;; k++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (k >= p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (v <= 0 || (r = read(pp->rfd, k, v)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v -= r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = k + r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*k == '\n' || *k == '\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*k == n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *k = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *k = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strcmp(ver, e))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin force = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(0, "probe processor %s version \"%s\" changed -- expected \"%s\"", proc, ver, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin procclose(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op >= 0 && (st.st_mode & S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(0, "%s probe information for %s language processor %s must be manually regenerated", tool, lang, proc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin force = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = exe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (force)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = "-f";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = "-s";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = (char*)lang;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = (char*)tool;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap++ = proc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (procrun(exe, arg, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (eaccess(path, R_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return path == buf ? strdup(path) : path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}