home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format 56
/
af056sub.adf
/
parnfs.lha
/
netfs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-02
|
25KB
|
1,098 lines
/*
* $Id: netfs.c,v 1.1 1993/12/02 20:45:46 Rhialto Exp $
* $Log: netfs.c,v $
* Revision 1.1 1993/12/02 20:45:46 Rhialto
* Initial revision
*
* Actually convert file system actions into network packets.
* All functions assume that the packet type has been set already,
* so that the code for some packets can be shared.
* Read and Write are an exception because they may split the
* operation in multiple packets.
*/
#include "netfs.h"
#include <string.h>
#ifdef DEBUG
# include "syslog.h"
#else
# define debug(x)
#endif
Prototype Packet ReqPacket;
Prototype ULONG Validation;
Prototype ULONG MyValidation;
Packet ReqPacket;
ULONG Validation;
ULONG MyValidation;
NetFileLock *RootLock;
struct List NameList;
struct Entry {
struct Node e_Node;
};
/*
* Remember device parts of names DH0:xx/yy,
* without the colons.
*/
void
AddRemoteName(char *bstr)
{
struct Entry *e;
int len;
char *n;
static int nestcount;
debug(("AddRemoteName %d '%.*s'\n", nestcount, bstr[0], bstr+1));
if (nestcount > 0)
return;
nestcount++;
n = memchr(bstr + 1, ':', (unsigned char)bstr[0]);
if (n == NULL) {
/* Can't happen */
len = bstr[0];
} else
len = n - (bstr + 1);
e = (void *)&NameList;
while (e = NextNode((struct MinNode *)e)) {
n = e->e_Node.ln_Name;
if (n[0] == len && strnicmp(n+1, bstr+1, len) == 0) {
debug(("AddName: Found it\n"));
goto end; /* Found it */
}
}
debug(("AddName: A new name\n"));
e = dosalloc(sizeof(struct Entry) + 1 + len);
if (e == NULL)
goto end;
n = e + 1;
e->e_Node.ln_Name = n;
n[0] = len;
memcpy(n + 1, bstr + 1, len);
AddTail(&NameList, &e->e_Node);
/* Now check if it was a reasonable thing to do... */
{
NetFileLock *nfl;
static Packet save;
save = ReqPacket;
ReqPacket.p_Action = ACTION_LOCATE_OBJECT;
if (nfl = NetLock(RootLock, n, SHARED_LOCK)) {
ReqPacket.p_Action = ACTION_FREE_LOCK;
NetUnLock(nfl);
} else {
Remove(e);
dosfree((void *)e);
}
ReqPacket = save;
}
end:
nestcount--;
}
char *
CopyString(char *to, char *from)
{
int len = from[0];
debug(("CopyString '%.*s'\n", from[0], from+1));
memcpy(to, from, 1 + len);
to = to + 1 + len;
*to++ = '\0';
/* Align to longword for conversion to BPTR by the server */
to = (char *)(((ULONG)to + 3) & ~3);
return to;
}
/*
* Some packets use C style 0-terminated strings.
* Convert them to counted strings, for consisteny.
*/
char *
CopyCString(char *to, char *from)
{
int len = strlen(from);
to[0] = len;
memcpy(to + 1, from, len);
to = to + 1 + len;
*to++ = '\0';
/* Align to longword for conversion to BPTR by the server */
to = (char *)(((ULONG)to + 3) & ~3);
return to;
}
void *
memchr(const void *cs, int c, size_t n)
{
while (n > 0) {
if (*(unsigned char *)cs == (unsigned char)c)
return cs;
cs = (char *)cs + 1;
n--;
}
return NULL;
}
void
bstrcpy(unsigned char *d, unsigned char *s)
{
memcpy(d, s, 1 + s[0]);
}
int NameIsNetRoot;
int NameIsRemoteDevice;
char *
CopyName(char *to, char *from, NetFileLock *parent)
{
int len = from[0];
char *p;
debug(("CopyName '%.*s'\n", from[0], from+1));
NameIsNetRoot = 0;
NameIsRemoteDevice = 0;
if (p = memchr(from + 1, ':', len)) {
/* NET:something -> something */
p++;
len -= (p - (from + 1));
to[0] = len;
if (len)
memcpy(to + 1, p, len);
} else
memcpy(to, from, 1 + len);
if (parent == RootLock) {
NameIsNetRoot = (len == 0);
p = memchr(to + 1, '/', len);
if (p) {
/* dh0/something -> dh0:something */
p[0] = ':';
} else {
if (len > 5 && strncmp(&to[1+len-5], ".info", 5) == 0) {
/* NET:DH0.info -> DH0:Node.rinfo */
strcpy(&to[1+len-5], ":Node.rinfo");
len += 6;
to[0] = len;
} else {
/* dh0 -> dh0: */
to[0] = ++len;
to[len] = ':';
NameIsRemoteDevice = 1;
}
}
if (!NameIsNetRoot) {
AddRemoteName(to);
}
}
to = to + 1 + len;
*to++ = '\0';
/* Align to longword for conversion to BPTR by the server */
to = (char *)(((ULONG)to + 3) & ~3);
return to;
}
NetFileLock *
ValidLock(NetFileLock *netfl)
{
if (netfl == NULL)
return RootLock;
if (netfl->nfl_Validation == Validation)
return netfl;
if (netfl->nfl_Validation == 0)
return netfl;
error = ERROR_DEVICE_NOT_MOUNTED;
return NULL;
}
int
ValidFile(NetFileHandle *netfh)
{
return netfh && netfh->nfh_Validation == Validation;
}
NetFileLock *
MakeNetLock(ULONG fl)
{
NetFileLock *netfl;
if (netfl = AllocMem(sizeof(*netfl), MEMF_PUBLIC|MEMF_CLEAR)) {
netfl->nfl_FileLock = fl;
netfl->nfl_Validation = Validation;
}
#ifdef DEBUG
debug(("MakeNetLock %x from %x\n", netfl, fl));
if (fl == 0)
debug(("!!! 0 remote lock !!!\n"));
#endif
return netfl;
}
void
FreeNetLock(NetFileLock *netfl)
{
if (netfl && netfl != RootLock)
FreeMem(netfl, sizeof(*netfl));
}
NetFileHandle *
MakeNetFile(ULONG fh)
{
NetFileHandle *netfh;
if (netfh = AllocMem(sizeof(*netfh), MEMF_PUBLIC|MEMF_CLEAR)) {
netfh->nfh_FileHandle = fh;
netfh->nfh_Validation = Validation;
}
debug(("MakeNetFile %x\n", netfh));
return netfh;
}
void
FreeNetFile(NetFileHandle *netfh)
{
if (netfh)
FreeMem(netfh, sizeof(*netfh));
}
/* ---------------------------------------------------------------------- */
Prototype NetFileLock *NetLock(NetFileLock *parent, char *name, ULONG mode);
NetFileLock *
NetLock(NetFileLock *parent, char *name, ULONG mode)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
ReqPacket.p_Arg[1] = mode;
end = CopyName((char *)&ReqPacket.p_Arg[2], name, parent);
debug(("NetLock: %x %s %d\n", parent, (char *)&ReqPacket.p_Arg[2]+1,
mode));
if (NameIsNetRoot)
return RootLock;
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1) {
return MakeNetLock(ReqPacket.p_Res1);
}
}
}
return NULL;
}
Prototype void NetUnLock(NetFileLock *netfl);
void
NetUnLock(NetFileLock *netfl)
{
if (netfl) {
if ((netfl = ValidLock(netfl))) {
if (netfl == RootLock)
return;
ReqPacket.p_Arg[0] = netfl->nfl_FileLock;
(void)SendRecv(&ReqPacket, REQSIZE(1), &ReqPacket, STDREPLY);
}
FreeNetLock(netfl);
}
}
Prototype NetFileLock *NetDupLock(NetFileLock *netfl);
NetFileLock *
NetDupLock(NetFileLock *netfl)
{
if (netfl = ValidLock(netfl)) {
if (netfl == RootLock)
return RootLock;
ReqPacket.p_Arg[0] = netfl->nfl_FileLock;
if (SendRecv(&ReqPacket, REQSIZE(1), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1) {
return MakeNetLock(ReqPacket.p_Res1);
}
}
}
return NULL;
}
Prototype NetFileLock *NetCreateDir(NetFileLock *parent, char *name);
NetFileLock *
NetCreateDir(NetFileLock *parent, char *name)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
end = CopyName((char *)&ReqPacket.p_Arg[1], name, parent);
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1) {
return MakeNetLock(ReqPacket.p_Res1);
}
}
}
return NULL;
}
Prototype ULONG NetDeleteFile(NetFileLock *parent, char *name);
ULONG
NetDeleteFile(NetFileLock *parent, char *name)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
end = CopyName((char *)&ReqPacket.p_Arg[1], name, parent);
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype NetFileLock *NetParentDir(NetFileLock *netfl);
NetFileLock *
NetParentDir(NetFileLock *netfl)
{
if (netfl == NULL) {
error = ERROR_OBJECT_NOT_FOUND;
} else if (netfl = ValidLock(netfl)) {
if (netfl == RootLock)
return NULL;
ReqPacket.p_Arg[0] = netfl->nfl_FileLock;
if (SendRecv(&ReqPacket, REQSIZE(1), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1)
return MakeNetLock(ReqPacket.p_Res1);
else if (error == 0)
return RootLock;
}
}
return NULL;
}
Prototype ULONG NetSameLock(NetFileLock *lock1, NetFileLock *lock2);
ULONG
NetSameLock(NetFileLock *lock1, NetFileLock *lock2)
{
if ((lock1 = ValidLock(lock1)) && (lock2 = ValidLock(lock2))) {
if (lock1 == lock2) {
debug(("NetSameLock: same local ptr %x\n", lock1));
return DOSTRUE;
}
#if 1
if (lock1 == RootLock || lock2 == RootLock) {
/*error = ERROR_DEVICE_NOT_MOUNTED;*/
error = ERROR_INVALID_LOCK;
return DOSFALSE;
}
#endif
if (lock1->nfl_FileLock == lock2->nfl_FileLock) {
debug(("NetSameLock: same remote ptr %x\n", lock1->nfl_FileLock));
return DOSTRUE;
}
debug(("NetSameLock: compare remote %x %x\n", lock1->nfl_FileLock, lock2->nfl_FileLock));
ReqPacket.p_Arg[0] = lock1->nfl_FileLock;
ReqPacket.p_Arg[1] = lock2->nfl_FileLock;
if (SendRecv(&ReqPacket, REQSIZE(2), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
ULONG
NetRelabel(NetFileLock *slock, char *sname, NetFileLock *dlock, char *dname)
{
char *end;
char *colon;
ReqPacket.p_Action = ACTION_RENAME_DISK;
end = CopyName((char *)&ReqPacket.p_Arg[0], sname, slock);
colon = end;
end = CopyName((char *)end, dname, dlock);
/* Remove colon from new name */
if (colon[colon[0]] == ':') {
colon[colon[0]] = '\0';
colon[0]--;
}
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
Prototype ULONG NetRename(NetFileLock *slock, char *sname, NetFileLock *dlock, char *dname);
ULONG
NetRename(NetFileLock *slock, char *sname, NetFileLock *dlock, char *dname)
{
char *end;
char root;
char dev;
if ((slock = ValidLock(slock)) && (dlock = ValidLock(dlock))) {
ReqPacket.p_Arg[0] = slock->nfl_FileLock;
ReqPacket.p_Arg[1] = dlock->nfl_FileLock;
end = CopyName((char *)&ReqPacket.p_Arg[2], sname, slock);
root = NameIsNetRoot;
dev = NameIsRemoteDevice;
end = CopyName((char *)end, dname, dlock);
root += NameIsNetRoot;
dev += NameIsRemoteDevice;
if (dev == 2)
return NetRelabel(slock, sname, dlock, dname);
if (root || dev) {
error = ERROR_RENAME_ACROSS_DEVICES;
return DOSFALSE;
}
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetSetProtect(NetFileLock *parent, char *name, ULONG protect);
ULONG
NetSetProtect(NetFileLock *parent, char *name, ULONG protect)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
ReqPacket.p_Arg[1] = protect;
end = CopyName((char *)&ReqPacket.p_Arg[2], name, parent);
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetExamine(NetFileLock *netfl, struct FileInfoBlock *fib);
ULONG
NetExamine(NetFileLock *netfl, struct FileInfoBlock *fib)
{
if (netfl = ValidLock(netfl)) {
if (netfl == RootLock) {
char *p;
memset(fib, 0, sizeof(*fib));
/* Includes fib_DiskKey = 0 */
fib->fib_DirEntryType =
fib->fib_EntryType = ST_ROOT;
p = BTOC(VolNode->dl_Name);
bstrcpy(&fib->fib_FileName[0], p);
fib->fib_Date = VolNode->dl_VolumeDate;
return DOSTRUE;
}
ReqPacket.p_Arg[0] = netfl->nfl_FileLock;
if (SendRecv2(&ReqPacket, REQSIZE(1), NULL, 0,
&ReqPacket, STDREPLY, fib, sizeof(*fib)) == 0) {
#ifdef DEBUG
{
debug(("key %x size %d name '%.*s'\n", fib->fib_DiskKey, fib->fib_Size,
fib->fib_FileName[0], &fib->fib_FileName[1]));
}
#endif
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetExNext(NetFileLock *netfl, struct FileInfoBlock *fib);
/*
* For ExNext, (a part of) the FileInfoBlock must be sent
* with the request. To be flexible, here is a define for
* how much we actually transmit. In this case, everything
* up to the end of the file name plus a bit of slop to
* survive round-down errors.
* See also notes in the server.
*/
#define EXNEXTFIBSIZE(f) (offsetof(struct FileInfoBlock, fib_FileName[0]) + \
f->fib_FileName[0] + 2)
ULONG
NetExNext(NetFileLock *netfl, struct FileInfoBlock *fib)
{
if (netfl = ValidLock(netfl)) {
if (netfl == RootLock) {
struct Entry *e;
int i;
if (fib->fib_DiskKey > 0 && fib->fib_DirEntryType == ST_USERDIR) {
fib->fib_DirEntryType =
fib->fib_EntryType = ST_FILE;
i = fib->fib_FileName[0];
strcpy(&fib->fib_FileName[1+i], ".info");
fib->fib_FileName[0] = i + 5;
return DOSTRUE;
}
e = NextNode((struct MinNode *)&NameList);
for (i = fib->fib_DiskKey; e && i > 0; i--)
e = NextNode((struct MinNode *)e);
if (e) {
fib->fib_DiskKey++;
fib->fib_DirEntryType =
fib->fib_EntryType = ST_USERDIR;
bstrcpy(&fib->fib_FileName[0], e->e_Node.ln_Name);
return DOSTRUE;
}
error = ERROR_NO_MORE_ENTRIES;
return DOSFALSE;
}
ReqPacket.p_Arg[0] = netfl->nfl_FileLock;
if (SendRecv2(&ReqPacket, REQSIZE(1), fib, EXNEXTFIBSIZE(fib),
&ReqPacket, STDREPLY, fib, sizeof(*fib)) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetDiskInfo(struct InfoData *id);
ULONG
NetDiskInfo(struct InfoData *id)
{
memset(id, 0, sizeof(*id));
id->id_DiskState = ID_VALIDATED;
id->id_NumBlocks = 1;
id->id_NumBlocksUsed = 1;
id->id_BytesPerBlock = MAXDATA;
id->id_DiskType = ID_DOS_DISK;
id->id_VolumeNode = CTOB(VolNode);
id->id_InUse = 1;
return DOSTRUE;
}
Prototype ULONG NetInfo(NetFileLock *netfl, struct InfoData *id);
ULONG
NetInfo(NetFileLock *netfl, struct InfoData *id)
{
if (netfl == RootLock)
return NetDiskInfo(id);
if (netfl = ValidLock(netfl)) {
ReqPacket.p_Arg[0] = netfl->nfl_FileLock;
if (SendRecv2(&ReqPacket, REQSIZE(1), NULL, 0,
&ReqPacket, STDREPLY, id, sizeof(*id)) == 0) {
id->id_VolumeNode = NULL;
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetSetComment(NetFileLock *parent, char *name, char *comment);
ULONG
NetSetComment(NetFileLock *parent, char *name, char *comment)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
end = CopyName((char *)&ReqPacket.p_Arg[1], name, parent);
end = CopyString(end, comment);
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetSetDate(NetFileLock *parent, char *name, struct DateStamp *ds);
ULONG
NetSetDate(NetFileLock *parent, char *name, struct DateStamp *ds)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
ReqPacket.p_Arg[1] = ds->ds_Days;
ReqPacket.p_Arg[2] = ds->ds_Minute;
ReqPacket.p_Arg[3] = ds->ds_Tick;
end = CopyName((char *)&ReqPacket.p_Arg[4], name, parent);
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype NetFileHandle *NetOpen(NetFileLock *parent, char *name, ULONG mode);
NetFileHandle *
NetOpen(NetFileLock *parent, char *name, ULONG mode)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
end = CopyName((char *)&ReqPacket.p_Arg[1], name, parent);
/* mode is actually the packet type */
debug(("NetOpen: %x %s %d\n", parent, (char *)&ReqPacket.p_Arg[1]+1,
mode));
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1) {
return MakeNetFile(ReqPacket.p_Res1);
}
}
}
return NULL;
}
Prototype LONG NetRead(NetFileHandle *netfh, char *buffer, LONG length);
LONG
NetRead(NetFileHandle *netfh, char *buffer, LONG length)
{
LONG done = 0;
if (ValidFile(netfh)) {
while (length > 0) {
ReqPacket.p_Action = ACTION_READ;
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
ReqPacket.p_Arg[1] = min(length, MAXDATA);
if (SendRecv2(&ReqPacket, REQSIZE(2), NULL, 0,
&ReqPacket, STDREPLY, buffer, ReqPacket.p_Arg[1]) != 0)
break;
if ((long)ReqPacket.p_Res1 <= 0)
break;
length -= ReqPacket.p_Res1;
buffer += ReqPacket.p_Res1;
done += ReqPacket.p_Res1;
}
error = ReqPacket.p_Res2;
return done;
}
return -1;
}
Prototype LONG NetWrite(NetFileHandle *netfh, char *buffer, LONG length);
LONG
NetWrite(NetFileHandle *netfh, char *buffer, LONG length)
{
LONG done = 0;
if (ValidFile(netfh)) {
while (length > 0) {
LONG thislength = min(length, MAXDATA);
ReqPacket.p_Action = ACTION_WRITE;
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
ReqPacket.p_Arg[1] = thislength;
if (SendRecv2(&ReqPacket, REQSIZE(2), buffer, thislength,
&ReqPacket, STDREPLY, NULL, 0) != 0)
break;
if (ReqPacket.p_Res1 == -1)
break;
done += ReqPacket.p_Res1;
if (ReqPacket.p_Res1 != thislength)
break;
length -= ReqPacket.p_Res1;
buffer += ReqPacket.p_Res1;
}
error = ReqPacket.p_Res2;
return done;
}
return -1;
}
Prototype ULONG NetClose(NetFileHandle *netfh);
ULONG
NetClose(NetFileHandle *netfh)
{
if (ValidFile(netfh)) {
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
if (SendRecv(&ReqPacket, REQSIZE(1), &ReqPacket, STDREPLY) == 0) {
if (ReqPacket.p_Res1 && (error = ReqPacket.p_Res2) == 0) {
FreeNetFile(netfh);
}
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
Prototype ULONG NetSeek(NetFileHandle *netfh, ULONG position, ULONG mode);
ULONG
NetSeek(NetFileHandle *netfh, ULONG position, ULONG mode)
{
if (ValidFile(netfh)) {
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
ReqPacket.p_Arg[1] = position;
ReqPacket.p_Arg[2] = mode;
if (SendRecv(&ReqPacket, REQSIZE(3), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
/*
* Target can be eith
*/
Prototype ULONG NetMakeLink(NetFileLock *parent, char *name, void *target, ULONG mode);
ULONG
NetMakeLink(NetFileLock *parent, char *name, void *target, ULONG soft)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
ReqPacket.p_Arg[1] = soft;
if (soft) {
/* XXX Is this a BCPL or C string? */
end = CopyCString((char *)&ReqPacket.p_Arg[2], target);
} else {
NetFileLock *tlock = ValidLock((NetFileLock *)target);
debug(("MakeLink hard %s -> %x\n", name, target));
if (tlock == 0) {
error = ERROR_INVALID_LOCK;
return DOSFALSE;
}
ReqPacket.p_Arg[2] = tlock->nfl_FileLock;
end = &ReqPacket.p_Arg[3];
}
end = CopyName(end, name, parent);
if (SendRecv(&ReqPacket, end - &ReqPacket, &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return NULL;
}
Prototype ULONG NetReadLink(NetFileLock *parent, char *name, char *target, ULONG length);
ULONG
NetReadLink(NetFileLock *parent, char *name, char *target, ULONG length)
{
char *end;
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
ReqPacket.p_Arg[1] = length;
end = CopyCString((char *)&ReqPacket.p_Arg[2], name); /* XXX should be CopyCName */
if (SendRecv2(&ReqPacket, end - &ReqPacket, NULL, 0,
&ReqPacket, STDREPLY, target, length) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return NULL;
}
Prototype ULONG NetSetFileSize(NetFileHandle *netfh, ULONG position, ULONG mode);
ULONG
NetSetFileSize(NetFileHandle *netfh, ULONG position, ULONG mode)
{
/* Same arguments and result */
return NetSeek(netfh, position, mode);
}
Prototype NetFileHandle *NetOpenFromLock(NetFileLock *parent);
NetFileHandle *
NetOpenFromLock(NetFileLock *parent)
{
if (parent = ValidLock(parent)) {
ReqPacket.p_Arg[0] = parent->nfl_FileLock;
if (SendRecv(&ReqPacket, REQSIZE(1), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1) {
return MakeNetFile(ReqPacket.p_Res1);
}
}
}
return NULL;
}
Prototype NetFileLock *NetParentOfFH(NetFileHandle *netfh);
NetFileLock *
NetParentOfFH(NetFileHandle *netfh)
{
if (ValidFile(netfh)) {
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
if (SendRecv(&ReqPacket, REQSIZE(1), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
if (ReqPacket.p_Res1) {
return MakeNetLock(ReqPacket.p_Res1);
}
}
}
return NULL;
}
Prototype ULONG NetChangeMode(ULONG type, void *object, ULONG mode);
ULONG
NetChangeMode(ULONG type, void *object, ULONG mode)
{
ULONG object2 = 0;
switch (type) {
case CHANGE_FH:
if (object = ValidLock(object))
object2 = ((NetFileHandle *)object)->nfh_FileHandle;
break;
case CHANGE_LOCK:
if (ValidFile(object))
object2 = ((NetFileLock *)object)->nfl_FileLock;
break;
}
if (object2) {
ReqPacket.p_Arg[0] = type;
ReqPacket.p_Arg[1] = object2;
ReqPacket.p_Arg[2] = mode;
if (SendRecv(&ReqPacket, REQSIZE(3), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
error = ERROR_OBJECT_WRONG_TYPE;
return DOSFALSE;
}
Prototype NetFileLock *NetDupLockFromFH(NetFileHandle *netfh);
NetFileLock *
NetDupLockFromFH(NetFileHandle *netfh)
{
return NetParentOfFH(netfh);
}
Prototype ULONG NetExamineFH(NetFileHandle *netfh, struct FileInfoBlock *fib);
ULONG
NetExamineFH(NetFileHandle *netfh, struct FileInfoBlock *fib)
{
if (ValidFile(netfh)) {
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
if (SendRecv2(&ReqPacket, REQSIZE(1), NULL, 0,
&ReqPacket, STDREPLY, fib, sizeof(*fib)) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return DOSFALSE;
}
void
NetLockRecordReply(struct DosPacket *dp, ULONG res1, ULONG res2)
{
debug(("NetLockRecordReply %x %x\n", res1, res2));
dp->dp_Res1 = res1;
dp->dp_Res2 = res2;
returnpacket(dp);
}
Prototype void NetLockRecord(struct DosPacket *dp, NetFileHandle *netfh, LONG start, LONG length, LONG mode, LONG timeout);
void
NetLockRecord(struct DosPacket *dp, NetFileHandle *netfh, LONG start,
LONG length, LONG mode, LONG timeout)
{
debug(("NetLockRecord %x %x->%x\n", dp, netfh, netfh->nfh_FileHandle));
if (ValidFile(netfh)) {
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
ReqPacket.p_Arg[1] = start;
ReqPacket.p_Arg[2] = length;
ReqPacket.p_Arg[3] = mode;
ReqPacket.p_Arg[4] = timeout;
ReqPacket.p_Arg[5] = dp; /* extra */
if (Send2(&ReqPacket, REQSIZE(6), NULL, 0) != 0) {
NetLockRecordReply(dp, DOSFALSE, ERROR_NO_FREE_STORE);
}
} else {
debug(("Bad NetFH\n"));
NetLockRecordReply(dp, DOSFALSE, ERROR_OBJECT_WRONG_TYPE);
}
}
Prototype ULONG NetFreeRecord(NetFileHandle *netfh, LONG start, LONG length);
ULONG
NetFreeRecord(NetFileHandle *netfh, LONG start, LONG length)
{
if (ValidFile(netfh)) {
ReqPacket.p_Arg[0] = netfh->nfh_FileHandle;
ReqPacket.p_Arg[1] = start;
ReqPacket.p_Arg[2] = length;
if (SendRecv(&ReqPacket, REQSIZE(3), &ReqPacket, STDREPLY) == 0) {
error = ReqPacket.p_Res2;
return ReqPacket.p_Res1;
}
}
return NULL;
}
/* ---------------------------------------------------------------------- */
Prototype void DoAsyncReply(Packet *pkt);
void
DoAsyncReply(Packet *pkt)
{
debug(("DoAsyncReply\n"));
switch (pkt->p_Data[0]) {
case ACTION_LOCK_RECORD:
NetLockRecordReply((void *)pkt->p_Data[1], pkt->p_Res1, pkt->p_Res2);
break;
default:
debug(("Weird AsyncReply, %d\n", pkt->p_Data[0]));
}
}
/* ---------------------------------------------------------------------- */
Prototype ULONG OpenNetFS(void);
ULONG
OpenNetFS(void)
{
ULONG error;
debug(("OpenNetFS\n"));
error = OpenNetwork();
if (error == 0) {
RootLock = MakeNetLock(0);
RootLock->nfl_Validation = 0;
NewList(&NameList);
}
debug(("OpenNetFS done\n"));
return error;
}
Prototype ULONG CloseNetFS(void);
ULONG
CloseNetFS(void)
{
NetFileLock *nfl;
debug(("CloseNetFS\n"));
CloseNetwork();
nfl = RootLock;
RootLock = NULL;
FreeNetLock(nfl);
return 0;
}