mirror of
https://github.com/mabam/CAP.git
synced 2024-06-14 05:29:33 +00:00
706 lines
16 KiB
C
706 lines
16 KiB
C
/*
|
|
* $Author: djh $ $Date: 1995/06/26 05:49:55 $
|
|
* $Header: /local/mulga/mac/src/cap60/applications/aufs/RCS/afpfork.c,v 2.8 1995/06/26 05:49:55 djh Rel djh $
|
|
* $Revision: 2.8 $
|
|
*/
|
|
|
|
/*
|
|
* afpfork.c - Appletalk Filing Protocol Fork Level Routines
|
|
*
|
|
* AppleTalk package for UNIX (4.2 BSD).
|
|
*
|
|
* Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the
|
|
* City of New York.
|
|
*
|
|
* Edit History:
|
|
*
|
|
* March 1987 Schilit Created.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Non OS dependant support routines for:
|
|
*
|
|
* FPGetForkParms()
|
|
* FPSetForkParms()
|
|
* FPOpenFork()
|
|
* FPCloseFork()
|
|
* FPRead()
|
|
* FPWrite()
|
|
* FPFlushFork()
|
|
* FPByteRangeLock()
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <sys/param.h>
|
|
#ifndef _TYPES
|
|
/* assume included by param.h */
|
|
# include <sys/types.h>
|
|
#endif
|
|
#include <netat/appletalk.h>
|
|
#include <netat/afp.h>
|
|
#include <netat/afpcmd.h>
|
|
#include "afps.h"
|
|
#include "afpntoh.h"
|
|
#include "afposncs.h"
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
extern FILE *dbg;
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
typedef struct {
|
|
int ofn_fd; /* file descriptor */
|
|
sdword ofn_pos; /* file position */
|
|
IDirP ofn_ipdir;
|
|
int ofn_ivol;
|
|
int ofn_efn; /* external file number */
|
|
char ofn_fnam[MAXUFLEN]; /* file name */
|
|
int ofn_mode;
|
|
int ofn_type; /* data or rsrc */
|
|
int ofn_flgs; /* file flags */
|
|
#define OF_EOF 0x020 /* eof on file */
|
|
#define OF_NOTOPEN 0x02 /* to support non-existent files */
|
|
#define OF_INUSE 0x04 /* OFN is in use */
|
|
int ofn_trans_table; /* Translation table if any */
|
|
} OFN;
|
|
|
|
#define MaxOFN 30
|
|
|
|
private OFN OFNTBL[MaxOFN];
|
|
|
|
private int oinit = FALSE;
|
|
|
|
private
|
|
iniofn()
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i < MaxOFN; i++) {
|
|
OFNTBL[i].ofn_flgs = 0;
|
|
OFNTBL[i].ofn_pos = -1;
|
|
OFNTBL[i].ofn_trans_table = -1; /* no index */
|
|
OFNTBL[i].ofn_efn = i+1;
|
|
}
|
|
oinit = TRUE;
|
|
}
|
|
|
|
private word
|
|
ItoEOFN(o)
|
|
OFN *o;
|
|
{
|
|
return(o->ofn_efn);
|
|
}
|
|
|
|
private OFN *
|
|
EtoIOFN(i)
|
|
int i;
|
|
{
|
|
i = i-1;
|
|
if (i > MaxOFN || i < 0) {
|
|
printf("EtoIOFN: bad file number\n");
|
|
return(NULL);
|
|
}
|
|
if (!oinit || (OFNTBL[i].ofn_flgs & OF_INUSE) == 0) /* ofn assigned? */
|
|
return(NULL); /* no, mark as bad */
|
|
return(&OFNTBL[i]);
|
|
}
|
|
|
|
private void
|
|
relofn(ofn)
|
|
OFN *ofn;
|
|
{
|
|
ofn->ofn_flgs = 0;
|
|
ofn->ofn_pos = -1;
|
|
ofn->ofn_trans_table = -1; /* delete */
|
|
}
|
|
|
|
private OFN *
|
|
asnofn()
|
|
{
|
|
int i;
|
|
if (!oinit)
|
|
iniofn();
|
|
for (i=0; i < MaxOFN; i++)
|
|
if ((OFNTBL[i].ofn_flgs & OF_INUSE) == 0) {
|
|
OFNTBL[i].ofn_trans_table = -1; /* paranoia: no index */
|
|
OFNTBL[i].ofn_flgs = OF_INUSE;
|
|
return(&OFNTBL[i]);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* This is a horrible hack that is necessary to ensure that renames
|
|
* get reflected back. Really, really, points to the need for internal
|
|
* directory of names.... Can't use fstat because file name is required
|
|
* to return some of the information (from finderinfo). Sigh...
|
|
*
|
|
*/
|
|
OFNFIXUP(oipdir, ofile, nipdir, nfile)
|
|
IDirP oipdir;
|
|
char *ofile;
|
|
IDirP nipdir;
|
|
char *nfile;
|
|
{
|
|
OFN *ofn;
|
|
if (!oinit)
|
|
return(-1);
|
|
|
|
for (ofn = OFNTBL; ofn < OFNTBL+MaxOFN; ofn++)
|
|
if (ofn->ofn_flgs & OF_INUSE) {
|
|
if (ofn->ofn_ipdir == oipdir && strcmp(ofn->ofn_fnam, ofile) == 0) {
|
|
ofn->ofn_ipdir = nipdir; /* remember new directory */
|
|
strcpy(ofn->ofn_fnam, nfile); /* remember new file */
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* determine if file is already open
|
|
*
|
|
*/
|
|
|
|
int
|
|
is_open_file(ipdir, file)
|
|
IDirP ipdir;
|
|
char *file;
|
|
{
|
|
OFN *ofn;
|
|
|
|
if (!oinit)
|
|
return(0);
|
|
|
|
for (ofn = OFNTBL; ofn < OFNTBL+MaxOFN; ofn++)
|
|
if (ofn->ofn_flgs & OF_INUSE)
|
|
if (ofn->ofn_ipdir == ipdir
|
|
&& strcmp(ofn->ofn_fnam, file) == 0)
|
|
return(1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* OSErr FPGetForkParms(...)
|
|
*
|
|
* This call is used to retrieve parameters for a file associated with
|
|
* a particular open fork.
|
|
*
|
|
* Inputs:
|
|
* refnum Open fork refnum
|
|
* bitmap Bitmap describing which parameters are to be retrieved.
|
|
* This field is the same as the FPGetFileDirParms call.
|
|
*
|
|
* Outputs:
|
|
* Same as FPGetFileDirParms.
|
|
*
|
|
* Errors:
|
|
* ParamErr, BitMapErr, AccessDenied.
|
|
*
|
|
* The fork must be open for read.
|
|
*
|
|
*/
|
|
|
|
OSErr
|
|
FPGetForkParms(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
GetForkParmsPkt gfp;
|
|
FileDirParm fdp;
|
|
int err;
|
|
OFN *ofn;
|
|
|
|
ntohPackX(PsGetForkParms,p,l,(byte *) &gfp);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
void dbg_print_bmap();
|
|
fprintf(dbg, "\tRefNum: %d\n", gfp.gfp_refnum);
|
|
fprintf(dbg, "\tBitMap: %04x\t", gfp.gfp_bitmap);
|
|
dbg_print_bmap(gfp.gfp_bitmap, 0);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if ((ofn = EtoIOFN(gfp.gfp_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
|
|
fdp.fdp_pdirid = ItoEdirid(ofn->ofn_ipdir,ofn->ofn_ivol);
|
|
fdp.fdp_dbitmap = 0;
|
|
fdp.fdp_fbitmap = gfp.gfp_bitmap;
|
|
fdp.fdp_zero = 0;
|
|
err = OSFileDirInfo(ofn->ofn_ipdir,NILDIR,ofn->ofn_fnam,&fdp,ofn->ofn_ivol);
|
|
if (err != noErr)
|
|
return(err);
|
|
PackWord(gfp.gfp_bitmap,r);
|
|
*rl = 2;
|
|
*rl += htonPackX(FilePackR,(byte *) &fdp,r+(*rl));
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
void dbg_print_parm();
|
|
fprintf(dbg, " Return Parameters:\n");
|
|
dbg_print_parm(fdp.fdp_fbitmap, r+2, (*rl)-2, 0);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
return(noErr);
|
|
}
|
|
|
|
/*
|
|
* OSErr FPSetForkParms(...)
|
|
*
|
|
* Inputs:
|
|
*
|
|
* refnum Open fork refnum.
|
|
* bitmap Bitmap describing which params are to be set.
|
|
*
|
|
* Output:
|
|
* Function Result.
|
|
*
|
|
* Errors:
|
|
* ParamErr, BitMapErr, DiskFull, LockErr, AccessDenied.
|
|
*
|
|
* The bitmap is the same as FPSetFileDirParms, however in AFP 1.1
|
|
* only the fork length may be set.
|
|
*
|
|
* The fork must be opened for write.
|
|
*
|
|
*/
|
|
|
|
/*ARGSUSED*/
|
|
OSErr
|
|
FPSetForkParms(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
SetForkParmsPkt sfkp;
|
|
OFN *ofn;
|
|
sdword len;
|
|
|
|
ntohPackX(PsSetForkParms,p,l,(byte *) &sfkp);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
void dbg_print_bmap();
|
|
fprintf(dbg, "\tRefNum: %d\n", sfkp.sfkp_refnum);
|
|
fprintf(dbg, "\tBitMap: %04x\t", sfkp.sfkp_bitmap);
|
|
dbg_print_bmap(sfkp.sfkp_bitmap, 0);
|
|
fprintf(dbg, "\tForkLn: %d\n",
|
|
(sfkp.sfkp_bitmap & FP_DFLEN) ? sfkp.sfkp_dflen : sfkp.sfkp_rflen);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if ((ofn = EtoIOFN(sfkp.sfkp_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
|
|
if (DBFRK)
|
|
printf("FPSetForkParms: ofn=%d\n",sfkp.sfkp_refnum);
|
|
|
|
if ((sfkp.sfkp_bitmap & ~(FP_DFLEN|FP_RFLEN)) != 0 || sfkp.sfkp_bitmap==0) {
|
|
printf("FPSetForkParms: bad bitmap %x\n",sfkp.sfkp_bitmap);
|
|
return(aeBitMapErr);
|
|
}
|
|
|
|
len = (sfkp.sfkp_bitmap & FP_DFLEN) ? sfkp.sfkp_dflen : sfkp.sfkp_rflen;
|
|
/* can only set fork length for now */
|
|
return((ofn->ofn_flgs&OF_NOTOPEN) ? noErr : OSSetForklen(ofn->ofn_fd, len));
|
|
}
|
|
|
|
|
|
OSErr
|
|
FPOpenFork(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
OpenForkPkt ofk;
|
|
OpenForkReplyPkt ofr;
|
|
FileDirParm fdp;
|
|
int ivol,err,err1,flg,fhdl,len, ttidx;
|
|
IDirP idir,ipdir;
|
|
char file[MAXUFLEN];
|
|
byte finderinfo[FINFOLEN];
|
|
OFN *ofn;
|
|
extern PackEntry ProtoOFkRP[];
|
|
|
|
ntohPackX(PsOpenFork,p,l,(byte *) &ofk);
|
|
|
|
err = EtoIfile(file,&idir,&ipdir,&ivol,ofk.ofk_dirid,
|
|
ofk.ofk_volid,ofk.ofk_ptype,ofk.ofk_path);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
void dbg_print_mode();
|
|
void dbg_print_bmap();
|
|
void dbg_print_path();
|
|
fprintf(dbg, "\tOFork: %s\n", (ofk.ofk_rdflg) ? "Resource" : "Data");
|
|
fprintf(dbg, "\tVolID: %04x\n", ofk.ofk_volid);
|
|
fprintf(dbg, "\tDirID: %08x\n", ofk.ofk_dirid);
|
|
fprintf(dbg, "\tBtMap: %04x\t", ofk.ofk_bitmap);
|
|
dbg_print_bmap(ofk.ofk_bitmap, 0);
|
|
fprintf(dbg, "\tAMode: %04x\t", ofk.ofk_mode);
|
|
dbg_print_mode(ofk.ofk_mode);
|
|
fprintf(dbg, "\tPType: %d\t(%s Names)\n", ofk.ofk_ptype,
|
|
(ofk.ofk_ptype == 1) ? "Short" : "Long");
|
|
dbg_print_path(ofk.ofk_path);
|
|
if (err == noErr)
|
|
fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file);
|
|
else
|
|
fprintf(dbg, "\tUPath: <EtoIfile returned %d>\n", err);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if (err != noErr)
|
|
return(err);
|
|
|
|
if (DBFRK)
|
|
printf("OpenFork: rdflg=%d, mode=%d, path=%s file=%s\n",
|
|
ofk.ofk_rdflg,ofk.ofk_mode,pathstr(ipdir),file);
|
|
|
|
flg = (ofk.ofk_rdflg == 0) ? F_DATA : F_RSRC;
|
|
|
|
err = OSOpenFork(ipdir,file,ofk.ofk_mode,flg,&fhdl);
|
|
|
|
if (err != noErr
|
|
&& err != aeDenyConflict
|
|
&& !(flg == F_RSRC && err == aeObjectNotFound))
|
|
return(err);
|
|
|
|
/*
|
|
* now, if data fork exists and resource
|
|
* open failed, allow go ahead
|
|
*
|
|
*/
|
|
if (err == aeObjectNotFound) {
|
|
#ifdef notdef
|
|
/* why did I do this? */
|
|
if (ofk.ofk_mode & OFK_MWR) /* don't allow write access */
|
|
return(aeAccessDenied);
|
|
#endif
|
|
if (OSFileExists(ipdir, file, F_DATA) != noErr)
|
|
return(aeObjectNotFound);
|
|
else {
|
|
if (DBFRK)
|
|
printf("Allowing fake access to resource fork\n");
|
|
}
|
|
}
|
|
|
|
if ((ofn = asnofn()) == 0) {
|
|
if (err == noErr)
|
|
OSClose(fhdl);
|
|
return(aeTooManyFilesOpen);
|
|
}
|
|
ofn->ofn_fd = fhdl;
|
|
ofn->ofn_mode = ofk.ofk_mode;
|
|
ofn->ofn_type = flg;
|
|
ofn->ofn_ipdir = ipdir;
|
|
ofn->ofn_ivol = ivol;
|
|
|
|
if (err == aeObjectNotFound
|
|
|| err == aeDenyConflict)
|
|
ofn->ofn_flgs |= OF_NOTOPEN;
|
|
|
|
if (flg == F_DATA) {
|
|
/* Never translate resource fork */
|
|
OSGetFNDR(ipdir, file, finderinfo); /* check file type */
|
|
#ifdef SHORT_NAMES
|
|
if (DBFRK)
|
|
printf("afpfork, ofk.ofk_path %d\n",ofk.ofk_ptype);
|
|
if ((ttidx = ncs_istrans(finderinfo, file, ofk.ofk_ptype)) >= 0) {
|
|
#else SHORT_NAMES
|
|
if ((ttidx = ncs_istrans(finderinfo, file)) >= 0) {
|
|
#endif SHORT_NAMES
|
|
ofn->ofn_trans_table = ttidx;
|
|
if (DBFRK)
|
|
printf("Open fork: translation table: %s\n", ncs_tt_name(ttidx));
|
|
}
|
|
}
|
|
|
|
strcpy(ofn->ofn_fnam,file); /* remember file name (UGH!!!!) */
|
|
|
|
fdp.fdp_fbitmap = ofk.ofk_bitmap;
|
|
fdp.fdp_dbitmap = 0;
|
|
if ((err1 = OSFileDirInfo(ipdir,NILDIR,file,&fdp,ivol)) != noErr) {
|
|
if (err != noErr)
|
|
OSClose(fhdl);
|
|
relofn(ofn);
|
|
return(err1);
|
|
}
|
|
|
|
ofr.ofkr_bitmap = ofk.ofk_bitmap;
|
|
ofr.ofkr_refnum = (err == aeDenyConflict) ? 0x0000 : ItoEOFN(ofn);
|
|
len = htonPackX(ProtoOFkRP, &ofr, r); /* pack away */
|
|
*rl = len + htonPackX(FilePackR,(byte *) &fdp,r+len);
|
|
|
|
if (err == aeDenyConflict) {
|
|
relofn(ofn);
|
|
return(err);
|
|
}
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
void dbg_print_parm();
|
|
void dbg_print_bmap();
|
|
fprintf(dbg, " Return Parameters:\n");
|
|
fprintf(dbg, "\tFDescr: %d\n", ofn->ofn_fd);
|
|
fprintf(dbg, "\tBitMap: %04x\t", ofr.ofkr_bitmap);
|
|
dbg_print_bmap(ofk.ofk_bitmap, 0);
|
|
fprintf(dbg, "\tRefNum: %d\n", ofr.ofkr_refnum);
|
|
dbg_print_parm(ofr.ofkr_bitmap, r+len, *rl, 0);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
return(noErr);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
OSErr
|
|
FPCloseFork(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
CloseForkPkt cfk;
|
|
word attr;
|
|
OFN *ofn;
|
|
int err;
|
|
|
|
ntohPackX(PsCloseFork,p,l,(byte *) &cfk);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, "\tRefNum: %d\n", cfk.cfk_refnum);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if (DBFRK)
|
|
printf("CloseFork: refnum=%d\n",cfk.cfk_refnum);
|
|
if ((ofn = EtoIOFN(cfk.cfk_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
|
|
if ((ofn->ofn_mode & OFK_MWR) != 0) /* if opened for write */
|
|
VolModified(ofn->ofn_ivol); /* then set volume modification dt */
|
|
|
|
err = (ofn->ofn_flgs & OF_NOTOPEN) ? noErr : OSClose(ofn->ofn_fd);
|
|
|
|
if (err == noErr) {
|
|
OSGetAttr(ofn->ofn_ipdir, ofn->ofn_fnam, &attr);
|
|
attr &= ~((ofn->ofn_type == F_DATA) ? FPA_DAO : FPA_RAO);
|
|
OSSetAttr(ofn->ofn_ipdir, ofn->ofn_fnam, attr);
|
|
}
|
|
|
|
relofn(ofn);
|
|
return(err);
|
|
}
|
|
|
|
|
|
/*
|
|
*
|
|
* FPRead(...)
|
|
*
|
|
* The fork is read starting offset bytes from the beginning of the fork
|
|
* and terminating at the first newline-char encountered.
|
|
*
|
|
*/
|
|
|
|
OSErr
|
|
FPRead(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
ReadPkt rp;
|
|
OFN *ofn;
|
|
extern int sqs; /* get max send quantum size */
|
|
|
|
ntohPackX(PsRead,p,l,(byte *) &rp);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, "\tRefNum: %d\n", rp.rdf_refnum);
|
|
fprintf(dbg, "\tOffSet: %d\n", rp.rdf_offset);
|
|
fprintf(dbg, "\tReqCnt: %d\n", rp.rdf_reqcnt);
|
|
fprintf(dbg, "\tNLMask: %d\n", rp.rdf_flag);
|
|
fprintf(dbg, "\tNLChar: 0x%02x\n", rp.rdf_nlchar);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if (DBFRK)
|
|
printf("Read: ofn=%d, offset=%d, reqcnt=%d, flg=%d, nlc=%02x\n",
|
|
rp.rdf_refnum,rp.rdf_offset,rp.rdf_reqcnt,
|
|
rp.rdf_flag,rp.rdf_nlchar);
|
|
|
|
if ((ofn = EtoIOFN(rp.rdf_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
|
|
if (ofn->ofn_flgs & OF_NOTOPEN) {
|
|
*rl = 0;
|
|
return(aeEOFErr);
|
|
}
|
|
|
|
return(OSRead(ofn->ofn_fd,rp.rdf_offset,
|
|
min(rp.rdf_reqcnt,sqs),
|
|
rp.rdf_flag,rp.rdf_nlchar,r,rl,&ofn->ofn_pos,
|
|
ofn->ofn_trans_table));
|
|
}
|
|
|
|
OSErr
|
|
FPWrite(p,l,r,rl,cno,reqref)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
int cno;
|
|
ReqRefNumType reqref;
|
|
{
|
|
WritePkt wrt;
|
|
int rcvlen;
|
|
int comp,err;
|
|
OFN *ofn;
|
|
extern int n_rrpkts;
|
|
|
|
ntohPackX(PsWrite,p,l,(byte *) &wrt);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, "\tS/EFlg: %02x\n", wrt.wrt_flag);
|
|
fprintf(dbg, "\tRefNum: %d\n", wrt.wrt_refnum);
|
|
fprintf(dbg, "\tOffset: %d\n", wrt.wrt_offset);
|
|
fprintf(dbg, "\tReqCnt: %d\n", wrt.wrt_reqcnt);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if ((ofn = EtoIOFN(wrt.wrt_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
if (DBFRK)
|
|
printf("FPWrite: ofn=%d, flg=%d, offs=%d, req=%d\n",
|
|
wrt.wrt_refnum,wrt.wrt_flag,wrt.wrt_offset,wrt.wrt_reqcnt);
|
|
if (ofn->ofn_flgs & OF_NOTOPEN) {
|
|
if (wrt.wrt_reqcnt != 0) /* allow zero length requests */
|
|
return(aeAccessDenied);
|
|
}
|
|
|
|
err = dsiWrtContinue(cno,reqref,r,n_rrpkts*atpMaxData,&rcvlen,-1,&comp);
|
|
if (err != noErr)
|
|
return(err);
|
|
do { abSleep(4,TRUE); } while (comp > 0);
|
|
if (comp < 0)
|
|
return(comp);
|
|
err = OSWrite(ofn->ofn_fd,r,(sdword) rcvlen,
|
|
wrt.wrt_offset,wrt.wrt_flag,&ofn->ofn_pos,
|
|
ofn->ofn_trans_table);
|
|
if (err != noErr)
|
|
return(err);
|
|
PackDWord(ofn->ofn_pos,r);
|
|
*rl = sizeof(ofn->ofn_pos);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, " Return Parameters:\n");
|
|
fprintf(dbg, "\tWrittn: %d\n", ofn->ofn_pos);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
return(noErr);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
OSErr
|
|
FPFlushFork(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
OFN *ofn;
|
|
FlushForkPkt flf;
|
|
|
|
ntohPackX(PsFlush, p, l, (byte *)&flf);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL ) {
|
|
fprintf(dbg, "\tRefNum: %d\n", flf.flf_refnum);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if ((ofn = EtoIOFN(flf.flf_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
if (DBFRK)
|
|
printf("FLFlush: ofn=%d\n", flf.flf_refnum);
|
|
return((ofn->ofn_flgs & OF_NOTOPEN) ? noErr : OSFlushFork(ofn->ofn_fd));
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
OSErr
|
|
FPByteRangeLock(p,l,r,rl)
|
|
byte *p,*r;
|
|
int l,*rl;
|
|
{
|
|
OFN *ofn;
|
|
ByteRangeLockPkt brl;
|
|
OSErr err;
|
|
|
|
ntohPackX(PsByteRangeLock, p, l, (byte *)&brl);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, "\tULFlag: %s\n", (brl.brl_flg & 0x01) ? "UNLOCK" : "LOCK");
|
|
fprintf(dbg, "\tSEFlag: %s\n", (brl.brl_flg & 0x80) ? "END" : "START");
|
|
fprintf(dbg, "\tRefNum: %d\n", brl.brl_refnum);
|
|
fprintf(dbg, "\tOffset: %d\n", brl.brl_offset);
|
|
fprintf(dbg, "\tLength: %d\n", brl.brl_length);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
if ((ofn = EtoIOFN(brl.brl_refnum)) == NULL)
|
|
return(aeParamErr);
|
|
if (DBFRK)
|
|
printf("Byte Range Lock: ofn=%d (file %s)\n",ofn->ofn_fd,ofn->ofn_fnam);
|
|
if (ofn->ofn_flgs & OF_NOTOPEN)
|
|
ofn->ofn_pos = brl.brl_offset;
|
|
else {
|
|
err = OSByteRangeLock(ofn->ofn_fd, brl.brl_offset, brl.brl_length,
|
|
brl.brl_flg, &ofn->ofn_pos);
|
|
if (err != noErr)
|
|
return(err);
|
|
}
|
|
PackDWord(ofn->ofn_pos,r);
|
|
*rl = sizeof(ofn->ofn_pos);
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, " Return Parameters:\n");
|
|
fprintf(dbg, "\tRStart: %d\n", ofn->ofn_pos);
|
|
fflush(dbg);
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|
|
|
|
return(noErr);
|
|
}
|
|
|
|
#ifdef DEBUG_AFP_CMD
|
|
void
|
|
dbg_print_mode(mode)
|
|
u_short mode;
|
|
{
|
|
if (dbg != NULL) {
|
|
fprintf(dbg, "(");
|
|
if (mode & 0x0001)
|
|
fprintf(dbg, "Read ");
|
|
if (mode & 0x0002)
|
|
fprintf(dbg, "Write ");
|
|
if (mode & 0x0004)
|
|
fprintf(dbg, "DenyRead ");
|
|
if (mode & 0x0008)
|
|
fprintf(dbg, "DenyWrite ");
|
|
fprintf(dbg, ")\n");
|
|
}
|
|
}
|
|
#endif /* DEBUG_AFP_CMD */
|