386BSD 0.1 development
[unix-history] / usr / othersrc / public / cvs-1.3 / src / checkin.c
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS 1.3 kit.
*
* Check In
*
* Does a very careful checkin of the file "user", and tries not to spoil its
* modification time (to avoid needless recompilations). When RCS ID keywords
* get expanded on checkout, however, the modification time is updated and
* there is no good way to get around this.
*
* Returns non-zero on error.
*/
#include "cvs.h"
#ifndef lint
static char rcsid[] = "@(#)checkin.c 1.40 92/03/31";
#endif
int
Checkin (type, file, repository, rcs, rev, tag, message, entries)
int type;
char *file;
char *repository;
char *rcs;
char *rev;
char *tag;
char *message;
List *entries;
{
char fname[PATH_MAX];
Vers_TS *vers;
(void) printf ("Checking in %s;\n", file);
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
/*
* Move the user file to a backup file, so as to preserve its
* modification times, then place a copy back in the original file name
* for the checkin and checkout.
*/
if (!noexec)
copy_file (file, fname);
run_setup ("%s%s -f %s%s", Rcsbin, RCS_CI,
rev ? "-r" : "", rev ? rev : "");
run_args ("-m%s", message);
run_arg (rcs);
switch (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL))
{
case 0: /* everything normal */
/*
* The checkin succeeded, so now check the new file back out and
* see if it matches exactly with the one we checked in. If it
* does, just move the original user file back, thus preserving
* the modes; otherwise, we have no recourse but to leave the
* newly checkout file as the user file and remove the old
* original user file.
*/
/* XXX - make sure -k options are used on the co; and tag/date? */
run_setup ("%s%s -q %s%s", Rcsbin, RCS_CO,
rev ? "-r" : "", rev ? rev : "");
run_arg (rcs);
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
xchmod (file, 1);
if (xcmp (file, fname) == 0)
rename_file (fname, file);
else
(void) unlink_file (fname);
/*
* If we want read-only files, muck the permissions here, before
* getting the file time-stamp.
*/
if (cvswrite == FALSE)
xchmod (file, 0);
/* for added files with symbolic tags, need to add the tag too */
if (type == 'A' && tag && !isdigit (*tag))
{
run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, tag, rev);
run_arg (rcs);
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
}
/* re-register with the new data */
vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL,
file, 1, 1, entries, (List *) NULL);
if (strcmp (vers->options, "-V4") == 0)
vers->options[0] = '\0';
Register (entries, file, vers->vn_rcs, vers->ts_user, vers->options,
vers->tag, vers->date);
history_write (type, (char *) 0, vers->vn_rcs, file, repository);
freevers_ts (&vers);
break;
case -1: /* fork failed */
if (!noexec)
error (1, errno, "could not check in %s -- fork failed", file);
return (1);
default: /* ci failed */
/*
* The checkin failed, for some unknown reason, so we restore the
* original user file, print an error, and return an error
*/
if (!noexec)
{
rename_file (fname, file);
error (0, 0, "could not check in %s", file);
}
return (1);
}
/*
* When checking in a specific revision, we may have locked the wrong
* branch, so to be sure, we do an extra unlock here before
* returning.
*/
if (rev)
{
run_setup ("%s%s -q -u", Rcsbin, RCS);
run_arg (rcs);
(void) run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL);
}
return (0);
}