diff -up rcs-5.8/man/co.1in.sameuserlocks rcs-5.8/man/co.1in --- rcs-5.8/man/co.1in.sameuserlocks 2011-01-07 13:27:18.000000000 +0100 +++ rcs-5.8/man/co.1in 2011-09-08 11:41:09.545810466 +0200 @@ -318,6 +318,10 @@ Use this option with care; it can confus retrieves the latest revision on the selected branch whose state is set to .IR state . .TP +.BI \-S +Turns on same user locks. When this is enabled the user cannot check out +the same file twice. +.TP .B \-T Preserve the modification time on the \*o even if the \*o changes because a lock is added or removed. diff -up rcs-5.8/src/b-excwho.c.sameuserlocks rcs-5.8/src/b-excwho.c --- rcs-5.8/src/b-excwho.c.sameuserlocks 2011-01-07 13:27:18.000000000 +0100 +++ rcs-5.8/src/b-excwho.c 2011-09-08 11:41:09.546810466 +0200 @@ -205,9 +205,9 @@ getcaller (void) } bool -caller_login_p (char const *login) +caller_login_p (char const *login, int sameuserlocks) { - return STR_SAME (getcaller (), login); + return STR_SAME (getcaller (), login) && !sameuserlocks; } struct link * @@ -255,7 +255,7 @@ lock_drop (struct link *box, struct link } int -addlock (struct delta *delta, bool verbose) +addlock (struct delta *delta, bool verbose, int sameuserlocks) /* Add a lock held by caller to ‘delta’ and return 1 if successful. Print an error message if ‘verbose’ and return -1 if no lock is added because ‘delta’ is locked by somebody other than caller. @@ -266,7 +266,7 @@ addlock (struct delta *delta, bool verbo if (was) { - if (caller_login_p (was->login)) + if (caller_login_p (was->login, sameuserlocks)) return 0; if (verbose) RERR ("Revision %s is already locked by %s.", delta->num, was->login); diff -up rcs-5.8/src/b-excwho.h.sameuserlocks rcs-5.8/src/b-excwho.h --- rcs-5.8/src/b-excwho.h.sameuserlocks 2011-01-07 13:27:18.000000000 +0100 +++ rcs-5.8/src/b-excwho.h 2011-09-08 11:43:06.424809351 +0200 @@ -27,11 +27,11 @@ extern void seteid (void); extern void setrid (void); extern char const *getusername (bool suspicious); extern char const *getcaller (void); -extern bool caller_login_p (char const *login); +extern bool caller_login_p (char const *login, int sameuserlocks); extern struct link *lock_memq (struct link *ls, bool loginp, void const *x); extern struct rcslock const *lock_on (struct delta const *delta); extern void lock_drop (struct link *box, struct link *tp); -extern int addlock (struct delta *delta, bool verbose); +extern int addlock (struct delta *delta, bool verbose, int sameuserlocks); /* Idioms. */ diff -up rcs-5.8/src/ci.c.sameuserlocks rcs-5.8/src/ci.c --- rcs-5.8/src/ci.c.sameuserlocks 2011-08-08 14:00:25.000000000 +0200 +++ rcs-5.8/src/ci.c 2011-09-08 11:41:09.585810465 +0200 @@ -153,7 +153,7 @@ removelock (struct delta *delta) return -1; } rl = tp->next->entry; - if (! caller_login_p (rl->login)) + if (! caller_login_p (rl->login, false)) { RERR ("revision %s locked by %s", num, rl->login); return -1; @@ -260,7 +260,7 @@ addbranch (struct delta *branchpoint, st newbranch.entry = &newdelta; newdelta.ilk = NULL; if (branchpoint->lockedby) - if (caller_login_p (branchpoint->lockedby)) + if (caller_login_p (branchpoint->lockedby, false)) return removelock (branchpoint); /* This returns 1. */ return removedlock; } @@ -1006,7 +1006,7 @@ main (int argc, char **argv) continue; } - if (lockflag && addlock (&newdelta, true) < 0) + if (lockflag && addlock (&newdelta, true, false) < 0) continue; if (keepflag && (pv = PREV (name))) diff -up rcs-5.8/src/co.c.sameuserlocks rcs-5.8/src/co.c --- rcs-5.8/src/co.c.sameuserlocks 2011-08-08 14:00:25.000000000 +0200 +++ rcs-5.8/src/co.c 2011-09-08 11:41:09.587810465 +0200 @@ -135,7 +135,7 @@ rmlock (struct delta const *delta) /* No lock on ‘delta’. */ return 0; rl = tp->next->entry; - if (!caller_login_p (rl->login)) + if (!caller_login_p (rl->login, false)) /* Found a lock on ‘delta’ by someone else. */ { RERR ("revision %s locked by %s; use co -r or rcs -u", @@ -441,6 +441,7 @@ main (int argc, char **argv) int changelock; int expmode, r, workstatstat; bool tostdout, Ttimeflag; + int sameuserlocks; char finaldate[datesize]; #if OPEN_O_BINARY int stdout_mode = 0; @@ -464,6 +465,7 @@ main (int argc, char **argv) BE (pe) = X_DEFAULT; tostdout = false; Ttimeflag = false; + sameuserlocks = false; argc = getRCSINIT (argc, argv, &newargv); argv = newargv; @@ -543,6 +545,14 @@ main (int argc, char **argv) } break; + case 'S': + /* + * Enable strict locks (i.e. even the same user cannot + * re-check out a file with a lock that he owns. + */ + sameuserlocks = true; + break; + case 'T': if (*a) goto unknown; @@ -699,7 +709,7 @@ main (int argc, char **argv) /* Check reservations. */ changelock = lockflag < 0 ? rmlock (targetdelta) - : lockflag == 0 ? 0 : addlock (targetdelta, true); + : lockflag == 0 ? 0 : addlock (targetdelta, true, sameuserlocks); if (changelock < 0 || (changelock && !checkaccesslist ()) diff -up rcs-5.8/src/rcsclean.c.sameuserlocks rcs-5.8/src/rcsclean.c --- rcs-5.8/src/rcsclean.c.sameuserlocks 2011-08-08 14:00:25.000000000 +0200 +++ rcs-5.8/src/rcsclean.c 2011-09-08 11:41:09.588810465 +0200 @@ -66,7 +66,7 @@ unlock (struct delta *delta) struct link box, *tp; if (delta && delta->lockedby - && caller_login_p (delta->lockedby) + && caller_login_p (delta->lockedby, false) && (box.next = GROK (locks)) && (tp = lock_delta_memq (&box, delta))) { diff -up rcs-5.8/src/rcs.c.sameuserlocks rcs-5.8/src/rcs.c --- rcs-5.8/src/rcs.c.sameuserlocks 2011-08-08 13:58:59.000000000 +0200 +++ rcs-5.8/src/rcs.c 2011-09-08 11:41:09.590810465 +0200 @@ -495,7 +495,7 @@ breaklock (struct delta const *delta) } rl = tp->next->entry; before = rl->login; - if (!caller_login_p (before) + if (!caller_login_p (before, false) && !sendmail (num, before)) { RERR ("revision %s still locked by %s", num, before); @@ -794,8 +794,8 @@ setlock (char const *rev, struct wlink * RERR ("can't lock nonexisting revision %s", numrev.string); else { - if ((r = addlock (target, false)) < 0 && breaklock (target)) - r = addlock (target, true); + if ((r = addlock (target, false, false)) < 0 && breaklock (target)) + r = addlock (target, true, false); if (0 <= r) { if (r) diff -up rcs-5.8/src/rcsedit.c.sameuserlocks rcs-5.8/src/rcsedit.c --- rcs-5.8/src/rcsedit.c.sameuserlocks 2011-08-08 14:00:25.000000000 +0200 +++ rcs-5.8/src/rcsedit.c 2011-09-08 11:41:09.591810465 +0200 @@ -1086,11 +1086,11 @@ checkaccesslist (void) { struct link *ls = GROK (access); - if (!ls || stat_mine_p (&REPO (stat)) || caller_login_p ("root")) + if (!ls || stat_mine_p (&REPO (stat)) || caller_login_p ("root", false)) return true; for (; ls; ls = ls->next) - if (caller_login_p (ls->entry)) + if (caller_login_p (ls->entry, false)) return true; RERR ("user %s not on the access list", getcaller ());