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]; InboxCount: PROGRAM IMPORTS BasicTime, IO, GVNames, Process, Rope, ViewerIO SHARES GVNames = BEGIN 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, sv, es, henr, wbst, dlos, rx, xrcc, dc, lb, sthq, ogc, eosa, guest, osda, siemens, chi}; BoxNum: TYPE = [0..2); registry: ARRAY Registry OF ROPE = [ pa: "PA", fx: "FX", pasa: "Pasa", sv: "SV", es: "ES", henr: "Henr", wbst: "Wbst", dlos: "Dlos", rx: "RX", xrcc: "XRCC", dc: "DC", lb: "LB", sthq: "Sthq", ogc: "OGC", eosa: "EOSA", guest: "Guest", osda: "OSDA", siemens: "Siemens", chi: "CHI"]; expected: ARRAY Registry OF LIST OF ROPE = [ pa: LIST["OSBUNorth", "OSBUBayshore", "PARC"], fx: LIST["IWAFX", "ShinjukuMizunoFX"], pasa: LIST["XSIS", "XSISHQ", "ns"], sv: LIST["EIS"], es: LIST["OSBUSouth", "ElSegundo", "osdassociates", "ESCP8", "ESXC15", "ESXC16", "esxcost", "ESGSDWCO", "SanDiegoXCSS"], henr: LIST["ns"], wbst: LIST["Wbst128", "Wbst129","Roch805","WBST311", "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"], dc: NIL, lb: LIST["ns"], sthq: LIST["ns"], ogc: NIL, eosa: NIL, guest: NIL, osda: LIST["pavisitors"], siemens: LIST["TLSiemens", "OsbuBayshore", "ZTISOF"], chi: NIL]; TotalRec: TYPE = RECORD[i: INT_0, ns: INT_0]; totals: ARRAY Registry OF TotalRec _ [ pa: [0,0], fx: [0,0], pasa: [0,0], sv: [0,0], es: [0,0], henr: [0,0], wbst: [0,0], dlos: [0,0], rx: [0,0], xrcc: [0,0], dc: [0,0], lb: [0,0], sthq: [0,0], ogc: [0,0], eosa: [0,0], guest: [0,0], osda: [0,0], siemens: [0,0], chi: [0,0]]; ServerNum: TYPE = [0..24); server: ARRAY ServerNum OF ROPE = [ "Cabernet.ms", "Chardonnay.ms", "Salvador.ms", "Semillon.ms", "Burger.ms", "Riesling.ms", "Zinfandel.ms", "Koshu.ms", "PinotNoir.ms", "Concord.ms", "Mission.ms", "CheninBlanc.ms", "Flora.ms", "Gamay.ms", "Merlot.ms", "Muscat.ms", "Catawba.ms", "Aurora.ms", "BacoNoir.ms", "Chelois.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, 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] = BEGIN 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; END; DoRegistry: PROC [r: Registry, g: group GVNames.MemberInfo] = BEGIN individuals, 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; 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.\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; totals[r].ns _ nsForwarding; totalUsers _ totalUsers + individuals - forwarding - empty; totalnsForwarding _ totalnsForwarding + nsForwarding; END; out: IO.STREAM = ViewerIO.CreateViewerStreams["Inbox Count"].out; DoIt: PROC = BEGIN 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 users in the system.\n", IO.int[totalUsers]]; out.PutF["%g of these are forwarded to NS.\n\n\n", IO.int[totalnsForwarding]]; FOR r: Registry IN Registry DO out.PutF[" %g individuals in %g.\n", IO.int[totals[r].i], [rope[registry[r]]] ]; out.PutF[" %g forwarded to NS.\n\n", IO.int[totals[r].ns]]; ENDLOOP; primary _ ALL[NIL]; secondary _ ALL[NIL]; -- ka wahammy END; Process.Detach[FORK DoIt[]]; END. 0InboxCount.mesa (derived from GVWatcher.mesa), produce inbox counts for each server/registry M. D. Schroeder, December 31, 1982 4:55 pm Hal Murray June 6, 1985 7:40:04 pm PDT John Larson, December 18, 1985 9:44:56 pm PST There must be a better way, but I don't want to get hit with a Bounds Fault Κ ο˜šœ\™\Jšœ*™*Jšœ&™&Icode™-—J˜šΟk ˜ Jšœ œ˜JšœœI˜VJšœœœ˜2Jšœœ ˜Jšœœ#œ ˜;Jšœ œ˜%—J˜šœ ˜Jšœ œ3˜HJ˜—Jš˜J˜Jšœœœ˜J˜šΟnœœœœœœœœœœ˜PJš˜Jš œœ œœœ˜+š œœœœ˜+šœ œœ˜Jšœ œœ˜Jšœ ˜—Jšœ˜—Jšœ˜J˜—š ž œœœœ œ˜:Jš˜Jšœœ˜ š œœ œœ˜)Jšœœœ'˜NJšœœœœ˜Jšœ˜ —Jšœ˜—J˜Jšœ œj˜xJ˜J˜Jšœœ ˜J˜Jšœ œ œœχ˜—J˜J˜Jš1œ œ œœœœ œ+œ&œœ œwœœ8œcœ’œœœœœœ œ œœ.œ˜άJš œ œœœœ˜.šœ œ œ ˜'Jšœφ˜φ—J˜Jšœ œ ˜Jšœœ œœα˜€J˜Jšœœ˜šœœ œ ˜?J˜—Jšœœ œœ œœœœœœœ˜RJšœœ˜'Jšœ œ œœœœœœ˜4Jšœ œ œœœœœœ˜6Jš œ!œœœž˜5šž œœœ œœœœ˜`Jš˜Jšœœ˜%š œœœœœœ˜DJš œœœœœ˜9Jšœœœœ˜!Jšœ˜—Jš˜—J˜šž œœ-˜=Jš˜Jšœ.œ˜6šœ2œœ˜FJšœ˜Jšœœ˜Jšœ œ˜Jšœ(˜(Jšœœœ˜šœœ˜šœœ$˜*Jš˜J˜Jšœ œœ˜Jšœ œœœ˜*Jšœœœœ˜&Jšœ˜šœ œœ˜Jšœœ˜ š˜Jšœœ ˜2šœ,œ˜7Jšœ6˜6Jšœ œ˜Jšœ œ˜—šœ-˜-Jšœ6˜6Jšœ ˜ Jšœ œ˜Jšœ œ˜—Jšœ#˜*—šœ2œœ˜GJšœœ˜šœ˜Jšœ5œœ ˜V—Jšœ*œœ ˜PJšœΟc ˜——š œ œœ œœ œ˜7Jšœ˜Jšœ-˜-—šœ0œœ˜EJšœœ˜šœœ ˜ šœœ˜,Jšœ"˜"Jšœœ4˜AJšœ9˜=Jšœ˜—šœœ˜Jšœœœ˜>Jšœ2œœ˜W—JšœŸ˜—Jšœœ œ ˜#JšœŸ ˜—JšœŸ˜—Jšœœ˜—JšœŸ œ˜—Jšœ=œœ˜hJšœœ'œ˜QJšœœ-œ˜[Jšœ œ)œ ˜Išœœœ˜JšœO˜Oš œœœœœœ˜CJšœœ˜*Jšœœ˜$Jšœ˜—Jšœ˜Jšœœ˜—šœœœ˜JšœM˜Mš œœœœœœ˜CJšœœ˜*Jšœœ˜$Jšœ˜—Jšœ˜Jšœœ˜—šœ œœ˜JšœG˜Gš œœœœœœ˜=Jšœœ˜$Jšœœ˜$Jšœ˜—Jšœ˜Jšœœ˜—Jšœ˜J˜Jšœ/˜/Jšœ˜Jšœ;˜;Jšœ6˜6Jš˜—J˜Jšœœœ3˜AJ˜šžœœ˜ Jš˜J˜Jšœ,œ ˜8J˜šœ œ ˜Jšœ œ˜Ašœ;œ˜JJšœ1˜1Jšœœ˜—JšœŸ˜—J˜Jšœ œ ˜+J˜J˜šœŸF˜YJ˜—Jš˜Jšœœ˜!Jšœ˜šœœœ ˜JšœK™Kšœ˜Jšœœœœ˜"Jšœ œ˜Jšœ˜—Jšœ#Ÿ ˜/šœ œ˜#J˜&Jšœ˜—J˜šœœ ˜ Jšœ œ7˜GJ˜&šœ œ˜#Jšœœœ˜BJšœ˜—J˜Jšœ˜—Jšœœœœ˜/Jšœ˜—šœ˜J˜—šœœœ ˜Jšœ œ7˜GJ˜J˜Iš œœœœœœ˜BJšœœ˜)Jšœœ˜$Jšœ˜—Jšœ˜Jšœ˜—šœœœ ˜Jšœ œ7˜GJ˜JšœK˜Kš œœœœœœ˜DJšœœ˜+Jšœœ˜$Jšœ˜—Jšœ˜Jšœ˜—J˜Jšœ˜J˜Jšœ0œ˜DJšœ3œ˜NJ˜šœ œ ˜Jšœ&œ)˜QJšœ&œ˜