2 * Copyright (c) 2010 Frank Lahm
3 * All Rights Reserved. See COPYRIGHT.
8 #endif /* HAVE_CONFIG_H */
14 #include <sys/param.h>
16 #include <sys/socket.h>
19 #include <atalk/logger.h>
20 #include <atalk/paths.h>
21 #include <atalk/util.h>
22 #include <atalk/compat.h>
24 #include "event2/event.h"
25 #include "event2/http.h"
26 #include "event2/rpc.h"
28 #include <atalk/lockrpc.gen.h>
30 EVRPC_HEADER(lock_msg, lock_req, lock_rep)
31 EVRPC_GENERATE(lock_msg, lock_req, lock_rep)
33 struct event_base *eventbase;
34 struct evrpc_base *rpcbase;
37 static void sighandler(int signal)
43 LOG(log_error, logtype_default, "shutting down on signal");
48 LOG(log_error, logtype_default, "bad signal" );
54 static void set_signal(void)
56 /* catch SIGTERM, SIGINT */
58 /* Log SIGBUS/SIGSEGV SBT */
63 memset(&sv, 0, sizeof(struct sigaction));
64 sv.sa_handler = SIG_IGN;
65 sv.sa_flags = SA_RESTART;
66 sigemptyset(&sv.sa_mask);
68 if (sigaction(SIGABRT, &sv, NULL) < 0) {
69 LOG(log_error, logtype_default, "error in sigaction(SIGABRT): %s", strerror(errno));
72 if (sigaction(SIGHUP, &sv, NULL) < 0) {
73 LOG(log_error, logtype_default, "error in sigaction(SIGHUP): %s", strerror(errno));
76 if (sigaction(SIGQUIT, &sv, NULL) < 0) {
77 LOG(log_error, logtype_default, "error in sigaction(SIGQUIT): %s", strerror(errno));
80 if (sigaction(SIGALRM, &sv, NULL) < 0) {
81 LOG(log_error, logtype_default, "error in sigaction(SIGALRM): %s", strerror(errno));
84 if (sigaction(SIGUSR1, &sv, NULL) < 0) {
85 LOG(log_error, logtype_default, "error in sigaction(SIGUSR1): %s", strerror(errno));
88 if (sigaction(SIGUSR2, &sv, NULL) < 0) {
89 LOG(log_error, logtype_default, "error in sigaction(SIGUSR2): %s", strerror(errno));
95 static void lock_msg_cb(EVRPC_STRUCT(lock_msg)* rpc, void *arg _U_)
99 struct lock_req *request = rpc->request;
100 struct lock_rep *reply = rpc->reply;
102 if (EVTAG_GET(request, req_filename, &filename) == -1) {
103 LOG(log_error, logtype_default, "lock_msg_cb: no filename");
107 LOG(log_warning, logtype_default, "lock_msg_cb(file: \"%s\")", filename);
109 /* we just want to fill in some non-sense */
110 EVTAG_ASSIGN(reply, result, 0);
111 EVTAG_ASSIGN(reply, rangestart, 0);
113 EVRPC_REQUEST_DONE(rpc);
116 static void ev_log_cb(int severity, const char *msg)
118 LOG(log_warning, logtype_default, (char *)msg);
121 static int rpc_setup(const char *addr, uint16_t port)
123 eventbase = event_base_new();
124 event_set_log_callback(ev_log_cb);
126 if ((http = evhttp_new(eventbase)) == NULL) {
127 LOG(log_error, logtype_default, "rpc_setup: error in evhttp_new: %s", strerror(errno));
131 if (evhttp_bind_socket(http, addr, port) != 0) {
132 LOG(log_error, logtype_default, "rpc_setup: error in evhttp_new: %s", strerror(errno));
136 rpcbase = evrpc_init(http);
138 EVRPC_REGISTER(rpcbase, lock_msg, lock_req, lock_rep, lock_msg_cb, NULL);
143 static void rpc_teardown(struct evrpc_base *rpcbase)
145 EVRPC_UNREGISTER(rpcbase, lock_msg);
149 int main(int argc, char **argv)
153 char *address = "127.0.0.1";
156 /* Default log setup: log to syslog */
157 set_processname("netalockd");
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 ) {
168 logfile = strdup(optarg);
171 loglevel = strdup(optarg);
174 address = strdup(optarg);
182 /* Check lockfile and daemonize */
183 switch(server_lock("netalockd", _PATH_NETALOCKD_LOCK, debug)) {
188 default: /* server */
194 strlcpy(logconfig + 8, loglevel, 13);
196 strcat(logconfig, " ");
199 strlcat(logconfig, logfile, MAXPATHLEN);
204 /* Setup signal stuff */
207 /* Start listening */
208 if (rpc_setup(address, port) != 0) {
209 LOG(log_error, logtype_default, "main: rpc setup error");
213 LOG(log_warning, logtype_default, "Running...");
215 /* wait for events - this is where we sit for most of our life */
216 event_base_dispatch(eventbase);
219 rpc_teardown(rpcbase);