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

1254 lines
25 KiB
C

#ifdef _POWER_PROLOG_
static char sccsid[] = "@(#)03 1.2 src/bldenv/md/md.c, ade_build, bos412, GOLDA411a 3/28/94 15:23:41";
/*
* ORIGINS: 27 71
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
*
* (C) COPYRIGHT International Business Machines Corp. 1992
* All Rights Reserved
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
#endif /* _POWER_PROLOG_ */
/*
*
* (c) Copyright 1991, OPEN SOFTWARE FOUNDATION, INC.
* ALL RIGHTS RESERVED
*
*/
/*
* OSF/1 1.1 Snapshot 2
*/
#if !defined(lint) && !defined(_NOIDENT)
static char rcsid[] = "@(#)$RCSfile: md.c,v $ $Revision: 1.9 $ (OSF) $Date: 91/01/07 16:52:09 $";
#endif
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/errno.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int errno;
#ifdef _BLD
#ifdef NO_DIRENT
#define dirent direct
#endif
char _argbreak;
#else
extern char _argbreak;
#endif
extern char *index();
extern char *rindex();
#if __STDC__
char *concat(char *buf, int buflen, ...);
int diag(char *fmt, ...);
int ewarn(char *fmt, ...);
int efatal(char *fmt, ...);
int warn(char *fmt, ...);
int fatal(char *fmt, ...);
#else
extern char *concat();
#endif
extern char *salloc();
extern char *nxtarg();
extern char *errmsg();
#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
#endif
#define FALSE 0
#define TRUE 1
struct table {
int max; /* max argc before realloc of argv */
int argc; /* current argument count */
char **argv; /* arguments */
};
struct target {
char *name;
struct table curdeps;
struct table stddeps;
};
char *prog;
struct table curincdirs;
struct table stdincdirs;
struct table keepincdirs;
struct table dependfiles;
struct table targets;
int depfile_bufsize;
char *depfile_buffer;
char *outfile = "depend.mk";
int all = FALSE;
int debug = FALSE;
int rmflag = FALSE;
int stdflag = FALSE;
int verbose = FALSE;
main(argc, argv)
int argc;
char **argv;
{
/*
* parse command line
*/
parse_command_line(argc, argv);
/*
* process dependency files
*/
read_dependencies();
/*
* update output file
*/
update_database();
/*
* remove dependency files
*/
remove_dependencies();
exit(0);
}
resize_table(tp)
struct table *tp;
{
if (tp->max == 0) {
tp->max = 4;
tp->argv = (char **) malloc((unsigned) tp->max * sizeof(char *));
} else {
tp->max <<= 1;
tp->argv = (char **) realloc((char *) tp->argv,
(unsigned) tp->max * sizeof(char *));
}
if (tp->argv == NULL)
fatal("table argv malloc failed");
}
/*
* 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';
}
usage()
{
fprintf(stderr, "usage: %s [ options ] <dependency-files>\n", prog);
fprintf(stderr, "options include:\n");
fprintf(stderr, " -I<include-directory>\n");
fprintf(stderr, " -K<include-directory>\n");
fprintf(stderr, " -all\n");
fprintf(stderr, " -file <output-file>\n");
fprintf(stderr, " -debug\n");
fprintf(stderr, " -rm\n");
fprintf(stderr, " -std\n");
fprintf(stderr, " -verbose\n");
exit(1);
}
parse_command_line(argc, argv)
int argc;
char **argv;
{
struct table *tp;
struct stat st;
DIR *dirp;
struct dirent *dp;
char buf[MAXPATHLEN];
char *p;
int l;
if (argc > 0) {
if ((prog = rindex(argv[0], '/')) != NULL)
prog++;
else
prog = argv[0];
argc--; argv++;
} else
prog = "md";
bzero((char *)&curincdirs, sizeof(curincdirs));
bzero((char *)&stdincdirs, sizeof(stdincdirs));
tp = &curincdirs;
while (argc > 0) {
if (argv[0][0] != '-')
break;
switch (argv[0][1]) {
case 'I':
if (strcmp(argv[0], "-I-") == 0) {
tp = &stdincdirs;
break;
}
if (tp->argc == tp->max)
resize_table(tp);
p = (argv[0]) + 2;
canonicalize("", p, buf, sizeof(buf));
if (*p == '/')
p = buf;
else
p = buf + 1;
p = salloc(p);
if (p == NULL)
efatal("-I salloc failed");
tp->argv[tp->argc++] = p;
break;
case 'K':
if (keepincdirs.argc == keepincdirs.max)
resize_table(&keepincdirs);
p = (argv[0]) + 2;
canonicalize("", p, buf, sizeof(buf));
if (*p == '/')
p = buf;
else
p = buf + 1;
p = salloc(p);
if (p == NULL)
efatal("-K salloc failed");
keepincdirs.argv[keepincdirs.argc++] = p;
break;
case 'a':
if (strcmp(argv[0], "-all") == 0)
all = TRUE;
else {
warn("unknown switch: %s", argv[0]);
usage();
}
break;
case 'd':
if (strcmp(argv[0], "-debug") == 0)
debug = TRUE;
else {
warn("unknown switch: %s", argv[0]);
usage();
}
break;
case 'f':
if (strcmp(argv[0], "-file") == 0) {
if (argc == 1)
fatal("missing argument to %s", argv[0]);
argc--; argv++;
outfile = argv[0];
} else {
warn("unknown switch: %s", argv[0]);
usage();
}
break;
case 'r':
if (strcmp(argv[0], "-rm") == 0)
rmflag = TRUE;
else {
warn("unknown switch: %s", argv[0]);
usage();
}
break;
case 's':
if (strcmp(argv[0], "-std") == 0)
stdflag = TRUE;
else {
warn("unknown switch: %s", argv[0]);
usage();
}
break;
case 'v':
if (strcmp(argv[0], "-verbose") == 0)
verbose = TRUE;
else {
warn("unknown switch: %s", argv[0]);
usage();
}
break;
default:
warn("unknown switch: %s", argv[0]);
usage();
}
argc--; argv++;
}
if (argc == 0)
usage();
if (!all && tp == &curincdirs && tp->argc > 0) {
bcopy((char *)&curincdirs, &stdincdirs, sizeof(curincdirs));
bzero((char *)&curincdirs, sizeof(curincdirs));
}
bzero((char *)&dependfiles, sizeof(dependfiles));
tp = &dependfiles;
while (argc > 0) {
if (stat(argv[0], &st) < 0)
efatal("stat %s", argv[0]);
if (S_ISREG(st.st_mode)) {
if (tp->argc == tp->max)
resize_table(tp);
tp->argv[tp->argc++] = argv[0];
argc--; argv++;
continue;
}
if (!S_ISDIR(st.st_mode))
fatal("%s: Not a directory or regular file", argv[0]);
if ((dirp = opendir(argv[0])) == NULL)
efatal("opendir %s", argv[0]);
while ((dp = readdir(dirp)) != NULL) {
p = dp->d_name;
l = strlen(p);
if (l < 2 || p[l-2] != '.' || (p[l-1] != 'u' && p[l-1] != 'u'))
continue;
if (concat(buf, sizeof(buf), argv[0], "/", p, NULL) == NULL)
fatal("no room in buffer for %s/%s", argv[0], p);
p = salloc(buf);
if (p == NULL)
efatal("salloc dirent name");
if (tp->argc == tp->max)
resize_table(tp);
tp->argv[tp->argc++] = p;
}
(void) closedir(dirp);
argc--; argv++;
}
/*
* print tables
*/
if (verbose) {
print_table(&curincdirs);
print_table(&stdincdirs);
print_table(&dependfiles);
}
}
print_table(tp)
struct table *tp;
{
int i;
printf("table %x max %d argc %d\n", tp, tp->max, tp->argc);
for (i = 0; i < tp->argc; i++)
printf(" argv[%d] = %s\n", i, tp->argv[i]);
}
char *normalize_name(depbuf)
char *depbuf;
{
static char *backedsourcedir = NULL;
static struct table source_dirs;
static struct table above_source;
char *ptr, *p, *lastslash;
char buf[MAXPATHLEN];
char buf2[MAXPATHLEN];
int i, len;
if (!backedsourcedir) {
bzero((char *)&source_dirs, sizeof(source_dirs));
bzero((char *)&above_source, sizeof(above_source));
if ((backedsourcedir = getenv("BACKED_SOURCEDIR")) == NULL)
/* We must not be in a sandbox */
if ((backedsourcedir = getenv("SOURCEBASE")) == NULL) {
fprintf(stderr, "SOURCEBASE not defined.\n");
exit(1);
}
for (ptr=strtok(backedsourcedir, ":"); ptr != NULL;
ptr=strtok(NULL, ":")) {
p = salloc(ptr);
if (p == NULL)
efatal("salloc sourcedir name");
if (source_dirs.argc == source_dirs.max)
resize_table(&source_dirs);
source_dirs.argv[source_dirs.argc++] = p;
lastslash = NULL;
for (p=ptr; *p != '\0'; p++)
if (*p == '/') lastslash=p;
if (lastslash) {
*lastslash='\0';
p = salloc(ptr);
if (p == NULL)
efatal("salloc sourcedir name");
if (above_source.argc == above_source.max)
resize_table(&above_source);
above_source.argv[above_source.argc++] = p;
}
}
}
canonicalize("", depbuf, buf, sizeof(buf));
if (*depbuf != '/') {
p = salloc(buf+1);
if (p == NULL)
efatal("salloc normalize_name relative");
return(p);
}
for (i=0; i< source_dirs.argc; i++) {
len=strlen(source_dirs.argv[i]);
if (strncmp(buf, source_dirs.argv[i], len) == 0) {
strcpy(buf2, "${MAKETOP}");
strcat(buf2, buf+len+1);
p = salloc(buf2);
if (p == NULL)
efatal("salloc buf2 source_dirs");
return(p);
}
}
for (i=0; i< above_source.argc; i++) {
len=strlen(above_source.argv[i]);
if (strncmp(buf, above_source.argv[i], len) == 0) {
strcpy(buf2, "${MAKETOP}..");
strcat(buf2, buf+len);
p = salloc(buf2);
if (p == NULL)
efatal("salloc buf2 above_source");
return(p);
}
}
p = salloc(buf);
if (p == NULL)
efatal("salloc buf no_match");
return(p);
}
shorten_name(depbuf)
char *depbuf;
{
char buf[MAXPATHLEN];
char *ptr;
int l1, l2, lmax;
int maxcur, maxstd;
int i;
char *dep;
canonicalize("", depbuf, buf, sizeof(buf));
if (*depbuf == '/')
dep = buf;
else
dep = buf + 1;
l1 = strlen(dep);
lmax = -1;
maxcur = 0;
for (i = 0; i < curincdirs.argc; i++) {
ptr = curincdirs.argv[i];
l2 = strlen(ptr);
if (l1 < l2 || l2 <= lmax)
continue;
if (l2 == 0) {
if (*dep == '/')
continue;
} else {
if (l1 > l2 && dep[l2] != '/')
continue;
if (bcmp(ptr, dep, l2) != 0)
continue;
}
lmax = l2;
maxcur = 1;
}
maxstd = 0;
for (i = 0; i < stdincdirs.argc; i++) {
ptr = stdincdirs.argv[i];
l2 = strlen(ptr);
if (l1 < l2 || l2 <= lmax)
continue;
if (l2 == 0) {
if (*dep == '/')
continue;
} else {
if (l1 > l2 && dep[l2] != '/')
continue;
if (bcmp(ptr, dep, l2) != 0)
continue;
}
lmax = l2;
maxstd = 1;
}
if (lmax == -1)
return(-1);
for (i = 0; i < keepincdirs.argc; i++) {
ptr = keepincdirs.argv[i];
l2 = strlen(ptr);
if (l2 == lmax && bcmp(ptr, dep, l2) == 0) {
(void) strcpy(depbuf, dep);
return(maxstd ? 1 : 0);
}
}
ptr = dep + lmax;
while (*ptr == '/')
ptr++;
(void) strcpy(depbuf, ptr);
return(maxstd ? 1 : 0);
}
#define skip_target \
if (last_char == 'u') { \
while (*ptr != '\0' && *ptr != ':') \
ptr++; \
if (*ptr == ':' ) \
ptr++; \
}
read_target_dependencies(file)
char *file;
{
char buf[MAXPATHLEN];
int fd;
char *ptr, *dep, c_source_file[MAXPATHLEN];
struct stat st;
struct target *targ;
struct table *tp;
int cnt;
int status;
char last_char;
last_char = file[strlen(file)-1];
targ = (struct target *) calloc(1, sizeof(struct target));
if (targ == NULL)
efatal("target calloc failed");
if ((fd = open(file, O_RDONLY, 0)) < 0)
efatal("open %s", file);
if (fstat(fd, &st) < 0)
efatal("fstat %s", file);
if (st.st_size >= depfile_bufsize) {
depfile_bufsize += 1024;
if (st.st_size >= depfile_bufsize)
depfile_bufsize = st.st_size + 1;
depfile_buffer = realloc(depfile_buffer, depfile_bufsize);
if (depfile_buffer == NULL)
efatal("depfile_buffer realloc failed");
}
ptr = depfile_buffer;
while (st.st_size > 0) {
if ((cnt = read(fd, ptr, st.st_size)) < 0)
efatal("read %s", file);
if (cnt == 0)
fatal("premature EOF on %s",file);
st.st_size -= cnt;
ptr += cnt;
}
*ptr = '\0';
if (close(fd) < 0)
efatal("close %s", file);
ptr = depfile_buffer;
targ->name = basename(nxtarg(&ptr, " \t:"));
if (*targ->name == '\0') {
diag("%s: no dependencies", file);
canonicalize("", file, buf, sizeof(buf));
dep = rindex(buf, '/');
targ->name = salloc(dep + 1);
if (targ->name == NULL)
efatal("target name salloc failed");
dep = targ->name + strlen(targ->name);
while (dep > targ->name && *(dep-1) != '.')
dep--;
if (*dep == '\0') {
diag("%s: unable to generate filename");
return;
}
*dep = 'o';
} else {
targ->name = salloc(targ->name);
if (targ->name == NULL)
efatal("target name salloc failed");
if (_argbreak != ':') {
while (*ptr == ' ' || *ptr == '\t')
ptr++;
if (*ptr != ':') {
diag("%s: missing colon in dependency file", file);
return;
}
ptr++;
}
}
strcpy(c_source_file,targ->name);
c_source_file[strlen(c_source_file)-1] = 'c';
while (*ptr != '\0') {
dep = nxtarg(&ptr, " \t\\\n");
if (*dep == '\0')
continue;
/* No matter what the path is to the source (target).c, it will show
up as a simple file name. Since this file may be in a different
directory, we don't want it to be a dependency. */
if ( (strcmp(c_source_file, dep) == 0) || (strcmp(c_source_file,basename(dep)) == 0) ) {
skip_target
continue;
}
if (!all) {
status = shorten_name(dep);
if (status < 0) {
warn("%s: unable to shorten '%s' - skipped", file, dep);
skip_target
continue;
}
dep = salloc(dep);
if (dep == NULL)
efatal("dependent salloc failed");
}
else {
dep = normalize_name(dep);
status = 0;
}
tp = (status == 0 ? &targ->curdeps : &targ->stddeps);
if (tp->argc == tp->max)
resize_table(tp);
tp->argv[tp->argc++] = dep;
/* for .u files, skip up to the colon on each new line */
skip_target
}
if (targets.argc == targets.max)
resize_table(&targets);
targets.argv[targets.argc++] = (char *)targ;
}
read_dependencies()
{
char *file;
int i;
depfile_bufsize = (8*1024)+1;
depfile_buffer = malloc(depfile_bufsize);
if (depfile_buffer == NULL)
efatal("depfile_buffer realloc failed");
for (i = 0; i < dependfiles.argc; i++) {
file = dependfiles.argv[i];
read_target_dependencies(file);
}
}
cmp_targets(t1, t2)
struct target **t1, **t2;
{
return(strcmp((*t1)->name, (*t2)->name));
}
compare_targets(t1, t2)
char *t1, *t2;
{
char *p;
int cmp;
p = t1 + strlen(t1) - 1;
if (*p-- != '\n')
return(-1);
if (*p != ':')
return(-1);
*p = '\0';
cmp = strcmp(t1, t2);
*p = ':';
return(cmp);
}
update_database()
{
char buf[MAXPATHLEN];
char oldbuf[MAXPATHLEN];
char buffer[BUFSIZ];
FILE *inf, *outf;
int i, j;
char *p1, *p2;
struct target *targ;
int need_header;
int eof;
int cmp;
if (targets.argc == 0)
return;
qsort(targets.argv, targets.argc, sizeof(char *), cmp_targets);
if (debug) {
for (i = 0; i < targets.argc; i++) {
targ = (struct target *) targets.argv[i];
printf("curdeps[%d]\n", i);
print_table(&targ->curdeps);
printf("curdeps[%d]\n", i);
print_table(&targ->stddeps);
}
}
(void) concat(buf, sizeof(buf), outfile, ".tmp", NULL);
(void) unlink(buf);
if ((outf = fopen(buf, "w")) == NULL) {
ewarn("unable to open %s for write", buf);
(void) unlink(buf);
exit(1);
}
if ((inf = fopen(outfile, "r")) == NULL) {
if (errno != ENOENT) {
ewarn("unable to open %s for read", outfile);
(void) fclose(outf);
(void) unlink(buf);
exit(1);
}
for (i = 0; i < targets.argc; i++)
output_target(outf, (struct target *) targets.argv[i], TRUE);
if (ferror(outf) || fclose(outf) == EOF) {
ewarn("error writing %s", buf);
(void) fclose(outf);
(void) unlink(buf);
exit(1);
}
if (rename(buf, outfile) < 0)
efatal("rename %s to %s", buf, outfile);
return;
}
i = 0;
targ = (struct target *) targets.argv[i];
while ((fgets(buffer, sizeof(buffer), inf)) != NULL) {
if (bcmp("# dependents of ", buffer, 16) != 0) {
(void) fputs(buffer, outf);
continue;
}
cmp = compare_targets(buffer + 16, targ->name);
if (cmp < 0) {
(void) fputs(buffer, outf);
continue;
}
if (cmp == 0) {
(void) fputs(buffer, outf);
eof = TRUE;
while ((fgets(buffer, sizeof(buffer), inf)) != NULL)
if (bcmp("# dependents of ", buffer, 16) == 0) {
eof = FALSE;
break;
}
} else {
eof = FALSE;
(void) fputs("# dependents of ", outf);
(void) fputs(targ->name, outf);
(void) fputs(":\n", outf);
}
need_header = FALSE;
for (;;) {
output_target(outf, targ, need_header);
if (++i == targets.argc) {
if (!eof) {
(void) fputs("#\n", outf);
(void) fputs(buffer, outf);
ffilecopy(inf, outf);
}
break;
}
need_header = TRUE;
targ = (struct target *) targets.argv[i];
if (eof)
continue;
cmp = compare_targets(buffer + 16, targ->name);
if (cmp > 0)
continue;
if (cmp < 0) {
(void) fputs("#\n", outf);
(void) fputs(buffer, outf);
break;
}
(void) fputs("#\n", outf);
(void) fputs(buffer, outf);
eof = TRUE;
while ((fgets(buffer, sizeof(buffer), inf)) != NULL)
if (bcmp("# dependents of ", buffer, 16) == 0) {
eof = FALSE;
break;
}
need_header = FALSE;
}
if (i == targets.argc)
break;
}
while (i < targets.argc)
output_target(outf, (struct target *) targets.argv[i++], TRUE);
if (ferror(inf) || fclose(inf) == EOF) {
ewarn("error reading %s", outfile);
(void) fclose(inf);
(void) fclose(outf);
(void) unlink(buf);
exit(1);
}
if (ferror(outf) || fclose(outf) == EOF) {
ewarn("error writing %s", buf);
(void) fclose(outf);
(void) unlink(buf);
exit(1);
}
(void) concat(oldbuf, sizeof(oldbuf), outfile, ".old", NULL);
(void) unlink(oldbuf);
if (link(outfile, oldbuf) < 0) {
ewarn("link %s to %s", outfile, oldbuf);
(void) unlink(buf);
exit(1);
}
if (rename(buf, outfile) < 0) {
ewarn("rename %s to %s", buf, outfile);
exit(1);
}
}
output_target(outf, targ, need_header)
FILE *outf;
struct target *targ;
int need_header;
{
int i;
if (need_header) {
(void) fputs("#\n", outf);
(void) fputs("# dependents of ", outf);
(void) fputs(targ->name, outf);
(void) fputs(":\n", outf);
}
for (i = 0; i < targ->curdeps.argc; i++) {
(void) fputs(targ->name, outf);
(void) fputs(": ", outf);
(void) fputs(targ->curdeps.argv[i], outf);
(void) putc('\n', outf);
}
if (!stdflag)
return;
for (i = 0; i < targ->stddeps.argc; i++) {
(void) fputs("# ", outf);
(void) fputs(targ->name, outf);
(void) fputs(": <", outf);
(void) fputs(targ->stddeps.argv[i], outf);
(void) fputs(">\n", outf);
}
}
remove_dependencies()
{
char *file;
int i;
for (i = 0; i < dependfiles.argc; i++) {
file = dependfiles.argv[i];
if (rmflag && unlink(file) < 0)
ewarn("unlink %s", file);
}
}
/*
* error routines
*/
/*VARARGS1*/
#if __STDC__
diag(char *fmt, ...)
#else
diag(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list vargs;
(void) fflush(stdout);
#if __STDC__
va_start(vargs, fmt);
#else
va_start(vargs);
#endif
#ifdef _BLD
(void) _doprnt(fmt, vargs, stderr);
#else
(void) vfprintf(stderr, fmt, vargs);
#endif
va_end(vargs);
(void) putc('\n', stderr);
}
/*VARARGS1*/
#if __STDC__
ewarn(char *fmt, ...)
#else
ewarn(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list vargs;
int serrno = errno;
(void) fflush(stdout);
(void) fputs(prog, stderr);
(void) putc(':', stderr);
(void) putc(' ', stderr);
#if __STDC__
va_start(vargs, fmt);
#else
va_start(vargs);
#endif
#ifdef _BLD
(void) _doprnt(fmt, vargs, stderr);
#else
(void) vfprintf(stderr, fmt, vargs);
#endif
va_end(vargs);
(void) putc(':', stderr);
(void) putc(' ', stderr);
(void) fputs(errmsg(serrno), stderr);
(void) putc('\n', stderr);
}
/*VARARGS1*/
#if __STDC__
efatal(char *fmt, ...)
#else
efatal(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list vargs;
int serrno = errno;
(void) fflush(stdout);
(void) fputs(prog, stderr);
(void) putc(':', stderr);
(void) putc(' ', stderr);
#if __STDC__
va_start(vargs, fmt);
#else
va_start(vargs);
#endif
#ifdef _BLD
(void) _doprnt(fmt, vargs, stderr);
#else
(void) vfprintf(stderr, fmt, vargs);
#endif
va_end(vargs);
(void) putc(':', stderr);
(void) putc(' ', stderr);
(void) fputs(errmsg(serrno), stderr);
(void) putc('\n', stderr);
exit(1);
}
/*VARARGS1*/
#if __STDC__
warn(char *fmt, ...)
#else
warn(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list vargs;
(void) fflush(stdout);
(void) fputs(prog, stderr);
(void) putc(':', stderr);
(void) putc(' ', stderr);
#if __STDC__
va_start(vargs, fmt);
#else
va_start(vargs);
#endif
#ifdef _BLD
(void) _doprnt(fmt, vargs, stderr);
#else
(void) vfprintf(stderr, fmt, vargs);
#endif
va_end(vargs);
(void) putc('\n', stderr);
}
/*VARARGS1*/
#if __STDC__
fatal(char *fmt, ...)
#else
fatal(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list vargs;
(void) fflush(stdout);
(void) fputs(prog, stderr);
(void) putc(':', stderr);
(void) putc(' ', stderr);
#if __STDC__
va_start(vargs, fmt);
#else
va_start(vargs);
#endif
#ifdef _BLD
(void) _doprnt(fmt, vargs, stderr);
#else
(void) vfprintf(stderr, fmt, vargs);
#endif
va_end(vargs);
(void) putc('\n', stderr);
exit(1);
}
#ifdef _BLD
static unsigned char tab[256] = {
0
};
char *skipto (string,charset)
unsigned char *string, *charset;
{
register unsigned char *setp,*strp;
tab[0] = 1; /* Stop on a null, too. */
for (setp=charset; *setp; setp++) tab[*setp]=1;
for (strp=string; tab[*strp]==0; strp++) ;
for (setp=charset; *setp; setp++) tab[*setp]=0;
return ((char *)strp);
}
char *nxtarg (q,brk)
char **q,*brk;
{
register char *front,*back;
front = *q; /* start of string */
/* leading blanks and tabs */
while (*front && (*front == ' ' || *front == '\t')) front++;
/* find break character at end */
if (brk == 0) brk = " ";
back = skipto (front,brk);
_argbreak = *back;
*q = (*back ? back+1 : back); /* next arg start loc */
/* elim trailing blanks and tabs */
back -= 1;
while ((back >= front) && (*back == ' ' || *back == '\t')) back--;
back++;
if (*back) *back = '\0';
return (front);
}
#define BUFFERSIZE 10240
int filecopy (here,there)
int here,there;
{
register int kount;
char buffer[BUFFERSIZE];
kount = 0;
while (kount == 0 && (kount=read(here,buffer,BUFFERSIZE)) > 0)
kount -= write (there,buffer,kount);
return (kount ? -1 : 0);
}
int ffilecopy (here,there)
FILE *here, *there;
{
register int i, herefile, therefile;
herefile = fileno(here);
therefile = fileno(there);
if (fflush (there) == EOF) /* flush pending output */
return (EOF);
if ((here->_cnt) > 0) { /* flush buffered input */
i = write (therefile, here->_ptr, here->_cnt);
if (i != here->_cnt) return (EOF);
here->_ptr = here->_base;
here->_cnt = 0;
}
i = filecopy (herefile, therefile); /* fast file copy */
if (i < 0) return (EOF);
(here->_flag) |= _IOEOF; /* indicate EOF */
return (0);
}
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);
}
extern int sys_nerr;
extern char *sys_errlist[];
static char *itoa(p,n)
char *p;
unsigned n;
{
if (n >= 10)
p =itoa(p,n/10);
*p++ = (n%10)+'0';
return(p);
}
char *errmsg(cod)
int cod;
{
static char unkmsg[] = "Unknown error ";
static char unk[sizeof(unkmsg)+11]; /* trust us */
if (cod < 0) cod = errno;
if((cod >= 0) && (cod < sys_nerr))
return(sys_errlist[cod]);
strcpy(unk,unkmsg);
*itoa(&unk[sizeof(unkmsg)-1],cod) = '\0';
return(unk);
}
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);
}
/*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);
}
#endif /* _BLD */