summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/rcs/ci
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1995-10-28 21:07:39 +0000
committerpeter <peter@FreeBSD.org>1995-10-28 21:07:39 +0000
commitf88f3a686799dfede79eb3c8d8cfec9b1e7ae343 (patch)
treef3e1577c5b11357c106fe7ee15105d608cb96192 /gnu/usr.bin/rcs/ci
parent27378b5694b4941bb63a62097f7ee523da0a35bb (diff)
downloadFreeBSD-src-f88f3a686799dfede79eb3c8d8cfec9b1e7ae343.zip
FreeBSD-src-f88f3a686799dfede79eb3c8d8cfec9b1e7ae343.tar.gz
Import rcs-5.7, required for full support of cvs-1.6.
This is going to be pretty messy.... Although the vendor import was correct, both the vendor and release tags are the same "gnu"... :-/ Getting cvs to choose the correct one might be rather interesting...
Diffstat (limited to 'gnu/usr.bin/rcs/ci')
-rw-r--r--gnu/usr.bin/rcs/ci/Makefile9
-rw-r--r--gnu/usr.bin/rcs/ci/ci.1211
-rw-r--r--gnu/usr.bin/rcs/ci/ci.c584
3 files changed, 543 insertions, 261 deletions
diff --git a/gnu/usr.bin/rcs/ci/Makefile b/gnu/usr.bin/rcs/ci/Makefile
index 9b64e08..2fbb74f 100644
--- a/gnu/usr.bin/rcs/ci/Makefile
+++ b/gnu/usr.bin/rcs/ci/Makefile
@@ -1,7 +1,8 @@
-PROG= ci
-
-SRCS= ci.c
-LDADD= -L${.CURDIR}/../lib/obj -lrcs
+PROG= ci
+SRCS= ci.c
CFLAGS+= -I${.CURDIR}/../lib
+LDADD= ${LIBRCS}
+DPADD= ${LIBRCS}
+.include "../../Makefile.inc"
.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/ci/ci.1 b/gnu/usr.bin/rcs/ci/ci.1
index 5736dc9..d096096 100644
--- a/gnu/usr.bin/rcs/ci/ci.1
+++ b/gnu/usr.bin/rcs/ci/ci.1
@@ -2,8 +2,10 @@
.ds Rv \\$3
.ds Dt \\$4
..
-.Id $Id: ci.1,v 5.9 1991/10/07 17:32:46 eggert Exp $
+.Id $Id: ci.1,v 5.17 1995/06/16 06:19:24 eggert Exp $
+.ds i \&\s-1ISO\s0
.ds r \&\s-1RCS\s0
+.ds u \&\s-1UTC\s0
.if n .ds - \%--
.if t .ds - \(em
.TH CI 1 \*(Dt GNU
@@ -41,7 +43,7 @@ new branch can be created. This restriction is not enforced
for the owner of the file if non-strict locking is used
(see
.BR rcs (1)).
-A lock held by someone else may be broken with the
+A lock held by someone else can be broken with the
.B rcs
command.
.PP
@@ -105,7 +107,9 @@ The number
.I rev
of the deposited revision can be given by any of the options
.BR \-f ,
+.BR \-i ,
.BR \-I ,
+.BR \-j ,
.BR \-k ,
.BR \-l ,
.BR \-M ,
@@ -114,7 +118,15 @@ of the deposited revision can be given by any of the options
or
.BR \-u .
.I rev
-may be symbolic, numeric, or mixed.
+can be symbolic, numeric, or mixed.
+Symbolic names in
+.I rev
+must already be defined;
+see the
+.B \-n
+and
+.B \-N
+options for assigning names during checkin.
If
.I rev
is
@@ -124,6 +136,15 @@ determines the revision number from keyword values in the working file.
.PP
If
.I rev
+begins with a period,
+then the default branch (normally the trunk) is prepended to it.
+If
+.I rev
+is a branch number followed by a period,
+then the latest revision on that branch is used.
+.PP
+If
+.I rev
is a revision number, it must be higher than the latest
one on the branch to which
.I rev
@@ -172,25 +193,28 @@ Exception: On the trunk, revisions can be appended to the end, but
not inserted.
.SH OPTIONS
.TP
-.BR \-r [\f2rev\fP]
-checks in a revision, releases the corresponding lock, and
-removes the working file. This is the default.
-.RS
-.PP
-The
+.BI \-r rev
+Check in revision
+.IR rev .
+.TP
+.BR \-r
+The bare
.B \-r
-option has an unusual meaning in
+option (without any revision) has an unusual meaning in
.BR ci .
-In other \*r commands,
+With other \*r commands, a bare
.B \-r
-merely specifies a revision number,
-but in
-.B ci
-it also releases a lock and removes the working file.
-See
+option specifies the most recent revision on the default branch,
+but with
+.BR ci ,
+a bare
+.B \-r
+option reestablishes the default behavior of releasing a lock and
+removing the working file, and is used to override any default
+.B \-l
+or
.B \-u
-for a tricky example.
-.RE
+options established by shell aliases or scripts.
.TP
.BR \-l [\f2rev\fP]
works like
@@ -213,6 +237,7 @@ immediately after checkin.
.PP
The
.BR \-l ,
+bare
.BR \-r ,
and
.B \-u
@@ -221,7 +246,7 @@ For example,
.B "ci\ \-u\ \-r"
is equivalent to
.B "ci\ \-r"
-because
+because bare
.B \-r
overrides
.BR \-u .
@@ -244,7 +269,7 @@ several sites should be checked in with the
.B \-k
option at these sites to
preserve the original number, date, author, and state.
-The extracted keyword values and the default log message may be overridden
+The extracted keyword values and the default log message can be overridden
with the options
.BR \-d ,
.BR \-m ,
@@ -259,6 +284,14 @@ unless
.B \-f
is given.
.TP
+.BR \-i [\f2rev\fP]
+initial checkin; report an error if the \*r file already exists.
+This avoids race conditions in certain applications.
+.TP
+.BR \-j [\f2rev\fP]
+just checkin and do not initialize;
+report an error if the \*r file does not already exist.
+.TP
.BR \-I [\f2rev\fP]
interactive mode;
the user is prompted and questioned
@@ -296,6 +329,18 @@ Use this option with care; it can confuse
uses the string
.I msg
as the log message for all revisions checked in.
+By convention, log messages that start with
+.B #
+are comments and are ignored by programs like GNU Emacs's
+.B vc
+package.
+Also, log messages that start with
+.BI { clumpname }
+(followed by white space) are meant to be clumped together if possible,
+even if they are associated with different files; the
+.BI { clumpname }
+label is used only for clumping,
+and is not considered to be part of the log message itself.
.TP
.BI \-n "name"
assigns the symbolic name
@@ -326,7 +371,7 @@ into the \*r file,
deleting the existing text.
The
.I file
-may not begin with
+cannot begin with
.BR \- .
.TP
.BI \-t\- string
@@ -356,6 +401,41 @@ For backward compatibility with older versions of \*r, a bare
option is ignored.
.RE
.TP
+.B \-T
+Set the \*r file's modification time to the new revision's time
+if the former precedes the latter and there is a new revision;
+preserve the \*r file's modification time otherwise.
+If you have locked a revision,
+.B ci
+usually updates the \*r file's modification time to the current time,
+because the lock is stored in the \*r file
+and removing the lock requires changing the \*r file.
+This can create an \*r file newer than the working file in one of two ways:
+first,
+.B "ci\ \-M"
+can create a working file with a date before the current time;
+second, when reverting to the previous revision
+the \*r file can change while the working file remains unchanged.
+These two cases can cause excessive recompilation caused by a
+.BR make (1)
+dependency of the working file on the \*r file.
+The
+.B \-T
+option inhibits this recompilation by lying about the \*r file's date.
+Use this option with care; it can suppress recompilation even when
+a checkin of one working file should affect
+another working file associated with the same \*r file.
+For example, suppose the \*r file's time is 01:00,
+the (changed) working file's time is 02:00,
+some other copy of the working file has a time of 03:00,
+and the current time is 04:00.
+Then
+.B "ci\ \-d\ \-T"
+sets the \*r file's time to 02:00 instead of the usual 04:00;
+this causes
+.BR make (1)
+to think (incorrectly) that the other copy is newer than the \*r file.
+.TP
.BI \-w "login"
uses
.I login
@@ -364,6 +444,9 @@ Useful for lying about the author, and for
.B \-k
if no author is available.
.TP
+.BI \-V
+Print \*r's version number.
+.TP
.BI \-V n
Emulate \*r version
.IR n .
@@ -375,9 +458,9 @@ for details.
specifies the suffixes for \*r files.
A nonempty suffix matches any pathname ending in the suffix.
An empty suffix matches any pathname of the form
-.BI RCS/ file
+.BI RCS/ path
or
-.IB path /RCS/ file.
+.IB path1 /RCS/ path2.
The
.B \-x
option can specify a list of suffixes
@@ -398,10 +481,49 @@ The default for
.IR suffixes
is installation-dependent; normally it is
.B ,v/
-for hosts like Unix that permit commas in file names,
+for hosts like Unix that permit commas in filenames,
and is empty (i.e. just the empty suffix) for other hosts.
+.TP
+.BI \-z zone
+specifies the date output format in keyword substitution,
+and specifies the default time zone for
+.I date
+in the
+.BI \-d date
+option.
+The
+.I zone
+should be empty, a numeric \*u offset, or the special string
+.B LT
+for local time.
+The default is an empty
+.IR zone ,
+which uses the traditional \*r format of \*u without any time zone indication
+and with slashes separating the parts of the date;
+otherwise, times are output in \*i 8601 format with time zone indication.
+For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
+eight hours west of \*u,
+then the time is output as follows:
+.RS
+.LP
+.RS
+.nf
+.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
+.ne 4
+\f2option\fP \f2time output\fP
+\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
+\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
+\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
+.ta 4n +4n +4n +4n
+.fi
+.RE
+.LP
+The
+.B \-z
+option does not affect dates stored in \*r files,
+which are always \*u.
.SH "FILE NAMING"
-Pairs of \*r files and working files may be specified in three ways
+Pairs of \*r files and working files can be specified in three ways
(see also the
example section).
.PP
@@ -423,9 +545,9 @@ If
.I X
is empty,
.IB path1 /
-must be
+must start with
.B RCS/
-or must end in
+or must contain
.BR /RCS/ .
.PP
2) Only the \*r file is given. Then the working file is created in the current
@@ -516,7 +638,7 @@ preserves its read and execute permissions.
.B ci
always turns off all write permissions of \*r files.
.SH FILES
-Several temporary files may be created in the directory containing
+Temporary files are created in the directory containing
the working file, and also in the temporary directory (see
.B \s-1TMPDIR\s0
under
@@ -576,21 +698,23 @@ who can check in new revisions but cannot otherwise change the \*r files.
.SH "SETUID USE"
To prevent anybody but their \*r administrator from deleting revisions,
a set of users can employ setuid privileges as follows.
-.nr n \w'\(bu '+1n-1/1n
-.IP \(bu \nn
+.nr n \w'\(bu'+2n-1/1n
+.ds n \nn
+.if \n(.g .if r an-tag-sep .ds n \w'\(bu'u+\n[an-tag-sep]u
+.IP \(bu \*n
Check that the host supports \*r setuid use.
Consult a trustworthy expert if there are any doubts.
It is best if the
-.B seteuid()
+.B seteuid
system call works as described in Posix 1003.1a Draft 5,
because \*r can switch back and forth easily
between real and effective users, even if the real user is
.BR root .
If not, the second best is if the
-.B setuid()
+.B setuid
system call supports saved setuid
(the {\s-1_POSIX_SAVED_IDS\s0} behavior of Posix 1003.1-1990);
-this fails only if the real user is
+this fails only if the real or effective user is
.BR root .
If \*r detects any failure in setuid, it quits immediately.
.IP \(bu \nn
@@ -599,7 +723,7 @@ Choose a user
to serve as \*r administrator for the set of users.
Only
.I A
-will be able to invoke the
+can invoke the
.B rcs
command on the users' \*r files.
.I A
@@ -608,9 +732,9 @@ should not be
or any other user with special powers.
Mutually suspicious sets of users should use different administrators.
.IP \(bu \nn
-Choose a path name
+Choose a pathname
.I B
-that will be a directory of files to be executed by the users.
+to be a directory of files to be executed by the users.
.IP \(bu \nn
Have
.I A
@@ -733,8 +857,9 @@ Useful
options include
.BR \-q ,
.BR \-V ,
+.BR \-x ,
and
-.BR \-x .
+.BR \-z .
.TP
.B \s-1TMPDIR\s0
Name of the temporary directory.
@@ -755,14 +880,16 @@ The exit status is zero if and only if all operations were successful.
.SH IDENTIFICATION
Author: Walter F. Tichy.
.br
-Revision Number: \*(Rv; Release Date: \*(Dt.
+Manual Page Revision: \*(Rv; Release Date: \*(Dt.
.br
-Copyright \(co 1982, 1988, 1989 by Walter F. Tichy.
+Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
.br
-Copyright \(co 1990, 1991 by Paul Eggert.
+Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
.SH "SEE ALSO"
-co(1), ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1),
-rcsintro(1), rcsmerge(1), rlog(1), rcsfile(5)
+co(1),
+emacs(1),
+ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1),
+rcsintro(1), rcsmerge(1), rlog(1), setuid(2), rcsfile(5)
.br
Walter F. Tichy,
\*r\*-A System for Version Control,
diff --git a/gnu/usr.bin/rcs/ci/ci.c b/gnu/usr.bin/rcs/ci/ci.c
index 566747e..c9671d1 100644
--- a/gnu/usr.bin/rcs/ci/ci.c
+++ b/gnu/usr.bin/rcs/ci/ci.c
@@ -1,5 +1,7 @@
-/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991 by Paul Eggert
+/* Check in revisions of RCS files from working files. */
+
+/* Copyright 1982, 1988, 1989 Walter Tichy
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
Distributed under license by the Free Software Foundation, Inc.
This file is part of RCS.
@@ -15,8 +17,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.
+along with RCS; see the file COPYING.
+If not, write to the Free Software Foundation,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Report problems and direct all questions to:
@@ -25,16 +28,50 @@ Report problems and direct all questions to:
*/
/*
- * RCS checkin operation
- */
-/*******************************************************************
- * check revisions into RCS files
- *******************************************************************
- */
-
-
-
-/* $Log: ci.c,v $
+ * $Log: ci.c,v $
+ * Revision 5.30 1995/06/16 06:19:24 eggert
+ * Update FSF address.
+ *
+ * Revision 5.29 1995/06/01 16:23:43 eggert
+ * (main): Add -kb.
+ * Use `cmpdate', not `cmpnum', to compare dates.
+ * This is for MKS RCS's incompatible 20th-century date format.
+ * Don't worry about errno after ftruncate fails.
+ * Fix input file rewinding bug when large_memory && !maps_memory
+ * and checking in a branch tip.
+ *
+ * (fixwork): Fall back on chmod if fchmod fails, since it might be ENOSYS.
+ *
+ * Revision 5.28 1994/03/20 04:52:58 eggert
+ * Do not generate a corrupted RCS file if the user modifies the working file
+ * while `ci' is running.
+ * Do not remove the lock when `ci -l' reverts.
+ * Move buffer-flushes out of critical sections, since they aren't critical.
+ * Use ORCSerror to clean up after a fatal error.
+ * Specify subprocess input via file descriptor, not file name.
+ *
+ * Revision 5.27 1993/11/09 17:40:15 eggert
+ * -V now prints version on stdout and exits. Don't print usage twice.
+ *
+ * Revision 5.26 1993/11/03 17:42:27 eggert
+ * Add -z. Don't subtract from RCS file timestamp even if -T.
+ * Scan for and use Name keyword if -k.
+ * Don't discard ignored phrases. Improve quality of diagnostics.
+ *
+ * Revision 5.25 1992/07/28 16:12:44 eggert
+ * Add -i, -j, -V. Check that working and RCS files are distinct.
+ *
+ * Revision 5.24 1992/02/17 23:02:06 eggert
+ * `-rREV' now just specifies a revision REV; only bare `-r' reverts to default.
+ * Add -T.
+ *
+ * Revision 5.23 1992/01/27 16:42:51 eggert
+ * Always unlock branchpoint if caller has a lock.
+ * Add support for bad_chmod_close, bad_creat0. lint -> RCS_lint
+ *
+ * Revision 5.22 1992/01/06 02:42:34 eggert
+ * Invoke utime() before chmod() to keep some buggy systems happy.
+ *
* Revision 5.21 1991/11/20 17:58:07 eggert
* Don't read the delta tree from a nonexistent RCS file.
*
@@ -214,16 +251,16 @@ struct Symrev {
};
static char const *getcurdate P((void));
-static int addbranch P((struct hshentry*,struct buf*));
+static int addbranch P((struct hshentry*,struct buf*,int));
static int addelta P((void));
static int addsyms P((char const*));
-static int fixwork P((mode_t,char const*));
+static int fixwork P((mode_t,time_t));
static int removelock P((struct hshentry*));
-static int xpandfile P((RILE*,char const*,struct hshentry const*,char const**));
+static int xpandfile P((RILE*,struct hshentry const*,char const**,int));
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 *));
+static void addassoclst P((int,char const*));
static FILE *exfile;
static RILE *workptr; /* working file pointer */
@@ -236,37 +273,41 @@ 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;
+static struct Symrev *assoclst, **nextassoc;
-mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
+mainProg(ciId, "ci", "$Id: ci.c,v 5.30 1995/06/16 06:19:24 eggert Exp $")
{
static char const cmdusage[] =
- "\nci usage: ci -{fklqru}[rev] -mmsg -{nN}name -sstate -t[textfile] -Vn file ...";
+ "\nci usage: ci -{fIklMqru}[rev] -d[date] -mmsg -{nN}name -sstate -ttext -T -Vn -wwho -xsuff -zzone file ...";
static char const default_state[] = DEFAULTSTATE;
char altdate[datesize];
char olddate[datesize];
- char newdatebuf[datesize], targetdatebuf[datesize];
+ char newdatebuf[datesize + zonelenmax];
+ char targetdatebuf[datesize + zonelenmax];
char *a, **newargv, *textfile;
char const *author, *krev, *rev, *state;
- char const *diffilename, *expfilename;
- char const *workdiffname, *newworkfilename;
- char const *mtime;
- int lockflag, lockthis, mtimeflag, removedlock;
+ char const *diffname, *expname;
+ char const *newworkname;
+ int initflag, mustread;
+ int lockflag, lockthis, mtimeflag, removedlock, Ttimeflag;
int r;
- int changedRCS, changework, newhead;
+ int changedRCS, changework, dolog, newhead;
int usestatdate; /* Use mod time of file for -d. */
mode_t newworkmode; /* mode for working file */
+ time_t mtime, wtime;
struct hshentry *workdelta;
-
+
setrid();
- author = rev = state = textfile = nil;
- lockflag = false;
+ author = rev = state = textfile = 0;
+ initflag = lockflag = mustread = false;
mtimeflag = false;
+ Ttimeflag = false;
altdate[0]= '\0'; /* empty alternate date for -d */
usestatdate=false;
suffixes = X_DEFAULT;
+ nextassoc = &assoclst;
argc = getRCSINIT(argc, argv, &newargv);
argv = newargv;
@@ -274,7 +315,13 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
switch (*a++) {
case 'r':
+ if (*a)
+ goto revno;
keepworkingfile = lockflag = false;
+ break;
+
+ case 'l':
+ keepworkingfile = lockflag = true;
revno:
if (*a) {
if (rev) warn("redefinition of revision number");
@@ -282,14 +329,18 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
}
break;
- case 'l':
- keepworkingfile=lockflag=true;
- goto revno;
-
case 'u':
keepworkingfile=true; lockflag=false;
goto revno;
+ case 'i':
+ initflag = true;
+ goto revno;
+
+ case 'j':
+ mustread = true;
+ goto revno;
+
case 'I':
interactiveflag = true;
goto revno;
@@ -310,7 +361,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
if (msg.size) redefined('m');
msg = cleanlogmsg(a, strlen(a));
if (!msg.size)
- warn("missing message for -m option");
+ error("missing message for -m option");
break;
case 'n':
@@ -318,7 +369,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
error("missing symbolic name after -n");
break;
}
- checksid(a);
+ checkssym(a);
addassoclst(false, a);
break;
@@ -327,7 +378,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
error("missing symbolic name after -N");
break;
}
- checksid(a);
+ checkssym(a);
addassoclst(true, a);
break;
@@ -337,7 +388,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
checksid(a);
state = a;
} else
- warn("missing state for -s option");
+ error("missing state for -s option");
break;
case 't':
@@ -350,7 +401,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
case 'd':
if (altdate[0] || usestatdate)
redefined('d');
- altdate[0] = 0;
+ altdate[0] = '\0';
if (!(usestatdate = !*a))
str2date(a, altdate);
break;
@@ -365,7 +416,7 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
checksid(a);
author = a;
} else
- warn("missing author for -w option");
+ error("missing author for -w option");
break;
case 'x':
@@ -376,26 +427,34 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
setRCSversion(*argv);
break;
+ case 'z':
+ zone_set(a);
+ break;
-
+ case 'T':
+ if (!*a) {
+ Ttimeflag = true;
+ break;
+ }
+ /* fall into */
default:
- faterror("unknown option: %s%s", *argv, cmdusage);
+ error("unknown option: %s%s", *argv, cmdusage);
};
} /* end processing of options */
- if (argc<1) faterror("no input file%s", cmdusage);
-
- /* now handle all filenames */
- do {
- targetdelta=nil;
+ /* Handle all pathnames. */
+ if (nerror) cleanup();
+ else if (argc < 1) faterror("no input file%s", cmdusage);
+ else for (; 0 < argc; cleanup(), ++argv, --argc) {
+ targetdelta = 0;
ffree();
- switch (pairfilenames(argc, argv, rcswriteopen, false, false)) {
+ switch (pairnames(argc, argv, rcswriteopen, mustread, false)) {
case -1: /* New RCS file */
# if has_setuid && has_getuid
if (euid() != ruid()) {
- error("setuid initial checkin prohibited; use `rcs -i -a' first");
+ workerror("setuid initial checkin prohibited; use `rcs -i -a' first");
continue;
}
# endif
@@ -406,38 +465,52 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
continue;
case 1: /* Normal checkin with prev . RCS file */
+ if (initflag) {
+ rcserror("already exists");
+ continue;
+ }
rcsinitflag = !Head;
}
- /* now RCSfilename contains the name of the RCS file, and
- * workfilename contains the name of the working file.
+ /*
+ * RCSname contains the name of the RCS file, and
+ * workname contains the name of the working file.
* If the RCS file exists, finptr contains the file descriptor for the
- * RCS file. The admin node is initialized.
- * RCSstat is set.
+ * RCS file, and RCSstat is set. The admin node is initialized.
*/
- diagnose("%s <-- %s\n", RCSfilename,workfilename);
+ diagnose("%s <-- %s\n", RCSname, workname);
- if (!(workptr = Iopen(workfilename, FOPEN_R_WORK, &workstat))) {
- eerror(workfilename);
+ if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
+ eerror(workname);
continue;
}
- if (finptr && !checkaccesslist()) continue; /* give up */
+
+ if (finptr) {
+ if (same_file(RCSstat, workstat, 0)) {
+ rcserror("RCS file is the same as working file %s.",
+ workname
+ );
+ continue;
+ }
+ if (!checkaccesslist())
+ continue;
+ }
krev = rev;
if (keepflag) {
/* get keyword values from working file */
if (!getoldkeys(workptr)) continue;
if (!rev && !*(krev = prevrev.string)) {
- error("can't find a revision number in %s",workfilename);
+ workerror("can't find a revision number");
continue;
}
if (!*prevdate.string && *altdate=='\0' && usestatdate==false)
- warn("can't find a date in %s", workfilename);
+ workwarn("can't find a date");
if (!*prevauthor.string && !author)
- warn("can't find an author in %s", workfilename);
+ workwarn("can't find an author");
if (!*prevstate.string && !state)
- warn("can't find a state in %s", workfilename);
+ workwarn("can't find a state");
} /* end processing keepflag */
/* Read the delta tree. */
@@ -453,17 +526,20 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
continue;
newdelta.num = newdelnum.string;
- newdelta.branches=nil;
- newdelta.lockedby=nil; /*might be changed by addlock() */
+ newdelta.branches = 0;
+ newdelta.lockedby = 0; /* This might be changed by addlock(). */
newdelta.selector = true;
+ newdelta.name = 0;
+ clear_buf(&newdelta.ig);
+ clear_buf(&newdelta.igtext);
/* set author */
- if (author!=nil)
+ if (author)
newdelta.author=author; /* set author given by -w */
else if (keepflag && *prevauthor.string)
newdelta.author=prevauthor.string; /* preserve old author if possible*/
else newdelta.author=getcaller();/* otherwise use caller's id */
newdelta.state = default_state;
- if (state!=nil)
+ if (state)
newdelta.state=state; /* set state given by -s */
else if (keepflag && *prevstate.string)
newdelta.state=prevstate.string; /* preserve old state if possible */
@@ -479,9 +555,9 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
} else
newdelta.date = getcurdate(); /* use current date */
/* now check validity of date -- needed because of -d and -k */
- if (targetdelta!=nil &&
- cmpnum(newdelta.date,targetdelta->date) < 0) {
- error("Date %s precedes %s in existing revision %s.",
+ if (targetdelta &&
+ cmpdate(newdelta.date,targetdelta->date) < 0) {
+ rcserror("Date %s precedes %s in revision %s.",
date2str(newdelta.date, newdatebuf),
date2str(targetdelta->date, targetdatebuf),
targetdelta->num
@@ -490,48 +566,46 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
}
- if (lockflag && addlock(&newdelta) < 0) continue;
+ if (lockflag && addlock(&newdelta, true) < 0) continue;
+
+ if (keepflag && *prevname.string)
+ if (addsymbol(newdelta.num, prevname.string, false) < 0)
+ continue;
if (!addsyms(newdelta.num))
continue;
- putadmin(frewrite);
+ putadmin();
puttree(Head,frewrite);
putdesc(false,textfile);
- changework = Expand != OLD_EXPAND;
+ changework = Expand < MIN_UNCHANGED_EXPAND;
+ dolog = true;
lockthis = lockflag;
workdelta = &newdelta;
/* build rest of file */
if (rcsinitflag) {
- diagnose("initial revision: %s\n", newdelnum.string);
+ diagnose("initial revision: %s\n", newdelta.num);
/* get logmessage */
newdelta.log=getlogmsg();
- if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue;
+ putdftext(&newdelta, workptr, frewrite, false);
RCSstat.st_mode = workstat.st_mode;
+ RCSstat.st_nlink = 0;
changedRCS = true;
} else {
- diffilename = maketemp(0);
- workdiffname = workfilename;
- if (workdiffname[0] == '+') {
- /* Some diffs have options with leading '+'. */
- char *dp = ftnalloc(char, strlen(workfilename)+3);
- workdiffname = dp;
- *dp++ = '.';
- *dp++ = SLASH;
- VOID strcpy(dp, workfilename);
- }
+ diffname = maketemp(0);
newhead = Head == &newdelta;
if (!newhead)
foutptr = frewrite;
- expfilename = buildrevision(
+ expname = buildrevision(
gendeltas, targetdelta, (FILE*)0, false
);
if (
!forceciflag &&
+ strcmp(newdelta.state, targetdelta->state) == 0 &&
(changework = rcsfcmp(
- workptr, &workstat, expfilename, targetdelta
+ workptr, &workstat, expname, targetdelta
)) <= 0
) {
diagnose("file is unchanged; reverting to previous revision %s\n",
@@ -541,12 +615,8 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
diagnose("previous revision was not locked; ignoring -l option\n");
lockthis = 0;
}
- if (!(changedRCS =
- lockflag < removedlock
- || assoclst
- || newdelta.state != default_state
- && strcmp(newdelta.state, targetdelta->state) != 0
- ))
+ dolog = false;
+ if (! (changedRCS = lockflag<removedlock || assoclst))
workdelta = targetdelta;
else {
/*
@@ -555,20 +625,22 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
*/
long hwm = ftell(frewrite);
int bad_truncate;
- if (fseek(frewrite, 0L, SEEK_SET) != 0)
- Oerror();
+ Orewind(frewrite);
+
+ /*
+ * Work around a common ftruncate() bug:
+ * NFS won't let you truncate a file that you
+ * currently lack permissions for, even if you
+ * had permissions when you opened it.
+ * Also, Posix 1003.1b-1993 sec 5.6.7.2 p 128 l 1022
+ * says ftruncate might fail because it's not supported.
+ */
# if !has_ftruncate
- bad_truncate = 1;
-# else
- /*
- * Work around a common ftruncate() bug.
- * We can't rely on has_truncate, because we might
- * be using a filesystem exported to us via NFS.
- */
- bad_truncate = ftruncate(fileno(frewrite),(off_t)0);
- if (bad_truncate && errno != EACCES)
- Oerror();
+# undef ftruncate
+# define ftruncate(fd,length) (-1)
# endif
+ bad_truncate = ftruncate(fileno(frewrite), (off_t)0);
+
Irewind(finptr);
Lexinit();
getadmin();
@@ -581,11 +653,11 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
workdelta->log = targetdelta->log;
if (newdelta.state != default_state)
workdelta->state = newdelta.state;
- if (removedlock && removelock(workdelta)<0)
+ if (lockthis<removedlock && removelock(workdelta)<0)
continue;
if (!addsyms(workdelta->num))
continue;
- if (!dorewrite(true, true))
+ if (dorewrite(true, true) != 0)
continue;
fastcopy(finptr, frewrite);
if (bad_truncate)
@@ -595,48 +667,127 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
afputc('\n', frewrite);
}
} else {
+ int wfd = Ifileno(workptr);
+ struct stat checkworkstat;
+ char const *diffv[6 + !!OPEN_O_BINARY], **diffp;
+# if large_memory && !maps_memory
+ FILE *wfile = workptr->stream;
+ long wfile_off;
+# endif
+# if !has_fflush_input && !(large_memory && maps_memory)
+ off_t wfd_off;
+# endif
+
diagnose("new revision: %s; previous revision: %s\n",
- newdelnum.string, targetdelta->num
+ newdelta.num, targetdelta->num
);
newdelta.log = getlogmsg();
- switch (run((char*)0, diffilename,
- DIFF DIFF_FLAGS,
- newhead ? workdiffname : expfilename,
- newhead ? expfilename : workdiffname,
- (char*)0
- )) {
+# if !large_memory
+ Irewind(workptr);
+# if has_fflush_input
+ if (fflush(workptr) != 0)
+ Ierror();
+# endif
+# else
+# if !maps_memory
+ if (
+ (wfile_off = ftell(wfile)) == -1
+ || fseek(wfile, 0L, SEEK_SET) != 0
+# if has_fflush_input
+ || fflush(wfile) != 0
+# endif
+ )
+ Ierror();
+# endif
+# endif
+# if !has_fflush_input && !(large_memory && maps_memory)
+ wfd_off = lseek(wfd, (off_t)0, SEEK_CUR);
+ if (wfd_off == -1
+ || (wfd_off != 0
+ && lseek(wfd, (off_t)0, SEEK_SET) != 0))
+ Ierror();
+# endif
+ diffp = diffv;
+ *++diffp = DIFF;
+ *++diffp = DIFFFLAGS;
+# if OPEN_O_BINARY
+ if (Expand == BINARY_EXPAND)
+ *++diffp = "--binary";
+# endif
+ *++diffp = newhead ? "-" : expname;
+ *++diffp = newhead ? expname : "-";
+ *++diffp = 0;
+ switch (runv(wfd, diffname, diffv)) {
case DIFF_FAILURE: case DIFF_SUCCESS: break;
- default: faterror("diff failed");
+ default: rcsfaterror("diff failed");
}
+# if !has_fflush_input && !(large_memory && maps_memory)
+ if (lseek(wfd, wfd_off, SEEK_CUR) == -1)
+ Ierror();
+# endif
+# if large_memory && !maps_memory
+ if (fseek(wfile, wfile_off, SEEK_SET) != 0)
+ Ierror();
+# endif
if (newhead) {
Irewind(workptr);
- if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue;
- if (!putdtext(targetdelta->num,targetdelta->log,diffilename,frewrite,true)) continue;
+ putdftext(&newdelta, workptr, frewrite, false);
+ if (!putdtext(targetdelta,diffname,frewrite,true)) continue;
} else
- if (!putdtext(newdelnum.string,newdelta.log,diffilename,frewrite,true)) continue;
+ if (!putdtext(&newdelta,diffname,frewrite,true)) continue;
+
+ /*
+ * Check whether the working file changed during checkin,
+ * to avoid producing an inconsistent RCS file.
+ */
+ if (
+ fstat(wfd, &checkworkstat) != 0
+ || workstat.st_mtime != checkworkstat.st_mtime
+ || workstat.st_size != checkworkstat.st_size
+ ) {
+ workerror("file changed during checkin");
+ continue;
+ }
+
changedRCS = true;
}
}
- if (!donerewrite(changedRCS))
+
+ /* Deduce time_t of new revision if it is needed later. */
+ wtime = (time_t)-1;
+ if (mtimeflag | Ttimeflag)
+ wtime = date2time(workdelta->date);
+
+ if (donerewrite(changedRCS,
+ !Ttimeflag ? (time_t)-1
+ : finptr && wtime < RCSstat.st_mtime ? RCSstat.st_mtime
+ : wtime
+ ) != 0)
continue;
if (!keepworkingfile) {
Izclose(&workptr);
- r = un_link(workfilename); /* Get rid of old file */
+ r = un_link(workname); /* Get rid of old file */
} else {
newworkmode = WORKMODE(RCSstat.st_mode,
! (Expand==VAL_EXPAND || lockthis < StrictLocks)
);
- mtime = mtimeflag ? workdelta->date : (char const*)0;
+ mtime = mtimeflag ? wtime : (time_t)-1;
/* Expand if it might change or if we can't fix mode, time. */
if (changework || (r=fixwork(newworkmode,mtime)) != 0) {
Irewind(workptr);
/* Expand keywords in file. */
locker_expansion = lockthis;
+ workdelta->name =
+ namedrev(
+ assoclst ? assoclst->ssymbol
+ : keepflag && *prevname.string ? prevname.string
+ : rev,
+ workdelta
+ );
switch (xpandfile(
- workptr, workfilename,
- workdelta, &newworkfilename
+ workptr, workdelta, &newworkname, dolog
)) {
default:
continue;
@@ -651,24 +802,24 @@ mainProg(ciId, "ci", "$Id: ci.c,v 5.21 1991/11/20 17:58:07 eggert Exp $")
break;
/* fall into */
case 1:
- if (!(r = setfiledate(newworkfilename,mtime))) {
- Izclose(&workptr);
- ignoreints();
- r = chnamemod(&exfile, newworkfilename, workfilename, newworkmode);
- keepdirtemp(newworkfilename);
- restoreints();
- }
+ Izclose(&workptr);
+ aflush(exfile);
+ ignoreints();
+ r = chnamemod(&exfile, newworkname,
+ workname, 1, newworkmode, mtime
+ );
+ keepdirtemp(newworkname);
+ restoreints();
}
}
}
if (r != 0) {
- eerror(workfilename);
+ eerror(workname);
continue;
}
diagnose("done\n");
- } while (cleanup(),
- ++argv, --argc >=1);
+ }
tempunlink();
exitmain(exitstatus);
@@ -682,16 +833,17 @@ cleanup()
Izclose(&workptr);
Ozclose(&exfile);
Ozclose(&fcopy);
- Ozclose(&frewrite);
+ ORCSclose();
dirtempunlink();
}
-#if lint
+#if RCS_lint
# define exiterr ciExit
#endif
- exiting void
+ void
exiterr()
{
+ ORCSerror();
dirtempunlink();
tempunlink();
_exit(EXIT_FAILURE);
@@ -710,26 +862,28 @@ addelta()
*/
{
register char *tp;
- register unsigned i;
+ register int i;
int removedlock;
- unsigned newdnumlength; /* actual length of new rev. num. */
+ int newdnumlength; /* actual length of new rev. num. */
newdnumlength = countnumflds(newdelnum.string);
if (rcsinitflag) {
/* this covers non-existing RCS file and a file initialized with rcs -i */
- if ((newdnumlength==0)&&(Dbranch!=nil)) {
+ if (newdnumlength==0 && Dbranch) {
bufscpy(&newdelnum, Dbranch);
newdnumlength = countnumflds(Dbranch);
}
if (newdnumlength==0) bufscpy(&newdelnum, "1.1");
else if (newdnumlength==1) bufscat(&newdelnum, ".1");
else if (newdnumlength>2) {
- error("Branch point doesn't exist for %s.",newdelnum.string);
+ rcserror("Branch point doesn't exist for revision %s.",
+ newdelnum.string
+ );
return -1;
} /* newdnumlength == 2 is OK; */
Head = &newdelta;
- newdelta.next=nil;
+ newdelta.next = 0;
return 0;
}
if (newdnumlength==0) {
@@ -752,11 +906,11 @@ addelta()
} else if (!targetdelta->next && countnumflds(targetdelta->num)>2) {
/* new tip revision on side branch */
targetdelta->next= &newdelta;
- newdelta.next = nil;
+ newdelta.next = 0;
} else {
/* middle revision; start a new branch */
bufscpy(&newdelnum, "");
- return addbranch(targetdelta,&newdelnum);
+ return addbranch(targetdelta, &newdelnum, 1);
}
incnum(targetdelta->num, &newdelnum);
return 1; /* successful use of existing lock */
@@ -765,7 +919,7 @@ addelta()
/* no existing lock; try Dbranch */
/* update newdelnum */
if (StrictLocks || !myself(RCSstat.st_uid)) {
- error("no lock set by %s",getcaller());
+ rcserror("no lock set by %s", getcaller());
return -1;
}
if (Dbranch) {
@@ -787,8 +941,9 @@ addelta()
bufscat(&newdelnum, ".1");
}
if (cmpnum(newdelnum.string,Head->num) <= 0) {
- error("deltanumber %s too low; must be higher than %s",
- newdelnum.string, Head->num);
+ rcserror("revision %s too low; must be higher than %s",
+ newdelnum.string, Head->num
+ );
return -1;
}
targetdelta = Head;
@@ -803,44 +958,46 @@ addelta()
/* put new revision on side branch */
/*first, get branch point */
tp = newdelnum.string;
- for (i = newdnumlength - (newdnumlength&1 ^ 1); (--i); )
+ for (i = newdnumlength - ((newdnumlength&1) ^ 1); --i; )
while (*tp++ != '.')
- ;
+ continue;
*--tp = 0; /* Kill final dot to get old delta temporarily. */
- if (!(targetdelta=genrevs(newdelnum.string,(char*)nil,(char*)nil,(char*)nil,&gendeltas)))
+ if (!(targetdelta=genrevs(newdelnum.string,(char*)0,(char*)0,(char*)0,&gendeltas)))
return -1;
if (cmpnum(targetdelta->num, newdelnum.string) != 0) {
- error("can't find branchpoint %s", newdelnum.string);
+ rcserror("can't find branch point %s", newdelnum.string);
return -1;
}
*tp = '.'; /* Restore final dot. */
- return addbranch(targetdelta,&newdelnum);
+ return addbranch(targetdelta, &newdelnum, 0);
}
}
static int
-addbranch(branchpoint,num)
+addbranch(branchpoint, num, removedlock)
struct hshentry *branchpoint;
struct buf *num;
+ int removedlock;
/* adds a new branch and branch delta at branchpoint.
* If num is the null string, appends the new branch, incrementing
* the highest branch number (initially 1), and setting the level number to 1.
* the new delta and branchhead are in globals newdelta and newbranch, resp.
* the new number is placed into num.
* Return -1 on error, 1 if a lock is removed, 0 otherwise.
+ * If REMOVEDLOCK is 1, a lock was already removed.
*/
{
struct branchhead *bhead, **btrail;
struct buf branchnum;
- int removedlock, result;
- unsigned field, numlength;
+ int result;
+ int field, numlength;
static struct branchhead newbranch; /* new branch to be inserted */
numlength = countnumflds(num->string);
- if (branchpoint->branches==nil) {
+ if (!branchpoint->branches) {
/* start first branch */
branchpoint->branches = &newbranch;
if (numlength==0) {
@@ -848,7 +1005,7 @@ addbranch(branchpoint,num)
bufscat(num, ".1.1");
} else if (numlength&1)
bufscat(num, ".1");
- newbranch.nextbranch=nil;
+ newbranch.nextbranch = 0;
} else if (numlength==0) {
/* append new branch to the end */
@@ -860,10 +1017,10 @@ addbranch(branchpoint,num)
incnum(branchnum.string, num);
bufautoend(&branchnum);
bufscat(num, ".1");
- newbranch.nextbranch=nil;
+ newbranch.nextbranch = 0;
} else {
/* place the branch properly */
- field = numlength - (numlength&1 ^ 1);
+ field = numlength - ((numlength&1) ^ 1);
/* field of branch number */
btrail = &branchpoint->branches;
while (0 < (result=cmpnumfld(num->string,(*btrail)->hsh->num,field))) {
@@ -882,17 +1039,22 @@ addbranch(branchpoint,num)
/* branch exists; append to end */
bufautobegin(&branchnum);
getbranchno(num->string, &branchnum);
- targetdelta=genrevs(branchnum.string,(char*)nil,
- (char*)nil,(char*)nil,&gendeltas);
+ targetdelta = genrevs(
+ branchnum.string, (char*)0, (char*)0, (char*)0,
+ &gendeltas
+ );
bufautoend(&branchnum);
if (!targetdelta)
return -1;
if (cmpnum(num->string,targetdelta->num) <= 0) {
- error("deltanumber %s too low; must be higher than %s",
- num->string,targetdelta->num);
+ rcserror("revision %s too low; must be higher than %s",
+ num->string, targetdelta->num
+ );
return -1;
}
- if (0 <= (removedlock = removelock(targetdelta))) {
+ if (!removedlock
+ && 0 <= (removedlock = removelock(targetdelta))
+ ) {
if (numlength&1)
incnum(targetdelta->num,num);
targetdelta->next = &newdelta;
@@ -903,8 +1065,11 @@ addbranch(branchpoint,num)
}
}
newbranch.hsh = &newdelta;
- newdelta.next=nil;
- return 0;
+ newdelta.next = 0;
+ if (branchpoint->lockedby)
+ if (strcmp(branchpoint->lockedby, getcaller()) == 0)
+ return removelock(branchpoint); /* This returns 1. */
+ return removedlock;
}
static int
@@ -914,7 +1079,7 @@ addsyms(num)
register struct Symrev *p;
for (p = assoclst; p; p = p->nextsym)
- if (!addsymbol(num, p->ssymbol, p->override))
+ if (addsymbol(num, p->ssymbol, p->override) < 0)
return false;
return true;
}
@@ -966,7 +1131,7 @@ struct hshentry * delta;
* return 0; return 1 if a lock is actually removed.
*/
{
- register struct lock *next, **trail;
+ register struct rcslock *next, **trail;
char const *num;
num=delta->num;
@@ -978,12 +1143,12 @@ struct hshentry * delta;
delta->lockedby = 0;
return 1;
} else {
- error("revision %s locked by %s",num,next->login);
+ rcserror("revision %s locked by %s", num, next->login);
return -1;
}
if (!StrictLocks && myself(RCSstat.st_uid))
return 0;
- error("no lock set by %s for revision %s", getcaller(), num);
+ rcserror("no lock set by %s for revision %s", getcaller(), num);
return -1;
}
@@ -994,76 +1159,70 @@ getcurdate()
/* Return a pointer to the current date. */
{
static char buffer[datesize]; /* date buffer */
- time_t t;
- if (!buffer[0]) {
- t = time((time_t *)0);
- if (t == -1)
- faterror("time not available");
- time2date(t, buffer);
- }
+ if (!buffer[0])
+ time2date(now(), buffer);
return buffer;
}
static int
#if has_prototypes
-fixwork(mode_t newworkmode, char const *mtime)
+fixwork(mode_t newworkmode, time_t mtime)
/* The `#if has_prototypes' is needed because mode_t might promote to int. */
#else
fixwork(newworkmode, mtime)
mode_t newworkmode;
- char const *mtime;
+ time_t mtime;
#endif
{
- int r;
return
1 < workstat.st_nlink
- || newworkmode&S_IWUSR && !myself(workstat.st_uid)
+ || (newworkmode&S_IWUSR && !myself(workstat.st_uid))
+ || setmtime(workname, mtime) != 0
? -1
- :
- workstat.st_mode != newworkmode
- &&
- (r =
-# if has_fchmod
- fchmod(Ifileno(workptr), newworkmode)
-# else
- chmod(workfilename, newworkmode)
-# endif
- ) != 0
- ? r
- :
- setfiledate(workfilename, mtime);
+ : workstat.st_mode == newworkmode ? 0
+#if has_fchmod
+ : fchmod(Ifileno(workptr), newworkmode) == 0 ? 0
+#endif
+#if bad_chmod_close
+ : -1
+#else
+ : chmod(workname, newworkmode)
+#endif
+ ;
}
static int
-xpandfile(unexfile, dir, delta, exfilename)
+xpandfile(unexfile, delta, exname, dolog)
RILE *unexfile;
- char const *dir;
struct hshentry const *delta;
- char const **exfilename;
+ char const **exname;
+ int dolog;
/*
* Read unexfile and copy it to a
- * file in dir, performing keyword substitution with data from delta.
+ * file, performing keyword substitution with data from delta.
* Return -1 if unsuccessful, 1 if expansion occurred, 0 otherwise.
* If successful, stores the stream descriptor into *EXFILEP
- * and its name into *EXFILENAME.
+ * and its name into *EXNAME.
*/
{
- char const *targetfname;
+ char const *targetname;
int e, r;
- targetfname = makedirtemp(dir, 1);
- if (!(exfile = fopen(targetfname, FOPEN_W_WORK))) {
- eerror(targetfname);
- error("can't expand working file");
+ targetname = makedirtemp(1);
+ if (!(exfile = fopenSafer(targetname, FOPEN_W_WORK))) {
+ eerror(targetname);
+ workerror("can't build working file");
return -1;
}
r = 0;
- if (Expand == OLD_EXPAND)
+ if (MIN_UNEXPAND <= Expand)
fastcopy(unexfile,exfile);
else {
for (;;) {
- e = expandline(unexfile,exfile,delta,false,(FILE*)nil);
+ e = expandline(
+ unexfile, exfile, delta, false, (FILE*)0, dolog
+ );
if (e < 0)
break;
r |= e;
@@ -1071,8 +1230,7 @@ xpandfile(unexfile, dir, delta, exfilename)
break;
}
}
- *exfilename = targetfname;
- aflush(exfile);
+ *exname = targetname;
return r & 1;
}
@@ -1113,7 +1271,7 @@ getlogmsg()
/* generate std. log message */
caller = getcaller();
i = sizeof(ciklog)+strlen(caller)+3;
- bufalloc(&logbuf, i+datesize);
+ bufalloc(&logbuf, i + datesize + zonelenmax);
tp = logbuf.string;
VOID sprintf(tp, "%s%s at ", ciklog, caller);
VOID date2str(getcurdate(), tp+i);
@@ -1147,19 +1305,15 @@ getlogmsg()
static void
addassoclst(flag, sp)
-int flag;
-char * sp;
+ int flag;
+ char const *sp;
{
struct Symrev *pt;
pt = talloc(struct Symrev);
pt->ssymbol = sp;
pt->override = flag;
- pt->nextsym = nil;
- if (lastassoc)
- lastassoc->nextsym = pt;
- else
- assoclst = pt;
- lastassoc = pt;
- return;
+ pt->nextsym = 0;
+ *nextassoc = pt;
+ nextassoc = &pt->nextsym;
}
OpenPOWER on IntegriCloud