Subject: [netatalk-admins] movieplayer and such with afpd

From: a sun <[email-masked]>
Date: Tue, 25 Nov 1997 19:16:44 -0800 (PST)

i finally decided to figure out why movieplayer didn't like playing
stuff from an afpd volume. it turns out that file locking was being
done incorrectly. here's a synopsis of the fix which will be in my a18
patchset. if i get motiviated, i might even include fnctl()-based
byte-range locks. 

the following check in afp_openfork() isn't correct:
    if (access & ( OPENACC_WR|OPENACC_DRD )) {          /* exclusive lock */
        lockop = LOCK_EX;
    } else if (access & ( OPENACC_RD|OPENACC_DWR ))

the above will actually match either of the two perm bits instead of
both of them. the obvious fix is of course:

    if ( (access & ( OPENACC_WR|OPENACC_DRD )) ==
         (OPENACC_WR | OPENACC_DRD)) {          /* exclusive lock */
        lockop = LOCK_EX;
    } else if ( (access & ( OPENACC_RD|OPENACC_DWR )) ==
                (OPENACC_RD | OPENACC_DWR)) {   /* shared lock */

---

From: [email-masked]
Date: Sun, 14 Dec 1997 13:10:49 -0500

> From:    a sun <[email-masked]>
> To:      [email-masked], [email-masked]

> 		(OPENACC_RD | OPENACC_DWR)) {   /* shared lock */

Actually, the original code does the "correct" thing.  Consider this:
if you open a file OPENACC_WR, but don't get the exclusive lock, how
are you going to detect that someone already has opened the file
OPENACC_WR|OPENACC_DRD?

AFP defines four access modes.  Read, write, deny-read, and
deny-write.  RD, WR, dRD, and dWR.  If a file is opened dRD, RD must
fail, dWR, WR must fail.  RD and WR don't interact, and dRD and dWR
don't interact.  The original code was designed to be more restrictive
than the AFP spec.  To wit, dRD and WR generate a LOCK_EX, dWR and RD
generate a LOCK_SH.  This preserves the semantic that dWR and WR can't
both be set, and that dRD and RD can't both be set.  However, it adds
the semantic that WR blocks RD and WR.  Given that Unix only has two
operators, LOCK_EX and LOCK_SH, this is the obvious result.

I think that your code change has probably broken this semantic.  I'm
not sure if your byte-range locking code has fixed it.  It all requires
some analysis.

:wes