UNSAFE MODULE; IMPORT ASCII, CText, Ctypes, Logger, LoggerClass, M3toC, MySyslog, Text, TextIntTbl, Word; REVEAL T = Public BRANDED OBJECT OVERRIDES init := Init; put := Put; close := Close; END; CONST PrioMap = ARRAY Logger.Priority OF Ctypes.int{ MySyslog.LOG_EMERG, MySyslog.LOG_ALERT, MySyslog.LOG_CRIT, MySyslog.LOG_ERR, MySyslog.LOG_WARNING, MySyslog.LOG_NOTICE, MySyslog.LOG_INFO, MySyslog.LOG_DEBUG }; FacilityNames = ARRAY Facility OF TEXT{ "Kern", "User", "Mail", "Daemon", "Auth", "Syslog", "Lpr", "News", "Uucp", "Cron", "Authpriv", "Ftp", "Local0", "Local1", "Local2", "Local3", "Local4", "Local5", "Local6", "Local7" }; VAR FacilityTable: TextIntTbl.T; (* CONST *) PROCEDURE SysLogger Init (self: T; ident: TEXT; facility: Facility; options := Options{}; level: Logger.Priority := Logger.Priority.Debug): T = VAR uident: Ctypes.char_star; ufacility: Ctypes.int; ulogopt: Ctypes.int; BEGIN EVAL Logger.T.init(self, level); uident := M3toC.CopyTtoS(ident); CASE facility OF | Facility.Kern => ufacility := MySyslog.LOG_KERN; | Facility.User => ufacility := MySyslog.LOG_USER; | Facility.Mail => ufacility := MySyslog.LOG_MAIL; | Facility.Daemon => ufacility := MySyslog.LOG_DAEMON; | Facility.Auth => ufacility := MySyslog.LOG_AUTH; | Facility.Syslog => ufacility := MySyslog.LOG_SYSLOG; | Facility.Lpr => ufacility := MySyslog.LOG_LPR; | Facility.News => ufacility := MySyslog.LOG_NEWS; | Facility.Uucp => ufacility := MySyslog.LOG_UUCP; | Facility.Cron => ufacility := MySyslog.LOG_CRON; | Facility.Authpriv => ufacility := MySyslog.LOG_AUTHPRIV; | Facility.Ftp => ufacility := MySyslog.LOG_FTP; | Facility.Local0 => ufacility := MySyslog.LOG_LOCAL0; | Facility.Local1 => ufacility := MySyslog.LOG_LOCAL1; | Facility.Local2 => ufacility := MySyslog.LOG_LOCAL2; | Facility.Local3 => ufacility := MySyslog.LOG_LOCAL3; | Facility.Local4 => ufacility := MySyslog.LOG_LOCAL4; | Facility.Local5 => ufacility := MySyslog.LOG_LOCAL5; | Facility.Local6 => ufacility := MySyslog.LOG_LOCAL6; | Facility.Local7 => ufacility := MySyslog.LOG_LOCAL7; END; ulogopt := 0; IF Option.Pid IN options THEN ulogopt := Word.Or(ulogopt, MySyslog.LOG_PID); END; IF Option.Cons IN options THEN ulogopt := Word.Or(ulogopt, MySyslog.LOG_CONS); END; IF Option.Ndelay IN options THEN ulogopt := Word.Or(ulogopt, MySyslog.LOG_NDELAY); END; IF Option.Nowait IN options THEN ulogopt := Word.Or(ulogopt, MySyslog.LOG_NOWAIT); END; IF Option.Perror IN options THEN ulogopt := Word.Or(ulogopt, MySyslog.LOG_PERROR); END; MySyslog.openlog(uident, ulogopt, ufacility); RETURN self; END Init; PROCEDUREPut (<*UNUSED*> self: T; priority: Logger.Priority; msg: TEXT) = VAR msgStr := CText.SharedTtoS(msg); BEGIN MySyslog.syslog(PrioMap[priority], msgStr); CText.FreeSharedS(msg, msgStr); END Put; PROCEDUREClose (<*UNUSED*> self: T) = BEGIN MySyslog.closelog(); END Close; PROCEDUREDecodeFacility (name: TEXT): Facility RAISES {Error} = VAR ord: INTEGER; BEGIN IF NOT FacilityTable.get(ToLower(name), ord) THEN RAISE Error("Invalid syslog facility \"" & name & "\""); END; RETURN VAL(ord, Facility); END DecodeFacility; PROCEDUREEncodeFacility (facility: Facility): TEXT = BEGIN RETURN FacilityNames[facility]; END EncodeFacility; PROCEDUREToLower (t: TEXT): TEXT = VAR len := Text.Length(t); chars := NEW(REF ARRAY OF CHAR, len); BEGIN Text.SetChars(chars^, t); FOR i := 0 TO len-1 DO chars[i] := ASCII.Lower[chars[i]]; END; RETURN Text.FromChars(chars^); END ToLower; BEGIN FacilityTable := NEW(TextIntTbl.Default).init(NUMBER(FacilityNames)); FOR facility := FIRST(FacilityNames) TO LAST(FacilityNames) DO EVAL FacilityTable.put(ToLower(FacilityNames[facility]), ORD(facility)); END; END SysLogger.