]> arthur.barton.de Git - netatalk.git/blob - etc/netalockd/main.c
Merge master
[netatalk.git] / etc / netalockd / main.c
1 /*
2  * Copyright (c) 2010 Frank Lahm
3  * All Rights Reserved.  See COPYRIGHT.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif /* HAVE_CONFIG_H */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <signal.h>
14 #include <sys/param.h>
15 #include <sys/time.h>
16 #include <sys/socket.h>
17 #include <errno.h>
18
19 #include <atalk/logger.h>
20 #include <atalk/paths.h>
21 #include <atalk/util.h>
22 #include <atalk/compat.h>
23
24 #include "event2/event.h"
25 #include "event2/http.h"
26 #include "event2/rpc.h"
27
28 #include <atalk/lockrpc.gen.h>
29
30 EVRPC_HEADER(lock_msg, lock_req, lock_rep)
31 EVRPC_GENERATE(lock_msg, lock_req, lock_rep)
32
33 struct event_base *eventbase;
34 struct evrpc_base *rpcbase;
35 struct evhttp *http;
36
37 static void sighandler(int signal)
38 {
39     switch( signal ) {
40
41     case SIGTERM :
42     case SIGINT:
43         LOG(log_error, logtype_default, "shutting down on signal");
44         exit(0);
45         break;
46
47     default :
48         LOG(log_error, logtype_default, "bad signal" );
49     }
50     return;
51 }
52
53
54 static void set_signal(void)
55 {
56     /* catch SIGTERM, SIGINT */
57
58     /* Log SIGBUS/SIGSEGV SBT */
59     fault_setup(NULL);
60
61     /* Ignore the rest */
62     struct sigaction sv;
63     memset(&sv, 0, sizeof(struct sigaction));
64     sv.sa_handler = SIG_IGN;
65     sv.sa_flags = SA_RESTART;
66     sigemptyset(&sv.sa_mask);
67
68     if (sigaction(SIGABRT, &sv, NULL) < 0) {
69         LOG(log_error, logtype_default, "error in sigaction(SIGABRT): %s", strerror(errno));
70         exit(EXIT_FAILURE);
71     }        
72     if (sigaction(SIGHUP, &sv, NULL) < 0) {
73         LOG(log_error, logtype_default, "error in sigaction(SIGHUP): %s", strerror(errno));
74         exit(EXIT_FAILURE);
75     }        
76     if (sigaction(SIGQUIT, &sv, NULL) < 0) {
77         LOG(log_error, logtype_default, "error in sigaction(SIGQUIT): %s", strerror(errno));
78         exit(EXIT_FAILURE);
79     }        
80     if (sigaction(SIGALRM, &sv, NULL) < 0) {
81         LOG(log_error, logtype_default, "error in sigaction(SIGALRM): %s", strerror(errno));
82         exit(EXIT_FAILURE);
83     }        
84     if (sigaction(SIGUSR1, &sv, NULL) < 0) {
85         LOG(log_error, logtype_default, "error in sigaction(SIGUSR1): %s", strerror(errno));
86         exit(EXIT_FAILURE);
87     }        
88     if (sigaction(SIGUSR2, &sv, NULL) < 0) {
89         LOG(log_error, logtype_default, "error in sigaction(SIGUSR2): %s", strerror(errno));
90         exit(EXIT_FAILURE);
91     }        
92
93 }
94
95 static void lock_msg_cb(EVRPC_STRUCT(lock_msg)* rpc, void *arg _U_)
96 {
97     int ret = 0;
98     char *filename;
99     struct lock_req *request = rpc->request;
100     struct lock_rep *reply = rpc->reply;
101
102     if (EVTAG_GET(request, req_filename, &filename) == -1) {
103         LOG(log_error, logtype_default, "lock_msg_cb: no filename");
104         exit(1);
105     }
106
107     LOG(log_warning, logtype_default, "lock_msg_cb(file: \"%s\")", filename);
108
109         /* we just want to fill in some non-sense */
110         EVTAG_ASSIGN(reply, result, 0);
111         EVTAG_ASSIGN(reply, rangestart, 0);
112
113         EVRPC_REQUEST_DONE(rpc);
114 }
115
116 static void ev_log_cb(int severity, const char *msg)
117 {
118     LOG(log_warning, logtype_default, (char *)msg);
119 }
120
121 static int rpc_setup(const char *addr, uint16_t port)
122 {
123     eventbase = event_base_new();
124     event_set_log_callback(ev_log_cb);
125
126         if ((http = evhttp_new(eventbase)) == NULL) {
127         LOG(log_error, logtype_default, "rpc_setup: error in evhttp_new: %s", strerror(errno));
128         return -1;
129     }
130
131         if (evhttp_bind_socket(http, addr, port) != 0) {
132         LOG(log_error, logtype_default, "rpc_setup: error in evhttp_new: %s", strerror(errno));
133         return -1;
134     }
135
136     rpcbase = evrpc_init(http);
137
138     EVRPC_REGISTER(rpcbase, lock_msg, lock_req, lock_rep, lock_msg_cb, NULL);
139
140         return 0;
141 }
142
143 static void rpc_teardown(struct evrpc_base *rpcbase)
144 {
145         EVRPC_UNREGISTER(rpcbase, lock_msg);
146         evrpc_free(rpcbase);
147 }
148
149 int main(int argc, char **argv)
150 {
151     int ret;
152     int debug = 0;
153     char *address = "127.0.0.1";
154     int port = 4701;
155
156     /* Default log setup: log to syslog */
157     set_processname("netalockd");
158
159     char c;
160     static char logconfig[MAXPATHLEN + 21 + 1] = "default log_note";
161     char *loglevel = NULL, *logfile = NULL;
162     while ((c = getopt(argc, argv, "df:l:n:p:")) != -1 ) {
163         switch (c) {
164         case 'd':
165             debug = 1;
166             break;
167         case 'f':
168             logfile = strdup(optarg);
169             break;
170         case 'l':
171             loglevel = strdup(optarg);
172             break;
173         case 'n':
174             address = strdup(optarg);
175             break;
176         case 'p':
177             port = atoi(optarg);
178             break;
179         }
180     }
181
182     /* Check lockfile and daemonize */
183     switch(server_lock("netalockd", _PATH_NETALOCKD_LOCK, debug)) {
184     case -1: /* error */
185         exit(EXITERR_SYS);
186     case 0: /* child */
187         break;
188     default: /* server */
189         exit(0);
190     }
191
192     /* Setup logging */
193     if (loglevel) {
194         strlcpy(logconfig + 8, loglevel, 13);
195         free(loglevel);
196         strcat(logconfig, " ");
197     }
198     if (logfile) {
199         strlcat(logconfig, logfile, MAXPATHLEN);
200         free(logfile);
201     }
202     setuplog(logconfig);
203
204     /* Setup signal stuff */
205     set_signal();
206
207     /* Start listening */
208     if (rpc_setup(address, port) != 0) {
209         LOG(log_error, logtype_default, "main: rpc setup error");
210         exit(1);
211     }
212
213     LOG(log_warning, logtype_default, "Running...");
214
215     /* wait for events - this is where we sit for most of our life */
216     event_base_dispatch(eventbase);
217
218 exit:
219     rpc_teardown(rpcbase);
220     evhttp_free(http);
221
222     return 0;
223 }