#include <u.h>
#include <libc.h>
#include "ncp.h"
Session *
Attach(int fd)
{
Session *s;
int err, len;
ushort msg;
if ((s = malloc(sizeof(Session))) == nil)
sysfatal("No memory for another Session connection");
memset(s, 0, sizeof(Session));
s->txsig = 0x446d6454; // not using signatures, signature
s->task = 1;
s->mtu = BASEMTU;
if ((s->buf = malloc(s->mtu)) == nil)
sysfatal("No memory for another Session connection");
s->p = s->buf;
memset(s->buf, 0, s->mtu);
pb32(s, s->txsig);
pb32(s, 23); // fixed packet len
pb32(s, NCPVER);
pb32(s, 0); // reply length
pb16(s, Mattach);
p8(s, s->seq);
p8(s, 0xff); // connection number (MSBs)
p8(s, 0); // task number (ignored)
p8(s, 0); // reserved (ignored)
p8(s, 0); // request code (ignored)
if (Debug)
fprint(2, "\n%N", s->buf);
len = s->p - s->buf;
if (write(fd, s->buf, len) != len){
werrstr("write to media failed");
free(s->buf);
free(s);
return nil;
}
s->p = s->buf;
memset(s->buf, 0, s->mtu);
if (read(fd, s->buf, s->mtu) == -1){
werrstr("read of media failed");
free(s->buf);
free(s);
return nil;
}
if (Debug)
fprint(2, "%N", s->buf);
s->rxsig = gb32(s);
gb32(s); // length
if ((msg = gb16(s)) != Mreply){
werrstr("read of media failed, 0x%4x", msg);
free(s->buf);
free(s);
return nil;
}
s->seq = g8(s);
s->conn = g8(s);
g8(s); // task number
s->conn |= (g8(s) << 8);
if ((err = g8(s)) != 0){
werrstr("%s", nwerrstr(err));
free(s->buf);
free(s);
return nil;
}
if ((err = g8(s)) != 0){
if (err & (1 << 6))
fprint(2, "broadcast message waiting");
else{
if (err & (1 << 0))
werrstr("bad service connection");
if (err & (1 << 2))
werrstr("no connections avaliable");
if (err & (1 << 4))
werrstr("server is down");
free(s->buf);
free(s);
return nil;
}
}
s->seq = (s->seq +1) % 256;
s->fd = fd;
return s;
}
int
Detach(Session *s)
{
int len;
s->p = s->buf;
memset(s->buf, 0, s->mtu);
pb32(s, s->txsig); // signature
pb32(s, 0x49); // fixed packet len
pb32(s, NCPVER); // packet version
pb32(s, 0); // max reply length
pb16(s, Mdetach); // packet type
p8(s, s->seq); // sequence number
p8(s, s->conn & 0xff); // server's connection # MSB
p8(s, s->task); // client's transaction nesting
p8(s, (s->conn >> 8) & 0xff); // server's connection # LSB
if (Debug)
fprint(2, "%N", s->buf);
len = s->p - s->buf;
if (write(s->fd, s->buf, len) != len){
werrstr("write to media failed");
free(s);
return -1;
}
/*
* ignore reply
*/
free(s->buf);
free(s);
return 0;
}
/*******************
* Login/logout
*/
int
Logout(Session *s)
{
ncphdr(s, 0x1900, Tsimple);
return ncpcall(s);
}
int
LoginObject(Session *s, char *name, int type, char *pass)
{
ncphdr(s, 0x1714, Tvarlen);
pb16(s, type);
pstr(s, name);
pstr(s, pass);
return ncpcall(s);
}
int
KeyedObjectLogin(Session *s, int type, char *name, uchar *key)
{
ncphdr(s, 0x1718, Tvarlen);
pmem(s, key, NWKEYLEN);
pb16(s, type);
pstr(s, name);
return ncpcall(s);
}
int
GetLoginKey(Session *s, int target, uchar *key)
{
ncphdr(s, 0x1717, Tvarlen);
p8(s, target);
if (ncpcall(s) == -1)
return -1;
gmem(s, key, NWKEYLEN);
return 0;
}
int
NegotiateBufferSize(Session *s, int *sz)
{
assert((*sz & ~0xffff) == 0);
ncphdr(s, 0x2100, Tsimple);
pb16(s, *sz);
if (ncpcall(s) == -1)
return -1;
*sz = gb16(s);
return 0;
}
/*******************
* File server config
*/
int
GetFileServerInfo(Session *s, FSInfo *fsi)
{
ncphdr(s, 0x1711, Tvarlen);
if (ncpcall(s) == -1)
return -1;
gmem(s, fsi->name, OBJNAMLEN);
fsi->fsvermaj = g8(s);
fsi->fsvermin = g8(s);
fsi->maxconn = gb16(s);
fsi->numconn = gb16(s);
fsi->numvol = gb16(s);
fsi->rev = g8(s);
fsi->sftlev = g8(s);
fsi->ttslev = g8(s);
fsi->mostconn = gb16(s);
fsi->acctver = g8(s);
fsi->vapver = g8(s);
fsi->quever = g8(s);
fsi->lprver = g8(s);
fsi->consver = g8(s);
fsi->restrct = g8(s);
fsi->bridgeflag = g8(s);
fsi->mixedpaths = g8(s);
fsi->locallogin = g8(s);
fsi->prodmaj = gb16(s);
fsi->prodmin = gb16(s);
fsi->prodver = gb16(s);
fsi->lang = g8(s);
fsi->bigfiles = g8(s);
return 0;
}
int
GetStationsLoggedInfo(Session *s, long conn, int *id, int *type, char *name, long *logtime)
{
ncphdr(s, 0x171c, Tvarlen);
pl32(s, conn);
if (ncpcall(s) == -1)
return -1;
*id = gb32(s);
*type = gb16(s);
gmem(s, name, OBJNAMLEN);
*logtime = gtbuf(s);
return 0;
}
int
GetInternetAddress(Session *s, long conn, uchar *addr, int *type)
{
ncphdr(s, 0x171a, Tvarlen);
pl32(s, conn);
if (ncpcall(s) == -1)
return -1;
gmem(s, addr, IPXADDRLEN);
*type = g8(s);
return 0;
}
int
GetFileServerDateAndTime(Session *s, long *now)
{
ncphdr(s, 0x1400, Tsimple);
if (ncpcall(s) == -1)
return -1;
*now = gtbuf(s);
return 0;
}
/*******************
* Volumes
*/
int
GetVolumeName(Session *s, int vol, char *name)
{
ncphdr(s, 0x1606, Tvarlen);
p8(s, vol);
if (ncpcall(s) == -1)
return -1;
gstr(s, name, VOLNAMLEN);
return 0;
}
int
GetVolumeNumber(Session *s, char *name, int *vol)
{
ncphdr(s, 0x1605, Tvarlen);
pstr(s, name);
if (ncpcall(s) == -1)
return -1;
*vol = g8(s);
return 0;
}
int
GetVolumeAndPurgeInfo(Session *s, int vol, VInfo *vi)
{
ncphdr(s, 0x162c, Tvarlen);
p8(s, vol);
if (ncpcall(s) == -1)
return -1;
vi->total = gl32(s);
vi->free = gl32(s);
vi->purgable = gl32(s);
vi->notpurged = gl32(s);
vi->dir_total = gl32(s);
vi->dir_avail = gl32(s);
gb32(s); // reserved
vi->sectperblock = g8(s);
gstr(s, vi->name, VOLNAMLEN);
return 0;
}
/*******************
* Bindery access
*/
int
GetBinderyObjectName(Session *s, ulong id, char *name, int *type)
{
ncphdr(s, 0x1736, Tvarlen);
pb32(s, id);
if (ncpcall(s) == -1)
return -1;
gb32(s); // ID, but we already know that
*type = gb16(s);
gmem(s, name, OBJNAMLEN);
return 0;
}
int
GetBinderyObjectId(Session *s, char *name, int type, ulong *id)
{
ncphdr(s, 0x1735, Tvarlen);
pb16(s, type);
pstr(s, name);
if (ncpcall(s) == -1)
return -1;
*id = gb32(s);
return 0;
}
int
ScanBinderyObject(Session *s, char *iname, int itype, int *id, char *oname,
int *otype, int *hasprops, int *flags, int *rights)
{
ncphdr(s, 0x1737, Tvarlen);
pb32(s, *id);
pb16(s, itype);
pstr(s, iname);
if (ncpcall(s) == -1)
return -1;
*id = gb32(s);
*otype = gb16(s);
gmem(s, oname, OBJNAMLEN);
*flags = g8(s);
*rights = g8(s);
*hasprops = g8(s);
return 0;
}
ScanProperty(Session *s, char *obj, int type, char *prop, long *seq,
char *name, int *flags, int *secure, int *hasval, int *ismore)
{
ncphdr(s, 0x173c, Tvarlen);
pb16(s, type);
pstr(s, obj);
pb32(s, *seq);
pstr(s, prop);
if (ncpcall(s) == -1)
return -1;
gmem(s, name, PROPNAMLEN);
*flags = g8(s);
*secure = g8(s);
*seq = gb32(s);
*hasval = g8(s);
*ismore = g8(s);
return(0);
}
ReadPropertyValue(Session *s, char *object, int type, char *property,
int seg, void *value, int *ismore, int *flags)
{
ncphdr(s, 0x173d, Tvarlen);
pb16(s, type);
pstr(s, object);
p8(s, seg);
pstr(s, property);
if (ncpcall(s) == -1)
return -1;
gmem(s, value, PROPLEN);
*flags = g8(s);
*ismore = g8(s);
return(0);
}
/*******************
* Directory manipulation
*/
int
DeteleFileOrDir(Session *s, int ns, int sa, char *path)
{
ncphdr(s, 0x5708, Tsubfun);
p8(s, ns);
p8(s, 0); // reserved
pl16(s, sa);
phps(s, path);
return ncpcall(s);
}
int
RenameOrMoveFileOrDir(Session *s, int ns, int flags, int sa, char *src, char *dst)
{
ncphdr(s, 0x5704, Tsubfun);
p8(s, ns);
p8(s, flags);
pl16(s, sa);
pphs2(s, src, dst);
return ncpcall(s);
}
int
ModifyFileOrDirInfo(Session *s, int ns, int sa, int mask,
Mfi *mfi, char *path)
{
ncphdr(s, 0x5707, Tsubfun);
p8(s, ns);
p8(s, 0); // reserved
pl16(s, sa);
pl32(s, mask);
pl32(s, mfi->attr);
pdatetime(s, mfi->created);
pb32(s, mfi->creator);
pdatetime(s, mfi->modified);
pb32(s, mfi->modifier);
pdatetime(s, mfi->archived);
pb32(s, mfi->archiver);
pdate(s, mfi->accessed);
pl16(s, mfi->grant);
pl16(s, mfi->revoke);
pl32(s, mfi->quota);
phps(s, path);
return ncpcall(s);
}
/*******************
* File I/O
*/
int
OpenCreateFileOrSubdir(Session *s, int ns, int mode, int sa, long mask, int rights,
long attr, char *name, int *action, Fh fh,FInfo *i)
{
ncphdr(s, 0x5701, Tsubfun);
p8(s, ns);
p8(s, mode);
pl16(s, sa);
pl32(s, mask);
pl32(s, attr);
pl16(s, rights); // inherited rights mask
phps(s, name);
if (ncpcall(s) ==-1)
return -1;
gfhand32(s, fh);
*action = g8(s);
g8(s); // reserved
ginfo(s, i);
return(0);
}
/*
* DANGER: netware versions before 5.0 require all transfers
* to be block aligned, where a block is that size negoiated
* at connection time with NegotiateBufferSize();
*/
int
ReadFromAFile(Session *s, Fh fh, void *b, long *len, long off)
{
ncphdr(s, 0x4800, Tsimple);
p8(s, 0); // reserved
pmem(s, fh, sizeof(Fh));
pb32(s, off);
pb16(s, *len);
if (ncpcall(s) == -1){
*len = -1;
return -1;
}
*len = gb16(s);
/*
* netware strangeness - if the request
* starts on an odd byte boundry then data will
* be prefixed by a single byte of garbage.
*/
if (off & 1L)
g8(s);
gmem(s, b, *len);
return 0;
}
/*
* DANGER: netware versions before 5.0 require all transfers
* to be block aligned, where a block is that size negoiated
* at connection time with NegotiateBufferSize();
*/
int
WriteToAFile(Session *s, Fh fh, void *b, int len, long off)
{
ncphdr(s, 0x4900, Tsimple);
p8(s, 0); // reserved
pmem(s, fh, sizeof(Fh));
pb32(s, off);
pb16(s, len);
pmem(s, b, len);
return ncpcall(s);
}
int
CommitFile(Session *s, Fh fh)
{
ncphdr(s, 0x3b00, Tsimple);
p8(s, 0); // reserved
pmem(s, fh, sizeof(Fh));
return ncpcall(s);
}
int
CloseFile(Session *s, Fh fh)
{
ncphdr(s, 0x4200, Tsimple);
p8(s, 0); // reserved
pmem(s, fh, sizeof(Fh));
return ncpcall(s);
}
/*******************
* Directory scanning
*/
int
InitializeSearch(Session *s, int ns, char *path, Srch srch)
{
ncphdr(s, 0x5702, Tsubfun);
p8(s, ns);
p8(s, 0); // reserved
phps(s, path);
if (ncpcall(s) == -1)
return -1;
gmem(s, srch, sizeof(Srch));
return(0);
}
int
SearchFileOrSubdirectory(Session *s, Srch srch, int ns, int ds,
int sa, char *path, int mask,FInfo *i)
{
ncphdr(s, 0x5703, Tsubfun);
p8(s, ns);
p8(s, ds);
pl16(s, sa);
pl32(s, mask);
pmem(s, srch, sizeof(Srch));
pstr(s, path);
if (ncpcall(s) == -1)
return -1;
gmem(s, srch, sizeof(Srch));
g8(s); // reserved
ginfo(s, i);
return(0);
}
int
SearchFileOrSubdirectorySet(Session *s, Srch srch, int sns, int dns,
int sa, char *path, long mask,FInfo *i, int *nent, int *more)
{
int n;
ncphdr(s, 0x5714, Tsubfun);
p8(s, sns);
p8(s, dns);
pl16(s, sa);
pl32(s, mask);
pl16(s, *nent);
pmem(s, srch, sizeof(Srch));
pstr(s, path);
if (ncpcall(s) == -1)
return -1;
gmem(s, srch, sizeof(Srch));
*more = g8(s);
*nent = gl16(s);
for (n = 0; n < *nent; n++, i++)
ginfo(s, i);
return(0);
}
int
ObtainFileOrDirInfo(Session *s, int sns, int dns, long mask, char *path,FInfo *i)
{
ncphdr(s, 0x5706, Tsubfun);
p8(s, sns);
p8(s, dns);
pl16(s, 0);
pl32(s, mask);
phps(s, path);
if (ncpcall(s) == -1)
return -1;
ginfo(s, i);
return 0;
}
|