Licensing/version updates for some files (forgot to commit, doh...)
[prosody.git] / util-src / pposix.c
1 /* Prosody IM v0.3
2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8 */
9
10 /*
11 * pposix.c
12 * POSIX support functions for Lua
13 */
14
15 #define MODULE_VERSION "0.3.0"
16
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <libgen.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23
24 #include <syslog.h>
25
26 #include <string.h>
27
28 #include "lua.h"
29 #include "lauxlib.h"
30
31 /* Daemonization support */
32
33 static int lc_daemonize(lua_State *L)
34 {
35
36         pid_t pid;
37         
38         if ( getppid() == 1 )
39         {
40                 lua_pushboolean(L, 0);
41                 lua_pushstring(L, "already-daemonized");
42                 return 2;
43         }
44         
45         /* Attempt initial fork */
46         if((pid = fork()) < 0)
47         {
48                 /* Forking failed */
49                 lua_pushboolean(L, 0);
50                 lua_pushstring(L, "fork-failed");
51                 return 2;
52         }
53         else if(pid != 0)
54         {
55                 /* We are the parent process */
56                 lua_pushboolean(L, 1);
57                 lua_pushnumber(L, pid);
58                 return 2;
59         }
60         
61         /* and we are the child process */
62         if(setsid() == -1)
63         {
64                 /* We failed to become session leader */
65                 /* (we probably already were) */
66                 lua_pushboolean(L, 0);
67                 lua_pushstring(L, "setsid-failed");
68                 return 2;
69         }
70
71         /* Close stdin, stdout, stderr */
72 /*      close(0);
73         close(1);
74         close(2);
75 */
76         /* Final fork, use it wisely */
77         if(fork())
78                 exit(0);
79
80         /* Show's over, let's continue */
81         lua_pushboolean(L, 1);
82         lua_pushnil(L);
83         return 2;
84 }
85
86 /* Syslog support */
87
88 char *facility_strings[] =      {       "auth",
89                                         "authpriv",
90                                         "cron",
91                                         "daemon",
92                                         "ftp",
93                                         "kern",
94                                         "local0",
95                                         "local1",
96                                         "local2",
97                                         "local3",
98                                         "local4",
99                                         "local5",
100                                         "local6",
101                                         "local7",
102                                         "lpr",
103                                         "mail",
104                                         "syslog",
105                                         "user",
106                                         "uucp",
107                                         NULL
108                                 };
109 int facility_constants[] =      {
110                                         LOG_AUTH,
111                                         LOG_AUTHPRIV,
112                                         LOG_CRON,
113                                         LOG_DAEMON,
114                                         LOG_FTP,
115                                         LOG_KERN,
116                                         LOG_LOCAL0,
117                                         LOG_LOCAL1,
118                                         LOG_LOCAL2,
119                                         LOG_LOCAL3,
120                                         LOG_LOCAL4,
121                                         LOG_LOCAL5,
122                                         LOG_LOCAL6,
123                                         LOG_LOCAL7,
124                                         LOG_LPR,
125                                         LOG_MAIL,
126                                         LOG_NEWS,
127                                         LOG_SYSLOG,
128                                         LOG_USER,
129                                         LOG_UUCP,
130                                         -1
131                                 };
132
133 /* "
134        The parameter ident in the call of openlog() is probably stored  as-is.
135        Thus,  if  the  string  it  points  to  is  changed, syslog() may start
136        prepending the changed string, and if the string it points to ceases to
137        exist,  the  results  are  undefined.  Most portable is to use a string
138        constant.
139    " -- syslog manpage
140 */ 
141 char* syslog_ident = NULL;
142
143 int lc_syslog_open(lua_State* L)
144 {
145         int facility = luaL_checkoption(L, 2, "daemon", &facility_strings);
146         facility = facility_constants[facility];
147
148         luaL_checkstring(L, 1);
149         
150         if(syslog_ident)
151                 free(syslog_ident);
152         
153         syslog_ident = strdup(lua_tostring(L, 1));
154         
155         openlog(syslog_ident, LOG_PID, facility);
156         return 0;
157 }
158
159 char *level_strings[] =         {
160                                 "debug",
161                                 "info",
162                                 "notice",
163                                 "warn",
164                                 "error",
165                                 NULL
166                         };
167 int level_constants[] =         {
168                                 LOG_DEBUG,
169                                 LOG_INFO,
170                                 LOG_NOTICE,
171                                 LOG_WARNING,
172                                 LOG_EMERG,
173                                 -1
174                         };
175 int lc_syslog_log(lua_State* L)
176 {
177         int level = luaL_checkoption(L, 1, "notice", &level_strings);
178         level = level_constants[level];
179
180         luaL_checkstring(L, 2);
181
182         syslog(level, "%s", lua_tostring(L, 2));
183         return 0;
184 }
185
186 int lc_syslog_close(lua_State* L)
187 {
188         closelog();
189         if(syslog_ident)
190         {
191                 free(syslog_ident);
192                 syslog_ident = NULL;
193         }
194         return 0;
195 }
196
197 int lc_syslog_setmask(lua_State* L)
198 {
199         int level_idx = luaL_checkoption(L, 1, "notice", &level_strings);
200         int mask = 0;
201         do
202         {
203                 mask |= LOG_MASK(level_constants[level_idx]);
204         } while (++level_idx<=4);
205
206         setlogmask(mask);
207         return 0;
208 }
209
210 /* getpid */
211
212 int lc_getpid(lua_State* L)
213 {
214         lua_pushinteger(L, getpid());
215         return 1;
216 }
217
218 /* Register functions */
219
220 int luaopen_util_pposix(lua_State *L)
221 {
222         lua_newtable(L);
223
224         lua_pushcfunction(L, lc_daemonize);
225         lua_setfield(L, -2, "daemonize");
226
227         lua_pushcfunction(L, lc_syslog_open);
228         lua_setfield(L, -2, "syslog_open");
229
230         lua_pushcfunction(L, lc_syslog_close);
231         lua_setfield(L, -2, "syslog_close");
232
233         lua_pushcfunction(L, lc_syslog_log);
234         lua_setfield(L, -2, "syslog_log");
235
236         lua_pushcfunction(L, lc_syslog_setmask);
237         lua_setfield(L, -2, "syslog_setminlevel");
238
239         lua_pushcfunction(L, lc_getpid);
240         lua_setfield(L, -2, "getpid");
241
242         lua_pushliteral(L, "pposix");
243         lua_setfield(L, -2, "_NAME");
244
245         lua_pushliteral(L, MODULE_VERSION);
246         lua_setfield(L, -2, "_VERSION");
247         
248         return 1;
249 };