summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/rcs/ci
diff options
context:
space:
mode:
authoreadler <eadler@FreeBSD.org>2013-10-07 02:23:00 +0000
committereadler <eadler@FreeBSD.org>2013-10-07 02:23:00 +0000
commitba3f99676351684264da1513884a8aae3359a3fb (patch)
tree5fdf6b3f346166d536a79653631f395ca5f6a1fc /gnu/usr.bin/rcs/ci
parent34d055e746b4dad0722315b2096024ed9e08cd69 (diff)
downloadFreeBSD-src-ba3f99676351684264da1513884a8aae3359a3fb.zip
FreeBSD-src-ba3f99676351684264da1513884a8aae3359a3fb.tar.gz
Good bye RCS. You will be missed.
(devel/rcs and devel/rcs57 are available as alternatives) Approved by: core Approved by: re (hrs)
Diffstat (limited to 'gnu/usr.bin/rcs/ci')
-rw-r--r--gnu/usr.bin/rcs/ci/Makefile8
-rw-r--r--gnu/usr.bin/rcs/ci/ci.1898
-rw-r--r--gnu/usr.bin/rcs/ci/ci.c1318
3 files changed, 0 insertions, 2224 deletions
diff --git a/gnu/usr.bin/rcs/ci/Makefile b/gnu/usr.bin/rcs/ci/Makefile
deleted file mode 100644
index 2fbb74f..0000000
--- a/gnu/usr.bin/rcs/ci/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 1378af2..0000000
--- a/gnu/usr.bin/rcs/ci/ci.1
+++ /dev/null
@@ -1,898 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.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
-.SH NAME
-ci \- check in RCS revisions
-.SH SYNOPSIS
-.B ci
-.RI [ options ] " file " .\|.\|.
-.SH DESCRIPTION
-.B ci
-stores new revisions into \*r files.
-Each pathname matching an \*r suffix
-is taken to be an \*r file.
-All others
-are assumed to be working files containing new revisions.
-.B ci
-deposits the contents of each working file
-into the corresponding \*r file.
-If only a working file is given,
-.B ci
-tries to find the corresponding \*r file in an \*r subdirectory
-and then in the working file's directory.
-For more details, see
-.SM "FILE NAMING"
-below.
-.PP
-For
-.B ci
-to work, the caller's login must be on the access list,
-except if the access list is empty or the caller is the superuser or the
-owner of the file.
-To append a new revision to an existing branch, the tip revision on
-that branch must be locked by the caller. Otherwise, only a
-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 can be broken with the
-.B rcs
-command.
-.PP
-Unless the
-.B \-f
-option is given,
-.B ci
-checks whether the revision to be deposited differs from the preceding one.
-If not, instead of creating a new revision
-.B ci
-reverts to the preceding one.
-To revert, ordinary
-.B ci
-removes the working file and any lock;
-.B "ci\ \-l"
-keeps and
-.B "ci\ \-u"
-removes any lock, and then they both generate a new working file much as if
-.B "co\ \-l"
-or
-.B "co\ \-u"
-had been applied to the preceding revision.
-When reverting, any
-.B \-n
-and
-.B \-s
-options apply to the preceding revision.
-.PP
-For each revision deposited,
-.B ci
-prompts for a log message.
-The log message should summarize the change and must be terminated by
-end-of-file or by a line containing
-.BR \&. "\ by"
-itself.
-If several files are checked in
-.B ci
-asks whether to reuse the
-previous log message.
-If the standard input is not a terminal,
-.B ci
-suppresses the prompt
-and uses the same log message for all files.
-See also
-.BR \-m .
-.PP
-If the \*r file does not exist,
-.B ci
-creates it and
-deposits the contents of the working file as the initial revision
-(default number:
-.BR 1.1 ).
-The access list is initialized to empty.
-Instead of the log message,
-.B ci
-requests descriptive text (see
-.B \-t
-below).
-.PP
-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 ,
-.BR \-q ,
-.BR \-r ,
-or
-.BR \-u .
-.I rev
-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
-.BR $ ,
-.B ci
-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
-belongs, or must start a new branch.
-.PP
-If
-.I rev
-is a branch rather than a revision number,
-the new revision is appended to that branch. The level number is obtained
-by incrementing the tip revision number of that branch.
-If
-.I rev
-indicates a non-existing branch,
-that branch is created with the initial revision numbered
-.IB rev .1\f1.\fP
-.br
-.ne 8
-.PP
-If
-.I rev
-is omitted,
-.B ci
-tries to derive the new revision number from
-the caller's last lock. If the caller has locked the tip revision of a branch,
-the new revision is appended to that branch.
-The new revision number is obtained
-by incrementing the tip revision number.
-If the caller locked a non-tip revision, a new branch is started at
-that revision by incrementing the highest branch number at that revision.
-The default initial branch and level numbers are
-.BR 1 .
-.PP
-If
-.I rev
-is omitted and the caller has no lock, but owns
-the file and locking
-is not set to
-.IR strict ,
-then the revision is appended to the
-default branch (normally the trunk; see the
-.B \-b
-option of
-.BR rcs (1)).
-.PP
-Exception: On the trunk, revisions can be appended to the end, but
-not inserted.
-.SH OPTIONS
-.TP
-.BI \-r rev
-Check in revision
-.IR rev .
-.TP
-.BR \-r
-The bare
-.B \-r
-option (without any revision) has an unusual meaning in
-.BR ci .
-With other \*r commands, a bare
-.B \-r
-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
-options established by shell aliases or scripts.
-.TP
-.BR \-l [\f2rev\fP]
-works like
-.BR \-r ,
-except it performs an additional
-.B "co\ \-l"
-for the
-deposited revision. Thus, the deposited revision is immediately
-checked out again and locked.
-This is useful for saving a revision although one wants to continue
-editing it after the checkin.
-.TP
-.BR \-u [\f2rev\fP]
-works like
-.BR \-l ,
-except that the deposited revision is not locked.
-This lets one read the working file
-immediately after checkin.
-.RS
-.PP
-The
-.BR \-l ,
-bare
-.BR \-r ,
-and
-.B \-u
-options are mutually exclusive and silently override each other.
-For example,
-.B "ci\ \-u\ \-r"
-is equivalent to
-.B "ci\ \-r"
-because bare
-.B \-r
-overrides
-.BR \-u .
-.RE
-.TP
-.BR \-f [\f2rev\fP]
-forces a deposit; the new revision is deposited even it is not different
-from the preceding one.
-.TP
-.BR \-k [\f2rev\fP]
-searches the working file for keyword values to determine its revision number,
-creation date, state, and author (see
-.BR co (1)),
-and assigns these
-values to the deposited revision, rather than computing them locally.
-It also generates a default login message noting the login of the caller
-and the actual checkin date.
-This option is useful for software distribution. A revision that is sent to
-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 can be overridden
-with the options
-.BR \-d ,
-.BR \-m ,
-.BR \-s ,
-.BR \-w ,
-and any option that carries a revision number.
-.TP
-.BR \-q [\f2rev\fP]
-quiet mode; diagnostic output is not printed.
-A revision that is not different from the preceding one is not deposited,
-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
-even if the standard input is not a terminal.
-.TP
-.BR \-d "[\f2date\fP]"
-uses
-.I date
-for the checkin date and time.
-The
-.I date
-is specified in free format as explained in
-.BR co (1).
-This is useful for lying about the checkin date, and for
-.B \-k
-if no date is available.
-If
-.I date
-is empty, the working file's time of last modification is used.
-.TP
-.BR \-M [\f2rev\fP]
-Set the modification time on any new working file
-to be the date of the retrieved revision.
-For example,
-.BI "ci\ \-d\ \-M\ \-u" "\ f"
-does not alter
-.IR f 's
-modification time, even if
-.IR f 's
-contents change due to keyword substitution.
-Use this option with care; it can confuse
-.BR make (1).
-.TP
-.BI \-m "msg"
-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
-.I name
-to the number of the checked-in revision.
-.B ci
-prints an error message if
-.I name
-is already assigned to another
-number.
-.TP
-.BI \-N "name"
-same as
-.BR \-n ,
-except that it overrides a previous assignment of
-.IR name .
-.TP
-.BI \-s "state"
-sets the state of the checked-in revision to the identifier
-.IR state .
-The default state is
-.BR Exp .
-.TP
-.BI \-t file
-writes descriptive text from the contents of the named
-.I file
-into the \*r file,
-deleting the existing text.
-The
-.I file
-cannot begin with
-.BR \- .
-.TP
-.BI \-t\- string
-Write descriptive text from the
-.I string
-into the \*r file, deleting the existing text.
-.RS
-.PP
-The
-.B \-t
-option, in both its forms, has effect only during an initial checkin;
-it is silently ignored otherwise.
-.PP
-During the initial checkin, if
-.B \-t
-is not given,
-.B ci
-obtains the text from standard input,
-terminated by end-of-file or by a line containing
-.BR \&. "\ by"
-itself.
-The user is prompted for the text if interaction is possible; see
-.BR \-I .
-.PP
-For backward compatibility with older versions of \*r, a bare
-.B \-t
-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
-for the author field of the deposited revision.
-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 .
-See
-.BR co (1)
-for details.
-.TP
-.BI \-x "suffixes"
-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/ path
-or
-.IB path1 /RCS/ path2.
-The
-.B \-x
-option can specify a list of suffixes
-separated by
-.BR / .
-For example,
-.B \-x,v/
-specifies two suffixes:
-.B ,v
-and the empty suffix.
-If two or more suffixes are specified,
-they are tried in order when looking for an \*r file;
-the first one that works is used for that file.
-If no \*r file is found but an \*r file can be created,
-the suffixes are tried in order
-to determine the new \*r file's name.
-The default for
-.IR suffixes
-is installation-dependent; normally it is
-.B ,v/
-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 can be specified in three ways
-(see also the
-example section).
-.PP
-1) Both the \*r file and the working file are given. The \*r pathname is of
-the form
-.IB path1 / workfileX
-and the working pathname is of the form
-.IB path2 / workfile
-where
-.IB path1 /
-and
-.IB path2 /
-are (possibly different or empty) paths,
-.I workfile
-is a filename, and
-.I X
-is an \*r suffix.
-If
-.I X
-is empty,
-.IB path1 /
-must start with
-.B RCS/
-or must contain
-.BR /RCS/ .
-.PP
-2) Only the \*r file is given. Then the working file is created in the current
-directory and its name is derived from the name of the \*r file
-by removing
-.IB path1 /
-and the suffix
-.IR X .
-.PP
-3) Only the working file is given.
-Then
-.B ci
-considers each \*r suffix
-.I X
-in turn, looking for an \*r file of the form
-.IB path2 /RCS/ workfileX
-or (if the former is not found and
-.I X
-is nonempty)
-.IB path2 / workfileX.
-.PP
-If the \*r file is specified without a path in 1) and 2),
-.B ci
-looks for the \*r file first in the directory
-.B ./RCS
-and then in the current
-directory.
-.PP
-.B ci
-reports an error if an attempt to open an \*r file fails for an unusual reason,
-even if the \*r file's pathname is just one of several possibilities.
-For example, to suppress use of \*r commands in a directory
-.IR d ,
-create a regular file named
-.IB d /RCS
-so that casual attempts to use \*r commands in
-.I d
-fail because
-.IB d /RCS
-is not a directory.
-.SH EXAMPLES
-Suppose
-.B ,v
-is an \*r suffix and the current directory contains a subdirectory
-.B RCS
-with an \*r file
-.BR io.c,v .
-Then each of the following commands check in a copy of
-.B io.c
-into
-.B RCS/io.c,v
-as the latest revision, removing
-.BR io.c .
-.LP
-.RS
-.nf
-.ft 3
-ci io.c; ci RCS/io.c,v; ci io.c,v;
-ci io.c RCS/io.c,v; ci io.c io.c,v;
-ci RCS/io.c,v io.c; ci io.c,v io.c;
-.ft
-.fi
-.RE
-.PP
-Suppose instead that the empty suffix
-is an \*r suffix and the current directory contains a subdirectory
-.B RCS
-with an \*r file
-.BR io.c .
-The each of the following commands checks in a new revision.
-.LP
-.RS
-.nf
-.ft 3
-ci io.c; ci RCS/io.c;
-ci io.c RCS/io.c;
-ci RCS/io.c io.c;
-.ft
-.fi
-.RE
-.SH "FILE MODES"
-An \*r file created by
-.B ci
-inherits the read and execute permissions
-from the working file. If the \*r file exists already,
-.B ci
-preserves its read and execute permissions.
-.B ci
-always turns off all write permissions of \*r files.
-.SH FILES
-Temporary files are created in the directory containing
-the working file, and also in the temporary directory (see
-.B \s-1TMPDIR\s0
-under
-.BR \s-1ENVIRONMENT\s0 ).
-A semaphore file or files are created in the directory containing the \*r file.
-With a nonempty suffix, the semaphore names begin with
-the first character of the suffix; therefore, do not specify an suffix
-whose first character could be that of a working filename.
-With an empty suffix, the semaphore names end with
-.B _
-so working filenames should not end in
-.BR _ .
-.PP
-.B ci
-never changes an \*r or working file.
-Normally,
-.B ci
-unlinks the file and creates a new one;
-but instead of breaking a chain of one or more symbolic links to an \*r file,
-it unlinks the destination file instead.
-Therefore,
-.B ci
-breaks any hard or symbolic links to any working file it changes;
-and hard links to \*r files are ineffective,
-but symbolic links to \*r files are preserved.
-.PP
-The effective user must be able to
-search and write the directory containing the \*r file.
-Normally, the real user must be able to
-read the \*r and working files
-and to search and write the directory containing the working file;
-however, some older hosts
-cannot easily switch between real and effective users,
-so on these hosts the effective user is used for all accesses.
-The effective user is the same as the real user
-unless your copies of
-.B ci
-and
-.B co
-have setuid privileges.
-As described in the next section,
-these privileges yield extra security if
-the effective user owns all \*r files and directories,
-and if only the effective user can write \*r directories.
-.PP
-Users can control access to \*r files by setting the permissions
-of the directory containing the files; only users with write access
-to the directory can use \*r commands to change its \*r files.
-For example, in hosts that allow a user to belong to several groups,
-one can make a group's \*r directories writable to that group only.
-This approach suffices for informal projects,
-but it means that any group member can arbitrarily change the group's \*r files,
-and can even remove them entirely.
-Hence more formal projects sometimes distinguish between an \*r administrator,
-who can change the \*r files at will, and other project members,
-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'+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
-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
-system call supports saved setuid
-(the {\s-1_POSIX_SAVED_IDS\s0} behavior of Posix 1003.1-1990);
-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
-Choose a user
-.I A
-to serve as \*r administrator for the set of users.
-Only
-.I A
-can invoke the
-.B rcs
-command on the users' \*r files.
-.I A
-should not be
-.B root
-or any other user with special powers.
-Mutually suspicious sets of users should use different administrators.
-.IP \(bu \nn
-Choose a pathname
-.I B
-to be a directory of files to be executed by the users.
-.IP \(bu \nn
-Have
-.I A
-set up
-.I B
-to contain copies of
-.B ci
-and
-.B co
-that are setuid to
-.I A
-by copying the commands from their standard installation directory
-.I D
-as follows:
-.LP
-.RS
-.nf
-.ne 3
-\f3mkdir\fP \f2B\fP
-\f3cp\fP \f2D\fP\^\f3/c[io]\fP \f2B\fP
-\f3chmod go\-w,u+s\fP \f2B\fP\f3/c[io]\fP
-.fi
-.RE
-.IP \(bu \nn
-Have each user prepend
-.I B
-to their path as follows:
-.LP
-.RS
-.nf
-.ne 2
-\f3PATH=\fP\f2B\fP\f3:$PATH; export PATH\fP # ordinary shell
-\f3set path=(\fP\f2B\fP \f3$path)\fP # C shell
-.fi
-.RE
-.IP \(bu \nn
-Have
-.I A
-create each \*r directory
-.I R
-with write access only to
-.I A
-as follows:
-.LP
-.RS
-.nf
-.ne 2
-\f3mkdir\fP \f2R\fP
-\f3chmod go\-w\fP \f2R\fP
-.fi
-.RE
-.IP \(bu \nn
-If you want to let only certain users read the \*r files,
-put the users into a group
-.IR G ,
-and have
-.I A
-further protect the \*r directory as follows:
-.LP
-.RS
-.nf
-.ne 2
-\f3chgrp\fP \f2G R\fP
-\f3chmod g\-w,o\-rwx\fP \f2R\fP
-.fi
-.RE
-.IP \(bu \nn
-Have
-.I A
-copy old \*r files (if any) into
-.IR R ,
-to ensure that
-.I A
-owns them.
-.IP \(bu \nn
-An \*r file's access list limits who can check in and lock revisions.
-The default access list is empty,
-which grants checkin access to anyone who can read the \*r file.
-If you want limit checkin access,
-have
-.I A
-invoke
-.B "rcs\ \-a"
-on the file; see
-.BR rcs (1).
-In particular,
-.BI "rcs\ \-e\ \-a" A
-limits access to just
-.IR A .
-.IP \(bu \nn
-Have
-.I A
-initialize any new \*r files with
-.B "rcs\ \-i"
-before initial checkin, adding the
-.B \-a
-option if you want to limit checkin access.
-.IP \(bu \nn
-Give setuid privileges only to
-.BR ci ,
-.BR co ,
-and
-.BR rcsclean ;
-do not give them to
-.B rcs
-or to any other command.
-.IP \(bu \nn
-Do not use other setuid commands to invoke \*r commands;
-setuid is trickier than you think!
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-A backslash escapes spaces within an option.
-The
-.B \s-1RCSINIT\s0
-options are prepended to the argument lists of most \*r commands.
-Useful
-.B \s-1RCSINIT\s0
-options include
-.BR \-q ,
-.BR \-V ,
-.BR \-x ,
-and
-.BR \-z .
-.TP
-.B \s-1TMPDIR\s0
-Name of the temporary directory.
-If not set, the environment variables
-.B \s-1TMP\s0
-and
-.B \s-1TEMP\s0
-are inspected instead and the first value found is taken;
-if none of them are set,
-a host-dependent default is used, typically
-.BR /tmp .
-.SH DIAGNOSTICS
-For each revision,
-.B ci
-prints the \*r file, the working file, and the number
-of both the deposited and the preceding revision.
-The exit status is zero if and only if all operations were successful.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-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), setuid(2), rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.br
diff --git a/gnu/usr.bin/rcs/ci/ci.c b/gnu/usr.bin/rcs/ci/ci.c
deleted file mode 100644
index 749a4cf..0000000
--- a/gnu/usr.bin/rcs/ci/ci.c
+++ /dev/null
@@ -1,1318 +0,0 @@
-/* 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.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * 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.
- *
- * Revision 5.20 1991/10/07 17:32:46 eggert
- * Fix log bugs. Remove lint.
- *
- * Revision 5.19 1991/09/26 23:10:30 eggert
- * Plug file descriptor leak.
- *
- * Revision 5.18 1991/09/18 07:29:10 eggert
- * Work around a common ftruncate() bug.
- *
- * Revision 5.17 1991/09/10 22:15:46 eggert
- * Fix test for redirected stdin.
- *
- * Revision 5.16 1991/08/19 23:17:54 eggert
- * When there are no changes, revert to previous revision instead of aborting.
- * Add piece tables, -M, -r$. Tune.
- *
- * Revision 5.15 1991/04/21 11:58:14 eggert
- * Ensure that working file is newer than RCS file after ci -[lu].
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.14 1991/02/28 19:18:47 eggert
- * Don't let a setuid ci create a new RCS file; rcs -i -a must be run first.
- * Fix ci -ko -l mode bug. Open work file at most once.
- *
- * Revision 5.13 1991/02/25 07:12:33 eggert
- * getdate -> getcurdate (SVR4 name clash)
- *
- * Revision 5.12 1990/12/31 01:00:12 eggert
- * Don't use uninitialized storage when handling -{N,n}.
- *
- * Revision 5.11 1990/12/04 05:18:36 eggert
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.10 1990/11/05 20:30:10 eggert
- * Don't remove working file when aborting due to no changes.
- *
- * Revision 5.9 1990/11/01 05:03:23 eggert
- * Add -I and new -t behavior. Permit arbitrary data in logs.
- *
- * Revision 5.8 1990/10/04 06:30:09 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.7 1990/09/25 20:11:46 hammer
- * fixed another small typo
- *
- * Revision 5.6 1990/09/24 21:48:50 hammer
- * added cleanups from Paul Eggert.
- *
- * Revision 5.5 1990/09/21 06:16:38 hammer
- * made it handle multiple -{N,n}'s. Also, made it treat re-directed stdin
- * the same as the terminal
- *
- * Revision 5.4 1990/09/20 02:38:51 eggert
- * ci -k now checks dates more thoroughly.
- *
- * Revision 5.3 1990/09/11 02:41:07 eggert
- * Fix revision bug with `ci -k file1 file2'.
- *
- * Revision 5.2 1990/09/04 08:02:10 eggert
- * Permit adjacent revisions with identical time stamps (possible on fast hosts).
- * Improve incomplete line handling. Standardize yes-or-no procedure.
- *
- * Revision 5.1 1990/08/29 07:13:44 eggert
- * Expand locker value like co. Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:10:00 eggert
- * Don't require a final newline.
- * Make lock and temp files faster and safer.
- * Remove compile-time limits; use malloc instead.
- * Permit dates past 1999/12/31. Switch to GMT.
- * Add setuid support. Don't pass +args to diff. Check diff's output.
- * Ansify and Posixate. Add -k, -V. Remove snooping. Tune.
- * Check diff's output.
- *
- * Revision 4.9 89/05/01 15:10:54 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.8 88/11/08 13:38:23 narten
- * changes from root@seismo.CSS.GOV (Super User)
- * -d with no arguments uses the mod time of the file it is checking in
- *
- * Revision 4.7 88/08/09 19:12:07 eggert
- * Make sure workfile is a regular file; use its mode if RCSfile doesn't have one.
- * Use execv(), not system(); allow cc -R; remove lint.
- * isatty(fileno(stdin)) -> ttystdin()
- *
- * Revision 4.6 87/12/18 11:34:41 narten
- * lint cleanups (from Guy Harris)
- *
- * Revision 4.5 87/10/18 10:18:48 narten
- * Updating version numbers. Changes relative to revision 1.1 are actually
- * relative to 4.3
- *
- * Revision 1.3 87/09/24 13:57:19 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:21:33 jenkins
- * Port to suns
- *
- * Revision 4.3 83/12/15 12:28:54 wft
- * ci -u and ci -l now set mode of working file properly.
- *
- * Revision 4.2 83/12/05 13:40:54 wft
- * Merged with 3.9.1.1: added calls to clearerr(stdin).
- * made rewriteflag external.
- *
- * Revision 4.1 83/05/10 17:03:06 wft
- * Added option -d and -w, and updated assingment of date, etc. to new delta.
- * Added handling of default branches.
- * Option -k generates std. log message; fixed undef. pointer in reading of log.
- * Replaced getlock() with findlock(), link--unlink with rename(),
- * getpwuid() with getcaller().
- * Moved all revision number generation to new routine addelta().
- * Removed calls to stat(); now done by pairfilenames().
- * Changed most calls to catchints() with restoreints().
- * Directed all interactive messages to stderr.
- *
- * Revision 3.9.1.1 83/10/19 04:21:03 lepreau
- * Added clearerr(stdin) to getlogmsg() for re-reading stdin.
- *
- * Revision 3.9 83/02/15 15:25:44 wft
- * 4.2 prerelease
- *
- * Revision 3.9 83/02/15 15:25:44 wft
- * Added call to fastcopy() to copy remainder of RCS file.
- *
- * Revision 3.8 83/01/14 15:34:05 wft
- * Added ignoring of interrupts while new RCS file is renamed;
- * Avoids deletion of RCS files by interrupts.
- *
- * Revision 3.7 82/12/10 16:09:20 wft
- * Corrected checking of return code from diff.
- *
- * Revision 3.6 82/12/08 21:34:49 wft
- * Using DATEFORM to prepare date of checked-in revision;
- * Fixed return from addbranch().
- *
- * Revision 3.5 82/12/04 18:32:42 wft
- * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE. Updated
- * field lockedby in removelock(), moved getlogmsg() before calling diff.
- *
- * Revision 3.4 82/12/02 13:27:13 wft
- * added option -k.
- *
- * Revision 3.3 82/11/28 20:53:31 wft
- * Added mustcheckin() to check for redundant checkins.
- * Added xpandfile() to do keyword expansion for -u and -l;
- * -m appends linefeed to log message if necessary.
- * getlogmsg() suppresses prompt if stdin is not a terminal.
- * Replaced keeplock with lockflag, fclose() with ffclose(),
- * %02d with %.2d, getlogin() with getpwuid().
- *
- * Revision 3.2 82/10/18 20:57:23 wft
- * An RCS file inherits its mode during the first ci from the working file,
- * otherwise it stays the same, except that write permission is removed.
- * Fixed ci -l, added ci -u (both do an implicit co after the ci).
- * Fixed call to getlogin(), added call to getfullRCSname(), added check
- * for write error.
- * Changed conflicting identifiers.
- *
- * Revision 3.1 82/10/13 16:04:59 wft
- * fixed type of variables receiving from getc() (char -> int).
- * added include file dbm.h for getting BYTESIZ. This is used
- * to check the return code from diff portably.
- */
-
-#include "rcsbase.h"
-
-struct Symrev {
- char const *ssymbol;
- int override;
- struct Symrev * nextsym;
-};
-
-static char const *getcurdate P((void));
-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,time_t));
-static int removelock P((struct hshentry*));
-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 const*));
-
-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, **nextassoc;
-
-mainProg(ciId, "ci", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\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 + zonelenmax];
- char targetdatebuf[datesize + zonelenmax];
- char *a, **newargv, *textfile;
- char const *author, *krev, *rev, *state;
- char const *diffname, *expname;
- char const *newworkname;
- int initflag, mustread;
- int lockflag, lockthis, mtimeflag, removedlock, Ttimeflag;
- int r;
- 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 = 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;
- while (a = *++argv, 0<--argc && *a++=='-') {
- 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");
- rev = a;
- }
- break;
-
- 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;
-
- case 'q':
- quietflag=true;
- goto revno;
-
- case 'f':
- forceciflag=true;
- goto revno;
-
- case 'k':
- keepflag=true;
- goto revno;
-
- case 'm':
- if (msg.size) redefined('m');
- msg = cleanlogmsg(a, strlen(a));
- if (!msg.size)
- error("missing message for -m option");
- break;
-
- case 'n':
- if (!*a) {
- error("missing symbolic name after -n");
- break;
- }
- checkssym(a);
- addassoclst(false, a);
- break;
-
- case 'N':
- if (!*a) {
- error("missing symbolic name after -N");
- break;
- }
- checkssym(a);
- addassoclst(true, a);
- break;
-
- case 's':
- if (*a) {
- if (state) redefined('s');
- checksid(a);
- state = a;
- } else
- error("missing state for -s option");
- break;
-
- case 't':
- if (*a) {
- if (textfile) redefined('t');
- textfile = a;
- }
- break;
-
- case 'd':
- if (altdate[0] || usestatdate)
- redefined('d');
- altdate[0] = '\0';
- if (!(usestatdate = !*a))
- str2date(a, altdate);
- break;
-
- case 'M':
- mtimeflag = true;
- goto revno;
-
- case 'w':
- if (*a) {
- if (author) redefined('w');
- checksid(a);
- author = a;
- } else
- error("missing author for -w option");
- break;
-
- case 'x':
- suffixes = a;
- break;
-
- case 'V':
- setRCSversion(*argv);
- break;
-
- case 'z':
- zone_set(a);
- break;
-
- case 'T':
- if (!*a) {
- Ttimeflag = true;
- break;
- }
- /* fall into */
- default:
- error("unknown option: %s%s", *argv, cmdusage);
- };
- } /* end processing of options */
-
- /* 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 (pairnames(argc, argv, rcswriteopen, mustread, false)) {
-
- case -1: /* New RCS file */
-# if has_setuid && has_getuid
- if (euid() != ruid()) {
- workerror("setuid initial checkin prohibited; use `rcs -i -a' first");
- continue;
- }
-# endif
- rcsinitflag = true;
- break;
-
- case 0: /* Error */
- continue;
-
- case 1: /* Normal checkin with prev . RCS file */
- if (initflag) {
- rcserror("already exists");
- continue;
- }
- rcsinitflag = !Head;
- }
-
- /*
- * 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, and RCSstat is set. The admin node is initialized.
- */
-
- diagnose("%s <-- %s\n", RCSname, workname);
-
- if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
- eerror(workname);
- continue;
- }
-
- 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)) {
- workerror("can't find a revision number");
- continue;
- }
- if (!*prevdate.string && *altdate=='\0' && usestatdate==false)
- workwarn("can't find a date");
- if (!*prevauthor.string && !author)
- workwarn("can't find an author");
- if (!*prevstate.string && !state)
- workwarn("can't find a state");
- } /* end processing keepflag */
-
- /* Read the delta tree. */
- if (finptr)
- gettree();
-
- /* expand symbolic revision number */
- if (!fexpandsym(krev, &newdelnum, workptr))
- continue;
-
- /* splice new delta into tree */
- if ((removedlock = addelta()) < 0)
- continue;
-
- newdelta.num = newdelnum.string;
- 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)
- 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)
- newdelta.state=state; /* set state given by -s */
- else if (keepflag && *prevstate.string)
- newdelta.state=prevstate.string; /* preserve old state if possible */
- if (usestatdate) {
- time2date(workstat.st_mtime, altdate);
- }
- if (*altdate!='\0')
- newdelta.date=altdate; /* set date given by -d */
- else if (keepflag && *prevdate.string) {
- /* Preserve old date if possible. */
- str2date(prevdate.string, olddate);
- newdelta.date = olddate;
- } else
- newdelta.date = getcurdate(); /* use current date */
- /* now check validity of date -- needed because of -d and -k */
- 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
- );
- 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();
- puttree(Head,frewrite);
- putdesc(false,textfile);
-
- changework = Expand < MIN_UNCHANGED_EXPAND;
- dolog = true;
- lockthis = lockflag;
- workdelta = &newdelta;
-
- /* build rest of file */
- if (rcsinitflag) {
- diagnose("initial revision: %s\n", newdelta.num);
- /* get logmessage */
- newdelta.log=getlogmsg();
- putdftext(&newdelta, workptr, frewrite, false);
- RCSstat.st_mode = workstat.st_mode;
- RCSstat.st_nlink = 0;
- changedRCS = true;
- } else {
- diffname = maketemp(0);
- newhead = Head == &newdelta;
- if (!newhead)
- foutptr = frewrite;
- expname = buildrevision(
- gendeltas, targetdelta, (FILE*)0, false
- );
- if (
- !forceciflag &&
- strcmp(newdelta.state, targetdelta->state) == 0 &&
- (changework = rcsfcmp(
- workptr, &workstat, expname, targetdelta
- )) <= 0
- ) {
- diagnose("file is unchanged; reverting to previous revision %s\n",
- targetdelta->num
- );
- if (removedlock < lockflag) {
- diagnose("previous revision was not locked; ignoring -l option\n");
- lockthis = 0;
- }
- dolog = false;
- if (! (changedRCS = lockflag<removedlock || assoclst))
- workdelta = targetdelta;
- else {
- /*
- * We have started to build the wrong new RCS file.
- * Start over from the beginning.
- */
- long hwm = ftell(frewrite);
- int bad_truncate;
- 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
-# undef ftruncate
-# define ftruncate(fd,length) (-1)
-# endif
- bad_truncate = ftruncate(fileno(frewrite), (off_t)0);
-
- Irewind(finptr);
- Lexinit();
- getadmin();
- gettree();
- if (!(workdelta = genrevs(
- targetdelta->num, (char*)0, (char*)0, (char*)0,
- &gendeltas
- )))
- continue;
- workdelta->log = targetdelta->log;
- if (newdelta.state != default_state)
- workdelta->state = newdelta.state;
- if (lockthis<removedlock && removelock(workdelta)<0)
- continue;
- if (!addsyms(workdelta->num))
- continue;
- if (dorewrite(true, true) != 0)
- continue;
- fastcopy(finptr, frewrite);
- if (bad_truncate)
- while (ftell(frewrite) < hwm)
- /* White out any earlier mistake with '\n's. */
- /* This is unlikely. */
- 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",
- newdelta.num, targetdelta->num
- );
- newdelta.log = getlogmsg();
-# 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: 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);
- putdftext(&newdelta, workptr, frewrite, false);
- if (!putdtext(targetdelta,diffname,frewrite,true)) continue;
- } else
- 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;
- }
- }
-
- /* 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(workname); /* Get rid of old file */
- } else {
- newworkmode = WORKMODE(RCSstat.st_mode,
- ! (Expand==VAL_EXPAND || lockthis < StrictLocks)
- );
- 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, workdelta, &newworkname, dolog
- )) {
- default:
- continue;
-
- case 0:
- /*
- * No expansion occurred; try to reuse working file
- * unless we already tried and failed.
- */
- if (changework)
- if ((r=fixwork(newworkmode,mtime)) == 0)
- break;
- /* fall into */
- case 1:
- Izclose(&workptr);
- aflush(exfile);
- ignoreints();
- r = chnamemod(&exfile, newworkname,
- workname, 1, newworkmode, mtime
- );
- keepdirtemp(newworkname);
- restoreints();
- }
- }
- }
- if (r != 0) {
- eerror(workname);
- continue;
- }
- diagnose("done\n");
-
- }
-
- tempunlink();
- exitmain(exitstatus);
-} /* end of main (ci) */
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
- Izclose(&workptr);
- Ozclose(&exfile);
- Ozclose(&fcopy);
- ORCSclose();
- dirtempunlink();
-}
-
-#if RCS_lint
-# define exiterr ciExit
-#endif
- void
-exiterr()
-{
- ORCSerror();
- dirtempunlink();
- tempunlink();
- _exit(EXIT_FAILURE);
-}
-
-/*****************************************************************/
-/* the rest are auxiliary routines */
-
-
- static int
-addelta()
-/* Function: Appends a delta to the delta tree, whose number is
- * given by newdelnum. Updates Head, newdelnum, newdelnumlength,
- * and the links in newdelta.
- * Return -1 on error, 1 if a lock is removed, 0 otherwise.
- */
-{
- register char *tp;
- register int i;
- int removedlock;
- 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) {
- bufscpy(&newdelnum, Dbranch);
- newdnumlength = countnumflds(Dbranch);
- }
- if (newdnumlength==0) bufscpy(&newdelnum, "1.1");
- else if (newdnumlength==1) bufscat(&newdelnum, ".1");
- else if (newdnumlength>2) {
- rcserror("Branch point doesn't exist for revision %s.",
- newdelnum.string
- );
- return -1;
- } /* newdnumlength == 2 is OK; */
- Head = &newdelta;
- newdelta.next = 0;
- return 0;
- }
- if (newdnumlength==0) {
- /* derive new revision number from locks */
- switch (findlock(true, &targetdelta)) {
-
- default:
- /* found two or more old locks */
- return -1;
-
- case 1:
- /* found an old lock */
- /* check whether locked revision exists */
- if (!genrevs(targetdelta->num,(char*)0,(char*)0,(char*)0,&gendeltas))
- return -1;
- if (targetdelta==Head) {
- /* make new head */
- newdelta.next=Head;
- Head= &newdelta;
- } else if (!targetdelta->next && countnumflds(targetdelta->num)>2) {
- /* new tip revision on side branch */
- targetdelta->next= &newdelta;
- newdelta.next = 0;
- } else {
- /* middle revision; start a new branch */
- bufscpy(&newdelnum, "");
- return addbranch(targetdelta, &newdelnum, 1);
- }
- incnum(targetdelta->num, &newdelnum);
- return 1; /* successful use of existing lock */
-
- case 0:
- /* no existing lock; try Dbranch */
- /* update newdelnum */
- if (StrictLocks || !myself(RCSstat.st_uid)) {
- rcserror("no lock set by %s", getcaller());
- return -1;
- }
- if (Dbranch) {
- bufscpy(&newdelnum, Dbranch);
- } else {
- incnum(Head->num, &newdelnum);
- }
- newdnumlength = countnumflds(newdelnum.string);
- /* now fall into next statement */
- }
- }
- if (newdnumlength<=2) {
- /* add new head per given number */
- if(newdnumlength==1) {
- /* make a two-field number out of it*/
- if (cmpnumfld(newdelnum.string,Head->num,1)==0)
- incnum(Head->num, &newdelnum);
- else
- bufscat(&newdelnum, ".1");
- }
- if (cmpnum(newdelnum.string,Head->num) <= 0) {
- rcserror("revision %s too low; must be higher than %s",
- newdelnum.string, Head->num
- );
- return -1;
- }
- targetdelta = Head;
- if (0 <= (removedlock = removelock(Head))) {
- if (!genrevs(Head->num,(char*)0,(char*)0,(char*)0,&gendeltas))
- return -1;
- newdelta.next = Head;
- Head = &newdelta;
- }
- return removedlock;
- } else {
- /* put new revision on side branch */
- /*first, get branch point */
- tp = newdelnum.string;
- 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*)0,(char*)0,(char*)0,&gendeltas)))
- return -1;
- if (cmpnum(targetdelta->num, newdelnum.string) != 0) {
- rcserror("can't find branch point %s", newdelnum.string);
- return -1;
- }
- *tp = '.'; /* Restore final dot. */
- return addbranch(targetdelta, &newdelnum, 0);
- }
-}
-
-
-
- static int
-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 result;
- int field, numlength;
- static struct branchhead newbranch; /* new branch to be inserted */
-
- numlength = countnumflds(num->string);
-
- if (!branchpoint->branches) {
- /* start first branch */
- branchpoint->branches = &newbranch;
- if (numlength==0) {
- bufscpy(num, branchpoint->num);
- bufscat(num, ".1.1");
- } else if (numlength&1)
- bufscat(num, ".1");
- newbranch.nextbranch = 0;
-
- } else if (numlength==0) {
- /* append new branch to the end */
- bhead=branchpoint->branches;
- while (bhead->nextbranch) bhead=bhead->nextbranch;
- bhead->nextbranch = &newbranch;
- bufautobegin(&branchnum);
- getbranchno(bhead->hsh->num, &branchnum);
- incnum(branchnum.string, num);
- bufautoend(&branchnum);
- bufscat(num, ".1");
- newbranch.nextbranch = 0;
- } else {
- /* place the branch properly */
- field = numlength - ((numlength&1) ^ 1);
- /* field of branch number */
- btrail = &branchpoint->branches;
- while (0 < (result=cmpnumfld(num->string,(*btrail)->hsh->num,field))) {
- btrail = &(*btrail)->nextbranch;
- if (!*btrail) {
- result = -1;
- break;
- }
- }
- if (result < 0) {
- /* insert/append new branchhead */
- newbranch.nextbranch = *btrail;
- *btrail = &newbranch;
- if (numlength&1) bufscat(num, ".1");
- } else {
- /* branch exists; append to end */
- bufautobegin(&branchnum);
- getbranchno(num->string, &branchnum);
- targetdelta = genrevs(
- branchnum.string, (char*)0, (char*)0, (char*)0,
- &gendeltas
- );
- bufautoend(&branchnum);
- if (!targetdelta)
- return -1;
- if (cmpnum(num->string,targetdelta->num) <= 0) {
- rcserror("revision %s too low; must be higher than %s",
- num->string, targetdelta->num
- );
- return -1;
- }
- if (!removedlock
- && 0 <= (removedlock = removelock(targetdelta))
- ) {
- if (numlength&1)
- incnum(targetdelta->num,num);
- targetdelta->next = &newdelta;
- newdelta.next = 0;
- }
- return removedlock;
- /* Don't do anything to newbranch. */
- }
- }
- newbranch.hsh = &newdelta;
- newdelta.next = 0;
- if (branchpoint->lockedby)
- if (strcmp(branchpoint->lockedby, getcaller()) == 0)
- return removelock(branchpoint); /* This returns 1. */
- return removedlock;
-}
-
- static int
-addsyms(num)
- char const *num;
-{
- register struct Symrev *p;
-
- for (p = assoclst; p; p = p->nextsym)
- if (addsymbol(num, p->ssymbol, p->override) < 0)
- return false;
- return true;
-}
-
-
- static void
-incnum(onum,nnum)
- char const *onum;
- struct buf *nnum;
-/* Increment the last field of revision number onum by one and
- * place the result into nnum.
- */
-{
- register char *tp, *np;
- register size_t l;
-
- l = strlen(onum);
- bufalloc(nnum, l+2);
- np = tp = nnum->string;
- VOID strcpy(np, onum);
- for (tp = np + l; np != tp; )
- if (isdigit(*--tp)) {
- if (*tp != '9') {
- ++*tp;
- return;
- }
- *tp = '0';
- } else {
- tp++;
- break;
- }
- /* We changed 999 to 000; now change it to 1000. */
- *tp = '1';
- tp = np + l;
- *tp++ = '0';
- *tp = 0;
-}
-
-
-
- static int
-removelock(delta)
-struct hshentry * delta;
-/* function: Finds the lock held by caller on delta,
- * removes it, and returns nonzero if successful.
- * Print an error message and return -1 if there is no such lock.
- * An exception is if !StrictLocks, and caller is the owner of
- * the RCS file. If caller does not have a lock in this case,
- * return 0; return 1 if a lock is actually removed.
- */
-{
- register struct rcslock *next, **trail;
- char const *num;
-
- num=delta->num;
- for (trail = &Locks; (next = *trail); trail = &next->nextlock)
- if (next->delta == delta)
- if (strcmp(getcaller(), next->login) == 0) {
- /* We found a lock on delta by caller; delete it. */
- *trail = next->nextlock;
- delta->lockedby = 0;
- return 1;
- } else {
- rcserror("revision %s locked by %s", num, next->login);
- return -1;
- }
- if (!StrictLocks && myself(RCSstat.st_uid))
- return 0;
- rcserror("no lock set by %s for revision %s", getcaller(), num);
- return -1;
-}
-
-
-
- static char const *
-getcurdate()
-/* Return a pointer to the current date. */
-{
- static char buffer[datesize]; /* date buffer */
-
- if (!buffer[0])
- time2date(now(), buffer);
- return buffer;
-}
-
- static int
-#if has_prototypes
-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;
- time_t mtime;
-#endif
-{
- return
- 1 < workstat.st_nlink
- || (newworkmode&S_IWUSR && !myself(workstat.st_uid))
- || setmtime(workname, mtime) != 0
- ? -1
- : 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, delta, exname, dolog)
- RILE *unexfile;
- struct hshentry const *delta;
- char const **exname;
- int dolog;
-/*
- * Read unexfile and copy it to a
- * 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 *EXNAME.
- */
-{
- char const *targetname;
- int e, r;
-
- targetname = makedirtemp(1);
- if (!(exfile = fopenSafer(targetname, FOPEN_W_WORK))) {
- eerror(targetname);
- workerror("can't build working file");
- return -1;
- }
- r = 0;
- if (MIN_UNEXPAND <= Expand)
- fastcopy(unexfile,exfile);
- else {
- for (;;) {
- e = expandline(
- unexfile, exfile, delta, false, (FILE*)0, dolog
- );
- if (e < 0)
- break;
- r |= e;
- if (e <= 1)
- break;
- }
- }
- *exname = targetname;
- return r & 1;
-}
-
-
-
-
-/* --------------------- G E T L O G M S G --------------------------------*/
-
-
- static struct cbuf
-getlogmsg()
-/* Obtain and yield a log message.
- * If a log message is given with -m, yield that message.
- * If this is the initial revision, yield a standard log message.
- * Otherwise, reads a character string from the terminal.
- * Stops after reading EOF or a single '.' on a
- * line. getlogmsg prompts the first time it is called for the
- * log message; during all later calls it asks whether the previous
- * log message can be reused.
- */
-{
- static char const
- emptych[] = EMPTYLOG,
- initialch[] = "Initial revision";
- static struct cbuf const
- emptylog = { emptych, sizeof(emptych)-sizeof(char) },
- initiallog = { initialch, sizeof(initialch)-sizeof(char) };
- static struct buf logbuf;
- static struct cbuf logmsg;
-
- register char *tp;
- register size_t i;
- char const *caller;
-
- if (msg.size) return msg;
-
- if (keepflag) {
- /* generate std. log message */
- caller = getcaller();
- i = sizeof(ciklog)+strlen(caller)+3;
- bufalloc(&logbuf, i + datesize + zonelenmax);
- tp = logbuf.string;
- VOID sprintf(tp, "%s%s at ", ciklog, caller);
- VOID date2str(getcurdate(), tp+i);
- logmsg.string = tp;
- logmsg.size = strlen(tp);
- return logmsg;
- }
-
- if (!targetdelta && (
- cmpnum(newdelnum.string,"1.1")==0 ||
- cmpnum(newdelnum.string,"1.0")==0
- ))
- return initiallog;
-
- if (logmsg.size) {
- /*previous log available*/
- if (yesorno(true, "reuse log message of previous file? [yn](y): "))
- return logmsg;
- }
-
- /* now read string from stdin */
- logmsg = getsstdin("m", "log message", "", &logbuf);
-
- /* now check whether the log message is not empty */
- if (logmsg.size)
- return logmsg;
- return emptylog;
-}
-
-/* Make a linked list of Symbolic names */
-
- static void
-addassoclst(flag, sp)
- int flag;
- char const *sp;
-{
- struct Symrev *pt;
-
- pt = talloc(struct Symrev);
- pt->ssymbol = sp;
- pt->override = flag;
- pt->nextsym = 0;
- *nextassoc = pt;
- nextassoc = &pt->nextsym;
-}
OpenPOWER on IntegriCloud