<> <> <> <> <<>> DIRECTORY BasicTime USING [Now], GVNames USING [GetEntry, GetEntryInfo, GetMembers, MemberInfo, NameType, RListHandle], IO USING [int, PutF, PutRope, STREAM, rope, time], Process USING [Detach], Rope USING [Cat, Equal, Fetch, Find, Length, ROPE, Substr], ViewerIO USING [CreateViewerStreams]; << Beware; manual editing is required before running this tool >> InboxCount: CEDAR PROGRAM IMPORTS BasicTime, IO, GVNames, Process, Rope, ViewerIO SHARES GVNames = { ROPE: TYPE = Rope.ROPE; AppendRopeToList: PROC [list: LIST OF ROPE, rope: ROPE] RETURNS [LIST OF ROPE] = BEGIN IF list = NIL THEN RETURN[CONS[rope, NIL]]; FOR temp: LIST OF ROPE _ list, temp.rest DO IF temp.rest = NIL THEN { temp.rest _ CONS[rope, NIL]; RETURN[list]; }; ENDLOOP; END; FindRegistry: PROC [name: ROPE] RETURNS [registry: ROPE] = BEGIN length: INT _ Rope.Length[name]; FOR i: INT DECREASING IN [0 .. length) DO IF Rope.Fetch[name, i] = '. THEN RETURN[Rope.Substr[name, i+1, length - i-1]]; REPEAT FINISHED => RETURN[NIL]; ENDLOOP; END; Registry: TYPE = {pa, fx, pasa, es, henr, wbst, dlos, rx, xrcc, eosa, guest, osda, chi}; BoxNum: TYPE = [0..2); registry: ARRAY Registry OF ROPE = [ pa: "PA", fx: "FX", pasa: "Pasa", es: "ES", henr: "Henr", wbst: "Wbst", dlos: "Dlos", rx: "RX", xrcc: "XRCC", eosa: "EOSA", guest: "Guest", osda: "OSDA", chi: "CHI"]; expected: ARRAY Registry OF LIST OF ROPE = [ pa: LIST["OSBUNorth", "OSBUBayshore", "Sunnyvale", "PARC", "rdes", "sbderx", "esxc16", "ns", "SCB1Versatec", "ESCP8", "DlosLV", "SanDiegoXCSS"], fx: LIST["IWAFX", "ShinjukuMizunoFX", "pavisitors"], pasa: LIST["XSIS", "XSISHQ", "XOSMAR", "ns"], es: LIST["OSBUSouth", "ElSegundo", "osdassociates", "ESCP8", "ESM8", "ESXC15", "ESXC16", "esxcost", "ESGSDWCO", "SanDiegoXCSS", "osbunorth", "ns"], henr: LIST["WBST139", "ns"], wbst: LIST["Roch", "Wbst102A", "Wbst128", "Wbst129","Roch805","Wbst311", "WBST139", "ns"], dlos: LIST["dloslv", "dloslc", "dlosce", "DlosNSC", "Dloslv-Comm", "OSService", "dloscss", "dlosEtron"], rx: LIST["OSBURX", "RXHRX", "SBDERX", "WGCERX", "BUSRX", "SBDRXN", "AYLTSDRX", "SOLNAMORXS", "IHAIL", "CB19RXF", "EspooRXSF", "HKRXS", "ZurichRXCH", "osbuNorth"], xrcc: LIST["XRCC-NS", "Wbst147"], eosa: NIL, guest: NIL, osda: LIST["pavisitors"], chi: NIL]; TotalRec: TYPE = RECORD [i, ifs, ns: INT _ 0]; totals: ARRAY Registry OF TotalRec _ []; ServerNum: TYPE = [0..21); server: ARRAY ServerNum OF ROPE = [ "Cabernet.ms", "Chardonnay.ms", "Salvador.ms", "Semillon.ms", "Burger.ms", "Riesling.ms", "Koshu.ms", "PinotNoir.ms", "Concord.ms", "Mission.ms", "Gamay.ms", "CheninBlanc.ms", "Flora.ms", "Muscat.ms", "Catawba.ms", "Aurora.ms", "BacoNoir.ms", "Barbera.ms", "deChaunac.ms", "NoMailboxes.ms", "Other.ms"]; columnsPerPage: NAT = 7; pages: NAT = (Registry.LAST.ORD+columnsPerPage)/columnsPerPage; data: ARRAY ServerNum OF ARRAY Registry OF ARRAY BoxNum OF INT _ ALL[ALL[ALL[0]]]; totalUsers, totalIfs, totalNsForwarding: INT _ 0; primary: ARRAY ServerNum OF LIST OF ROPE _ ALL[NIL]; secondary: ARRAY ServerNum OF LIST OF ROPE _ ALL[NIL]; noMailboxes, nsMailboxes, finks: LIST OF ROPE _ NIL; NSForwarding: PROC [registry: Registry, user: ROPE, mailbox: ROPE] RETURNS [yes: BOOL _ FALSE] = { target: ROPE _ FindRegistry[mailbox]; FOR ok: LIST OF ROPE _ expected[registry], ok.rest UNTIL ok = NIL DO IF Rope.Equal[target, ok.first, FALSE] THEN RETURN[TRUE]; REPEAT FINISHED => RETURN[FALSE]; ENDLOOP; }; DoRegistry: PROC [r: Registry, g: group GVNames.MemberInfo] = { individuals, ifs, forwarding, nsForwarding, empty: INT _ 0; FOR mbrs: GVNames.RListHandle _ g.members, mbrs.rest UNTIL mbrs=NIL DO rc: GVNames.NameType; info: REF GVNames.GetEntryInfo; userName: ROPE _ mbrs.first; [rc, info] _ GVNames.GetEntry[userName]; IF rc # individual THEN ERROR; WITH info SELECT FROM i: REF GVNames.GetEntryInfo[individual] => BEGIN b: BoxNum _ 0; expectNone: BOOLEAN _ FALSE; forward: LIST OF ROPE _ i.forward.current; boxes: LIST OF ROPE _ i.sites.current; individuals _ individuals + 1; IF forward # NIL THEN { boxes _ NIL; SELECT TRUE FROM forward.rest # NIL => forwarding _ forwarding + 1; Rope.Equal[forward.first, "NoMailboxes.ms", FALSE] => { noMailboxes _ AppendRopeToList[noMailboxes, userName]; forward _ NIL; ifs _ ifs + 1; expectNone _ TRUE; }; NSForwarding[r, userName, forward.first] => { nsMailboxes _ AppendRopeToList[nsMailboxes, userName]; nsForwarding _ nsForwarding + 1; forward _ NIL; expectNone _ TRUE; }; ENDCASE => forwarding _ forwarding + 1; }; FOR sites: GVNames.RListHandle _ forward, sites.rest UNTIL sites=NIL DO site: ROPE = sites.first; IF site.Find["@"] # -1 THEN out.PutF[" %g has Arpanet forwarding to %g. ***\n", IO.rope[userName], IO.rope[site]] ELSE out.PutF[" %g has forwarding to %g.\n", IO.rope[userName], IO.rope[site]]; ENDLOOP; --i.sites-- IF boxes = NIL AND forward = NIL AND ~expectNone THEN { empty _ empty + 1; finks _ AppendRopeToList[finks, userName]; }; FOR sites: GVNames.RListHandle _ boxes, sites.rest UNTIL sites=NIL DO site: ROPE = sites.first; FOR s: ServerNum IN ServerNum DO IF Rope.Equal[site, server[s], FALSE] THEN { data[s][r][b] _ data[s][r][b] + 1; IF b = 0 THEN primary[s] _ AppendRopeToList[primary[s], userName] ELSE secondary[s] _ AppendRopeToList[secondary[s], userName]; EXIT}; REPEAT FINISHED => { data[LAST[ServerNum]][r][b] _ data[LAST[ServerNum]][r][b] + 1; out.PutF[" %g has a funny mailbox: %g. ****\n", IO.rope[userName], IO.rope[site]]; }; ENDLOOP; --s-- IF b # LAST[BoxNum] THEN b _ b + 1; ENDLOOP; --i.sites-- END; --individual-- ENDCASE => ERROR; ENDLOOP; --g.members-- out.PutF[" There are %g individuals in the %g registry.\n", IO.int[individuals], IO.rope[registry[r]]]; IF forwarding # 0 THEN out.PutF[" %g have forwarding.\n", IO.int[forwarding]]; IF nsForwarding # 0 THEN out.PutF[" %g have forwarding to NS mail addresses.\n", IO.int[nsForwarding]]; IF empty # 0 THEN out.PutF[" %g have no mailboxes.\n", IO.int[empty]]; IF noMailboxes # NIL THEN { out.PutRope[" The following individuals have forwarding to NoMailboxes.ms: "]; FOR none: LIST OF ROPE _ noMailboxes, none.rest UNTIL none = NIL DO IF none # noMailboxes THEN out.PutF[", "]; out.PutF["%g", IO.rope[none.first]]; ENDLOOP; out.PutF[".\n"]; noMailboxes _ NIL; }; IF nsMailboxes # NIL THEN { out.PutRope[" The following individuals have forwarding to NS Mailboxes: "]; FOR none: LIST OF ROPE _ nsMailboxes, none.rest UNTIL none = NIL DO IF none # nsMailboxes THEN out.PutF[", "]; out.PutF["%g", IO.rope[none.first]]; ENDLOOP; out.PutF[".\n"]; nsMailboxes _ NIL; }; IF finks # NIL THEN { out.PutRope[" ****** The following individuals have no mailboxes: "]; FOR fink: LIST OF ROPE _ finks, fink.rest UNTIL fink = NIL DO IF fink # finks THEN out.PutF[", "]; out.PutF["%g", IO.rope[fink.first]]; ENDLOOP; out.PutF[".\n"]; finks _ NIL; }; out.PutF["\n"]; totals[r].i _ individuals - forwarding - empty - ifs; totals[r].ifs _ ifs; totals[r].ns _ nsForwarding; totalUsers _ totalUsers + individuals - forwarding - empty - ifs; totalIfs _ totalIfs + ifs; totalNsForwarding _ totalNsForwarding + nsForwarding; }; out: IO.STREAM = ViewerIO.CreateViewerStreams["Inbox Count"].out; DoIt: PROC = { out.PutF["\n%t Inbox counter started.\n\n", IO.time[] ]; FOR r: Registry IN Registry DO out.PutF["%t Working on %g.\n", IO.time[], [rope[registry[r]]] ]; WITH GVNames.GetMembers[Rope.Cat["individuals.", registry[r]]] SELECT FROM g: GVNames.MemberInfo[group] => DoRegistry[r, g]; ENDCASE => ERROR; ENDLOOP; --r-- out.PutF["%t Scan Finished.\n", IO.time[]]; out.PutF["\014\n"]; -- This gets everything on one sheet if you use Cedar's Print command BEGIN first: Registry _ Registry.FIRST; last: Registry _ first; FOR page: INT IN [0..pages) DO <> THROUGH [0..columnsPerPage) DO IF last = Registry.LAST THEN EXIT; last _ last.SUCC; ENDLOOP; out.PutF["\014%15g", [rope[" "]]]; -- blanks -- FOR r: Registry IN [first..last] DO out.PutF["%-9g", [rope[registry[r]]]]; ENDLOOP; out.PutRope["\n\n"]; FOR s: ServerNum IN ServerNum DO serverName: ROPE _ Rope.Substr[server[s], 0, Rope.Length[server[s]]-3]; out.PutF["%-12g", [rope[serverName]]]; FOR r: Registry IN [first..last] DO out.PutF["%4d%4d ", IO.int[data[s][r][0]], IO.int[data[s][r][1]]]; ENDLOOP; out.PutRope["\n\n"]; ENDLOOP; IF last # Registry.LAST THEN first _ last.SUCC; ENDLOOP; END; FOR s: INT IN ServerNum DO serverName: ROPE _ Rope.Substr[server[s], 0, Rope.Length[server[s]]-3]; out.PutRope["\014\n"]; out.PutF["%g has the following primary mailboxes: ", [rope[serverName]]]; FOR list: LIST OF ROPE _ primary[s], list.rest UNTIL list = NIL DO IF list # primary[s] THEN out.PutF[", "]; out.PutF["%g", IO.rope[list.first]]; ENDLOOP; out.PutRope[".\n"]; ENDLOOP; FOR s: INT IN ServerNum DO serverName: ROPE _ Rope.Substr[server[s], 0, Rope.Length[server[s]]-3]; out.PutRope["\014\n"]; out.PutF["%g has the following secondary mailboxes: ", [rope[serverName]]]; FOR list: LIST OF ROPE _ secondary[s], list.rest UNTIL list = NIL DO IF list # secondary[s] THEN out.PutF[", "]; out.PutF["%g", IO.rope[list.first]]; ENDLOOP; out.PutRope[".\n"]; ENDLOOP; out.PutRope["\n\nTotals:\n\n"]; out.PutF["There are %g unique users in the system.\n", IO.int[totalUsers]]; out.PutF["%g of these have no mailboxes.\n", IO.int[totalIfs]]; out.PutF["%g are forwarded to NS mail addresses.\n\n\n", IO.int[totalNsForwarding]]; FOR r: Registry IN Registry DO out.PutF[" %g unique users in %g.\n", IO.int[totals[r].i], [rope[registry[r]]] ]; out.PutF[" %g of these have no mailboxes.\n", IO.int[totals[r].ifs]]; out.PutF[" %g are forwarded to NS mail addresses.\n\n", IO.int[totals[r].ns]]; ENDLOOP; primary _ ALL[NIL]; secondary _ ALL[NIL]; -- ka wahammy }; TRUSTED { Process.Detach[FORK DoIt[]]; }; }.