Retire ci(1), co(1), svclog(1)

Change-Id: I1bd1d92b9aacd4dfc4843c423862ae540fe2b557
This commit is contained in:
David van Moolenbroek 2015-09-20 15:33:41 +00:00
parent 33513d60e9
commit c0d9ad695c
10 changed files with 9 additions and 685 deletions

View file

@ -271,7 +271,7 @@
./usr/bin/chgrp minix-sys ./usr/bin/chgrp minix-sys
./usr/bin/chpass minix-sys ./usr/bin/chpass minix-sys
./usr/bin/chsh minix-sys ./usr/bin/chsh minix-sys
./usr/bin/ci minix-sys ./usr/bin/ci minix-sys obsolete
./usr/bin/cksum minix-sys ./usr/bin/cksum minix-sys
./usr/bin/clang++ minix-sys llvm,llvmcmds ./usr/bin/clang++ minix-sys llvm,llvmcmds
./usr/bin/clang minix-sys llvm,llvmcmds ./usr/bin/clang minix-sys llvm,llvmcmds
@ -280,7 +280,7 @@
./usr/bin/cleantmp minix-sys ./usr/bin/cleantmp minix-sys
./usr/bin/clear minix-sys ./usr/bin/clear minix-sys
./usr/bin/cmp minix-sys ./usr/bin/cmp minix-sys
./usr/bin/co minix-sys ./usr/bin/co minix-sys obsolete
./usr/bin/col minix-sys ./usr/bin/col minix-sys
./usr/bin/colcrt minix-sys ./usr/bin/colcrt minix-sys
./usr/bin/colrm minix-sys ./usr/bin/colrm minix-sys
@ -499,7 +499,7 @@
./usr/bin/strip minix-sys binutils ./usr/bin/strip minix-sys binutils
./usr/bin/su minix-sys ./usr/bin/su minix-sys
./usr/bin/sum minix-sys ./usr/bin/sum minix-sys
./usr/bin/svclog minix-sys ./usr/bin/svclog minix-sys obsolete
./usr/bin/svrctl minix-sys ./usr/bin/svrctl minix-sys
./usr/bin/swifi minix-sys ./usr/bin/swifi minix-sys
./usr/bin/synctree minix-sys ./usr/bin/synctree minix-sys
@ -2350,11 +2350,11 @@
./usr/man/man1/chmod.1 minix-sys ./usr/man/man1/chmod.1 minix-sys
./usr/man/man1/chpass.1 minix-sys ./usr/man/man1/chpass.1 minix-sys
./usr/man/man1/chsh.1 minix-sys ./usr/man/man1/chsh.1 minix-sys
./usr/man/man1/ci.1 minix-sys ./usr/man/man1/ci.1 minix-sys obsolete
./usr/man/man1/cksum.1 minix-sys ./usr/man/man1/cksum.1 minix-sys
./usr/man/man1/clear.1 minix-sys ./usr/man/man1/clear.1 minix-sys
./usr/man/man1/cmp.1 minix-sys ./usr/man/man1/cmp.1 minix-sys
./usr/man/man1/co.1 minix-sys ./usr/man/man1/co.1 minix-sys obsolete
./usr/man/man1/col.1 minix-sys ./usr/man/man1/col.1 minix-sys
./usr/man/man1/colcrt.1 minix-sys ./usr/man/man1/colcrt.1 minix-sys
./usr/man/man1/colrm.1 minix-sys ./usr/man/man1/colrm.1 minix-sys
@ -2589,7 +2589,7 @@
./usr/man/man1/stty.1 minix-sys ./usr/man/man1/stty.1 minix-sys
./usr/man/man1/su.1 minix-sys ./usr/man/man1/su.1 minix-sys
./usr/man/man1/sum.1 minix-sys ./usr/man/man1/sum.1 minix-sys
./usr/man/man1/svc.1 minix-sys ./usr/man/man1/svc.1 minix-sys obsolete
./usr/man/man1/svrctl.1 minix-sys ./usr/man/man1/svrctl.1 minix-sys
./usr/man/man1/synctree.1 minix-sys ./usr/man/man1/synctree.1 minix-sys
./usr/man/man1/sysenv.1 minix-sys ./usr/man/man1/sysenv.1 minix-sys

View file

@ -4,7 +4,7 @@
SUBDIR= add_route arp at backup \ SUBDIR= add_route arp at backup \
cawf cdprobe \ cawf cdprobe \
ci cleantmp co \ cleantmp \
compress crc cron crontab \ compress crc cron crontab \
decomp16 DESCRIBE devmand devsize dhcpd \ decomp16 DESCRIBE devmand devsize dhcpd \
dhrystone \ dhrystone \
@ -23,7 +23,7 @@ SUBDIR= add_route arp at backup \
remsync rget rlogin \ remsync rget rlogin \
rotate service setup \ rotate service setup \
slip spell sprofalyze sprofdiff srccrc \ slip spell sprofalyze sprofdiff srccrc \
svclog svrctl swifi synctree sysenv \ svrctl swifi synctree sysenv \
tcpd tcpdp tcpstat telnet \ tcpd tcpdp tcpstat telnet \
telnetd term termcap tget time \ telnetd term termcap tget time \
truncate udpstat umount \ truncate udpstat umount \

View file

@ -1,4 +0,0 @@
PROG= ci
MAN=
.include <bsd.prog.mk>

View file

@ -1,343 +0,0 @@
/* ci - check in Author: Peter S. Housel 12/17/87 */
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <pwd.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#define SUFFIX ",S" /* svc indicator */
#define SVCDIR "SVC" /* svc postfix indicator */
#define LINELEN 256 /* maximum line length */
#ifndef PATCH
#define FIX "fix $1 Fix.$1 > New.$1; mv New.$1 $1\n"
#else
#define FIX "patch -n -s $1 < Fix.$1; rm -f $1.orig\n"
#endif /* !PATCH */
#ifdef MAXPATHLEN
#define PATHLEN MAXPATHLEN
#else
#define PATHLEN 128 /* buffer length for filenames */
#endif
int unlocked = 0; /* leave unlocked after checkin */
int relock = 0; /* lock next revision after checkin */
char file[PATHLEN]; /* file to be checked in */
char svc[PATHLEN]; /* filename for svc file */
char newsvc[PATHLEN]; /* new copy of SVC file */
char line[LINELEN]; /* temporary line buffer */
char *p; /* scratch character pointer */
FILE *svcfp; /* svc file */
FILE *origfp, *newfp; /* "orig" and "new" temp files */
FILE *srcfp; /* source file */
int rev; /* new revision number */
int status; /* wait() buffer */
struct stat stb1, stb2; /* stat buffers for size compare */
char original[] = "/tmp/cioXXXXXX"; /* previous revision */
char diffout[] = "/tmp/cidXXXXXX"; /* diffs */
int main(int argc, char **argv);
void rundiff(void);
void logmsg(FILE *fp);
void fname(char *src, char *dst);
void svcname(char *src, char *dst);
int lockcheck(FILE *fp, int rev);
void onintr(int dummy);
void clean(void);
char *whoami(void);
int main(argc, argv)
int argc;
char **argv;
{
#ifdef perprintf
char errbuf[BUFSIZ];
setbuf(stderr, errbuf);
perprintf(stderr);
#endif
while (++argv, --argc) {
if ('-' == (*argv)[0]) {
if ('u' == (*argv)[1])
++unlocked;
else if ('l' == (*argv)[1])
++relock;
else {
fprintf(stderr, "ci: illegal option -%c\n", (*argv)[1]);
exit(1);
}
} else
break;
}
if (1 != argc) {
fprintf(stderr, "ci: bad number of files arguments\n");
exit(1);
}
fname(*argv, file);
svcname(file, svc);
fprintf(stderr, "%s -> %s\n", file, svc);
signal(SIGHUP, onintr);
signal(SIGINT, onintr);
signal(SIGTERM, onintr);
#ifndef BSD
if (NULL == (p = strrchr(file, '/')))
p = file;
else
++p;
if (strlen(p) > 13) {
fprintf(stderr, "ci: filename %s is too long\n", p);
exit(1);
}
#endif /* !BSD */
strcpy(newsvc, svc);
*(strrchr(newsvc, ',')) = ';'; /* temporary file will be "file;S" */
if (NULL == (newfp = fopen(newsvc, "w"))) {
perror("ci: can't create SVC temporary");
exit(1);
}
(void) mktemp(original);
(void) mktemp(diffout);
if (NULL != (svcfp = fopen(svc, "r"))) { /* does svc-file exist? */
fgets(line, LINELEN, svcfp);
if (1 != sscanf(line, "# %d", &rev)) {
fprintf(stderr, "ci: %s: illegal SVC file header\n", svc);
exit(1);
}
++rev;
if (!lockcheck(svcfp, rev)) {
fprintf(stderr, "Revision %d not locked\n", rev);
clean();
exit(1);
}
if (NULL == (origfp = fopen(original, "w"))) {
fprintf(stderr, "ci: can't create %s", original);
perror(" ");
}
fgets(line, LINELEN, svcfp); /* skip "cat <<***MAIN-eof***" line */
while (NULL != fgets(line, LINELEN, svcfp)
&& strcmp(line, "***MAIN-eof***\n")) {
fputs(line, origfp);
if (ferror(origfp)) {
perror("ci: origfile");
exit(1);
}
}
fclose(origfp);
rundiff();
if (0 != stat(original, &stb1) || 0 != stat(diffout, &stb2)) {
perror("ci: can't stat original or diffout");
clean();
exit(1);
}
} else { /* no - create one */
rev = 1;
}
fprintf(newfp, "# %d\n", rev);
fprintf(newfp, "cat <<***MAIN-eof*** >$1\n");
if (NULL == (srcfp = fopen(file, "r"))) {
perror("ci: can't read source file");
clean();
exit(1);
}
while (NULL != fgets(line, LINELEN, srcfp)) fputs(line, newfp);
fclose(srcfp);
fputs("***MAIN-eof***\n", newfp);
if (rev > 1) {
fprintf(newfp, "if test $2 -ge %d ; then rm -f Fix.$1 ; exit 0 ; fi ; cat <<***%d-eof*** >Fix.$1\n", rev, rev);
p = (stb1.st_size <= stb2.st_size) ? original : diffout;
if (NULL == (origfp = fopen(p, "r"))) {
perror("can't open diff output file");
clean();
exit(1);
}
while (NULL != fgets(line, LINELEN, origfp)) fputs(line, newfp);
fclose(origfp);
fprintf(newfp, "***%d-eof***\n", rev);
fputs((original == p) ? "mv Fix.$1 $1\n" : FIX, newfp);
logmsg(newfp);
while (NULL != fgets(line, LINELEN, svcfp) && strncmp(line, "#***SVCLOCK***", (size_t)14))
fputs(line, newfp);
} else {
logmsg(newfp);
fputs("rm -f Fix.$1\n", newfp);
}
if (relock) {
fprintf(stderr, "(relocking into revision %d)\n", rev + 1);
fprintf(newfp, "#***SVCLOCK*** %s %d\n", whoami(), rev + 1);
}
signal(SIGHUP, SIG_IGN); /* disable during critical section */
signal(SIGINT, SIG_IGN);
if (ferror(newfp) || fclose(newfp) || ((rev > 1) && unlink(svc))
|| link(newsvc, svc)) {
fprintf(stderr, "SVC file write/link error - Checkin aborted\n");
clean();
exit(1);
} else
fprintf(stderr, "Checkin complete.\n");
if (stat(svc, &stb1) < 0 || chmod(svc, stb1.st_mode & 0555) < 0)
perror("ci: can't chmod SVC file");
if (unlocked) {
if (stat(file, &stb1) < 0 || chmod(file, stb1.st_mode & 0555) < 0)
perror("ci: can't chmod source file");
} else if (relock) {
if (stat(file, &stb1) < 0 || chmod(file, stb1.st_mode | 0200) < 0)
perror("ci: can't chmod source file");
} else
unlink(file);
clean();
return(0);
}
void rundiff()
{ /* do "diff file original > diffout" */
int fd; /* redirected output file */
switch (fork()) {
case -1:
perror("ci: fork"); /* error */
clean();
exit(1);
case 0: /* child */
if ((fd = creat(diffout, 0600)) < 0 || -1 == dup2(fd, 1)) {
perror("ci: diffout");
clean();
exit(1);
}
close(fd);
execlp("diff", "diff", file, original, (char *) 0);
perror("ci: exec diff failed");
exit(1);
default: break; /* parent */
}
wait(&status);
if (0 != status && 1 << 8 != status) {
fprintf(stderr, "ci: bad return status (0x%x) from diff\n", status);
clean();
exit(1);
}
}
void logmsg(fp)
FILE *fp;
{
long now;
time(&now);
fprintf(stderr, "Enter log message for revision %d (end with ^D or '.'):\n", rev);
fprintf(fp, "#***SVC*** revision %d %s %s", rev, file, ctime(&now));
while (NULL != gets(line) && strcmp(line, "."))
fprintf(fp, "#***SVC*** %s\n", line);
}
void fname(src, dst)
char *src, *dst;
{
char *p;
strcpy(dst, src);
p = &dst[strlen(src) - strlen(SUFFIX)];
if (!strcmp(p, SUFFIX)) *p = '\0';
}
void svcname(src, dst)
char *src, *dst;
{
char *p;
strcpy(dst, src);
strcat(dst, SUFFIX);
if (0 != access(dst, 4)) {
char dirname[PATHLEN];
if (NULL != (p = strrchr(src, '/')))
strncpy(dirname, src, (size_t)(p - src + 1));
else
dirname[0] = '\0';
strcat(dirname, SVCDIR);
if (0 == access(dirname, 1)) {
strcpy(dst, dirname);
if (NULL == p) {
strcat(dst, "/");
strcat(dst, src);
} else
strcat(dst, p);
strcat(dst, SUFFIX);
}
}
}
int lockcheck(fp, rev)
FILE *fp;
int rev;
{
char lock[40], check[40];
long pos;
int ret;
sprintf(lock, "#***SVCLOCK*** %s %d\n", whoami(), rev);
pos = ftell(fp);
fseek(fp, -((long) strlen(lock)), 2);
fgets(check, 40, fp);
ret = (0 == strcmp(lock, check));
fseek(fp, pos, 0);
return ret;
}
void onintr(dummy)
int dummy; /* to keep the compiler happy */
{
fprintf(stderr, "Interrupt - Aborting checkin, cleaning up\n");
clean();
exit(1);
}
void clean()
{
if (strlen(original)) /* if only more programs made this check! */
unlink(original);
if (strlen(diffout)) unlink(diffout);
if (strlen(newsvc)) unlink(newsvc);
}
char *whoami()
{
struct passwd *pw;
if (NULL != (pw = getpwuid(getuid())))
return pw->pw_name;
else
return "nobody";
}

View file

@ -1,4 +0,0 @@
PROG= co
MAN=
.include <bsd.prog.mk>

View file

@ -1,252 +0,0 @@
/* co - check out Author: Peter S. Housel 12/24/87 */
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pwd.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define SUFFIX ",S" /* svc indicator */
#define SVCDIR "SVC" /* svc postfix indicator */
#define LINELEN 256 /* maximum line length */
#ifdef MAXPATHLEN
#define PATHLEN MAXPATHLEN
#else
#define PATHLEN 128 /* buffer length for filenames */
#endif
char file[PATHLEN]; /* file to be checked in */
char svc[PATHLEN]; /* filename for svc file */
char newsvc[PATHLEN]; /* new copy of SVC file */
char line[LINELEN]; /* temporary line buffer */
char *p; /* scratch character pointer */
FILE *svcfp; /* svc file */
int rev; /* old revision number */
int lastrev, lockrev; /* latest file revision, lock into */
int status; /* wait() buffer */
int svclock; /* lock the SVC file */
struct stat stb; /* stat() buffer */
char *base; /* basename of file */
char difftemp[PATHLEN]; /* extract() fix/patch input */
int main(int argc, char **argv);
void fname(char *src, char *dst);
void svcname(char *src, char *dst);
void extract(char *script, char *out, int rev);
char *basename(char *name);
char *whoami(void);
int getyn(void);
int main(argc, argv)
int argc;
char **argv;
{
#ifdef perprintf
char errbuf[BUFSIZ];
setbuf(stderr, errbuf);
perprintf(stderr);
#endif
while (++argv, --argc) {
if ('-' == (*argv)[0]) {
if ('r' == (*argv)[1]) {
--argc;
rev = atoi(*++argv);
if (rev < 1) {
fprintf(stderr, "Illegal revision number\n");
exit(1);
}
} else if ('l' == (*argv)[1])
++svclock;
else {
fprintf(stderr, "co: illegal option -%c\n", (*argv)[1]);
exit(1);
}
} else
break;
}
if (1 != argc) {
fprintf(stderr, "co: bad number of files arguments\n");
exit(1);
}
fname(*argv, file);
svcname(file, svc);
fprintf(stderr, "%s -> %s\n", svc, base = basename(file));
if (NULL == (svcfp = fopen(svc, "r"))) {
perror("co: can't read SVC file");
exit(1);
}
if (1 != fscanf(svcfp, "# %d", &lastrev) || lastrev < 1) {
fprintf(stderr, "co: illegal SVC file format\n");
exit(1);
}
fclose(svcfp);
if (stat(base, &stb) >= 0 && (stb.st_mode & 0222)) {
fprintf(stderr, "Writable %s exists - overwrite (n/y)? ", base);
if (!getyn()) {
fprintf(stderr, "Checkout aborted\n");
exit(1);
}
}
if (strlen(base)) unlink(base);
if (0 == rev) rev = lastrev;
fprintf(stderr, "Checking out revision %d", rev);
extract(svc, base, rev);
if (svclock) {
lockrev = lastrev + 1;
fprintf(stderr, "; Locking into revision %d\n", lockrev);
if (stat(svc, &stb) < 0 || chmod(svc, stb.st_mode | 0200) < 0)
perror("co: can't chmod SVC file");
if (stat(base, &stb) < 0 || chmod(base, stb.st_mode | 0200) < 0)
perror("co: can't chmod source file");
if (NULL == (svcfp = fopen(svc, "a"))
|| (fprintf(svcfp, "#***SVCLOCK*** %s %d\n", whoami(), lockrev), ferror(svcfp))) {
fprintf(stderr, "co: can't lock %s\n", svc);
exit(1);
}
if (stat(svc, &stb) < 0 || chmod(svc, stb.st_mode & 0555))
perror("co: can't chmod SVC file");
} else {
putchar('\n');
if (stat(base, &stb) < 0 || chmod(base, stb.st_mode & 0555))
perror("co: can't chmod source file");
}
return(0);
}
void fname(src, dst)
char *src, *dst;
{
char *p;
strcpy(dst, src);
p = &dst[strlen(src) - strlen(SUFFIX)];
if (!strcmp(p, SUFFIX)) *p = '\0';
}
void svcname(src, dst)
char *src, *dst;
{
char *p;
strcpy(dst, src);
strcat(dst, SUFFIX);
if (0 != access(dst, 4)) {
char dirname[PATHLEN];
if (NULL != (p = strrchr(src, '/')))
strncpy(dirname, src, (size_t)(p - src) + 1);
else
dirname[0] = '\0';
strcat(dirname, SVCDIR);
if (0 == access(dirname, 1)) {
strcpy(dst, dirname);
if (NULL == p) {
strcat(dst, "/");
strcat(dst, src);
} else
strcat(dst, p);
strcat(dst, SUFFIX);
}
}
}
void extract(script, out, rev)
char *script, *out;
int rev;
{
FILE *outfp;
int testrev;
char buf[80];
sprintf(difftemp, "Fix.%s", out);
svcfp = fopen(script, "r");
fgets(line, LINELEN, svcfp); /* skip '# rev' line */
fgets(line, LINELEN, svcfp); /* skip 'cat <***MAIN-eof***' line */
if (NULL == (outfp = fopen(out, "w"))) {
perror("co: can't create output file");
return;
}
while (NULL != fgets(line, LINELEN, svcfp) &&
strcmp(line, "***MAIN-eof***\n"))
fputs(line, outfp);
fclose(outfp);
while (NULL != fgets(line, LINELEN, svcfp)) {
if (!strncmp(line, "if ", (size_t)3)) {
sscanf(line, "if test $2 -ge %d", &testrev);
if (rev >= testrev) {
unlink(difftemp);
return;
}
if (NULL == (outfp = fopen(difftemp, "w"))) {
perror("co: can't create output file");
return;
}
sprintf(buf, "***%d-eof***\n", testrev);
while (NULL != fgets(line, LINELEN, svcfp) &&
strcmp(line, buf))
fputs(line, outfp);
fclose(outfp);
} else if (!strncmp(line, "mv ", (size_t)3)) {
sprintf(buf, "mv Fix.%s %s", out, out);
system(buf);
} else if (!strncmp(line, "fix ", (size_t)4)) {
sprintf(buf, "fix %s Fix.%s > New.%s; mv New.%s %s", out, out, out, out, out);
system(buf);
} else if (!strncmp(line, "patch ", (size_t)6)) {
sprintf(buf, "patch -n -s %s < Fix.%s; rm -f %s.orig", out, out, out);
system(buf);
} else { /* ignore */
}
}
unlink(difftemp);
return;
}
char *basename(name)
char *name;
{
char *p;
if (NULL == (p = strrchr(name, '/')))
return name;
else
return p + 1;
}
char *whoami()
{
struct passwd *pw;
if (NULL != (pw = getpwuid(getuid())))
return pw->pw_name;
else
return "nobody";
}
int getyn()
{
char ans[10];
return(NULL != fgets(ans, 10, stdin)) && ('y' == ans[0] || 'Y' == ans[0]);
}

View file

@ -1,4 +0,0 @@
SCRIPTS= svclog.sh
MAN=
.include <bsd.prog.mk>

View file

@ -1,6 +0,0 @@
#!/bin/sh
#
svc=`basename $1 ,S`,S
if test \( ! -r $svc \) -a -d "SVC" ; then svc=SVC/$svc ; fi
grep '^#\*\*\*SVC' $svc

View file

@ -14,7 +14,7 @@ MAN= at.1 \
playwave.1 prep.1 \ playwave.1 prep.1 \
profile.1 ps.1 recwave.1 \ profile.1 ps.1 recwave.1 \
remsync.1 rget.1 rlogin.1 rz.1 \ remsync.1 rget.1 rlogin.1 rz.1 \
spell.1 svc.1 svrctl.1 \ spell.1 svrctl.1 \
synctree.1 sysenv.1 sz.1 telnet.1 template.1 \ synctree.1 sysenv.1 sz.1 telnet.1 template.1 \
term.1 termcap.1 tget.1 time.1 \ term.1 termcap.1 tget.1 time.1 \
truncate.1 umount.1 \ truncate.1 umount.1 \
@ -22,7 +22,5 @@ MAN= at.1 \
yap.1 linkfarm.1 pkg_view.1 yap.1 linkfarm.1 pkg_view.1
MLINKS += compress.1 uncompress.1 MLINKS += compress.1 uncompress.1
MLINKS += svc.1 ci.1
MLINKS += svc.1 co.1
.include <bsd.man.mk> .include <bsd.man.mk>

View file

@ -1,61 +0,0 @@
.TH SVC 1
.SH NAME
svc, ci, co, svclog \- shell version control system
.SH SYNOPSIS
\fBci\fR [\fB\-lu\fR]\fR \fIfile\fR
.br
\fBco\fR [\fB\-l\fR]\fR [\fB\-r \fIrev\fR] \fIfile\fR
.br
\fBsvclog \fIfile\fR
.br
.de FL
.TP
\\fB\\$1\\fR
\\$2
..
.de EX
.TP 20
\\fB\\$1\\fR
# \\$2
..
.SH OPTIONS
.TP 5
.B \-l
# For \fIci\fR, checkin, checkout again, and lock file
.TP 5
.B \-l
# For \fIco\fR, checkout file and then lock the archive
.TP 5
.B \-u
# After checking in, do not delete the file
.TP 5
.B \-r
# Check out revision \fIrev\fR instead most recent revision
.SH EXAMPLES
.TP 20
.B ci \-u file
# Check in \fIfile\fR
.TP 20
.B co \-l file
# Check out \fIfile\fR and lock archive
.TP 20
.B co \-r 2 file
# Check out version 2
.SH DESCRIPTION
.PP
\fISvc\fR is the Shell Version Control system, patterned on RCS.
It maintains a sequence of versions in archive files, so that new versions
can be checked in (added to the archive), and old versions can be checked
out (made available).
To create an archive for \fIfile\fR, check it in with the \fB\-u\fR flag.
This action will prompt for a log message and then create an archive called
\fIfile,S\fR in the current directory, or in the subdirectory \fISVC\fR if
it exists.
The file will not be deleted, but will be made unwritable.
.PP
To update the file, check it out with the \fB\-l\fR flag.
Then modify it, and check it back in, giving a new message when prompted.
After this process has been repeated many times, the archive will contain
the entire history.
Any version can be checked out using the \fB\-r\fR flag.
To get a printout of the history, use \fIsvclog\fR.