home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
rcs
/
sources
/
checkin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-23
|
4KB
|
148 lines
#ifndef lint
static char rcsid[] = "$Id: checkin.c,v 1.10 89/11/19 23:19:46 berliner Exp $";
#endif
/*
* Copyright (c) 1989, 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.0 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 <ctype.h>
#include "cvs.h"
Checkin(revision, message)
char *revision;
char *message;
{
FILE *fp;
char fname[MAXPATHLEN];
char *tag;
int err = 0;
/*
* The revision that is passed in includes the "-r" option
* as well as a numeric revision, otherwise it is a pointer
* to a null string.
*/
if (revision[0] == '-')
tag = &revision[2];
else
tag = revision;
printf("Checking in %s;\n", User);
if (!use_editor)
printf("Log: %s\n", message);
(void) fflush(stdout);
(void) sprintf(Rcs, "%s%c%s%s", Repository, DIRSEP, User, RCSEXT);
(void) sprintf(fname, "%s%c%s%s", CVSADM, DIRSEP, CVSPREFIX, User);
/*
* 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.
*/
rename_file(User, fname);
copy_file(fname, User);
(void) sprintf(prog, "%s -f %s %s", RCS_CI, revision, Rcs);
if ((fp = popen(prog, "w")) == NULL) {
err++;
} else {
(void) fprintf(fp, "%s", message);
err = pclose(fp);
}
if (err == 0) {
/*
* 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.
*/
(void) sprintf(prog, "%s -q %s %s", RCS_CO, revision, Rcs);
(void) system(prog);
xchmod(User, 1); /* make it writable */
if (xcmp(User, fname) == 0)
rename_file(fname, User);
else
(void) unlink(fname);
/*
* If we want read-only files, muck the permissions here,
* before getting the user time-stamp.
*/
if (cvswrite == FALSE) {
xchmod(User, 0);
}
Version_TS(Rcs, tag, User);
Register(User, VN_Rcs, TS_User);
} else {
/*
* The checkin failed, for some unknown reason, so we restore
* the original user file, print an error, try to unlock the
* (supposedly locked) RCS file, and try to restore
* any default branches, if they applied for this file.
*/
rename_file(fname, User);
warn(0, "could not check in %s", User);
(void) sprintf(prog, "%s -u %s", RCS, Rcs);
if (system(prog) != 0)
warn(0, "could not UNlock %s", Rcs);
restore_branch();
return (1);
}
if (revision[0] != '\0') {
/*
* 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.
*/
(void) sprintf(prog, "%s -q -u %s 2>%s", RCS, Rcs, DEVNULL);
(void) system(prog);
}
return (0);
}
/*
* Called when the above checkin fails, because we may have to
* restore the default branch that existed before we attempted
* the checkin.
*
* Scan Blist for a match of the User file, and if it has a branch
* number tagged with it, do the "rcs -b" to set it back.
*/
static
restore_branch()
{
char blist[MAXLISTLEN];
char *cp, *user;
(void) strcpy(blist, Blist);
while ((cp = index(blist, ':')) != NULL) {
user = cp;
/*
* The next line is safe because we "know" that
* Blist always starts with a space if it has entries.
*/
while (!isspace(user[-1]))
user--;
*cp++ = '\0';
if (strcmp(User, user) == 0) {
(void) sprintf(prog, "%s -q -b%s %s", RCS, cp, Rcs);
if (system(prog) != 0)
warn(0, "cannot restore default branch %s for %s",
cp, Rcs);
return 0;
}
}
}