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