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