]> www.wagner.pp.ru Git - oss/tclsyslog.git/blob - tclsyslog.c
ca97600065e3b0d1ad0730fa44184ba8101c309e
[oss/tclsyslog.git] / tclsyslog.c
1 /* Syslog interface for tcl
2
3 */
4 #include <tcl.h>
5 #include <syslog.h>
6 #include <string.h>
7 typedef struct {
8                 int logOpened;
9                 int facility,options;
10                 char ident[32];
11                 Tcl_HashTable *priorities;
12                 Tcl_HashTable *facilities;
13                } SyslogInfo;
14
15 void Syslog_ListHash(Tcl_Interp *interp,Tcl_HashTable *table);         
16 /* SyslogHelp - puts usage message into interp->result
17  * 
18  *
19  */
20
21 void SyslogHelp(Tcl_Interp *interp,char *cmdname)
22 {  Tcl_AppendResult(interp,"Wrong # of args. should be ",cmdname, 
23            " ?option value? priority message",NULL);
24 }
25
26 /* Syslog_Log -
27  * implements syslog tcl command. General format: syslog ?options? level text
28  * options -facility -ident -options
29  * 
30  */
31
32
33 int Syslog_Log(ClientData data, Tcl_Interp *interp, int argc, char **argv)
34 {    SyslogInfo *info=(SyslogInfo *)data;
35     char *message = NULL;
36     int priority;
37     int i=1;
38     if (argc<=1) {
39         SyslogHelp(interp,argv[0]);
40         return TCL_ERROR;
41     }
42   while (i<argc-1) {
43     if (!strcmp(argv[i],"-facility")) {
44         Tcl_HashEntry * entry=Tcl_FindHashEntry(info->facilities,argv[i+1]);
45         if (!entry) {
46            Tcl_AppendResult(interp,"Invalid facility name: \"",argv[i+1],
47                    "\" available facilities:",
48                NULL);
49            Syslog_ListHash(interp,info->facilities);
50            return TCL_ERROR;
51         }
52         info->facility=(int)Tcl_GetHashValue(entry);
53         if (info-> logOpened) {
54             closelog();
55             info-> logOpened=0;
56         }
57      } else if (!strcmp(argv[i],"-options")) {
58          int tmp;
59         if (Tcl_GetInt(interp,argv[i+1],&tmp)==TCL_ERROR)
60              return TCL_ERROR;
61         info->options=tmp;
62         if (info->logOpened) {
63             closelog();
64             info->logOpened=0;
65         }
66      } else if (!strcmp(argv[i],"-ident")) {
67         strncpy(info->ident, argv[i+1],32);
68         info->ident[31]=0;
69         if (info->logOpened) {
70             closelog();
71             info->logOpened=0;
72         }
73      } else {
74        Tcl_HashEntry *entry=Tcl_FindHashEntry(info->priorities,argv[i]);
75        if (!entry) {
76           Tcl_AppendResult(interp,"Invalid syslog level \"",argv[i],
77                   "\" available levels:",
78                NULL);
79           Syslog_ListHash(interp,info->priorities); 
80           return TCL_ERROR;
81        }
82        priority=(int)Tcl_GetHashValue(entry);
83        message=argv[i+1];
84        i+=2;
85        if (i<argc-1) {
86            SyslogHelp(interp,argv[0]);
87            return TCL_ERROR;
88        }
89      }
90      i+=2;
91   }
92   if (i<argc-1) {
93      SyslogHelp(interp,argv[0]);
94      return TCL_ERROR;
95   }
96   if (message) {
97       if (!info->logOpened) {
98           openlog(info->ident,info->options,info->facility);
99           info->logOpened=1;
100       }
101       syslog(priority,"%s",message);
102   }
103   return TCL_OK;
104 }
105 /*
106  * Syslog_ListHash - appends to interp result all the values of given
107  * hash table
108  */
109 void Syslog_ListHash(Tcl_Interp *interp,Tcl_HashTable *table) 
110 {
111     Tcl_HashSearch *searchPtr=(Tcl_HashSearch *)
112           Tcl_Alloc(sizeof(Tcl_HashSearch));
113     Tcl_HashEntry *entry;
114     char separator[3]={' ',' ',0};   
115     entry=Tcl_FirstHashEntry(table,searchPtr);
116     while (entry) {
117         Tcl_AppendResult(interp,separator,Tcl_GetHashKey(table,entry),NULL);
118         separator[0]=',';
119         entry=Tcl_NextHashEntry(searchPtr);
120     }   
121     Tcl_Free((char *)searchPtr);
122
123 /* 
124  *  Syslog_Delete - Tcl_CmdDeleteProc for syslog command.
125  *  Frees all hash tables and closes log if it was opened.
126  */
127 void Syslog_Delete(ClientData data)
128 { SyslogInfo *info=(SyslogInfo *)data;
129   Tcl_DeleteHashTable(info->facilities);
130   Tcl_Free((char *)info->facilities);
131   Tcl_DeleteHashTable(info->priorities);
132   Tcl_Free((char *)info->priorities);
133   if (info->logOpened) {
134      closelog();
135   }
136   Tcl_Free((char *)info);
137 }
138 /*
139  * My simplified wrapper for add values into hash
140  *
141  */
142 void AddEntry(Tcl_HashTable *table,char *key,int value)
143 { int new;
144   Tcl_HashEntry *entry=Tcl_CreateHashEntry(table,key,&new);
145   Tcl_SetHashValue(entry,(ClientData)value);
146 }
147 /*
148  * Syslog_Init 
149  * Package initialization procedure for Syslog package. 
150  * Creates command 'syslog', fills hash tables to map symbolic prioriry 
151  * and facility names to system constants.
152  */
153 int Syslog_Init(Tcl_Interp *interp)
154 {  char *argv0;
155    SyslogInfo *info=(SyslogInfo *)Tcl_Alloc(sizeof(SyslogInfo));
156    info->logOpened=0;
157    info->options=0;
158    info->facility=LOG_USER;
159    argv0=Tcl_GetVar(interp,"argv0",TCL_GLOBAL_ONLY);
160    if (argv0) {
161        strncpy(info->ident,argv0,32);
162    } else {
163        strcpy(info->ident,"Tcl script");
164    }
165    info->ident[31]=0;
166    info->facilities =(Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable));
167    Tcl_InitHashTable(info->facilities,TCL_STRING_KEYS);
168    AddEntry(info->facilities,"auth",LOG_AUTH);  
169 #ifndef LOG_AUTHPRIV
170 # define LOG_AUTHPRIV LOG_AUTH
171 #endif
172    AddEntry(info->facilities,"authpriv",LOG_AUTHPRIV);  
173    AddEntry(info->facilities,"cron",LOG_CRON);  
174    AddEntry(info->facilities,"daemon",LOG_DAEMON);  
175    AddEntry(info->facilities,"kernel",LOG_KERN);
176    AddEntry(info->facilities,"lpr",LOG_LPR);
177    AddEntry(info->facilities,"mail",LOG_MAIL);
178    AddEntry(info->facilities,"news",LOG_NEWS);
179    AddEntry(info->facilities,"syslog",LOG_SYSLOG);
180    AddEntry(info->facilities,"user",LOG_USER);
181    AddEntry(info->facilities,"uucp",LOG_UUCP);
182    AddEntry(info->facilities,"local0",LOG_LOCAL0);
183    AddEntry(info->facilities,"local1",LOG_LOCAL1);
184    AddEntry(info->facilities,"local2",LOG_LOCAL2);
185    AddEntry(info->facilities,"local3",LOG_LOCAL3);
186    AddEntry(info->facilities,"local4",LOG_LOCAL4);
187    AddEntry(info->facilities,"local5",LOG_LOCAL5);
188    AddEntry(info->facilities,"local6",LOG_LOCAL6);
189    AddEntry(info->facilities,"local7",LOG_LOCAL7);
190    info->priorities = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable));
191    Tcl_InitHashTable(info->priorities,TCL_STRING_KEYS);
192    AddEntry(info->priorities,"emerg",LOG_EMERG);
193    AddEntry(info->priorities,"alert",LOG_ALERT);
194    AddEntry(info->priorities,"crit",LOG_CRIT);
195    AddEntry(info->priorities,"err",LOG_ERR);
196    AddEntry(info->priorities,"error",LOG_ERR);
197    AddEntry(info->priorities,"warning",LOG_WARNING);
198    AddEntry(info->priorities,"notice",LOG_NOTICE);
199    AddEntry(info->priorities,"info",LOG_INFO);
200    AddEntry(info->priorities,"debug",LOG_DEBUG);
201    Tcl_CreateCommand(interp,"syslog",Syslog_Log,(ClientData) info,
202             Syslog_Delete); 
203    return Tcl_PkgProvide(interp,"Syslog",VERSION);
204 }