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

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


#include <u.h>
#include <libc.h>
#include <bio.h>
#include "ncp.h"

extern Session *Sess;			// netware session

static char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

/*
 * Service Advertising Protocol Objcet Identifiers
 * This is a hopelessly provincial list for Snell & Wilcox,
 * though the info is not very usefull anyway
 */ 
static struct {
	int id;
	char *name;
} saptab[] = {
	{ 0x0000, "?" },
	{ 0x0001, "User" },
	{ 0x0002, "Group" },
	{ 0x0003, "Print queue" },
	{ 0x0004, "File server" },
	{ 0x0007, "Print server" },
	{ 0x0047, "Advertising print server" },
	{ 0x0107, "RSPX server" },
	{ 0x0119, "Comms server" },
	{ 0x0135, "NNS profile" },
	{ 0x0278, "NDS tree" },
	{ 0x030C, "HP LaserJet" },
	{ 0x023F, "SMS test & dev" },
	{ 0x0414, "NetSprint" },
	{ 0x044C, "Archive server" },
	{ 0x004B, "Btrieve server" },
	{ 0x0640, "NT RPC-Server" },
};

static long 
gval32(uchar **p)
{
	long l= *(*p)++;
	l = (l << 8) | *(*p)++;
	l = (l << 8) | *(*p)++;
	l = (l << 8) | *(*p)++;
	return l;
}

static char *
sapstr(int id)
{
	int i;
	static char buf[8];

	for (i = 0; i < nelem(saptab); i++)
		if (saptab[i].id == id)
			return saptab[i].name;
	snprint(buf, sizeof(buf), "0x%ud", id);
	return buf;
}

static void
netaddr(Fmt *f, uchar *s)
{
	uchar *nz;
	for (nz = s +IPXADDRLEN -1; *nz == 0 && nz > s; nz--)
		continue;

	if ((nz - s) == 0)
		return;

	/* looks like a TCP/IP address */
	if ((nz - s) == 3){
		fmtprint(f, "%ud.%ud.%ud.%ud", s[0], s[1], s[2], s[3]);
		return;
	}

	/* probably IPX -  network:address:port */
	fmtprint(f, "%02x%02x%02x%02x:", s[0], s[1], s[2], s[3]);
	fmtprint(f, "%02x%02x%02x%02x%02x%02x:", s[4], s[5], s[6], s[7], s[8], s[9]);
	fmtprint(f, "%02x%02x", s[10], s[11]);
}

static void
strlwrprop(Fmt *f, uchar *val)
{
	if (*val)
		fmtprint(f, "%q", strlwr((char *)val));
}

static void
strprop(Fmt *f, uchar *val)
{
	if (*val)
		fmtprint(f, "%q", (char *)val);
}

static void
acctbal(Fmt *f, uchar *val)
{
	long now = gval32(&val);
	long limit = gval32(&val);

	fmtprint(f, "%uld/%uld", now, limit);
}

static void
lastlog(Fmt *f, uchar *val)
{

	fmtprint(f, "'%d %s %d %d:%d:%d'", val[2], months[val[1]-1],
		val[0]+1900, val[3], val[4], val[5]);
}

static void
logctrl(Fmt *f, uchar *val)
{
	fmtprint(f, " acct_expire='%d %s %d'",
			val[2] +1, months[val[1]-1], val[0]+1900);
	fmtprint(f, " acct_expired=%s", (val[3])? "yes": "no");
	fmtprint(f, " pass_expiration='%d %s %d'",
			val[6] +1, months[val[5]], val[4]+1900);
	fmtprint(f, " pass_grace_logins=%d", val[7]);

	/* this is incomplete, its dull information anyway */
}
static void
idlist(Fmt *f, uchar *val)
{
	long n;

#ifndef NOCACHE
	char *name;
	uid2names(Sess, gval32(&val), &name, nil);
	fmtprint(f, "%q", strlwr(name));
	while((n = gval32(&val)) != 0){
		uid2names(Sess, n, &name, nil);
		fmtprint(f, ",%q", strlwr(name));
	}
#else
	int type;
	char name[OBJNAMLEN];
	if (GetBinderyObjectName(Sess, gval32(&val), name, &type) == 0)
		fmtprint(f, "%q", strlwr(name));
	while((n = gval32(&val)) != 0){
		if (GetBinderyObjectName(Sess, n, name, &type) != 0)
			break;
		fmtprint(f, ",%q", strlwr(name));
	}
#endif
}

struct {
	char *name;
	void (*func)(Fmt *, uchar *);
} proptab[] = {
	{ "object_class",	nil },		/* already know object type */
	{ "guid",		nil },		/* global unique ID */
	{ "revision",		nil },
	{ "version",		nil },
	{ "acl",		nil },
	{ "other_guid",		nil },
	{ "sap_name",		strlwrprop },
	{ "l",			strprop },	/* location */
	{ "ou",			strprop },	/* organisational unit */
	{ "o",			strprop },	/* organisation */
	{ "default_profile",	strprop },
	{ "phone_number",	strprop },
	{ "login_control",	logctrl },
	{ "back_link",		idlist },
	{ "security_equals",	idlist },
	{ "message_server",	nil },
	{ "operators",		idlist },
	{ "managers",		idlist },
	{ "ps_operators",	idlist },
	{ "q_operators",	idlist },
	{ "host_server",	idlist },
	{ "host_device",	idlist },
	{ "ps_users",		idlist },
	{ "q_users",		idlist },
	{ "q_servers",		idlist },
	{ "ps_directory",	strlwrprop },
	{ "q_directory",	strlwrprop },
	{ "account_balance",	acctbal },
	{ "description",	strprop },
	{ "surname",		strprop },
	{ "given_name",		strprop },
	{ "identification",	strprop },
	{ "homedirpath",	strlwrprop },
	{ "net_address",	netaddr },
	{ "misc_login_info",	lastlog },
	{ "groups_i'm_in",	idlist },
	{ "group_members",	idlist },
};

static void
dmp_prop(Fmt *f, char *obj, char *prop, int type)
{
	int i, seg, flags, more = 1;
	uchar buf[PROPLEN];

	strlwr(prop);
	seg = 1;
	while (more){
		if (ReadPropertyValue(Sess, obj, type, prop, seg++, buf, &more, &flags) != 0)
			break;

		for (i = 0; i < nelem(proptab); i++)
			if (strcmp(proptab[i].name, prop) == 0){
				if (proptab[i].func == nil)
					break;
				fmtprint(f, "%s=", prop);
				(*proptab[i].func)(f, buf);
				fmtprint(f, " ");
				break;
			}
		if (i >= nelem(proptab))
			fmtprint(f, "%s=?? ", prop);
	}	
}

int
bindery(Fmt *f)
{
	long seq;
	int more, type, id = -1L, flags, secure, hasprops, hasval;
	char *p, *name, namebuf[OBJNAMLEN], obj[OBJNAMLEN], prop[PROPNAMLEN];

	while (ScanBinderyObject(Sess, "*", OTwild, &id, obj, &type,
	    &hasprops, &flags, &secure) == 0){

		strcpy(namebuf, obj);
		name = namebuf;

		switch(type){
		case OTbtrive:
			if (strlen(name) > 13)
				name[13] = 0;
			break;
		case OTtreename:
			if ((p = strrchr(name + MAXTRENAM -1, '_')))
				while(*p == '_')
					p--;
				*(++p) = 0;
			break;
		case OTlaserjet:
			if (strlen(name) > 16)
				name += 16;
			break;
		default:
			break;
		}

		fmtprint(f, "name=%q type=%q ", strlwr(name), sapstr(type));
 
		if (!hasprops){
			fmtprint(f, "\n");
			continue;
		}
		
		seq = -1;
		more = 1;
		while(more){
			if (ScanProperty(Sess, obj, type, "*", &seq, 
			    prop, &flags, &secure, &hasval, &more) != 0){
				break;
			}
			if (hasval)
				dmp_prop(f, obj, prop, type);
		}
		fmtprint(f, "\n");
	}
	return 0;
}


int
who(Fmt *f)
{
	char *usr;
	int maxconn = MAXCONN;
	long sec, logtime;
	int days, hrs, min;
	uchar addr[IPXADDRLEN];
	int ct, i, id, type;
	char *p, name[OBJNAMLEN], when[32];
	static const char* contype[] = {
		"-", "Clib", "NCP", "NLM", "AFP",  "FTAM",
		"ANCP",  "ACP",  "SMB", "WinSock", "HTTP", "TCP/IP",
	};

	for (i = 0; i < maxconn; i++){
		*name = 0;
		memset(addr, 0, sizeof(addr));
		if (GetStationsLoggedInfo(Sess, i, &id, &type, name, &logtime) == 0){
			if (strcmp("NOT_LOGGED_IN", name) == 0)
				continue;

			if (*(usr = name) == '.')
				usr++;
			if ((p = strchr(usr, '.')) != nil)
				*p = 0;

			fmtprint(f, "%-20q ", strlwr(usr));

			sec = time(nil) - logtime;
			days = sec / (60L * 60L * 24L);
			sec -= days * (60L * 60L * 24L);
			hrs  = sec / (60L * 60L);
			sec -= hrs * (60L * 60L);
			min  = sec / 60L;
			sec -= min * 60L;
			if (days)
				snprint(when, sizeof(when), "%d %d:%d:%ld ", days, hrs, min, sec);
			else
				snprint(when, sizeof(when), "%d:%d:%ld ", hrs, min, sec);
			fmtprint(f, "%-16s", when);

			if (GetInternetAddress(Sess, i, addr, &ct) == 0){
				fmtprint(f, " %-8s ", contype[ct]);
				netaddr(f, addr);
			}
			fmtprint(f, "\n");
		}
	}
	return 0;
}

int
whoami(Fmt *f)
{
	int type, seg, more, flags;
	uchar val[PROPLEN];
	char name[PROPLEN], sur[PROPLEN], giv[PROPLEN],  ident[PROPLEN],
		tel[PROPLEN], loc[PROPLEN], dep[PROPLEN];

	*name = *sur = *giv = *ident = *tel = *loc = *dep = 0;

	GetBinderyObjectName(Sess, Myuid, name, &type);
	strlwr(name);

	ReadPropertyValue(Sess, name, type, "indentification", 1, ident, &more, &flags);
	ReadPropertyValue(Sess, name, type, "surname", 1, sur, &more, &flags);
	ReadPropertyValue(Sess, name, type, "given_name", 1, giv, &more, &flags);
	ReadPropertyValue(Sess, name, type, "phone_number", 1, tel, &more, &flags);
	ReadPropertyValue(Sess, name, type, "l", 1, loc, &more, &flags);
	ReadPropertyValue(Sess, name, type, "ou", 1, dep, &more, &flags);
	ReadPropertyValue(Sess, name, type, "login_control", 1, val, &more, &flags);

	fmtprint(f, "user:	%s\n", name);
	fmtprint(f, "host:	%s\n", Host);

	fmtprint(f, "groups:	");
	seg = 1;
	more = 1;
	while (more){
		if (ReadPropertyValue(Sess, name, type, "groups_i'm_in", seg++,
		    val, &more, &flags) != 0)
			break;
		idlist(f, val);
	}
	fmtprint(f, "\n");

	fmtprint(f, "really:	%s %s %s\n", giv, sur, ident);
	fmtprint(f, "phone:	%s\n", tel);
	fmtprint(f, "location:	%s\n", loc);
	fmtprint(f, "dept:	%s\n", dep);
	if (val[0] == 0)
		fmtprint(f, "acct:	forever\n");
	else
		fmtprint(f, "acct:	until %d %s %d\n",
			val[2] +1, months[val[1]-1], val[0]+1900);

	if (val[4] == 0)
		fmtprint(f, "passwd:	forever\n");
	else
		fmtprint(f, "passwd:	until %d %s %d\n",
			val[6] +1, months[val[5]-1], val[4]+1900);
	fmtprint(f, "grace-logins:	%d\n", val[7]);
	return 0;
}


int
volumes(Fmt *f)
{
	VInfo vi;
	int v, avail, m;

	for (v = 0; v < Numvol; v++)
		if (GetVolumeAndPurgeInfo(Sess, v, &vi) == 0 && *vi.name){
			m = 2048/vi.sectperblock;
			avail = vi.total - (vi.free + vi.purgable);
			if (vi.dir_total == 2147483647)
				vi.dir_avail = vi.dir_total = 0;
				
			fmtprint(f, "%-17s	%8d/%-8d	%6d/%-6d\n",
				strlwr(vi.name), avail / m, vi.total / m,
				vi.dir_avail, vi.dir_total);
		}
	return 0;
}

int
printers(Fmt *f)
{
	char name[OBJNAMLEN];
	int type, id = -1, flags, sec, hasp;

	while (ScanBinderyObject(Sess, "*", OTprintqueue, &id, name, &type, &hasp, &flags, &sec) == 0)
		fmtprint(f, "%s\n", strlwr(name));
	return 0;
}

int
session(Fmt *f)
{
	FSInfo fsi;
	long fstime;
	char *usr, *grp;

	GetFileServerInfo(Sess, &fsi);
	uid2names(Sess, Myuid, &usr, &grp);
	if (GetFileServerDateAndTime(Sess, &fstime) == 0)
		Slip = fstime - time(nil);

	fmtprint(f, "%s %s %d.%d %+d %d %d\n",
		usr, strlwr(fsi.name),
		fsi.fsvermaj, fsi.fsvermin,
		Slip, fsi.numconn, Sess->mtu);
	return 0;
}

int
servers(Fmt *f)
{
	char name[OBJNAMLEN];
	int type, id = -1, flags, sec, hasp;

	while (ScanBinderyObject(Sess, "*", OTfileserver, &id, name, &type, &hasp, &flags, &sec) == 0)
		fmtprint(f, "%s\n", strlwr(name));
			
	return 0;
}

int
users(Fmt *f)
{
	int more, type, id = -1, flags, sec, hasp;
	char sur[PROPLEN], giv[PROPLEN], name[OBJNAMLEN],
		ident[PROPLEN], tel[PROPLEN], loc[PROPLEN], dep[PROPLEN];

	while (ScanBinderyObject(Sess, "*", OTuser, &id, name, &type, &hasp, &flags, &sec) == 0){
		*giv = *sur = *tel = *loc = *dep = *ident = 0;

		ReadPropertyValue(Sess, name, type, "indentification", 1, ident, &more, &flags);
		ReadPropertyValue(Sess, name, type, "surname", 1, sur, &more, &flags);
		ReadPropertyValue(Sess, name, type, "given_name", 1, giv, &more, &flags);
		ReadPropertyValue(Sess, name, type, "phone_number", 1, tel, &more, &flags);
		ReadPropertyValue(Sess, name, type, "l", 1, loc, &more, &flags);
		ReadPropertyValue(Sess, name, type, "ou", 1, dep, &more, &flags);

		if (*giv == 0){
			strcpy(giv, sur);
			*sur = 0;
		}
		if (*ident)
			fmtprint(f, "%s:%ud:%s:%s:%s:%s\n", strlwr(name), id, ident, tel, dep, loc);
		else
			fmtprint(f, "%s:%ud:%s %s:%s:%s:%s\n", strlwr(name), id, giv, sur, tel, dep, loc);
	}
	return 0;
}

int
groups(Fmt *f)
{
	long seg;
	char obj[OBJNAMLEN];
	uchar buf[PROPLEN];
	int more, type, id = -1, flags, sec, hasp;

	while (ScanBinderyObject(Sess, "*", OTgroup, &id, obj, &type, &hasp, &flags, &sec) == 0){
		strlwr(obj);
		fmtprint(f, "%s:%ud:", obj, id);

		seg = 1;
		more = 1;
		while (more){
			if (ReadPropertyValue(Sess, obj, type, "group_members", seg++, buf, &more, &flags) != 0)
				break;
			idlist(f, buf);
		}
		fmtprint(f, "\n");
	}
	return 0;
}

int
ping(Fmt *f)
{
	FInfo i;
	vlong then;
	enum {
		RIMstat = RIMname|RIMattr|RIMsize|RIMarch|RIMmodif|
			RIMcreate|RIMns|RIMdir|RIMrights
	};

	then = nsec();
	if (ObtainFileOrDirInfo(Sess, NSlong, NSlong, RIMstat, "/user/Design", &i) != 0)
		return -1;
	fmtprint(f, "%llud\n", (nsec() - then) / 1000LL);
	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 [email protected].