/* ------------------------------------------------------------------------ :Program. ListServer :Contents. manages mailinglists :Author. Martin Horneffer [mh] :Address. Warmweiherstr.18 :Address. D-52066 Aachen :EMail. mh@umshq.dfv.rwth-aachen.de :EMail. mh@AC2.maus.de :Author. Kai Bolay [kai] :Address. Hoffmannstr. 168 :Address. D-71229 Leonberg :EMail. kai@amokle.stgt.sub.org :Copyright. Freely Distributable, © 1993-94 Martin Horneffer, Kai Bolay :Language. ARexx :Translator. RexxMast ------------------------------------------------------------------------ */ /* * * $Id: ListServer.rexx,v 2.14 1994/08/25 00:19:11 mh Exp $ * * 1.0 [mh] 28-Sep-93 * 1.1 [mh] 7-Dec-93 added config "alias" * 1.2 [mh] 21-Dec-93 fixed three bugs with multiple lists * 1.3 [mh] 23-Dec-93 now drops FidoID and MausID for new msgs * 1.4 [kai] 10-Jan-94 MakeFlags() * 2.0 [kai] 10-Feb-94 Added list management * * Revision 2.12 1994/05/04 08:10:19 mh * reduced mail-tailer lines to be only 70 chars wide * * Revision 2.11 1994/05/02 23:56:22 mh * LogicalToName/Addr * * Revision 2.10 1994/04/05 22:26:16 mh * don't use "iterate" * * Revision 2.9 1994/02/28 14:32:53 mh * fixed some bugs * * Revision 2.8 1994/02/28 14:15:42 mh * multiple notify-msgs for multiple adds/removes * * Revision 2.7 1994/02/28 14:09:13 mh * added auto help [kai] * added notification [kai] * some bugs fixed [kai] * notification only when needed * * Revision 2.6 1994/02/24 19:44:53 mh * Made commands and listnames case-insensitive. * Fixed a bug in FAQ and DESCRIPTION. * Added "accesss" config. * * Revision 2.5 1994/02/22 18:40:00 mh * fixed bug introduced in 1.3 * * Revision 2.4 1994/02/15 15:25:54 kai * first mail was not sent * * Revision 2.3 1994/02/14 21:08:07 kai * cleanup * * Revision 2.3 1994/02/14 21:08:07 kai * cleanup * * Revision 2.2 1994/02/10 17:37:17 kai * still some bugs to kill * * Revision 2.1 1994/02/10 16:01:07 kai * fixed lots of bugs * * Revision 2.0 1994/02/10 13:08:31 kai * started using RCS * * */ /* Config-File: mailinglist.hostname mailinglist.server mailinglist.helpfile mailinglist.lists mailinglist.list.group mailinglist.list.descfile mailinglist.list.alias mailinglist.list.users mailinglist.list.access */ /* Server-Commands: QUIT HELP USERS LIST/A INDEX ADD LIST/A,NAME/K,ADDR/K SUBSCRIBE LIST/A,NAME/K,ADDR/K REMOVE LIST/A,NAME/K,ADDR/K DELETE LIST/A,NAME/K,ADDR/K UNSUBSCRIBE LIST/A,NAME/K,ADDR/K DESCRIPTION LIST/A (DESC LIST/A) (FAQ LIST/A) */ /*** Startup ***/ options results options failat 20 signal on BREAK_C signal on BREAK_D signal on BREAK_E signal on BREAK_F signal on ERROR signal on HALT signal on IOERR signal on SYNTAX call addlib('ums.library', 0, -210, 8) call addlib('rexxdossupport.library', 0, -30, 1) UMS_Consts = include("REXX:UMSConsts.rexx") if UMS_Consts = "" then do say "cannot read UMS include-file!" exit 20 end interpret UMS_Consts parse arg arguments ProgramName = "ListServer"; ArgsTemplate = "NAME/A,PASSWORD,SERVER/K,LOOP/K" args.password = "" args.server = "" args.loop = "" if strip(arguments) = '?' then do address command 'echo noline "' ArgsTemplate ': "' pull arguments end; else nop if ~ReadArgs(arguments,ArgsTemplate,"args.") then do say Fault(RC,ProgramName) exit 10 end; else nop drop arguments account = UMSLogin(args.name, args.password, args.server) if account = 0 then do say "unable to login." exit 10 end /*** Main ***/ say '0a'x ||date() time()||"> Startup mailinglist-sever" if ReadConfig() then do say "Config ok" do forever call ProcessLists() if args.loop = '' then break address command args.loop end; end; else do say "Config trouble" end; say date() time()||"> Done" /*** Final cleanup ***/ RC = 0 call ERROR SYNTAX: say "syntax error" errortext(rc) BREAK_C: BREAK_D: BREAK_E: BREAK_F: ERROR: HALT: IOERR: IF RC ~= 0 THEN DO say "RC" rc "Line" sigl END /*** Logout ***/ if account ~= 0 then do call UMSLogout(account) account = 0 end exit /*** config stuff ***/ CheckAccess: procedure expose lists. true false string = arg(1) || "," || arg(2) list = upper(arg(3)) do i = 0 to lists.count if upper(lists.i.name) = list then do return MatchPattern( lists.i.access, string, "N") end end return false AddUser: procedure expose lists. true false user = arg(1); naddr = arg(2); list = upper(arg(3)) do i = 0 to lists.count if upper(lists.i.name) = list then do j = lists.i.mail.count + 1 lists.i.mail.j.name = user lists.i.mail.j.addr = naddr lists.i.mail.count = j return true end end return false RemUser: procedure expose lists. true false user = arg(1); naddr = arg(2); list = upper(arg(3)) do i = 0 to lists.count if upper(lists.i.name) = list then do remove = false do j = 0 to lists.i.mail.count if (lists.i.mail.j.name = user) & (lists.i.mail.j.addr = naddr) then do remove = true end if remove = true then do if j < lists.i.mail.count then do k = j + 1 lists.i.mail.j.name = lists.i.mail.k.name lists.i.mail.j.addr = lists.i.mail.k.addr end; else do drop lists.i.mail.j.name drop lists.i.mail.j.addr end end end if remove = true then do lists.i.mail.count = lists.i.mail.count - 1 return true end; else do return false end end end return false ReadConfig: lists.hostname = ReadUMSConfig(account, "mailinglist.hostname",,) if lists.hostname = "" then return false lists.server = ReadUMSConfig(account, "mailinglist.server",,) if lists.server = "" then return false lists.helpfile = ReadUMSConfig(account, "mailinglist.helpfile",,) temp = ReadUMSConfig(account, "mailinglist.lists",,) if temp = "" then return false i = 0 do forever parse var temp lists.i.name '0A'x temp if temp = "" then leave i = i + 1 end lists.count = i do i = 0 to lists.count lists.i.group = ReadUMSConfig(account, "mailinglist." || lists.i.name || ".group",,) lists.i.descfile = ReadUMSConfig(account, "mailinglist." || lists.i.name || ".descfile",,) lists.i.alias = ReadUMSConfig(account, "mailinglist." || lists.i.name || ".alias",,) lists.i.access = ReadUMSConfig(account, "mailinglist." || lists.i.name || ".access",,) temp = ReadUMSConfig(account, "mailinglist." || lists.i.name || ".users",,) if temp = "" then return false j = 0 do forever parse var temp args '0A'x temp parse var args usrname "," usraddr "," . if usrname = "" then return false lists.i.mail.j.name = strip(usrname) lists.i.mail.j.addr = strip(usraddr) if temp = "" then leave j = j + 1 end lists.i.mail.count = j end return true WriteConfig: call WriteUMSConfig(account, "mailinglist.hostname", lists.hostname,,) call checkerr() call WriteUMSConfig(account, "mailinglist.server", lists.server,,) call checkerr() if lists.helpfile ~= "" then do call WriteUMSConfig(account, "mailinglist.helpfile", lists.helpfile,,) call checkerr() end ltemp = "" do i = 0 to lists.count if i ~= 0 then ltemp = ltemp || '0A'x ltemp = ltemp || lists.i.name temp = "" do j = 0 to lists.i.mail.count if j ~= 0 then temp = temp || '0A'x temp = temp || lists.i.mail.j.name if lists.i.mail.addr ~= "" then do temp = temp || "," || lists.i.mail.j.addr end end call WriteUMSConfig(account, "mailinglist." || lists.i.name || ".users", temp,,) call checkerr() if lists.i.group ~= "" then do call WriteUMSConfig(account, "mailinglist." || lists.i.name || ".group", lists.i.group,,) call checkerr() end if lists.i.descfile ~= "" then do call WriteUMSConfig(account, "mailinglist." || lists.i.name || ".descfile", lists.i.descfile,,) call checkerr() end if lists.i.alias ~= "" then do call WriteUMSConfig(account, "mailinglist." || lists.i.name || ".alias", lists.i.alias,,) call checkerr() end end call WriteUMSConfig(account, "mailinglist.lists", ltemp,,) call checkerr() return true ShowConfig: do i = 0 to lists.count do j = 0 to lists.i.mail.count say lists.i.name lists.i.mail.j.name lists.i.mail.j.addr end end return /*** ProcessLists ***/ ProcessLists: procedure expose UMS_Consts account lists. interpret UMS_Consts l_new = MakeFlags(0) l_priv = MakeFlags(1) l_name = MakeFlags(2) l_newmail = BITOR(l_new,l_priv) l_newlist = BITOR(l_newmail,l_name) l_group = MakeFlags(3) l_newnews = BITOR(l_new,l_group) num = UMSSelectFlags(account,l,,l_new,,,l,l_new,l_new) num = UMSSelectFlags(account,l,l_new,,,,u,MakeFlags(UMSUSTAT_Old, UMSUSTAT_ReadAccess, UMSUSTAT_ViewAccess),MakeFlags(UMSUSTAT_ReadAccess, UMSUSTAT_ViewAccess)) num = UMSSelectField(account,l,l_priv,,,,UMSCODE_Group,"",true) num = UMSSelectFlags(account,l,,,,,l,l_newmail,l_newmail) say "New mails overall:" num '0a'x /*** process received control mails ***/ /* say "Processing control mails:" */ num = UMSSelectFlags(account,l,,l_name,,,l,l_name,l_name) num = UMSSelectField(account,l,l_name,,,,UMSCODE_ToName,lists.server) num = UMSSelectFlags(account,l,,,,,l,l_newlist,l_newlist) say "New mail for <" || lists.server ||">:" num changedconfig = false validcommand = false do curmsg = 0 by 0 curmsg = UMSSearchFlags(account,l,l_newlist,l_newlist,curmsg) if curmsg = 0 then leave drop msg. if ReadUMSMsgAll(account,curmsg,msg.) then do if symbol("msg." || UMSCODE_fromAddr) ~= "VAR" then msg.UMSCODE_fromAddr = "" say curmsg msg.UMSCODE_fromName "<"||msg.UMSCODE_fromAddr||"> :" msg.UMSCODE_subject drop newmsg. if symbol("msg." || UMSCODE_ReplyName) ~= "VAR" then do newmsg.UMSCODE_ToName = msg.UMSCODE_FromName if symbol("msg." || UMSCODE_FromAddr) = "VAR" then do newmsg.UMSCODE_ToAddr = msg.UMSCODE_FromAddr end end; else do newmsg.UMSCODE_ToName = msg.UMSCODE_ReplyName if symbol("msg." || UMSCODE_ReplyAddr) = "VAR" then do newmsg.UMSCODE_ToAddr = msg.UMSCODE_ReplyAddr end end newmsg.UMSCODE_RefID = msg.UMSCODE_MsgID newmsg.UMSCODE_FromName = lists.server newmsg.UMSCODE_ReplyName = "postmaster" newmsg.UMSCODE_Subject = "Listserver logfile" newmsg.UMSCODE_MsgText = "Listserver startup" || '0A'x do forever do forever parse var msg.UMSCODE_MsgText command '0A'x msg.UMSCODE_msgText command = strip(command) if command ~= "" then leave if msg.UMSCODE_MsgText = "" then leave end if command = "" then leave parse var command command " " arguments /* say '"' || command || '" "' || arguments || '"' */ drop args. upper command newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || '0A'x || ' > ' || command || ' ' || arguments || '0A'x || '0A'x select when command = "QUIT" then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "ok, stopped processing you mail" || '0A'x validcommand = true leave end when command = "HELP" then do if lists.helpfile = "" then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "sorry, no help available" || '0A'x end; else do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || Include(lists.helpfile) || '0A'x end validcommand = true end when command = "USERS" then do ArgsTemplate = "LIST/A" if ~ReadArgs(arguments,ArgsTemplate,"args.") then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || 'wrong arguments! Template: "' || ArgsTemplate || '"' || '0A'x end; else do upper args.list validcommand = true found = false do i = 0 to lists.count if args.list = upper(lists.i.name) then do do j = 0 to lists.i.mail.count temp = lists.i.mail.j.name temp = temp || " <" || lists.i.mail.j.addr || ">" newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || temp || '0A'x end found = true leave end end if ~found then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "mailinglist not found" || '0A'x end end end when command = "INDEX" then do do i = 0 to lists.count newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || lists.i.name || '0A'x end validcommand = true end when (command = "ADD") | (command = "SUBSCRIBE") then do ArgsTemplate = "LIST/A,NAME/K,ADDR/K" if ~ReadArgs(arguments,ArgsTemplate,"args.") then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || 'wrong arguments! Template: "' || ArgsTemplate || '"' || '0A'x end; else do if ~CheckAccess(msg.UMSCODE_FromName,msg.UMSCODE_FromAddr,args.list) then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || 'mailinglist "' || args.list || '" is private, ask the postmaster' || '0A'x end; else do validcommand = true neednotify = false if symbol("args.name") = "VAR" then neednotify = true else args.name = msg.UMSCODE_FromName if symbol("args.addr") = "VAR" then neednotify = true else args.addr = msg.UMSCODE_FromAddr if AddUser(args.name, args.addr, args.list) then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "added" args.name "<" || args.addr || '> to mailinglist "' || args.list || '"' || '0A'x changedconfig = true if neednotify then do drop notifymsg. notifymsg.UMSCODE_ToName = args.name notifymsg.UMSCODE_ToAddr = args.addr notifymsg.UMSCODE_RefID = msg.UMSCODE_MsgID notifymsg.UMSCODE_FromName = lists.server notifymsg.UMSCODE_ReplyName = "postmaster" notifymsg.UMSCODE_Subject = "Listserver notification" notifymsg.UMSCODE_MsgText = "You have been added to the mailinglist '" || args.list || "' by" || '0A'x notifymsg.UMSCODE_MsgText = notifymsg.UMSCODE_MsgText || msg.UMSCODE_FromName || " <" || msg.UMSCODE_FromAddr || ">" || '0A'x if WriteUMSMsg(account, notifymsg.) = 0 then call CheckErr end end; else do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "error, not added" || '0A'x end end end end when (command = "DELETE") | (command = "REMOVE") | (command = "UNSUBSCRIBE") then do ArgsTemplate = "LIST/A,NAME/K,ADDR/K" if ~ReadArgs(arguments,ArgsTemplate,"args.") then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || 'wrong arguments! Template: "' || ArgsTemplate || '"' || '0A'x end; else do validcommand = true neednotify = false if symbol("args.name") = "VAR" then neednotify = true else args.name = msg.UMSCODE_FromName if symbol("args.addr") = "VAR" then neednotify = true else args.addr = msg.UMSCODE_FromAddr if RemUser(args.name, args.addr, args.list) then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "removed" args.name "<" || args.addr || '> from mailinglist "' || args.list || '"' || '0A'x changedconfig = true if neednotify then do drop notifymsg. notifymsg.UMSCODE_ToName = args.name notifymsg.UMSCODE_ToAddr = args.addr notifymsg.UMSCODE_RefID = msg.UMSCODE_MsgID notifymsg.UMSCODE_FromName = lists.server notifymsg.UMSCODE_ReplyName = "postmaster" notifymsg.UMSCODE_Subject = "Listserver notification" notifymsg.UMSCODE_MsgText = "You have been removed from the mailinglist '" || args.list || "' by" || '0A'x notifymsg.UMSCODE_MsgText = notifymsg.UMSCODE_MsgText || msg.UMSCODE_FromName || " <" || msg.UMSCODE_FromAddr || ">" || '0A'x if WriteUMSMsg(account, notifymsg.) = 0 then call CheckErr end end; else do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "error, not removed" || '0A'x end end end when (command = "DESCRIPTION") | (command = "DESC") | (command = "FAQ") then do ArgsTemplate = "LIST/A" if ~ReadArgs(arguments,ArgsTemplate,"args.") then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || 'wrong arguments! Template: "' || ArgsTemplate || '"' || '0A'x end; else do upper args.list found = false do i = 0 to lists.count if args.list = upper(lists.i.name) then do if lists.i.descfile = "" then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "sorry, no description available" || '0A'x end; else do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || Include(lists.i.descfile) || '0A'x end found = true leave end end if ~found then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "mailinglist not found" || '0A'x end end end otherwise do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || "unknown command" || '0A'x end end end end; else call CheckErr newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || '0A'x if ~validcommand then do newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || '0A'x || "There was no valid command in this message. Here's some help:" || '0A'x newmsg.UMSCODE_MsgText = newmsg.UMSCODE_MsgText || Include(lists.helpfile) || '0A'x end if WriteUMSMsg(account, newmsg.) = 0 then call CheckErr end if changedconfig then do say "Config changed, writing.." if WriteConfig() then say "done" end do i = 0 to lists.count shortname = lists.i.name longname = "Mailinglist '" || lists.i.name || "'" /*** process received mails in lists ***/ /* say "Processing list <"|| shortname ||">:" */ num = UMSSelectFlags(account,l,,l_name,,,l,l_name,l_name) num = UMSSelectField(account,l,l_name,,,,UMSCODE_ToName,longname,true) num = UMSSelectField(account,l,l_name,,,,UMSCODE_ToName,shortname,true) if lists.i.alias ~= "" then do num = UMSSelectField(account,l,l_name,,,,UMSCODE_ToName,lists.i.alias,true) end num = UMSSelectFlags(account,l,,,,,l,l_newlist,l_newlist) say "New mail for <" || shortname || "> or <" || longname ||">:" num do curmsg = 0 by 0 curmsg = UMSSearchFlags(account,l,l_newlist,l_newlist,curmsg) if curmsg = 0 then leave drop msg. if ReadUMSMsgAll(account,curmsg,msg.) then do say curmsg msg.UMSCODE_fromName "<"||msg.UMSCODE_fromAddr||"> :" msg.UMSCODE_subject /*** write news article ***/ if lists.i.group ~= "" then do listgroup = lists.i.group /*** check ref-IDs ***/ if ReadUMSMsgInfo(account,curmsg,msg.) & (msg.up ~= 0) then do drop repmsg. if ReadUMSMsgField(account,msg.up,repmsg.,UMSCODE_Attributes) then do parse var repmsg.UMSCODE_Attributes "oid<" newsref ">" msg.UMSCODE_RefID = newsref end end /*** set up news hdr ***/ msg.UMSCODE_Group = listgroup msg.UMSCODE_Attributes = "oid<" || msg.UMSCODE_MsgID || "> " drop msg.UMSCODE_MsgID drop msg.UMSCODE_Comments drop msg.UMSCODE_FidoID drop msg.UMSCODE_MausID drop msg.UMSCODE_ErrorText drop msg.hardlink drop msg.softlink /*** write article ***/ newnum = WriteUMSMsg(account,msg.) if newnum = 0 then call CheckErr else do say "write article:" newnum call ReadUMSMsgField(account,newnum,msg.,UMSCODE_MsgID) end newsid = msg.UMSCODE_MsgID /*** change attributes ***/ drop msg. if ~ReadUMSMsgAll(account,curmsg,msg.) then call CheckErr if newsid ~= "" then do msg.msgnum = curmsg if symbol("msg.UMSCODE_Attributes") = "VAR" then msg.UMSCODE_Attributes = msg.UMSCODE_Attributes || " oid<" || newsid || "> " else msg.UMSCODE_Attributes = "oid<" || newsid || "> " if WriteUMSMsg(account,msg.) = 0 then call CheckErr end drop msg.msgnum end /*** set up mail hdr ***/ msg.UMSCODE_ReplyAddr = shortname || "@" || lists.hostname msg.UMSCODE_ReplyName = longname msg.UMSCODE_LogicalToAddr = shortname || "@" || lists.hostname msg.UMSCODE_LogicalToName = longname msg.UMSCODE_Comments = "" msg.softlink = curmsg /*** set up mail tailer ***/ msg.UMSCODE_MsgText = msg.UMSCODE_MsgText || "______________________________________________________________________" || '0A'x msg.UMSCODE_MsgText = msg.UMSCODE_MsgText || center(longname || " Admin: ", 70) || '0A'x msg.UMSCODE_MsgText = msg.UMSCODE_MsgText || center("Send listserv-requests to <" || lists.server || "@" || lists.hostname || ">", 70) || '0A'x /*** write mails ***/ firstnum = 0 do j = 0 to lists.i.mail.count msg.UMSCODE_toName = lists.i.mail.j.name msg.UMSCODE_toAddr = lists.i.mail.j.addr if (msg.UMSCODE_toName ~= msg.UMSCODE_fromName) | (msg.UMSCODE_toAddr ~= msg.UMSCODE_fromAddr) then do newnum = WriteUMSMsg(account,msg.) if newnum = 0 then call CheckErr else if firstnum = 0 then do firstnum = newnum call writech(stdout,"write mail:" newnum) end else call writech(stdout,".") end end if newnum ~= firstnum then say newnum end; else call CheckErr end /*** process new news ***/ if lists.i.group ~= "" then do listgroup = lists.i.group num = UMSSelectFlags(account,l,,l_group,,,l,l_group,l_group) num = UMSSelectField(account,l,l_group,,,,UMSCODE_Group,listgroup,true) num = UMSSelectFlags(account,l,,,,,l,l_newnews,l_newnews) say "New articles in group <"|| listgroup ||"> :" num do curmsg = 0 by 0 curmsg = UMSSearchFlags(account,l,l_newnews,l_newnews,curmsg) if curmsg = 0 then leave drop msg. if ReadUMSMsgAll(account,curmsg,msg.) then do say curmsg msg.UMSCODE_fromName "<"||msg.UMSCODE_fromAddr||"> :" msg.UMSCODE_subject /*** check ref-IDs ***/ if ReadUMSMsgInfo(account,curmsg,msg.) & (msg.up ~= 0) then do drop repmsg. if ReadUMSMsgField(account,msg.up,repmsg.,UMSCODE_Attributes) then do parse var repmsg.UMSCODE_Attributes "oid<" mailref ">" msg.UMSCODE_RefID = mailref end end /*** set up mail hdr ***/ msg.UMSCODE_Group = "" msg.UMSCODE_Attributes = "oid<" || msg.UMSCODE_MsgID || "> " msg.UMSCODE_replyAddr = shortname || "@" || lists.hostname msg.UMSCODE_replyName = longname msg.UMSCODE_LogicalToAddr = shortname || "@" || lists.hostname msg.UMSCODE_LogicalToName = longname msg.UMSCODE_MsgID = "" drop msg.UMSCODE_Comments drop msg.UMSCODE_FidoID drop msg.UMSCODE_MausID drop msg.UMSCODE_ErrorText drop msg.hardlink drop msg.softlink /*** set up mail tailer ***/ msg.UMSCODE_MsgText = msg.UMSCODE_MsgText || "______________________________________________________________________" || '0A'x msg.UMSCODE_MsgText = msg.UMSCODE_MsgText || center(longname || " Admin: ", 70) || '0A'x msg.UMSCODE_MsgText = msg.UMSCODE_MsgText || center("Send listserv-requests to <" || lists.server || "@" || lists.hostname || ">", 70) || '0A'x /*** write mails ***/ firstnum = 0 do j = 0 to lists.i.mail.count msg.UMSCODE_toName = lists.i.mail.j.name msg.UMSCODE_toAddr = lists.i.mail.j.addr if (msg.UMSCODE_toName ~= msg.UMSCODE_fromName) | (msg.UMSCODE_toAddr ~= msg.UMSCODE_fromAddr) then do newnum = WriteUMSMsg(account,msg.) if newnum = 0 then call CheckErr else do if firstnum = 0 then do firstnum = newnum call writech(stdout,"write mail:" newnum) end else call writech(stdout,".") if msg.UMSCODE_MsgID = "" then do call ReadUMSMsgField(account,newnum,msg.,UMSCODE_MsgID) msg.softlink = newnum end end end end if newnum ~= firstnum then say newnum /*** change attributes ***/ if symbol("msg.UMSCODE_MsgID") = "VAR" then do mailid = msg.UMSCODE_MsgID drop msg. if ~ReadUMSMsgAll(account,curmsg,msg.) then call CheckErr msg.msgnum = curmsg if symbol("msg.UMSCODE_Attributes") = "VAR" then msg.UMSCODE_Attributes = msg.UMSCODE_Attributes || " oid<" || mailid || "> " else msg.UMSCODE_Attributes = "oid<" || mailid || "> " if WriteUMSMsg(account,msg.) = 0 then call CheckErr end end end end end return /*** Support ***/ CheckErr: procedure expose account err = UMSErrNum(account) if err ~= 0 then do say "UMS Error #" || err || ": " || UMSErrTxt(account) end return Include: procedure if open(file,arg(1),r) then do string = readch(file,64000) call close(file) end; else do say "cannot read include-file '" || arg(1) || "'!" string = "" end return string