home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-19 | 72.2 KB | 2,896 lines |
- Newsgroups: comp.sources.unix
- From: hammer@cs.purdue.edu (Adam Hammer)
- Subject: v25i083: rcs-5.6 - Revision Control System, V5.6, Part07/11
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: hammer@cs.purdue.edu (Adam Hammer)
- Posting-Number: Volume 25, Issue 83
- Archive-Name: rcs-5.6/part07
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 7 (of 11)."
- # Contents: src/ci.c src/conf.sh
- # Wrapped by vixie@cognition.pa.dec.com on Fri Dec 20 16:23:41 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/ci.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/ci.c'\"
- else
- echo shar: Extracting \"'src/ci.c'\" \(33764 characters\)
- sed "s/^X//" >'src/ci.c' <<'END_OF_FILE'
- X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- X Copyright 1990, 1991 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- This file is part of RCS.
- X
- RCS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- X
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- X
- You should have received a copy of the GNU General Public License
- along with RCS; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Report problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X*/
- X
- X/*
- X * RCS checkin operation
- X */
- X/*******************************************************************
- X * check revisions into RCS files
- X *******************************************************************
- X */
- X
- X
- X
- X/* $Log: ci.c,v $
- X * Revision 5.21 1991/11/20 17:58:07 eggert
- X * Don't read the delta tree from a nonexistent RCS file.
- X *
- X * Revision 5.20 1991/10/07 17:32:46 eggert
- X * Fix log bugs. Remove lint.
- X *
- X * Revision 5.19 1991/09/26 23:10:30 eggert
- X * Plug file descriptor leak.
- X *
- X * Revision 5.18 1991/09/18 07:29:10 eggert
- X * Work around a common ftruncate() bug.
- X *
- X * Revision 5.17 1991/09/10 22:15:46 eggert
- X * Fix test for redirected stdin.
- X *
- X * Revision 5.16 1991/08/19 23:17:54 eggert
- X * When there are no changes, revert to previous revision instead of aborting.
- X * Add piece tables, -M, -r$. Tune.
- X *
- X * Revision 5.15 1991/04/21 11:58:14 eggert
- X * Ensure that working file is newer than RCS file after ci -[lu].
- X * Add -x, RCSINIT, MS-DOS support.
- X *
- X * Revision 5.14 1991/02/28 19:18:47 eggert
- X * Don't let a setuid ci create a new RCS file; rcs -i -a must be run first.
- X * Fix ci -ko -l mode bug. Open work file at most once.
- X *
- X * Revision 5.13 1991/02/25 07:12:33 eggert
- X * getdate -> getcurdate (SVR4 name clash)
- X *
- X * Revision 5.12 1990/12/31 01:00:12 eggert
- X * Don't use uninitialized storage when handling -{N,n}.
- X *
- X * Revision 5.11 1990/12/04 05:18:36 eggert
- X * Use -I for prompts and -q for diagnostics.
- X *
- X * Revision 5.10 1990/11/05 20:30:10 eggert
- X * Don't remove working file when aborting due to no changes.
- X *
- X * Revision 5.9 1990/11/01 05:03:23 eggert
- X * Add -I and new -t behavior. Permit arbitrary data in logs.
- X *
- X * Revision 5.8 1990/10/04 06:30:09 eggert
- X * Accumulate exit status across files.
- X *
- X * Revision 5.7 1990/09/25 20:11:46 hammer
- X * fixed another small typo
- X *
- X * Revision 5.6 1990/09/24 21:48:50 hammer
- X * added cleanups from Paul Eggert.
- X *
- X * Revision 5.5 1990/09/21 06:16:38 hammer
- X * made it handle multiple -{N,n}'s. Also, made it treat re-directed stdin
- X * the same as the terminal
- X *
- X * Revision 5.4 1990/09/20 02:38:51 eggert
- X * ci -k now checks dates more thoroughly.
- X *
- X * Revision 5.3 1990/09/11 02:41:07 eggert
- X * Fix revision bug with `ci -k file1 file2'.
- X *
- X * Revision 5.2 1990/09/04 08:02:10 eggert
- X * Permit adjacent revisions with identical time stamps (possible on fast hosts).
- X * Improve incomplete line handling. Standardize yes-or-no procedure.
- X *
- X * Revision 5.1 1990/08/29 07:13:44 eggert
- X * Expand locker value like co. Clean old log messages too.
- X *
- X * Revision 5.0 1990/08/22 08:10:00 eggert
- X * Don't require a final newline.
- X * Make lock and temp files faster and safer.
- X * Remove compile-time limits; use malloc instead.
- X * Permit dates past 1999/12/31. Switch to GMT.
- X * Add setuid support. Don't pass +args to diff. Check diff's output.
- X * Ansify and Posixate. Add -k, -V. Remove snooping. Tune.
- X * Check diff's output.
- X *
- X * Revision 4.9 89/05/01 15:10:54 narten
- X * changed copyright header to reflect current distribution rules
- X *
- X * Revision 4.8 88/11/08 13:38:23 narten
- X * changes from root@seismo.CSS.GOV (Super User)
- X * -d with no arguments uses the mod time of the file it is checking in
- X *
- X * Revision 4.7 88/08/09 19:12:07 eggert
- X * Make sure workfile is a regular file; use its mode if RCSfile doesn't have one.
- X * Use execv(), not system(); allow cc -R; remove lint.
- X * isatty(fileno(stdin)) -> ttystdin()
- X *
- X * Revision 4.6 87/12/18 11:34:41 narten
- X * lint cleanups (from Guy Harris)
- X *
- X * Revision 4.5 87/10/18 10:18:48 narten
- X * Updating version numbers. Changes relative to revision 1.1 are actually
- X * relative to 4.3
- X *
- X * Revision 1.3 87/09/24 13:57:19 narten
- X * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- X * warnings)
- X *
- X * Revision 1.2 87/03/27 14:21:33 jenkins
- X * Port to suns
- X *
- X * Revision 4.3 83/12/15 12:28:54 wft
- X * ci -u and ci -l now set mode of working file properly.
- X *
- X * Revision 4.2 83/12/05 13:40:54 wft
- X * Merged with 3.9.1.1: added calls to clearerr(stdin).
- X * made rewriteflag external.
- X *
- X * Revision 4.1 83/05/10 17:03:06 wft
- X * Added option -d and -w, and updated assingment of date, etc. to new delta.
- X * Added handling of default branches.
- X * Option -k generates std. log message; fixed undef. pointer in reading of log.
- X * Replaced getlock() with findlock(), link--unlink with rename(),
- X * getpwuid() with getcaller().
- X * Moved all revision number generation to new routine addelta().
- X * Removed calls to stat(); now done by pairfilenames().
- X * Changed most calls to catchints() with restoreints().
- X * Directed all interactive messages to stderr.
- X *
- X * Revision 3.9.1.1 83/10/19 04:21:03 lepreau
- X * Added clearerr(stdin) to getlogmsg() for re-reading stdin.
- X *
- X * Revision 3.9 83/02/15 15:25:44 wft
- X * 4.2 prerelease
- X *
- X * Revision 3.9 83/02/15 15:25:44 wft
- X * Added call to fastcopy() to copy remainder of RCS file.
- X *
- X * Revision 3.8 83/01/14 15:34:05 wft
- X * Added ignoring of interrupts while new RCS file is renamed;
- X * Avoids deletion of RCS files by interrupts.
- X *
- X * Revision 3.7 82/12/10 16:09:20 wft
- X * Corrected checking of return code from diff.
- X *
- X * Revision 3.6 82/12/08 21:34:49 wft
- X * Using DATEFORM to prepare date of checked-in revision;
- X * Fixed return from addbranch().
- X *
- X * Revision 3.5 82/12/04 18:32:42 wft
- X * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE. Updated
- X * field lockedby in removelock(), moved getlogmsg() before calling diff.
- X *
- X * Revision 3.4 82/12/02 13:27:13 wft
- X * added option -k.
- X *
- X * Revision 3.3 82/11/28 20:53:31 wft
- X * Added mustcheckin() to check for redundant checkins.
- X * Added xpandfile() to do keyword expansion for -u and -l;
- X * -m appends linefeed to log message if necessary.
- X * getlogmsg() suppresses prompt if stdin is not a terminal.
- X * Replaced keeplock with lockflag, fclose() with ffclose(),
- X * %02d with %.2d, getlogin() with getpwuid().
- X *
- X * Revision 3.2 82/10/18 20:57:23 wft
- X * An RCS file inherits its mode during the first ci from the working file,
- X * otherwise it stays the same, except that write permission is removed.
- X * Fixed ci -l, added ci -u (both do an implicit co after the ci).
- X * Fixed call to getlogin(), added call to getfullRCSname(), added check
- X * for write error.
- X * Changed conflicting identifiers.
- X *
- X * Revision 3.1 82/10/13 16:04:59 wft
- X * fixed type of variables receiving from getc() (char -> int).
- X * added include file dbm.h for getting BYTESIZ. This is used
- X * to check the return code from diff portably.
- X */
- X
- X#include "rcsbase.h"
- X
- struct Symrev {
- X char const *ssymbol;
- X int override;
- X struct Symrev * nextsym;
- X};
- X
- static char const *getcurdate P((void));
- static int addbranch P((struct hshentry*,struct buf*));
- static int addelta P((void));
- static int addsyms P((char const*));
- static int fixwork P((mode_t,char const*));
- static int removelock P((struct hshentry*));
- static int xpandfile P((RILE*,char const*,struct hshentry const*,char const**));
- static struct cbuf getlogmsg P((void));
- static void cleanup P((void));
- static void incnum P((char const*,struct buf*));
- static void addassoclst P((int, char *));
- X
- static FILE *exfile;
- static RILE *workptr; /* working file pointer */
- static struct buf newdelnum; /* new revision number */
- static struct cbuf msg;
- static int exitstatus;
- static int forceciflag; /* forces check in */
- static int keepflag, keepworkingfile, rcsinitflag;
- static struct hshentries *gendeltas; /* deltas to be generated */
- static struct hshentry *targetdelta; /* old delta to be generated */
- static struct hshentry newdelta; /* new delta to be inserted */
- static struct stat workstat;
- static struct Symrev *assoclst, *lastassoc;
- X
- mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
- X{
- X static char const cmdusage[] =
- X "\nci usage: ci -{fklqru}[rev] -mmsg -{nN}name -sstate -t[textfile] -Vn file ...";
- X static char const default_state[] = DEFAULTSTATE;
- X
- X char altdate[datesize];
- X char olddate[datesize];
- X char newdatebuf[datesize], targetdatebuf[datesize];
- X char *a, **newargv, *textfile;
- X char const *author, *krev, *rev, *state;
- X char const *diffilename, *expfilename;
- X char const *workdiffname, *newworkfilename;
- X char const *mtime;
- X int lockflag, lockthis, mtimeflag, removedlock;
- X int r;
- X int changedRCS, changework, newhead;
- X int usestatdate; /* Use mod time of file for -d. */
- X mode_t newworkmode; /* mode for working file */
- X struct hshentry *workdelta;
- X
- X setrid();
- X
- X author = rev = state = textfile = nil;
- X lockflag = false;
- X mtimeflag = false;
- X altdate[0]= '\0'; /* empty alternate date for -d */
- X usestatdate=false;
- X suffixes = X_DEFAULT;
- X
- X argc = getRCSINIT(argc, argv, &newargv);
- X argv = newargv;
- X while (a = *++argv, 0<--argc && *a++=='-') {
- X switch (*a++) {
- X
- X case 'r':
- X keepworkingfile = lockflag = false;
- X revno:
- X if (*a) {
- X if (rev) warn("redefinition of revision number");
- X rev = a;
- X }
- X break;
- X
- X case 'l':
- X keepworkingfile=lockflag=true;
- X goto revno;
- X
- X case 'u':
- X keepworkingfile=true; lockflag=false;
- X goto revno;
- X
- X case 'I':
- X interactiveflag = true;
- X goto revno;
- X
- X case 'q':
- X quietflag=true;
- X goto revno;
- X
- X case 'f':
- X forceciflag=true;
- X goto revno;
- X
- X case 'k':
- X keepflag=true;
- X goto revno;
- X
- X case 'm':
- X if (msg.size) redefined('m');
- X msg = cleanlogmsg(a, strlen(a));
- X if (!msg.size)
- X warn("missing message for -m option");
- X break;
- X
- X case 'n':
- X if (!*a) {
- X error("missing symbolic name after -n");
- X break;
- X }
- X checksid(a);
- X addassoclst(false, a);
- X break;
- X
- X case 'N':
- X if (!*a) {
- X error("missing symbolic name after -N");
- X break;
- X }
- X checksid(a);
- X addassoclst(true, a);
- X break;
- X
- X case 's':
- X if (*a) {
- X if (state) redefined('s');
- X checksid(a);
- X state = a;
- X } else
- X warn("missing state for -s option");
- X break;
- X
- X case 't':
- X if (*a) {
- X if (textfile) redefined('t');
- X textfile = a;
- X }
- X break;
- X
- X case 'd':
- X if (altdate[0] || usestatdate)
- X redefined('d');
- X altdate[0] = 0;
- X if (!(usestatdate = !*a))
- X str2date(a, altdate);
- X break;
- X
- X case 'M':
- X mtimeflag = true;
- X goto revno;
- X
- X case 'w':
- X if (*a) {
- X if (author) redefined('w');
- X checksid(a);
- X author = a;
- X } else
- X warn("missing author for -w option");
- X break;
- X
- X case 'x':
- X suffixes = a;
- X break;
- X
- X case 'V':
- X setRCSversion(*argv);
- X break;
- X
- X
- X
- X default:
- X faterror("unknown option: %s%s", *argv, cmdusage);
- X };
- X } /* end processing of options */
- X
- X if (argc<1) faterror("no input file%s", cmdusage);
- X
- X /* now handle all filenames */
- X do {
- X targetdelta=nil;
- X ffree();
- X
- X switch (pairfilenames(argc, argv, rcswriteopen, false, false)) {
- X
- X case -1: /* New RCS file */
- X# if has_setuid && has_getuid
- X if (euid() != ruid()) {
- X error("setuid initial checkin prohibited; use `rcs -i -a' first");
- X continue;
- X }
- X# endif
- X rcsinitflag = true;
- X break;
- X
- X case 0: /* Error */
- X continue;
- X
- X case 1: /* Normal checkin with prev . RCS file */
- X rcsinitflag = !Head;
- X }
- X
- X /* now RCSfilename contains the name of the RCS file, and
- X * workfilename contains the name of the working file.
- X * If the RCS file exists, finptr contains the file descriptor for the
- X * RCS file. The admin node is initialized.
- X * RCSstat is set.
- X */
- X
- X diagnose("%s <-- %s\n", RCSfilename,workfilename);
- X
- X if (!(workptr = Iopen(workfilename, FOPEN_R_WORK, &workstat))) {
- X eerror(workfilename);
- X continue;
- X }
- X if (finptr && !checkaccesslist()) continue; /* give up */
- X
- X krev = rev;
- X if (keepflag) {
- X /* get keyword values from working file */
- X if (!getoldkeys(workptr)) continue;
- X if (!rev && !*(krev = prevrev.string)) {
- X error("can't find a revision number in %s",workfilename);
- X continue;
- X }
- X if (!*prevdate.string && *altdate=='\0' && usestatdate==false)
- X warn("can't find a date in %s", workfilename);
- X if (!*prevauthor.string && !author)
- X warn("can't find an author in %s", workfilename);
- X if (!*prevstate.string && !state)
- X warn("can't find a state in %s", workfilename);
- X } /* end processing keepflag */
- X
- X /* Read the delta tree. */
- X if (finptr)
- X gettree();
- X
- X /* expand symbolic revision number */
- X if (!fexpandsym(krev, &newdelnum, workptr))
- X continue;
- X
- X /* splice new delta into tree */
- X if ((removedlock = addelta()) < 0)
- X continue;
- X
- X newdelta.num = newdelnum.string;
- X newdelta.branches=nil;
- X newdelta.lockedby=nil; /*might be changed by addlock() */
- X newdelta.selector = true;
- X /* set author */
- X if (author!=nil)
- X newdelta.author=author; /* set author given by -w */
- X else if (keepflag && *prevauthor.string)
- X newdelta.author=prevauthor.string; /* preserve old author if possible*/
- X else newdelta.author=getcaller();/* otherwise use caller's id */
- X newdelta.state = default_state;
- X if (state!=nil)
- X newdelta.state=state; /* set state given by -s */
- X else if (keepflag && *prevstate.string)
- X newdelta.state=prevstate.string; /* preserve old state if possible */
- X if (usestatdate) {
- X time2date(workstat.st_mtime, altdate);
- X }
- X if (*altdate!='\0')
- X newdelta.date=altdate; /* set date given by -d */
- X else if (keepflag && *prevdate.string) {
- X /* Preserve old date if possible. */
- X str2date(prevdate.string, olddate);
- X newdelta.date = olddate;
- X } else
- X newdelta.date = getcurdate(); /* use current date */
- X /* now check validity of date -- needed because of -d and -k */
- X if (targetdelta!=nil &&
- X cmpnum(newdelta.date,targetdelta->date) < 0) {
- X error("Date %s precedes %s in existing revision %s.",
- X date2str(newdelta.date, newdatebuf),
- X date2str(targetdelta->date, targetdatebuf),
- X targetdelta->num
- X );
- X continue;
- X }
- X
- X
- X if (lockflag && addlock(&newdelta) < 0) continue;
- X if (!addsyms(newdelta.num))
- X continue;
- X
- X
- X putadmin(frewrite);
- X puttree(Head,frewrite);
- X putdesc(false,textfile);
- X
- X changework = Expand != OLD_EXPAND;
- X lockthis = lockflag;
- X workdelta = &newdelta;
- X
- X /* build rest of file */
- X if (rcsinitflag) {
- X diagnose("initial revision: %s\n", newdelnum.string);
- X /* get logmessage */
- X newdelta.log=getlogmsg();
- X if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue;
- X RCSstat.st_mode = workstat.st_mode;
- X changedRCS = true;
- X } else {
- X diffilename = maketemp(0);
- X workdiffname = workfilename;
- X if (workdiffname[0] == '+') {
- X /* Some diffs have options with leading '+'. */
- X char *dp = ftnalloc(char, strlen(workfilename)+3);
- X workdiffname = dp;
- X *dp++ = '.';
- X *dp++ = SLASH;
- X VOID strcpy(dp, workfilename);
- X }
- X newhead = Head == &newdelta;
- X if (!newhead)
- X foutptr = frewrite;
- X expfilename = buildrevision(
- X gendeltas, targetdelta, (FILE*)0, false
- X );
- X if (
- X !forceciflag &&
- X (changework = rcsfcmp(
- X workptr, &workstat, expfilename, targetdelta
- X )) <= 0
- X ) {
- X diagnose("file is unchanged; reverting to previous revision %s\n",
- X targetdelta->num
- X );
- X if (removedlock < lockflag) {
- X diagnose("previous revision was not locked; ignoring -l option\n");
- X lockthis = 0;
- X }
- X if (!(changedRCS =
- X lockflag < removedlock
- X || assoclst
- X || newdelta.state != default_state
- X && strcmp(newdelta.state, targetdelta->state) != 0
- X ))
- X workdelta = targetdelta;
- X else {
- X /*
- X * We have started to build the wrong new RCS file.
- X * Start over from the beginning.
- X */
- X long hwm = ftell(frewrite);
- X int bad_truncate;
- X if (fseek(frewrite, 0L, SEEK_SET) != 0)
- X Oerror();
- X# if !has_ftruncate
- X bad_truncate = 1;
- X# else
- X /*
- X * Work around a common ftruncate() bug.
- X * We can't rely on has_truncate, because we might
- X * be using a filesystem exported to us via NFS.
- X */
- X bad_truncate = ftruncate(fileno(frewrite),(off_t)0);
- X if (bad_truncate && errno != EACCES)
- X Oerror();
- X# endif
- X Irewind(finptr);
- X Lexinit();
- X getadmin();
- X gettree();
- X if (!(workdelta = genrevs(
- X targetdelta->num, (char*)0, (char*)0, (char*)0,
- X &gendeltas
- X )))
- X continue;
- X workdelta->log = targetdelta->log;
- X if (newdelta.state != default_state)
- X workdelta->state = newdelta.state;
- X if (removedlock && removelock(workdelta)<0)
- X continue;
- X if (!addsyms(workdelta->num))
- X continue;
- X if (!dorewrite(true, true))
- X continue;
- X fastcopy(finptr, frewrite);
- X if (bad_truncate)
- X while (ftell(frewrite) < hwm)
- X /* White out any earlier mistake with '\n's. */
- X /* This is unlikely. */
- X afputc('\n', frewrite);
- X }
- X } else {
- X diagnose("new revision: %s; previous revision: %s\n",
- X newdelnum.string, targetdelta->num
- X );
- X newdelta.log = getlogmsg();
- X switch (run((char*)0, diffilename,
- X DIFF DIFF_FLAGS,
- X newhead ? workdiffname : expfilename,
- X newhead ? expfilename : workdiffname,
- X (char*)0
- X )) {
- X case DIFF_FAILURE: case DIFF_SUCCESS: break;
- X default: faterror("diff failed");
- X }
- X if (newhead) {
- X Irewind(workptr);
- X if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue;
- X if (!putdtext(targetdelta->num,targetdelta->log,diffilename,frewrite,true)) continue;
- X } else
- X if (!putdtext(newdelnum.string,newdelta.log,diffilename,frewrite,true)) continue;
- X changedRCS = true;
- X }
- X }
- X if (!donerewrite(changedRCS))
- X continue;
- X
- X if (!keepworkingfile) {
- X Izclose(&workptr);
- X r = un_link(workfilename); /* Get rid of old file */
- X } else {
- X newworkmode = WORKMODE(RCSstat.st_mode,
- X ! (Expand==VAL_EXPAND || lockthis < StrictLocks)
- X );
- X mtime = mtimeflag ? workdelta->date : (char const*)0;
- X
- X /* Expand if it might change or if we can't fix mode, time. */
- X if (changework || (r=fixwork(newworkmode,mtime)) != 0) {
- X Irewind(workptr);
- X /* Expand keywords in file. */
- X locker_expansion = lockthis;
- X switch (xpandfile(
- X workptr, workfilename,
- X workdelta, &newworkfilename
- X )) {
- X default:
- X continue;
- X
- X case 0:
- X /*
- X * No expansion occurred; try to reuse working file
- X * unless we already tried and failed.
- X */
- X if (changework)
- X if ((r=fixwork(newworkmode,mtime)) == 0)
- X break;
- X /* fall into */
- X case 1:
- X if (!(r = setfiledate(newworkfilename,mtime))) {
- X Izclose(&workptr);
- X ignoreints();
- X r = chnamemod(&exfile, newworkfilename, workfilename, newworkmode);
- X keepdirtemp(newworkfilename);
- X restoreints();
- X }
- X }
- X }
- X }
- X if (r != 0) {
- X eerror(workfilename);
- X continue;
- X }
- X diagnose("done\n");
- X
- X } while (cleanup(),
- X ++argv, --argc >=1);
- X
- X tempunlink();
- X exitmain(exitstatus);
- X} /* end of main (ci) */
- X
- X static void
- cleanup()
- X{
- X if (nerror) exitstatus = EXIT_FAILURE;
- X Izclose(&finptr);
- X Izclose(&workptr);
- X Ozclose(&exfile);
- X Ozclose(&fcopy);
- X Ozclose(&frewrite);
- X dirtempunlink();
- X}
- X
- X#if lint
- X# define exiterr ciExit
- X#endif
- X exiting void
- exiterr()
- X{
- X dirtempunlink();
- X tempunlink();
- X _exit(EXIT_FAILURE);
- X}
- X
- X/*****************************************************************/
- X/* the rest are auxiliary routines */
- X
- X
- X static int
- addelta()
- X/* Function: Appends a delta to the delta tree, whose number is
- X * given by newdelnum. Updates Head, newdelnum, newdelnumlength,
- X * and the links in newdelta.
- X * Return -1 on error, 1 if a lock is removed, 0 otherwise.
- X */
- X{
- X register char *tp;
- X register unsigned i;
- X int removedlock;
- X unsigned newdnumlength; /* actual length of new rev. num. */
- X
- X newdnumlength = countnumflds(newdelnum.string);
- X
- X if (rcsinitflag) {
- X /* this covers non-existing RCS file and a file initialized with rcs -i */
- X if ((newdnumlength==0)&&(Dbranch!=nil)) {
- X bufscpy(&newdelnum, Dbranch);
- X newdnumlength = countnumflds(Dbranch);
- X }
- X if (newdnumlength==0) bufscpy(&newdelnum, "1.1");
- X else if (newdnumlength==1) bufscat(&newdelnum, ".1");
- X else if (newdnumlength>2) {
- X error("Branch point doesn't exist for %s.",newdelnum.string);
- X return -1;
- X } /* newdnumlength == 2 is OK; */
- X Head = &newdelta;
- X newdelta.next=nil;
- X return 0;
- X }
- X if (newdnumlength==0) {
- X /* derive new revision number from locks */
- X switch (findlock(true, &targetdelta)) {
- X
- X default:
- X /* found two or more old locks */
- X return -1;
- X
- X case 1:
- X /* found an old lock */
- X /* check whether locked revision exists */
- X if (!genrevs(targetdelta->num,(char*)0,(char*)0,(char*)0,&gendeltas))
- X return -1;
- X if (targetdelta==Head) {
- X /* make new head */
- X newdelta.next=Head;
- X Head= &newdelta;
- X } else if (!targetdelta->next && countnumflds(targetdelta->num)>2) {
- X /* new tip revision on side branch */
- X targetdelta->next= &newdelta;
- X newdelta.next = nil;
- X } else {
- X /* middle revision; start a new branch */
- X bufscpy(&newdelnum, "");
- X return addbranch(targetdelta,&newdelnum);
- X }
- X incnum(targetdelta->num, &newdelnum);
- X return 1; /* successful use of existing lock */
- X
- X case 0:
- X /* no existing lock; try Dbranch */
- X /* update newdelnum */
- X if (StrictLocks || !myself(RCSstat.st_uid)) {
- X error("no lock set by %s",getcaller());
- X return -1;
- X }
- X if (Dbranch) {
- X bufscpy(&newdelnum, Dbranch);
- X } else {
- X incnum(Head->num, &newdelnum);
- X }
- X newdnumlength = countnumflds(newdelnum.string);
- X /* now fall into next statement */
- X }
- X }
- X if (newdnumlength<=2) {
- X /* add new head per given number */
- X if(newdnumlength==1) {
- X /* make a two-field number out of it*/
- X if (cmpnumfld(newdelnum.string,Head->num,1)==0)
- X incnum(Head->num, &newdelnum);
- X else
- X bufscat(&newdelnum, ".1");
- X }
- X if (cmpnum(newdelnum.string,Head->num) <= 0) {
- X error("deltanumber %s too low; must be higher than %s",
- X newdelnum.string, Head->num);
- X return -1;
- X }
- X targetdelta = Head;
- X if (0 <= (removedlock = removelock(Head))) {
- X if (!genrevs(Head->num,(char*)0,(char*)0,(char*)0,&gendeltas))
- X return -1;
- X newdelta.next = Head;
- X Head = &newdelta;
- X }
- X return removedlock;
- X } else {
- X /* put new revision on side branch */
- X /*first, get branch point */
- X tp = newdelnum.string;
- X for (i = newdnumlength - (newdnumlength&1 ^ 1); (--i); )
- X while (*tp++ != '.')
- X ;
- X *--tp = 0; /* Kill final dot to get old delta temporarily. */
- X if (!(targetdelta=genrevs(newdelnum.string,(char*)nil,(char*)nil,(char*)nil,&gendeltas)))
- X return -1;
- X if (cmpnum(targetdelta->num, newdelnum.string) != 0) {
- X error("can't find branchpoint %s", newdelnum.string);
- X return -1;
- X }
- X *tp = '.'; /* Restore final dot. */
- X return addbranch(targetdelta,&newdelnum);
- X }
- X}
- X
- X
- X
- X static int
- addbranch(branchpoint,num)
- X struct hshentry *branchpoint;
- X struct buf *num;
- X/* adds a new branch and branch delta at branchpoint.
- X * If num is the null string, appends the new branch, incrementing
- X * the highest branch number (initially 1), and setting the level number to 1.
- X * the new delta and branchhead are in globals newdelta and newbranch, resp.
- X * the new number is placed into num.
- X * Return -1 on error, 1 if a lock is removed, 0 otherwise.
- X */
- X{
- X struct branchhead *bhead, **btrail;
- X struct buf branchnum;
- X int removedlock, result;
- X unsigned field, numlength;
- X static struct branchhead newbranch; /* new branch to be inserted */
- X
- X numlength = countnumflds(num->string);
- X
- X if (branchpoint->branches==nil) {
- X /* start first branch */
- X branchpoint->branches = &newbranch;
- X if (numlength==0) {
- X bufscpy(num, branchpoint->num);
- X bufscat(num, ".1.1");
- X } else if (numlength&1)
- X bufscat(num, ".1");
- X newbranch.nextbranch=nil;
- X
- X } else if (numlength==0) {
- X /* append new branch to the end */
- X bhead=branchpoint->branches;
- X while (bhead->nextbranch) bhead=bhead->nextbranch;
- X bhead->nextbranch = &newbranch;
- X bufautobegin(&branchnum);
- X getbranchno(bhead->hsh->num, &branchnum);
- X incnum(branchnum.string, num);
- X bufautoend(&branchnum);
- X bufscat(num, ".1");
- X newbranch.nextbranch=nil;
- X } else {
- X /* place the branch properly */
- X field = numlength - (numlength&1 ^ 1);
- X /* field of branch number */
- X btrail = &branchpoint->branches;
- X while (0 < (result=cmpnumfld(num->string,(*btrail)->hsh->num,field))) {
- X btrail = &(*btrail)->nextbranch;
- X if (!*btrail) {
- X result = -1;
- X break;
- X }
- X }
- X if (result < 0) {
- X /* insert/append new branchhead */
- X newbranch.nextbranch = *btrail;
- X *btrail = &newbranch;
- X if (numlength&1) bufscat(num, ".1");
- X } else {
- X /* branch exists; append to end */
- X bufautobegin(&branchnum);
- X getbranchno(num->string, &branchnum);
- X targetdelta=genrevs(branchnum.string,(char*)nil,
- X (char*)nil,(char*)nil,&gendeltas);
- X bufautoend(&branchnum);
- X if (!targetdelta)
- X return -1;
- X if (cmpnum(num->string,targetdelta->num) <= 0) {
- X error("deltanumber %s too low; must be higher than %s",
- X num->string,targetdelta->num);
- X return -1;
- X }
- X if (0 <= (removedlock = removelock(targetdelta))) {
- X if (numlength&1)
- X incnum(targetdelta->num,num);
- X targetdelta->next = &newdelta;
- X newdelta.next = 0;
- X }
- X return removedlock;
- X /* Don't do anything to newbranch. */
- X }
- X }
- X newbranch.hsh = &newdelta;
- X newdelta.next=nil;
- X return 0;
- X}
- X
- X static int
- addsyms(num)
- X char const *num;
- X{
- X register struct Symrev *p;
- X
- X for (p = assoclst; p; p = p->nextsym)
- X if (!addsymbol(num, p->ssymbol, p->override))
- X return false;
- X return true;
- X}
- X
- X
- X static void
- incnum(onum,nnum)
- X char const *onum;
- X struct buf *nnum;
- X/* Increment the last field of revision number onum by one and
- X * place the result into nnum.
- X */
- X{
- X register char *tp, *np;
- X register size_t l;
- X
- X l = strlen(onum);
- X bufalloc(nnum, l+2);
- X np = tp = nnum->string;
- X VOID strcpy(np, onum);
- X for (tp = np + l; np != tp; )
- X if (isdigit(*--tp)) {
- X if (*tp != '9') {
- X ++*tp;
- X return;
- X }
- X *tp = '0';
- X } else {
- X tp++;
- X break;
- X }
- X /* We changed 999 to 000; now change it to 1000. */
- X *tp = '1';
- X tp = np + l;
- X *tp++ = '0';
- X *tp = 0;
- X}
- X
- X
- X
- X static int
- removelock(delta)
- struct hshentry * delta;
- X/* function: Finds the lock held by caller on delta,
- X * removes it, and returns nonzero if successful.
- X * Print an error message and return -1 if there is no such lock.
- X * An exception is if !StrictLocks, and caller is the owner of
- X * the RCS file. If caller does not have a lock in this case,
- X * return 0; return 1 if a lock is actually removed.
- X */
- X{
- X register struct lock *next, **trail;
- X char const *num;
- X
- X num=delta->num;
- X for (trail = &Locks; (next = *trail); trail = &next->nextlock)
- X if (next->delta == delta)
- X if (strcmp(getcaller(), next->login) == 0) {
- X /* We found a lock on delta by caller; delete it. */
- X *trail = next->nextlock;
- X delta->lockedby = 0;
- X return 1;
- X } else {
- X error("revision %s locked by %s",num,next->login);
- X return -1;
- X }
- X if (!StrictLocks && myself(RCSstat.st_uid))
- X return 0;
- X error("no lock set by %s for revision %s", getcaller(), num);
- X return -1;
- X}
- X
- X
- X
- X static char const *
- getcurdate()
- X/* Return a pointer to the current date. */
- X{
- X static char buffer[datesize]; /* date buffer */
- X time_t t;
- X
- X if (!buffer[0]) {
- X t = time((time_t *)0);
- X if (t == -1)
- X faterror("time not available");
- X time2date(t, buffer);
- X }
- X return buffer;
- X}
- X
- X static int
- X#if has_prototypes
- fixwork(mode_t newworkmode, char const *mtime)
- X /* The `#if has_prototypes' is needed because mode_t might promote to int. */
- X#else
- X fixwork(newworkmode, mtime)
- X mode_t newworkmode;
- X char const *mtime;
- X#endif
- X{
- X int r;
- X return
- X 1 < workstat.st_nlink
- X || newworkmode&S_IWUSR && !myself(workstat.st_uid)
- X ? -1
- X :
- X workstat.st_mode != newworkmode
- X &&
- X (r =
- X# if has_fchmod
- X fchmod(Ifileno(workptr), newworkmode)
- X# else
- X chmod(workfilename, newworkmode)
- X# endif
- X ) != 0
- X ? r
- X :
- X setfiledate(workfilename, mtime);
- X}
- X
- X static int
- xpandfile(unexfile, dir, delta, exfilename)
- X RILE *unexfile;
- X char const *dir;
- X struct hshentry const *delta;
- X char const **exfilename;
- X/*
- X * Read unexfile and copy it to a
- X * file in dir, performing keyword substitution with data from delta.
- X * Return -1 if unsuccessful, 1 if expansion occurred, 0 otherwise.
- X * If successful, stores the stream descriptor into *EXFILEP
- X * and its name into *EXFILENAME.
- X */
- X{
- X char const *targetfname;
- X int e, r;
- X
- X targetfname = makedirtemp(dir, 1);
- X if (!(exfile = fopen(targetfname, FOPEN_W_WORK))) {
- X eerror(targetfname);
- X error("can't expand working file");
- X return -1;
- X }
- X r = 0;
- X if (Expand == OLD_EXPAND)
- X fastcopy(unexfile,exfile);
- X else {
- X for (;;) {
- X e = expandline(unexfile,exfile,delta,false,(FILE*)nil);
- X if (e < 0)
- X break;
- X r |= e;
- X if (e <= 1)
- X break;
- X }
- X }
- X *exfilename = targetfname;
- X aflush(exfile);
- X return r & 1;
- X}
- X
- X
- X
- X
- X/* --------------------- G E T L O G M S G --------------------------------*/
- X
- X
- X static struct cbuf
- getlogmsg()
- X/* Obtain and yield a log message.
- X * If a log message is given with -m, yield that message.
- X * If this is the initial revision, yield a standard log message.
- X * Otherwise, reads a character string from the terminal.
- X * Stops after reading EOF or a single '.' on a
- X * line. getlogmsg prompts the first time it is called for the
- X * log message; during all later calls it asks whether the previous
- X * log message can be reused.
- X */
- X{
- X static char const
- X emptych[] = EMPTYLOG,
- X initialch[] = "Initial revision";
- X static struct cbuf const
- X emptylog = { emptych, sizeof(emptych)-sizeof(char) },
- X initiallog = { initialch, sizeof(initialch)-sizeof(char) };
- X static struct buf logbuf;
- X static struct cbuf logmsg;
- X
- X register char *tp;
- X register size_t i;
- X char const *caller;
- X
- X if (msg.size) return msg;
- X
- X if (keepflag) {
- X /* generate std. log message */
- X caller = getcaller();
- X i = sizeof(ciklog)+strlen(caller)+3;
- X bufalloc(&logbuf, i+datesize);
- X tp = logbuf.string;
- X VOID sprintf(tp, "%s%s at ", ciklog, caller);
- X VOID date2str(getcurdate(), tp+i);
- X logmsg.string = tp;
- X logmsg.size = strlen(tp);
- X return logmsg;
- X }
- X
- X if (!targetdelta && (
- X cmpnum(newdelnum.string,"1.1")==0 ||
- X cmpnum(newdelnum.string,"1.0")==0
- X ))
- X return initiallog;
- X
- X if (logmsg.size) {
- X /*previous log available*/
- X if (yesorno(true, "reuse log message of previous file? [yn](y): "))
- X return logmsg;
- X }
- X
- X /* now read string from stdin */
- X logmsg = getsstdin("m", "log message", "", &logbuf);
- X
- X /* now check whether the log message is not empty */
- X if (logmsg.size)
- X return logmsg;
- X return emptylog;
- X}
- X
- X/* Make a linked list of Symbolic names */
- X
- X static void
- addassoclst(flag, sp)
- int flag;
- char * sp;
- X{
- X struct Symrev *pt;
- X
- X pt = talloc(struct Symrev);
- X pt->ssymbol = sp;
- X pt->override = flag;
- X pt->nextsym = nil;
- X if (lastassoc)
- X lastassoc->nextsym = pt;
- X else
- X assoclst = pt;
- X lastassoc = pt;
- X return;
- X}
- END_OF_FILE
- if test 33764 -ne `wc -c <'src/ci.c'`; then
- echo shar: \"'src/ci.c'\" unpacked with wrong size!
- fi
- # end of 'src/ci.c'
- fi
- if test -f 'src/conf.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/conf.sh'\"
- else
- echo shar: Extracting \"'src/conf.sh'\" \(35856 characters\)
- sed "s/^X//" >'src/conf.sh' <<'END_OF_FILE'
- X#!/bin/sh
- X# Output RCS compile-time configuration.
- Id='$Id: conf.sh,v 5.14 1991/11/20 18:21:10 eggert Exp $'
- X# Copyright 1990, 1991 by Paul Eggert
- X# Distributed under license by the Free Software Foundation, Inc.
- X
- X# This file is part of RCS.
- X#
- X# RCS is free software; you can redistribute it and/or modify
- X# it under the terms of the GNU General Public License as published by
- X# the Free Software Foundation; either version 2, or (at your option)
- X# any later version.
- X#
- X# RCS is distributed in the hope that it will be useful,
- X# but WITHOUT ANY WARRANTY; without even the implied warranty of
- X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X# GNU General Public License for more details.
- X#
- X# You should have received a copy of the GNU General Public License
- X# along with RCS; see the file COPYING. If not, write to
- X# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X#
- X# Report problems and direct all questions to:
- X#
- X# rcs-bugs@cs.purdue.edu
- X
- X
- X# Standard output should already be directed to "a.h";
- X# later parts of this procedure need it.
- X# Standard error can be ignored if a.h is OK,
- X# and can be inspected for clues otherwise.
- X
- X# The Makefile overrides the following defaults.
- X: ${CC=cc}
- X: ${CFLAGS=-O}
- X: ${COMPAT2=0}
- X: ${DIFF3=${RCSPREFIX}diff3}
- X: ${DIFF3_BIN=1}
- X: ${DIFF=${RCSPREFIX}diff}
- X: ${DIFF_FLAGS=-an}
- X: ${DIFF_L=1}
- X: ${DIFF_SUCCESS=0} ${DIFF_FAILURE=1} ${DIFF_TROUBLE=2}
- X: ${ED=/bin/ed}
- X: ${RCSPREFIX=/usr/local/bin/}
- X: ${SENDMAIL='"/usr/lib/sendmail"'}
- X# : ${LDFLAGS=} ${LDLIBS=} tickles old shell bug
- X
- C="$CC $CFLAGS"
- CL="$CC $CFLAGS $LDFLAGS"
- L=$LDLIBS
- RM='rm -f a.out'
- X
- cat <<EOF
- X/* RCS compile-time configuration */
- X
- X /* $Id */
- X
- X/*
- X * This file is generated automatically.
- X * If you edit it by hand your changes may be lost.
- X * Instead, please try to fix conf.sh,
- X * and send your fixes to rcs-bugs@cs.purdue.edu.
- X */
- X
- XEOF
- X
- X: exitmain
- cat >a.c <<EOF
- X#include "a.h"
- int main(argc,argv) int argc; char **argv; { return argc-1; }
- XEOF
- X$RM && $CL a.c $L >&2 || exit
- e='exit(n), 3 /* lint fodder */'
- if ./a.out -
- then :
- elif ./a.out
- then e=n
- fi
- echo "#define exitmain(n) return $e /* how to exit from main() */"
- X
- X: _POSIX_SOURCE
- cat >a.c <<'EOF'
- X#include "a.h"
- X#include <stdio.h>
- int main() { exitmain(fileno(stdout) < 0); }
- XEOF
- a='/* ' z='*/ '
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then :
- elif $RM || exit; ($CL -D_POSIX_SOURCE a.c $L && ./a.out) >&2
- then a= z=
- fi
- cat <<EOF
- X$a#define _POSIX_SOURCE $z/* Define this if Posix + strict Standard C. */
- X
- X#include <errno.h>
- X#include <stdio.h>
- X#include <time.h>
- XEOF
- X
- cat <<'EOF'
- X
- X/* Comment out #include lines below that do not work. */
- XEOF
- X
- X# Run `$CS a.c $LS' instead of `$CL a.c $L' for compile-time checking only.
- X# This speeds up the configuration process.
- if $C -S a.c >&2
- then CS="$C -S" LS= # Generate assembly language output.
- elif $C -c a.c >&2
- then CS="$C -c" LS= # Generate object code.
- else CS=$CL LS=$L # Generate an executable.
- fi
- X
- X# standard include files
- X# sys/types.h and sys/stat.h must come first because others depend on them.
- has_signal=1
- for h in \
- X sys/types sys/stat \
- X dirent fcntl limits pwd signal stdlib string sys/mman sys/wait unistd utime vfork
- do
- X i="#include <$h.h>"
- X : $i
- X cat >a.c <<EOF
- X#include "a.h"
- X$i
- int main(){ exitmain(0); }
- XEOF
- X $RM || exit
- X ($CL a.c $L && ./a.out) >&2 || {
- X case $h in
- X string)
- X i='#include <strings.h>';;
- X *)
- X i="/* $i */"
- X esac
- X case $h in
- X signal) has_signal=0
- X esac
- X }
- X echo "$i"
- done
- X
- cat <<'EOF'
- X
- X/* Define the following symbols to be 1 or 0. */
- XEOF
- X
- X# has_sys_*_h
- for H in dir param
- do
- X : has_sys_${H}_h
- X cat >a.c <<EOF
- X#include "a.h"
- X#include <sys/$H.h>
- int main() { exitmain(0); }
- XEOF
- X $RM || exit
- X if ($CL a.c $L && ./a.out) >&2
- X then h=1
- X else h=0
- X fi
- X echo "#define has_sys_${H}_h $h /* Does #include <sys/$H.h> work? */"
- done
- X
- X
- X# We must do NAME_MAX and has_readlink next, because they might generate
- X# #include directives that affect later definitions.
- X
- X: NAME_MAX
- cat >a.c <<'EOF'
- X#include "a.h"
- char b[NAME_MAX + 2];
- main()
- X{
- X#if !defined(NAME_MAX)
- X exitmain(1);
- X#else
- X int i;
- X b[0] = 'a'; b[1] = '.';
- X for (i = 2; i < NAME_MAX; i++)
- X b[i] = 'a';
- X b[i] = 'b';
- X exitmain(creat(b, 0) < 0);
- X#endif
- X}
- XEOF
- X$RM a.*ab || exit
- if $CL a.c $L >&2 && ./a.out && test -f a.*ab
- then a= z=
- else a='/* ' z='*/ '
- fi
- rm -f a.*ab || exit
- X
- X: has_readlink
- cat >a.c <<'EOF'
- X#include "a.h"
- char b[7];
- int main()
- X{
- X exitmain(readlink("a.sym2",b,7) != 6 || strcmp(b, "a.sym1") != 0);
- X}
- XEOF
- X$RM a.sym* || exit
- if (ln -s a.sym1 a.sym2 && $CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- cat <<EOF
- X#define has_readlink $h /* Does readlink() work? */
- X
- X$a#undef NAME_MAX $z/* Uncomment this if NAME_MAX is broken. */
- X
- X#if !defined(NAME_MAX) && !defined(_POSIX_NAME_MAX)
- X# if has_sys_dir_h
- X# include <sys/dir.h>
- X# endif
- X# ifndef NAME_MAX
- X# ifndef MAXNAMLEN
- X# define MAXNAMLEN 14
- X# endif
- X# define NAME_MAX MAXNAMLEN
- X# endif
- X#endif
- X#if !defined(PATH_MAX) && !defined(_POSIX_PATH_MAX)
- X# if has_sys_param_h
- X# include <sys/param.h>
- X# define included_sys_param_h 1
- X# endif
- X# ifndef PATH_MAX
- X# ifndef MAXPATHLEN
- X# define MAXPATHLEN 1024
- X# endif
- X# define PATH_MAX (MAXPATHLEN-1)
- X# endif
- X#endif
- X#if has_readlink && !defined(MAXSYMLINKS)
- X# if has_sys_param_h && !included_sys_param_h
- X# include <sys/param.h>
- X# endif
- X# ifndef MAXSYMLINKS
- X# define MAXSYMLINKS 20 /* BSD; not standard yet */
- X# endif
- X#endif
- XEOF
- X
- cat <<'EOF'
- X
- X/* Comment out the keyword definitions below if the keywords work. */
- XEOF
- X
- X: const, volatile
- for i in const volatile
- do
- X cat >a.c <<EOF
- X# include "a.h"
- X enum Boolean { false, true };
- X static enum Boolean $i zero;
- X static enum Boolean $i * $i azero = &zero;
- X static enum Boolean $i * $i * $i aazero = &azero;
- X int main() { exitmain(!!**aazero); }
- XEOF
- X a= z=
- X if $CS a.c $LS >&2
- X then
- X cat >a.c <<EOF
- X typedef unsigned char $i *Iptr_type;
- X struct { Iptr_type lim; } s, *f = &s;
- X int main() {
- X Iptr_type lim;
- X lim = f->lim;
- X return !!lim;
- X }
- XEOF
- X if $CS a.c $LS >&2
- X then a='/* ' z=' */'
- X fi
- X fi
- X echo "$a#define $i$z"
- done
- X
- X# *_t
- cat <<'EOF'
- X
- X/* Comment out the typedefs below if the types are already declared. */
- X/* Fix any uncommented typedefs that are wrong. */
- XEOF
- cat >a.c <<'EOF'
- X#include "a.h"
- t x;
- int main() { exitmain(0); }
- XEOF
- for t in mode_t pid_t sig_atomic_t size_t ssize_t time_t uid_t
- do
- X : $t
- X case $t in
- X size_t) i=unsigned;;
- X time_t) i=long;;
- X *) i=int;;
- X esac
- X if $CS -Dt=$t a.c $LS >&2
- X then a='/* ' z=' */'
- X else a= z=
- X fi
- X echo "${a}typedef $i $t;$z"
- done
- X
- X: has_prototypes, has_stdarg, has_varargs, va_start_args
- cat >a.ha <<'EOF'
- X#if has_prototypes
- X# define P(params) params
- X#else
- X# define P(params) ()
- X#endif
- X#if has_stdarg
- X# include <stdarg.h>
- X#else
- X# if has_varargs
- X# include <varargs.h>
- X# else
- X typedef char *va_list;
- X# define va_dcl int va_alist;
- X# define va_start(ap) ((ap) = (va_list)&va_alist)
- X# define va_arg(ap,t) (((t*) ((ap)+=sizeof(t))) [-1])
- X# define va_end(ap)
- X# endif
- X#endif
- X#if va_start_args == 2
- X# define vararg_start va_start
- X#else
- X# define vararg_start(ap,p) va_start(ap)
- X#endif
- XEOF
- cat >a.c <<'EOF'
- X#include "a.h"
- X#include "a.ha"
- X#if has_prototypes
- char *f(char **p, ...)
- X#else
- char *f(p, va_alist) char **p; va_dcl
- X#endif
- X{
- X char *s;
- X va_list v;
- X vararg_start(v,p);
- X s = p[va_arg(v,int)];
- X va_end(v);
- X return s;
- X}
- int main P((int, char**));
- int main(argc, argv) int argc; char **argv; {
- X exitmain(f(argv,0) != argv[0] || f(argv,1) != argv[1]);
- X}
- XEOF
- for has_prototypes in 1 0
- do
- X for has_stdarg in 1 v 0
- X do
- X case $has_stdarg in
- X v) has_varargs=1 has_stdarg=0;;
- X *) has_varargs=0
- X esac
- X case $has_stdarg in
- X 0) as='1 2';;
- X 1) as='2 1'
- X esac
- X for va_start_args in $as
- X do
- X $RM || exit
- X $CL \
- X -Dhas_prototypes=$has_prototypes \
- X -Dhas_stdarg=$has_stdarg \
- X -Dhas_varargs=$has_varargs \
- X -Dva_start_args=$va_start_args \
- X a.c $L >&2 && ./a.out && break
- X done && break
- X done && break
- done || {
- X echo >&2 "cannot deduce has_prototypes, has_stdarg, va_start_args"
- X exit 1
- X}
- cat - a.ha <<EOF
- X
- X/* Define the following symbols to be 1 or 0. */
- X#define has_prototypes $has_prototypes /* Do function prototypes work? */
- X#define has_stdarg $has_stdarg /* Does <stdarg.h> work? */
- X#define has_varargs $has_varargs /* Does <varargs.h> work? */
- X#define va_start_args $va_start_args /* How many args does va_start() take? */
- XEOF
- X
- X: text_equals_binary_stdio, FOPEN_...
- cat >a.c <<'EOF'
- X#include "a.h"
- X int
- copyto(filename, mode)
- X char const *filename, *mode;
- X{
- X int c;
- X FILE *f, *g;
- X if (!(f = fopen("a.out", "rb")) || !(g = fopen(filename, mode)))
- X return 1;
- X while (c=getc(f), !feof(f))
- X if (ferror(f) || putc(c,g)<0 && ferror(g))
- X return 1;
- X return fclose(f)!=0 || fclose(g)!=0;
- X}
- int main() { exitmain(copyto("a.d", "w+b") || copyto("a.e", "w+")); }
- XEOF
- e=1
- X$RM a.d a.e || exit
- X$CL a.c $L >&2 && ./a.out && cmp a.out a.d && {
- X cmp a.out a.e || e=0
- X}
- cat <<EOF
- X
- X#define text_equals_binary_stdio $e /* Does stdio treat text like binary? */
- X#define text_work_stdio 0 /* Text i/o for working file, binary for RCS file? */
- X#if text_equals_binary_stdio
- X /* Text and binary i/o behave the same, or binary i/o does not work. */
- X# define FOPEN_R "r"
- X# define FOPEN_W "w"
- X# define FOPEN_WPLUS "w+"
- X#else
- X /* Text and binary i/o behave differently. */
- X /* This is incompatible with Posix and Unix. */
- X# define FOPEN_R "rb"
- X# define FOPEN_W "wb"
- X# define FOPEN_WPLUS "w+b"
- X#endif
- X#if text_work_stdio
- X# define FOPEN_R_WORK "r"
- X# define FOPEN_W_WORK "w"
- X# define FOPEN_WPLUS_WORK "w+"
- X#else
- X# define FOPEN_R_WORK FOPEN_R
- X# define FOPEN_W_WORK FOPEN_W
- X# define FOPEN_WPLUS_WORK FOPEN_WPLUS
- X#endif
- X
- X/* Define or comment out the following symbols as needed. */
- XEOF
- X
- X: bad_fopen_wplus
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(!fopen("a.d",FOPEN_WPLUS)); }
- XEOF
- X$RM || exit
- if echo nonempty >a.d && $CL a.c $L >&2 && ./a.out && test ! -s a.d
- then b=0
- else b=1
- fi
- echo "#define bad_fopen_wplus $b /* Does fopen(f,FOPEN_WPLUS) fail to truncate f? */"
- X
- X: getlogin_is_secure
- echo "#define getlogin_is_secure 0 /* Is getlogin() secure? Usually it's not. */"
- X
- X: has_dirent
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() {
- X DIR *d = opendir(".");
- X struct dirent *e;
- X while ((e = readdir(d)))
- X if (strcmp(e->d_name, "a.c") == 0 && closedir(d) == 0)
- X exitmain(0);
- X exitmain(1);
- X}
- XEOF
- X$RM || exit
- if $CL a.c $L >&2 && ./a.out
- then h=1
- else h=0
- fi
- echo "#define has_dirent $h /* Do opendir(), readdir(), closedir() work? */"
- X
- X: has_fchmod
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(fchmod(fileno(stdin),0) != 0); }
- XEOF
- X$RM || exit
- if $CL a.c $L >&2 && ./a.out <a.c && test ! -r a.c
- then h=1
- else h=0
- fi
- echo "#define has_fchmod $h /* Does fchmod() work? */"
- rm -f a.c || exit
- X
- X: has_fputs
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(fputs("Hello\"\nworld", stdout) != 12); }
- XEOF
- Hello='Hello"
- world'
- X$RM || exit
- if $CL a.c $L >&2 && ./a.out >/dev/null && x=`./a.out` && test " $x" = " $Hello"
- then h=1
- else h=0
- fi
- echo "#define has_fputs $h /* Does fputs() work? */"
- X
- X: has_ftruncate
- cat >a.c <<'EOF'
- X#include "a.h"
- int main(argc, argv) int argc; char **argv; {
- X int f = creat(argv[1], 0);
- X if (f<0 || write(f,"abc",3)!=3 || ftruncate(f,(off_t)0)!=0 || close(f)!=0)
- X exitmain(1);
- X exitmain(0);
- X}
- XEOF
- X$RM || exit
- if $CL a.c $L >&2
- then
- X h=1
- X # Check out /tmp too; it's buggy on some hosts.
- X for d in . /tmp
- X do
- X if test -d $d
- X then
- X f=$d/a.d
- X rm -f $f || exit
- X ./a.out $f && test ! -s $f && test -f $f || h=0
- X rm -f $f || exit
- X fi
- X done
- else h=0
- fi
- echo "#define has_ftruncate $h /* Does ftruncate() work? */"
- X
- X: has_getuid
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef getuid
- X uid_t getuid();
- X#endif
- int main() { exitmain(getuid()!=getuid()); }
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then has_getuid=1
- else has_getuid=0
- fi
- echo "#define has_getuid $has_getuid /* Does getuid() work? */"
- X
- X: has_getpwuid
- case $has_getuid in
- X0)
- X a='/* ' z='*/ ' h=?;;
- X*)
- X a= z=
- X cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(!getpwuid(0)); }
- XEOF
- X $RM || exit
- X if ($CL a.c $L && ./a.out) >&2
- X then h=1
- X else h=0
- X fi
- esac
- echo "$a#define has_getpwuid $h $z/* Does getpwuid() work? */"
- X
- X: has_link
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(link("a.c","a.d") != 0); }
- XEOF
- X$RM a.d || exit
- if ($CL a.c $L && ./a.out && cmp a.c a.d) >&2
- then h=1
- else h=0
- fi
- rm -f a.d || exit
- echo "#define has_link $h /* Does link() work? */"
- X
- X: has_memcmp
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(memcmp("beautiful","beautiful",10) != 0); }
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_memcmp $h /* Does memcmp() work? */"
- X
- X: has_memcpy
- cat >a.c <<'EOF'
- X#include "a.h"
- char a[3];
- int main() {
- X memcpy(a,"xy",3);
- X exitmain(strcmp(a,"xy")!=0);
- X}
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_memcpy $h /* Does memcpy() work? */"
- X
- X: has_memmove
- cat >a.c <<'EOF'
- X#include "a.h"
- char a[4];
- int main() {
- X strcpy(a, "xy");
- X memmove(a+1, a, 3);
- X exitmain(strcmp(a,"xxy")!=0);
- X}
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_memmove $h /* Does memmove() work? */"
- X
- X: has_mmap, has_madvise
- cat >a.c <<'EOF'
- X#define CHAR1 '#' /* the first character in this file */
- X#include "a.h"
- X#ifndef mmap
- X caddr_t mmap();
- X#endif
- caddr_t a;
- struct stat b;
- X#ifndef MADVISE_OK
- X# define MADVISE_OK (madvise(a,b.st_size,MADV_SEQUENTIAL)==0 && madvise(a,b.st_size,MADV_NORMAL)==0)
- X#endif
- int main()
- X{
- X if (fstat(fileno(stdin), &b) != 0)
- X exitmain(1);
- X a = mmap(
- X (caddr_t)0, b.st_size, PROT_READ, MAP_SHARED,
- X fileno(stdin), (off_t)0
- X );
- X exitmain(
- X a == (caddr_t)-1 ||
- X !MADVISE_OK ||
- X *a != CHAR1 ||
- X munmap(a, b.st_size) != 0
- X );
- X}
- XEOF
- a=0 has_mmap=0
- X$RM || exit
- if ($CL -DMADVISE_OK=1 a.c $L && ./a.out <a.c) >&2
- then
- X has_mmap=1
- X $RM || exit
- X ($CL a.c $L && ./a.out <a.c) >&2 && a=1
- fi
- echo "#define has_madvise $a /* Does madvise() work? */"
- echo "#define has_mmap $has_mmap /* Does mmap() work on regular files? */"
- X
- X: has_rename, bad_a_rename, bad_b_rename
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(rename("a.a","a.b") != 0); }
- XEOF
- echo a >a.a && $RM a.b || exit
- if ($CL a.c $L && ./a.out && test -f a.b) >&2
- then
- X h=1
- X rm -f a.a a.b &&
- X echo a >a.a && chmod -w a.a || exit
- X if ./a.out && test ! -f a.a && test -f a.b
- X then a=0
- X else a=1
- X fi
- X rm -f a.a a.b &&
- X echo a >a.a && echo b >a.b && chmod -w a.b || exit
- X if ./a.out && test ! -f a.a && test -f a.b
- X then b=0
- X else b=1
- X fi
- X rm -f a.a a.b || exit
- else h=0 a=0 b=0
- fi
- echo "#define has_rename $h /* Does rename() work? */"
- echo "#define bad_a_rename $a /* Does rename(A,B) fail if A is unwritable? */"
- echo "#define bad_b_rename $b /* Does rename(A,B) fail if B is unwritable? */"
- X
- X: void, VOID
- cat >a.c <<'EOF'
- X#include "a.h"
- void f() {}
- int main() {f(); exitmain(0);}
- XEOF
- if $CS a.c $LS >&2
- then
- X v='(void) '
- else
- X v=
- X echo 'typedef int void;'
- fi
- echo "#define VOID $v/* 'VOID e;' discards the value of an expression 'e'. */"
- X
- X: has_seteuid
- case $has_getuid in
- X0)
- X a='/* ' z='*/ ' has_seteuid=?;;
- X*)
- X a= z=
- X cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef geteuid
- X uid_t geteuid();
- X#endif
- int main() {
- X/* Guess, don't test. Ugh. Testing would require running conf.sh setuid. */
- X/* seteuid() isn't standardized yet, so the guess below may well be wrong. */
- X#if !_POSIX_VERSION || _POSIX_VERSION<=199009L&&!defined(sgi)&&!defined(__sgi__)&&!defined(sun)&&!defined(__sun__)
- X exitmain(1);
- X#else
- X exitmain(seteuid(geteuid()) != 0);
- X#endif
- X}
- XEOF
- X $RM || exit
- X if ($CL a.c $L && ./a.out) >&2
- X then has_seteuid=1
- X else has_seteuid=0
- X fi
- esac
- echo "$a#define has_seteuid $has_seteuid $z/* Does seteuid() work? See README. */"
- X
- X: has_setuid
- h=$has_seteuid
- case $h in
- X0)
- X cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef getuid
- X uid_t getuid();
- X#endif
- int main() { exitmain(setuid(getuid()) != 0); }
- XEOF
- X $RM || exit
- X ($CL a.c $L && ./a.out) >&2 && h=1
- esac
- echo "$a#define has_setuid $h $z/* Does setuid() exist? */"
- X
- X: has_signal, signal_args, signal_type, sig_zaps_handler
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef getpid
- X pid_t getpid();
- X#endif
- X#if !defined(signal) && declare_signal
- X signal_type (*signal P((int,signal_type(*)signal_args)))signal_args;
- X#endif
- signal_type nothing(i) int i; {}
- int main(argc, argv) int argc; char **argv;
- X{
- X signal(SIGINT, nothing);
- X while (--argc)
- X kill(getpid(), SIGINT);
- X exitmain(0);
- X}
- XEOF
- for declare_signal in 1 0
- do
- X for signal_type in void int
- X do
- X for signal_args in 'P((int))' '()'
- X do
- X $RM || exit
- X ($CL \
- X -Ddeclare_signal=$declare_signal \
- X -Dsignal_args="$signal_args" \
- X -Dsignal_type=$signal_type \
- X a.c $L && ./a.out 1) >&2 && break
- X done && break
- X done && break
- done || {
- X echo >&2 "cannot deduce signal_args, signal_type"
- X exit 1
- X}
- if ./a.out 1 2 >&2
- then z=0
- else z=1
- fi
- cat <<EOF
- X#define has_signal $has_signal /* Does signal() work? */
- X#define signal_args $signal_args /* arguments of signal handlers */
- X#define signal_type $signal_type /* type returned by signal handlers */
- X#define sig_zaps_handler $z /* Must a signal handler reinvoke signal()? */
- XEOF
- X
- X: has_sigaction
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef getpid
- X pid_t getpid();
- X#endif
- static sig_atomic_t volatile gotsig;
- static void getsig(i) int i; { gotsig = 1; }
- int main(argc, argv) int argc; char **argv;
- X{
- X struct sigaction s;
- X sigset_t t;
- X if (sigemptyset(&t) != 0 || sigaddset(&t, SIGINT) != 0)
- X exitmain(1);
- X if (sigaction(SIGINT, (struct sigaction const*)0, &s) != 0)
- X exitmain(1);
- X s.sa_handler = getsig;
- X s.sa_mask = t;
- X if (sigaction(SIGINT, &s, (struct sigaction*)0) != 0)
- X exitmain(1);
- X kill(getpid(), SIGINT);
- X exitmain(gotsig != 1);
- X}
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then has_sigaction=1
- else has_sigaction=0
- fi
- echo "#define has_sigaction $has_sigaction /* Does struct sigaction work? */"
- X
- X: has_sigblock, sigmask
- a='/* ' z='*/ '
- b='/* ' y='*/ '
- case $has_sigaction in
- X1)
- X h=? n=?;;
- X*)
- X a= z=
- X cat >a.c <<'EOF'
- X#include "a.h"
- X#include <signal.h>
- X#if define_sigmask
- X# define sigmask(s) (1 << ((s)-1))
- X#endif
- int main()
- X{
- X sigblock(sigmask(SIGHUP));
- X exitmain(kill(getpid(), SIGHUP) != 0);
- X}
- XEOF
- X if $RM || exit; ($CL a.c $L && ./a.out) >&2
- X then h=1
- X elif $RM || exit; ($CL -Ddefine_sigmask=1 a.c $L && ./a.out) >&2
- X then h=1 b= y=
- X else h=0
- X fi
- esac
- echo "$a#define has_sigblock $h $z/* Does sigblock() work? */"
- echo "$b#define sigmask(s) (1 << ((s)-1)) $y/* Yield mask for signal number. */"
- X
- X: has_sys_siglist
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef sys_siglist
- X extern char const *sys_siglist[];
- X#endif
- int main() { exitmain(!sys_siglist[1][0]); }
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_sys_siglist $h /* Does sys_siglist[] work? */"
- X
- X: fread_type, Fread, Fwrite
- cat >a.c <<'EOF'
- X#define CHAR1 '#' /* the first character in this file */
- X#include "a.h"
- X#if !defined(fread) && declare_fread
- X fread_type fread P((void*,freadarg_type,freadarg_type,FILE*));
- X#endif
- int main()
- X{
- X char b;
- X exitmain(!(
- X fread(&b, (freadarg_type)1, (freadarg_type)1, stdin) == 1 &&
- X b==CHAR1
- X ));
- X}
- XEOF
- for declare_fread in 1 0
- do
- X for fread_type in ssize_t size_t int unsigned
- X do
- X for freadarg_type in size_t ssize_t unsigned int
- X do
- X $RM || exit
- X (
- X $CL \
- X -Ddeclare_fread=$declare_fread \
- X -Dfreadarg_type=$freadarg_type \
- X -Dfread_type=$fread_type \
- X a.c $L &&
- X ./a.out <a.c
- X ) >&2 && break
- X done && break
- X done && break
- done || {
- X echo >&2 "cannot deduce fread types"
- X exit 1
- X}
- cat <<EOF
- typedef $fread_type fread_type; /* type returned by fread() and fwrite() */
- typedef $freadarg_type freadarg_type; /* type of their size arguments */
- XEOF
- X
- X: malloc_type
- cat >a.c <<'EOF'
- X#include "a.h"
- typedef void *malloc_type;
- X#ifndef malloc
- X malloc_type malloc();
- X#endif
- int main() { exitmain(!malloc(1)); }
- XEOF
- if $CS a.c $LS >&2
- then t=void
- else t=char
- fi
- echo "typedef $t *malloc_type; /* type returned by malloc() */"
- X
- X: has_getcwd
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef getcwd
- X char *getcwd();
- X#endif
- char buf[10000];
- int main() { exitmain(!getcwd(buf,10000)); }
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then has_getcwd=1
- else has_getcwd=0
- fi
- echo "#define has_getcwd $has_getcwd /* Does getcwd() work? */"
- X
- X: has_getwd
- case $has_getcwd in
- X1)
- X a='/* ' z='*/ ' h=?;;
- X*)
- X a= z=
- X cat >a.c <<'EOF'
- X#include "a.h"
- X#include <sys/param.h>
- X#ifndef getwd
- X char *getwd();
- X#endif
- char buf[MAXPATHLEN];
- int main() { exitmain(!getwd(buf)); }
- XEOF
- X $RM || exit
- X if ($CL a.c $L && ./a.out) >&2
- X then h=1
- X else h=0
- X fi
- esac
- echo "$a#define has_getwd $h $z/* Does getwd() work? */"
- X
- X: has_mktemp
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef mktemp
- X char *mktemp();
- X#endif
- int main()
- X{
- X char b[9];
- X strcpy(b, "a.XXXXXX");
- X exitmain(!mktemp(b));
- X}
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_mktemp $h /* Does mktemp() work? */"
- X
- X: has_NFS
- echo "#define has_NFS 1 /* Might NFS be used? */"
- X
- X: strchr
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef strchr
- X char *strchr();
- X#endif
- int main() {exitmain(!strchr("abc", 'c'));}
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then a='/* ' z='*/ '
- else a= z=
- fi
- echo "$a#define strchr index $z/* Use old-fashioned name for strchr()? */"
- X
- X: strrchr
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef strrchr
- X char *strrchr();
- X#endif
- int main() {exitmain(!strrchr("abc", 'c'));}
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then a='/* ' z='*/ '
- else a= z=
- fi
- echo "$a#define strrchr rindex $z/* Use old-fashioned name for strrchr()? */"
- X
- X: bad_unlink
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(unlink("a.c") != 0); }
- XEOF
- X$RM && chmod -w a.c || exit
- if $CL a.c $L >&2 && ./a.out >/dev/null && test ! -f a.c
- then b=0
- else b=1
- fi
- rm -f a.c || exit
- echo "#define bad_unlink $b /* Does unlink() fail on unwritable files? */"
- X
- X: has_vfork, has_fork, has_spawn, has_wait, has_waitpid, RCS_SHELL
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifndef getpid
- X pid_t getpid();
- X#endif
- X#if TRY_VFORK
- X# ifndef vfork
- X pid_t vfork();
- X# endif
- X#else
- X# ifndef fork
- X pid_t fork();
- X# endif
- X# undef vfork
- X# define vfork fork
- X#endif
- X#if TRY_WAITPID
- X# ifndef waitpid
- X pid_t waitpid();
- X# endif
- X#else
- X# ifndef wait
- X pid_t wait();
- X# endif
- X#endif
- pid_t child;
- int status;
- struct stat st;
- int main()
- X{
- X pid_t parent = getpid();
- X if (!(child = vfork())) {
- X /* Tickle vfork/compiler bug (e.g. sparc gcc -O (1.37.1). */
- X pid_t i = getpid(), j = getpid();
- X if (i!=getpid() || j!=getpid())
- X _exit(!i);
- X /* Tickle file descriptor bug (e.g. IRIX 3.3). */
- X _exit(close(1) != 0);
- X } else {
- X# if TRY_WAITPID
- X if (waitpid(child, &status, 0) != child)
- X exitmain(1);
- X# else
- X while (wait(&status) != child)
- X ;
- X# endif
- X /* Test for presence of bugs. */
- X exitmain(status || parent != getpid() || fstat(1,&st) != 0);
- X }
- X}
- XEOF
- X$RM || exit
- if ($CL -DTRY_VFORK=1 a.c $L && ./a.out) >&2
- then has_vfork=1
- else has_vfork=0
- fi
- echo "#define has_vfork $has_vfork /* Does vfork() work? */"
- h=$has_vfork
- case $h in
- X0)
- X $RM || exit
- X ($CL a.c $L && ./a.out) >&2 && h=1
- esac
- echo "#define has_fork $h /* Does fork() work? */"
- X$RM || exit
- if ($CL -DTRY_VFORK=$has_vfork -DTRY_WAITPID=1 a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_spawn 0 /* Does spawn*() work? */"
- echo "#define has_wait 1 /* Does wait() work? */"
- echo "#define has_waitpid $h /* Does waitpid() work? */"
- echo '#define RCS_SHELL "/bin/sh" /* shell to run RCS subprograms */'
- X
- X: has_vfprintf
- cat >a.c <<'EOF'
- X#include "a.h"
- X#if has_prototypes
- int p(char const*format,...)
- X#else
- X/*VARARGS1*/ int p(format, va_alist) char *format; va_dcl
- X#endif
- X{
- X int r;
- X va_list args;
- X vararg_start(args, format);
- X r = vfprintf(stderr, format, args);
- X va_end(args);
- X return r;
- X}
- int main() { exitmain(p("") != 0); }
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then h=1
- else h=0
- fi
- echo "#define has_vfprintf $h /* Does vfprintf() work? */"
- X
- X: has__doprintf, has__doprnt
- case $h in
- X1)
- X h=? a='/* ' z='*/ ';;
- X*)
- X a= z=
- X cat >a.c <<'EOF'
- X#include "a.h"
- X#if has_prototypes
- int p(char const*format,...)
- X#else
- X/*VARARGS1*/ int p(format, va_alist) char *format; va_dcl
- X#endif
- X{
- X va_list args;
- X vararg_start(args, format);
- X# if TRY__DOPRINTF
- X _doprintf(stderr, format, args);
- X# else
- X _doprnt(format, args, stderr);
- X# endif
- X va_end(args);
- X}
- int main() { p(""); exitmain(ferror(stderr) != 0); }
- XEOF
- X $RM || exit
- X if ($CL -DTRY__DOPRINTF=1 a.c $L && ./a.out) >&2
- X then h=1
- X else h=0
- X fi
- esac
- echo "$a#define has__doprintf $h $z/* Does _doprintf() work? */"
- case $h in
- X0)
- X $RM || exit
- X if ($CL a.c $L && ./a.out) >&2
- X then h=1
- X else h=0
- X fi
- X a= z=;;
- X*)
- X h=? a='/* ' z='*/ '
- esac
- echo "$a#define has__doprnt $h $z/* Does _doprnt() work? */"
- X
- X: EXIT_FAILURE
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { exitmain(EXIT_FAILURE); }
- XEOF
- X$RM || exit
- if $CL a.c $L >&2 && ./a.out
- then a= z=
- else a='/* ' z='*/ '
- fi
- echo "$a#undef EXIT_FAILURE $z/* Uncomment this if EXIT_FAILURE is broken. */"
- X
- X: large_memory
- echo "#define large_memory $has_mmap /* Can main memory hold entire RCS files? */"
- X
- X: ULONG_MAX
- cat >a.c <<'EOF'
- X#include "a.h"
- X#ifdef ULONG_MAX
- X /*
- X * "#if ULONG_MAX/10 <= 0" does not always work,
- X * because some buggy implementations put casts in ULONG_MAX.
- X */
- X int main() { exitmain(ULONG_MAX/10 <= 0); }
- X#else
- X int main() { exitmain(1); }
- X#endif
- XEOF
- X$RM || exit
- if $CL a.c $L >&2 && ./a.out
- then a='/* ' z='*/ '
- else a= z=
- fi
- echo "$a#undef ULONG_MAX $z/* Uncomment this if ULONG_MAX is broken (e.g. < 0). */"
- X
- X: struct utimbuf
- cat >a.c <<'EOF'
- X#include "a.h"
- struct utimbuf s;
- int main() { s.actime = s.modtime = 1; exitmain(utime("a.c", &s) != 0); }
- XEOF
- X$RM || exit
- if ($CL a.c $L && ./a.out) >&2
- then a='/* ' z=' */'
- else a= z=
- fi
- echo "${a}struct utimbuf { time_t actime, modtime; };$z /* Uncomment this if needed. */"
- X
- X: CO
- echo "#define CO \"${RCSPREFIX}co\" /* name of 'co' program */"
- X
- X: COMPAT2
- echo "#define COMPAT2 $COMPAT2 /* Are version 2 files supported? */"
- X
- X: DATEFORM
- cat >a.c <<'EOF'
- X#include "a.h"
- int main() { printf("%.2d", 1); exitmain(0); }
- XEOF
- X$RM && $CL a.c $L >&2 && r=`./a.out` || exit
- case $r in
- X01) f=%.2d;;
- X*) f=%02d
- esac
- echo "#define DATEFORM \"$f.$f.$f.$f.$f.${f}\" /* e.g. 01.01.01.01.01.01 */"
- X
- X: DIFF
- echo "#define DIFF \"${DIFF}\" /* name of 'diff' program */"
- X
- X: DIFF3
- echo "#define DIFF3 \"${DIFF3}\" /* name of 'diff3' program */"
- X
- echo "#define DIFF3_BIN $DIFF3_BIN /* Is diff3 user-visible (not the /usr/lib auxiliary)? */"
- X
- X: DIFF_FLAGS
- dfs=
- for df in $DIFF_FLAGS
- do dfs="$dfs, \"${df}\""
- done
- echo "#define DIFF_FLAGS $dfs /* Make diff output suitable for RCS. */"
- X
- X: DIFF_L
- echo "#define DIFF_L $DIFF_L /* Does diff -L work? */"
- X
- X: DIFF_SUCCESS, DIFF_FAILURE, DIFF_TROUBLE
- cat <<EOF
- X#define DIFF_SUCCESS $DIFF_SUCCESS /* DIFF status if no differences are found */
- X#define DIFF_FAILURE $DIFF_FAILURE /* DIFF status if differences are found */
- X#define DIFF_TROUBLE $DIFF_TROUBLE /* DIFF status if trouble */
- XEOF
- X
- X: ED
- echo "#define ED \"${ED}\" /* name of 'ed' program (used only if !DIFF3_BIN) */"
- X
- X: MERGE
- echo "#define MERGE \"${RCSPREFIX}merge\" /* name of 'merge' program */"
- X
- X: '*SLASH*', ROOTPATH, TMPDIR, X_DEFAULT
- case ${PWD-`pwd`} in
- X/*) # Posix
- X SLASH=/
- X qSLASH="'/'"
- X SLASHes=$qSLASH
- X isSLASH='#define isSLASH(c) ((c) == SLASH)'
- X ROOTPATH='isSLASH((p)[0])'
- X X_DEFAULT=",v$SLASH";;
- X?:[/\\]*) # MS-DOS
- X SLASH='\'
- X qSLASH="'\\\\'"
- X SLASHes="$qSLASH: case '/': case ':'"
- X isSLASH='int isSLASH P((int));'
- X ROOTPATH='((p)[0] && (p)[1]==':' && isSLASH((p)[2]))'
- X X_DEFAULT="$SLASH,v";;
- X*)
- X echo >&2 "cannot deduce SLASH"; exit 1
- esac
- cat <<EOF
- X#define TMPDIR "${SLASH}tmp" /* default directory for temporary files */
- X#define SLASH $qSLASH /* principal pathname separator */
- X#define SLASHes $SLASHes /* \`case SLASHes:' labels all pathname separators */
- X$isSLASH /* Is arg a pathname separator? */
- X#define ROOTPATH(p) $ROOTPATH /* Is p an absolute pathname? */
- X#define X_DEFAULT "$X_DEFAULT" /* default value for -x option */
- XEOF
- X
- X: DIFF_ABSOLUTE
- case $DIFF in
- X"$SLASH"*) a=1;;
- X*) a=0
- esac
- echo "#define DIFF_ABSOLUTE $a /* Is ROOTPATH(DIFF) true? */"
- X
- X: ALL_ABSOLUTE
- a=1
- for i in "$DIFF" "$DIFF3" "$ED" "$RCSPREFIX" "$SENDMAIL"/
- do
- X case $i in
- X "$SLASH"* | "\"$SLASH"*) ;;
- X *) a=0 break
- X esac
- done
- echo "#define ALL_ABSOLUTE $a /* Are all subprograms absolute pathnames? */"
- X
- X: SENDMAIL
- case $SENDMAIL in
- X'') a='/* ' z='*/ ';;
- X*) a= z=
- esac
- echo "$a#define SENDMAIL $SENDMAIL $z/* how to send mail */"
- X
- X: TZ_must_be_set
- echo "#define TZ_must_be_set 0 /* Must TZ be set for gmtime() to work? */"
- X
- X
- X: standard function declarations
- X
- cat <<'EOF'
- X
- X
- X
- X/* Adjust the following declarations as needed. */
- X
- X
- X#if __GNUC__ && !__STRICT_ANSI__
- X# define exiting volatile /* GCC extension: function cannot return */
- X#else
- X# define exiting
- X#endif
- XEOF
- X
- cat >a.ha <<EOF
- X
- X#if has_ftruncate
- X int ftruncate P((int,off_t));
- X#endif
- X
- X/* <sys/mman.h> */
- X#if has_madvise
- X int madvise P((caddr_t,size_t,int));
- X#endif
- X#if has_mmap
- X caddr_t mmap P((caddr_t,size_t,int,int,int,off_t));
- X int munmap P((caddr_t,size_t));
- X#endif
- X
- X
- X/* Posix (ISO/IEC 9945-1: 1990 / IEEE Std 1003.1-1990) */
- X/* These definitions are for the benefit of non-Posix hosts, and */
- X/* Posix hosts that have Standard C compilers but traditional include files. */
- X/* Unfortunately, mixed-up hosts are all too common. */
- X
- X/* <fcntl.h> */
- X#ifdef F_DUPFD
- X int fcntl P((int,int,...));
- X#else
- X int dup2 P((int,int));
- X#endif
- X#ifndef O_BINARY /* some non-Posix hosts need O_BINARY */
- X# define O_BINARY 0 /* no effect on Posix */
- X#endif
- X#ifdef O_CREAT
- X# define open_can_creat 1
- X#else
- X# define open_can_creat 0
- X# define O_RDONLY 0
- X# define O_WRONLY 1
- X# define O_RDWR 2
- X# define O_CREAT 01000
- X# define O_TRUNC 02000
- X int creat P((char const*,mode_t));
- X#endif
- X#ifndef O_EXCL
- X# define O_EXCL 0
- X#endif
- X
- X/* <pwd.h> */
- X#if has_getpwuid
- X struct passwd *getpwuid P((uid_t));
- X#endif
- X
- X/* <signal.h> */
- X#if has_sigaction
- X int sigaction P((int,struct sigaction const*,struct sigaction*));
- X int sigaddset P((sigset_t*,int));
- X int sigemptyset P((sigset_t*));
- X#else
- X#if has_sigblock
- X /* BSD */
- X int sigblock P((int));
- X int sigmask P((int));
- X int sigsetmask P((int));
- X#endif
- X#endif
- X
- X/* <stdio.h> */
- XFILE *fdopen P((int,char const*));
- int fileno P((FILE*));
- X
- X/* <sys/stat.h> */
- int chmod P((char const*,mode_t));
- int fstat P((int,struct stat*));
- int stat P((char const*,struct stat*));
- mode_t umask P((mode_t));
- X#if has_fchmod
- X int fchmod P((int,mode_t));
- X#endif
- X#ifndef S_IRUSR
- X# ifdef S_IREAD
- X# define S_IRUSR S_IREAD
- X# else
- X# define S_IRUSR 0400
- X# endif
- X# ifdef S_IWRITE
- X# define S_IWUSR S_IWRITE
- X# else
- X# define S_IWUSR (S_IRUSR/2)
- X# endif
- X#endif
- X#ifndef S_IRGRP
- X# if has_getuid
- X# define S_IRGRP (S_IRUSR / 0010)
- X# define S_IWGRP (S_IWUSR / 0010)
- X# define S_IROTH (S_IRUSR / 0100)
- X# define S_IWOTH (S_IWUSR / 0100)
- X# else
- X /* single user OS -- not Posix or Unix */
- X# define S_IRGRP 0
- X# define S_IWGRP 0
- X# define S_IROTH 0
- X# define S_IWOTH 0
- X# endif
- X#endif
- X#ifndef S_ISREG
- X# define S_ISREG(n) (((n) & S_IFMT) == S_IFREG)
- X#endif
- X
- X/* <sys/wait.h> */
- X#if has_wait
- X pid_t wait P((int*));
- X#endif
- X#ifndef WEXITSTATUS
- X# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
- X# undef WIFEXITED /* Avoid 4.3BSD incompatibility with Posix. */
- X#endif
- X#ifndef WIFEXITED
- X# define WIFEXITED(stat_val) (!((stat_val) & 255))
- X#endif
- X
- X/* <unistd.h> */
- char *getlogin P((void));
- int close P((int));
- int isatty P((int));
- int link P((char const*,char const*));
- int open P((char const*,int,...));
- int unlink P((char const*));
- int _filbuf P((FILE*)); /* keeps lint quiet in traditional C */
- int _flsbuf P((int,FILE*)); /* keeps lint quiet in traditional C */
- long pathconf P((char const*,int));
- ssize_t write P((int,void const*,size_t));
- X#ifndef STDIN_FILENO
- X# define STDIN_FILENO 0
- X# define STDOUT_FILENO 1
- X# define STDERR_FILENO 2
- X#endif
- X#if has_fork
- X# if !has_vfork
- X# undef vfork
- X# define vfork fork
- X# endif
- X pid_t vfork P((void)); /* vfork is nonstandard but faster */
- X#endif
- X#if has_getcwd || !has_getwd
- X char *getcwd P((char*,size_t));
- X#else
- X char *getwd P((char*));
- X#endif
- X#if has_getuid
- X uid_t getuid P((void));
- X#endif
- X#if has_readlink
- X ssize_t readlink P((char const*,char*,size_t)); /* BSD; not standard yet */
- X#endif
- X#if has_setuid
- X# if !has_seteuid
- X# undef seteuid
- X# define seteuid setuid
- X# endif
- X int seteuid P((uid_t));
- X uid_t geteuid P((void));
- X#endif
- X#if has_spawn
- X int spawnv P((int,char const*,char*const*));
- X# if ALL_ABSOLUTE
- X# define spawn_RCS spawnv
- X# else
- X# define spawn_RCS spawnvp
- X int spawnvp P((int,char const*,char*const*));
- X# endif
- X#else
- X int execv P((char const*,char*const*));
- X# if ALL_ABSOLUTE
- X# define exec_RCS execv
- X# else
- X# define exec_RCS execvp
- X int execvp P((char const*,char*const*));
- X# endif
- X#endif
- X
- X/* utime.h */
- int utime P((char const*,struct utimbuf const*));
- X
- X
- X/* Standard C library */
- X/* These definitions are for the benefit of hosts that have */
- X/* traditional C include files, possibly with Standard C compilers. */
- X/* Unfortunately, mixed-up hosts are all too common. */
- X
- X/* <errno.h> */
- extern int errno;
- X
- X/* <limits.h> */
- X#ifndef ULONG_MAX
- X /* This does not work in #ifs, but it's good enough for us. */
- X# define ULONG_MAX ((unsigned long)-1)
- X#endif
- X
- X/* <signal.h> */
- X#if has_signal
- X signal_type (*signal P((int,signal_type(*)signal_args)))signal_args;
- X#endif
- X
- X/* <stdio.h> */
- XFILE *fopen P((char const*,char const*));
- fread_type fread P((void*,freadarg_type,freadarg_type,FILE*));
- fread_type fwrite P((void const*,freadarg_type,freadarg_type,FILE*));
- int fclose P((FILE*));
- int feof P((FILE*));
- int ferror P((FILE*));
- int fflush P((FILE*));
- int fprintf P((FILE*,char const*,...));
- int fputs P((char const*,FILE*));
- int fseek P((FILE*,long,int));
- int printf P((char const*,...));
- int rename P((char const*,char const*));
- int sprintf P((char*,char const*,...));
- long ftell P((FILE*));
- void clearerr P((FILE*));
- void perror P((char const*));
- X#ifndef L_tmpnam
- X# define L_tmpnam 32 /* power of 2 > sizeof("/usr/tmp/xxxxxxxxxxxxxxx") */
- X#endif
- X#ifndef SEEK_SET
- X# define SEEK_SET 0
- X#endif
- X#if has_mktemp
- X char *mktemp P((char*)); /* traditional */
- X#else
- X char *tmpnam P((char*));
- X#endif
- X#if has_vfprintf
- X int vfprintf P((FILE*,char const*,va_list));
- X#else
- X#if has__doprintf
- X void _doprintf P((FILE*,char const*,va_list)); /* Minix */
- X#else
- X void _doprnt P((char const*,va_list,FILE*)); /* BSD */
- X#endif
- X#endif
- X
- X/* <stdlib.h> */
- char *getenv P((char const*));
- exiting void _exit P((int));
- exiting void exit P((int));
- malloc_type malloc P((size_t));
- malloc_type realloc P((malloc_type,size_t));
- void free P((malloc_type));
- X#ifndef EXIT_FAILURE
- X# define EXIT_FAILURE 1
- X#endif
- X#ifndef EXIT_SUCCESS
- X# define EXIT_SUCCESS 0
- X#endif
- X#if !has_fork && !has_spawn
- X int system P((char const*));
- X#endif
- X
- X/* <string.h> */
- char *strcpy P((char*,char const*));
- char *strchr P((char const*,int));
- char *strrchr P((char const*,int));
- int memcmp P((void const*,void const*,size_t));
- int strcmp P((char const*,char const*));
- size_t strlen P((char const*));
- void *memcpy P((void*,void const*,size_t));
- X#if has_memmove
- X void *memmove P((void*,void const*,size_t));
- X#endif
- X
- X/* <time.h> */
- time_t time P((time_t*));
- XEOF
- X
- cat >a.c <<'EOF'
- X#include "a.h"
- X#define a 0
- X#define b 1
- X#if h==a
- X# include "a.ha"
- X#else
- X# include "a.hb"
- X#endif
- int main() { exitmain(0); }
- XEOF
- X
- X# Comment out lines in a.ha that the compiler rejects.
- X# a.ha may not contain comments that cross line boundaries.
- X# Leave the result in a.h$h.
- h=a l=1
- U=`wc -l <a.ha | sed 's| ||g'`
- commentOut='s|^[^#/][^/]*|/* & */|'
- X
- until test $U -lt $l || $CS -Dh=$h a.c $LS >&2
- do
- X case $h in
- X a) i=b;;
- X *) i=a
- X esac
- X
- X # The compiler rejects some line in l..U.
- X # Use binary search to set l to be the index of the first bad line in l..U.
- X u=$U
- X while test $l -lt $u
- X do
- X M=`expr '(' $l + $u ')' / 2`
- X M1=`expr $M + 1`
- X sed "$M1,\$$commentOut" a.h$h >a.h$i || exit
- X if $CS -Dh=$i a.c $LS >&2
- X then l=$M1
- X else u=$M
- X fi
- X done
- X
- X # Comment out the bad line.
- X sed "$l$commentOut" a.h$h >a.h$i || exit
- X
- X h=$i
- X l=`expr $l + 1`
- done
- X
- cat a.h$h
- END_OF_FILE
- if test 35856 -ne `wc -c <'src/conf.sh'`; then
- echo shar: \"'src/conf.sh'\" unpacked with wrong size!
- fi
- # end of 'src/conf.sh'
- fi
- echo shar: End of archive 7 \(of 11\).
- cp /dev/null ark7isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-