Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

628 lines
14 KiB
C

static char sccsid[] = "@(#)97 1.2 src/bldenv/genpath/genpath.c, bldprocess, bos412, GOLDA411a 2/3/93 16:34:42";
/*
* COMPONENT_NAME: BOSBUILD
*
* FUNCTIONS: canonicalize
* concat
* defined
* expand_flag
* main
* path_relative_to
* print_revision
* print_usage
* salloc
* vconcat
*
*
* ORIGINS: 71
*
*
* (C) COPYRIGHT International Business Machines Corp. 1993
* All Rights Reserved
* Licensed Materials - Property of IBM
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*
* @OSF_FREE_COPYRIGHT@
*
* Copyright (c) 1990, 1991, 1992
* Open Software Foundation, Inc.
*
* Permission is hereby granted to use, copy, modify and freely distribute
* the software in this file and its documentation for any purpose without
* fee, provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation. Further, provided that the name of Open
* Software Foundation, Inc. ("OSF") not be used in advertising or
* publicity pertaining to distribution of the software without prior
* written permission from OSF. OSF makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/*
* ODE 2.1.1
*/
#if !defined(lint) && !defined(_NOIDENT)
static char rcsid[] = "@(#)$RCSfile: genpath.c,v $ $Revision: 1.7 $ (OSF) $Date: 1991/12/05 20:41:20 $";
#endif
/*
* program to generate command flags for sandboxes
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifndef _BLD
#include <ode/parse_rc_file.h>
#endif
extern int errno;
extern char *index();
extern char *rindex();
extern char *malloc();
extern char *salloc();
extern char *getenv();
#if __STDC__
char *concat(char *buf, int buflen, ...);
#else
char *concat();
#endif
char *vconcat();
char **expand_flag();
char *path_relative_to();
char *progname; /* program name */
print_usage()
{
fprintf(stderr, "usage: %s [ options ] [ switches ... ]\n", progname);
fprintf(stderr, "options include:\n");
fprintf(stderr, " -rc <rc_file>\n");
fprintf(stderr, " -sb <sandbox_name>\n");
fprintf(stderr, " -sb_rc <sandbox_rc_file>\n");
fprintf(stderr, " -usage | -version\n");
fprintf(stderr, " -verbose\n");
exit(1);
}
/* show the revision of this program */
print_revision()
{
printf("%s $Revision: 1.7 $ $Date: 1991/12/05 20:41:20 $\n", progname);
}
main(argc, argv)
int argc;
char *argv[];
{
char *rcfile_source_base;
char *rcfile_object_base;
char *sandbox = NULL;
char *basedir = NULL;
char *sb_rcfile = NULL;
char *usr_rcfile = NULL;
char search_path[1024*2];
char source_base[1024];
char sourcebase[1024];
char sourcedir[1024];
char curdir[1024];
int curdir_len;
char *relpath;
int i, j, k;
char ch,*b,*p,*p2,*p3,**nargv;
int nargc;
char buf[1024+2];
char ibuf[1024+2];
int verbose = 0;
char *space;
#ifndef _BLD
struct rcfile rcfile;
struct field *field_p;
struct arg_list *args_p;
#endif
int read_rcfile;
int in_objdir;
if (argc > 0) {
if ((progname = rindex(argv[0], '/')) != NULL)
progname++;
else
progname = argv[0];
argc--; argv++;
} else
progname = "genpath";
#ifndef _BLD
bzero(&rcfile, sizeof(struct rcfile));
#endif
read_rcfile = 0;
while (argc > 0) {
if (strcmp(argv[0], "-version") == 0)
{
print_revision();
exit(0);
}
if (strncmp(argv[0], "-v", strlen("-v")) == 0) {
verbose++;
argv++;
argc--;
continue;
}
if (strcmp(argv[0], "-sb") == 0) {
read_rcfile = 1;
if (argc == 1) {
fprintf(stderr, "%s: missing argument to %s switch\n",
progname, argv[0]);
print_usage();
}
argc--;
argv++;
sandbox = argv[0];
argc--;
argv++;
continue;
}
if (strcmp(argv[0], "-sb_rc") == 0) {
read_rcfile = 1;
if (argc == 1) {
fprintf(stderr, "%s: missing argument to %s switch\n",
progname, argv[0]);
print_usage();
}
argc--;
argv++;
sb_rcfile = argv[0];
argc--;
argv++;
continue;
}
if (strcmp(argv[0], "-rc") == 0) {
read_rcfile = 1;
if (argc == 1) {
fprintf(stderr, "%s: missing argument to %s switch\n",
progname, argv[0]);
print_usage();
}
argc--;
argv++;
usr_rcfile = argv[0];
argc--;
argv++;
continue;
}
if (strcmp(argv[0], "-usage") == 0)
print_usage();
break;
}
if (argc == 0)
exit(0);
for (i = 0; i < argc; i++) {
if (argv[i][0] != '-') {
fprintf(stderr, "%s: argument %s is not a switch\n",
progname, argv[i]);
exit(1);
}
if (argv[i][1] != 'I' && argv[i][1] != 'L') {
fprintf(stderr, "%s: switch %s not recognized\n",
progname, argv[i]);
exit(1);
}
}
if (read_rcfile ||
(b = getenv("SOURCEBASE")) == NULL ||
(p = getenv("SOURCEDIR")) == NULL) {
#ifdef _BLD
fprintf(stderr, "%s: SOURCEBASE or SOURCEDIR not defined\n", progname);
exit(1);
#else /* _BLD */
read_rcfile = 1;
if (current_sb (&sandbox, &basedir, &sb_rcfile, &usr_rcfile) != 0) {
fprintf(stderr, "%s: unable to get sandbox basedir\n", progname);
exit(1);
}
if (parse_rc_file(sb_rcfile, &rcfile) != 0) {
fprintf(stderr, "%s: unable to parse %s sandbox description\n",
progname, sandbox);
exit(1);
}
if (rc_file_field(&rcfile, "source_base", &field_p) != 0) {
fprintf(stderr, "%s: source_base not defined\n", progname);
exit(1);
}
args_p = field_p->args;
if (args_p->ntokens != 1) {
fprintf(stderr, "%s: improper source_base\n", progname);
exit(1);
}
rcfile_source_base = args_p->tokens[0];
if (*rcfile_source_base != '/') {
fprintf(stderr, "%s: source_base is not an absolute path\n", progname);
exit(1);
}
if (rc_file_field(&rcfile, "object_base", &field_p) != 0) {
fprintf(stderr, "%s: object_base not defined\n", progname);
exit(1);
}
args_p = field_p->args;
if (args_p->ntokens != 1) {
fprintf(stderr, "%s: improper object_base\n", progname);
exit(1);
}
rcfile_object_base = args_p->tokens[0];
if (*rcfile_object_base != '/') {
fprintf(stderr, "%s: object_base is not an absolute path\n", progname);
exit(1);
}
if ((b = getenv("SOURCEBASE")) == NULL) {
fprintf(stderr, "%s: SOURCEBASE is not defined\n", progname);
exit(1);
}
if ((p = getenv("SOURCEDIR")) == NULL) {
fprintf(stderr, "%s: SOURCEDIR is not defined\n", progname);
exit(1);
}
#endif /* _BLD */
}
(void) strcpy(source_base, b);
if (verbose)
fprintf(stderr, "[ SOURCEBASE %s ]\n", b);
(void) strcpy(sourcedir, p);
if (verbose)
fprintf(stderr, "[ SOURCEDIR %s ]\n", p);
if (getwd(curdir) == NULL) {
fprintf(stderr, "%s: getwd .: %s\n", progname, curdir);
exit(1);
}
curdir_len = strlen(curdir);
if (curdir_len == 0 || curdir[0] != '/') {
fprintf(stderr, "%s: getwd returned bad directory \"%s\"\n",
progname, curdir);
exit(1);
}
if (verbose)
fprintf(stderr, "[ curdir %s ]\n", curdir);
if (read_rcfile || (p = getenv("OBJECTDIR")) != NULL) {
if (read_rcfile)
p = rcfile_object_base;
if (verbose)
fprintf(stderr, "[ OBJECTDIR %s ]\n", p);
if (*p != '/') {
canonicalize(source_base, p, buf, sizeof(buf));
p = buf;
}
if (verbose)
fprintf(stderr, "[ object_base %s ]\n", p);
relpath = path_relative_to(p, curdir, curdir_len);
in_objdir = (relpath != NULL);
} else
in_objdir = 0;
if (!in_objdir)
relpath = path_relative_to(source_base, curdir, curdir_len);
if (relpath == NULL) {
fprintf(stderr, "%s: unable to find path within sandbox\n", progname);
return(1);
}
if (verbose)
fprintf(stderr, "[ relative path %s ]\n", relpath);
b = source_base;
p = sourcedir;
if (*p == '\0')
(void) concat(search_path, sizeof(search_path), ":", b, relpath, NULL);
else if (*relpath == '\0')
(void) concat(search_path, sizeof(search_path), ":", b, ":", p, NULL);
else {
p3 = concat(search_path, sizeof(search_path), ":", b, relpath, NULL);
for (;;) {
p2 = p;
while (*p && *p != ':')
p++;
ch = *p;
*p = '\0';
if (*p2 != '/') {
fprintf(stderr, "%s: SOURCEDIR contains a relative path\n",
progname);
exit(1);
}
p3 = concat(p3, search_path + sizeof(search_path) - p3,
":", p2, relpath, NULL);
if (ch == '\0')
break;
*p++ = ch;
}
}
if (verbose)
fprintf(stderr, "[ search_path %s ]\n", search_path);
nargc = argc;
nargv = (char **)malloc(nargc*sizeof(char *));
j = 0; /* argument counter for new arg list */
for (i = 0; i < argc; i++) {
if (argv[i][2] == '/') {
nargv[j++] = argv[i];
continue;
}
nargv = expand_flag(&j, &nargc, nargv, argv[i], search_path);
}
space = "";
for (i = 0; i < j; i++) {
printf("%s%s", space, nargv[i]);
space = " ";
}
if (j > 0)
printf("\n");
exit(0);
}
/*
* canonicalize path - similar to abspath
*/
canonicalize(base, relpath, outbuf, outbuf_size)
char *base;
char *relpath;
char *outbuf;
int outbuf_size;
{
char *from;
char *to;
char *slash;
char *peek;
/*
* concatenate parts of path into buffer
*/
if (concat(outbuf, outbuf_size, base, "/", relpath, "/", NULL) == NULL) {
fprintf(stderr, "%s: path length exceeds buffer size\n");
return(-1);
}
/*
* remember position of first slash
*/
slash = index(outbuf, '/');
from = to = slash + 1;
/*
* canonicalize the path
*/
while (*from != '\0') {
if ((*to++ = *from++) != '/')
continue;
peek = to-2;
if (*peek == '/') {
/*
* found "//", back up one
*/
to--;
continue;
}
if (*peek != '.')
continue;
peek--;
if (*peek == '/') {
/*
* found "/./", back up two
*/
to -= 2;
continue;
}
if (*peek != '.')
continue;
peek--;
if (*peek != '/')
continue;
/*
* found "/../", try to remove preceding token
*/
if (peek == slash) {
/*
* hit the "first" slash, update to not remove any more tokens
*/
slash = to-1;
continue;
}
/*
* backup one token
*/
while (*--peek != '/')
;
to = peek+1;
}
*to-- = '\0';
if (to > outbuf && *to == '/')
*to = '\0';
}
char **
expand_flag(j, nargc, nargv, rel, search_path)
int *j;
int *nargc;
char **nargv;
char *rel;
char *search_path;
{
char ibuf[1024+2];
char ch;
char *p;
char *p2;
char *p3;
ibuf[0] = *rel++;
ibuf[1] = *rel++;
p = search_path;
for (;;) {
p2 = p;
while (*p && *p != ':')
p++;
ch = *p;
*p = '\0';
p3 = NULL;
if (*p2 == '\0' || (*p2 == '.' && *(p2+1) == '\0'))
p3 = rel;
else if (*rel == '\0' || (*rel == '.' && *(rel+1) == '\0'))
p3 = p2;
if (p3 == NULL)
canonicalize(p2, rel, ibuf+2, sizeof(ibuf)-2);
else if (*p3 == '/')
canonicalize("", p3, ibuf+2, sizeof(ibuf)-2);
else {
canonicalize("", p3, ibuf+1, sizeof(ibuf)-1);
ibuf[1] = *(rel-1);
if (ibuf[2] == '\0') {
ibuf[2] = '.';
ibuf[3] = '\0';
}
}
(*nargc)++;
nargv = (char **)realloc((char *)nargv, (*nargc)*sizeof(char *));
nargv[(*j)++] = salloc(ibuf);
if (ch == '\0')
break;
*p++ = ch;
}
return(nargv);
}
/*
* If we are within the directory subtree of base_dir, return the path
* from there to the current directory. Otherwise, return NULL.
*/
char *
path_relative_to(base_dir, curdir, curdir_len)
char *base_dir, *curdir;
int curdir_len;
{
char errbuf[BUFSIZ];
int save_errno;
char basedir[1024];
char *path;
int len;
if (chdir(base_dir) < 0) {
save_errno = errno;
(void) sprintf(errbuf, "%s: chdir %s", progname, base_dir);
errno = save_errno;
perror(errbuf);
exit(1);
}
if (getwd(basedir) == NULL) {
fprintf(stderr, "%s: getwd %s: %s\n", progname, base_dir, basedir);
exit(1);
}
if (chdir(curdir) < 0) {
save_errno = errno;
(void) sprintf(errbuf, "%s: chdir %s", progname, base_dir);
errno = save_errno;
perror(errbuf);
exit(1);
}
len = strlen(basedir);
if (len == 0 || basedir[0] != '/') {
fprintf(stderr, "%s: getwd returned bad base directory \"%s\"\n",
progname, basedir);
exit(1);
}
if (curdir_len < len)
return(NULL);
if (bcmp(basedir, curdir, len) != 0)
return(NULL);
if (curdir[len] != '\0' && curdir[len] != '/')
return(NULL);
if ((path = salloc(curdir+len)) == NULL) {
save_errno = errno;
(void) sprintf(errbuf, "%s: salloc relative path", progname);
errno = save_errno;
perror(errbuf);
exit(1);
}
return(path);
}
#ifdef _BLD
char *salloc(p)
char *p;
{
register char *q;
register int l;
q = malloc(l = strlen(p) + 1);
if (q != 0)
bcopy(p, q, l);
return(q);
}
/*VARARGS2*/
char *
#if __STDC__
concat(char *buf, int buflen, ...)
#else
concat(va_alist)
va_dcl
#endif
{
#if !__STDC__
char *buf;
int buflen;
#endif
va_list ap;
char *ptr;
#if __STDC__
va_start(ap, buflen);
#else
va_start(ap);
buf = va_arg(ap, char *);
buflen = va_arg(ap, int);
#endif
ptr = vconcat(buf, buflen, ap);
va_end(ap);
return(ptr);
}
char *
vconcat(buf, buflen, ap)
char *buf;
int buflen;
va_list ap;
{
register char *arg, *ptr, *ep;
if (buf == NULL)
return(NULL);
if (buflen <= 0)
return(NULL);
ptr = buf;
*ptr = '\0';
ep = buf + buflen;
while (ptr != NULL && (arg = va_arg(ap, char *)) != NULL)
while (*ptr = *arg++)
if (++ptr == ep) {
ptr = NULL;
break;
}
return(ptr);
}
#endif /* _BLD */