Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/root/sys/src/cmd/aux/ncpfs/rpc.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.