]> arthur.barton.de Git - netatalk.git/blob - etc/netalockd/main.c
netalockd starts and listens for RPCs
[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
23 #include "event2/event.h"
24 #include "event2/http.h"
25 #include "event2/rpc.h"
26
27 #include <atalk/lockrpc.gen.h>
28
29 EVRPC_HEADER(lock_msg, lock_req, lock_rep)
30 EVRPC_GENERATE(lock_msg, lock_req, lock_rep)
31
32 struct event_base *eventbase;
33 struct evrpc_base *rpcbase;
34 struct evhttp *http;
35
36 static void sighandler(int signal)
37 {
38     switch( signal ) {
39
40     case SIGTERM :
41     case SIGINT:
42         LOG(log_error, logtype_default, "shutting down on signal");
43         exit(0);
44         break;
45
46     default :
47         LOG(log_error, logtype_default, "bad signal" );
48     }
49     return;
50 }
51
52
53 static void set_signal(void)
54 {
55     /* catch SIGTERM, SIGINT */
56
57     /* Log SIGBUS/SIGSEGV SBT */
58     fault_setup(NULL);
59
60     /* Ignore the rest */
61     struct sigaction sv;
62     memset(&sv, 0, sizeof(struct sigaction));
63     sv.sa_handler = SIG_IGN;
64     sv.sa_flags = SA_RESTART;
65     sigemptyset(&sv.sa_mask);
66
67     if (sigaction(SIGABRT, &sv, NULL) < 0) {
68         LOG(log_error, logtype_default, "error in sigaction(SIGABRT): %s", strerror(errno));
69         exit(EXIT_FAILURE);
70     }        
71     if (sigaction(SIGHUP, &sv, NULL) < 0) {
72         LOG(log_error, logtype_default, "error in sigaction(SIGHUP): %s", strerror(errno));
73         exit(EXIT_FAILURE);
74     }        
75     if (sigaction(SIGQUIT, &sv, NULL) < 0) {
76         LOG(log_error, logtype_default, "error in sigaction(SIGQUIT): %s", strerror(errno));
77         exit(EXIT_FAILURE);
78     }        
79     if (sigaction(SIGALRM, &sv, NULL) < 0) {
80         LOG(log_error, logtype_default, "error in sigaction(SIGALRM): %s", strerror(errno));
81         exit(EXIT_FAILURE);
82     }        
83     if (sigaction(SIGUSR1, &sv, NULL) < 0) {
84         LOG(log_error, logtype_default, "error in sigaction(SIGUSR1): %s", strerror(errno));
85         exit(EXIT_FAILURE);
86     }        
87     if (sigaction(SIGUSR2, &sv, NULL) < 0) {
88         LOG(log_error, logtype_default, "error in sigaction(SIGUSR2): %s", strerror(errno));
89         exit(EXIT_FAILURE);
90     }        
91
92 }
93
94 static void lock_msg_cb(EVRPC_STRUCT(lock_msg)* rpc, void *arg _U_)
95 {
96     int ret = 0;
97     char *filename;
98     struct lock_req *request = rpc->request;
99     struct lock_rep *reply = rpc->reply;
100
101     if (EVTAG_GET(request, req_filename, &filename) == -1) {
102         LOG(log_error, logtype_default, "lock_msg_cb: no filename");
103         exit(1);
104     }
105
106     LOG(log_warning, logtype_default, "lock_msg_cb(file: \"%s\")", filename);
107
108         /* we just want to fill in some non-sense */
109         EVTAG_ASSIGN(reply, result, 0);
110
111         /* no reply to the RPC */
112         EVRPC_REQUEST_DONE(rpc);
113 }
114
115 static int rpc_setup(const char *addr, uint16_t port)
116 {
117     eventbase = event_base_new();
118     
119         if ((http = evhttp_new(eventbase)) == NULL) {
120         LOG(log_error, logtype_default, "rpc_setup: error in evhttp_new: %s", strerror(errno));
121         return -1;
122     }
123
124         if (evhttp_bind_socket(http, addr, port) != 0) {
125         LOG(log_error, logtype_default, "rpc_setup: error in evhttp_new: %s", strerror(errno));
126         return -1;
127     }
128
129     rpcbase = evrpc_init(http);
130
131     EVRPC_REGISTER(rpcbase, lock_msg, lock_req, lock_rep, lock_msg_cb, NULL);
132
133         return 0;
134 }
135
136 static void rpc_teardown(struct evrpc_base *rpcbase)
137 {
138         EVRPC_UNREGISTER(rpcbase, lock_msg);
139         evrpc_free(rpcbase);
140 }
141
142 int main(int ac, char **av)
143 {
144     int ret;
145
146     /* Default log setup: log to syslog */
147     set_processname("netalockd");
148     setuplog("default log_note");
149
150     /* Check lockfile and daemonize */
151     switch(server_lock("netalockd", _PATH_NETALOCKD_LOCK, 0)) {
152     case -1: /* error */
153         exit(EXITERR_SYS);
154     case 0: /* child */
155         break;
156     default: /* server */
157         exit(0);
158     }
159
160     /* Setup signal stuff */
161     set_signal();
162
163     /* Start listening */
164     if (rpc_setup("127.0.0.1", 4701) != 0) {
165         LOG(log_error, logtype_default, "main: rpc setup error");
166         exit(1);
167     }
168
169     LOG(log_warning, logtype_default, "Running...");
170
171     /* wait for events - this is where we sit for most of our life */
172     event_base_dispatch(eventbase);
173
174 exit:
175     rpc_teardown(rpcbase);
176     evhttp_free(http);
177
178     return 0;
179 }