Git init
[pkgs/e/elektra.git] / src / backends / daemon / kdbd.c
1 /***************************************************************************
2                    kdbd.c  -  The server for the daemon backend
3                              -------------------
4     copyright            : (C) 2006 by Yannick Lecaillez
5     email                : sizon5@gmail.com
6  ***************************************************************************/
7
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the BSD License (revised).                      *
12  *                                                                         *
13  ***************************************************************************/
14
15
16 /* Subversion stuff
17
18 $Id$
19
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "kdbbackend.h"
27
28 #include "protocol.h"
29 #include "message.h"
30 #include "kdb_wrapper.h"
31 #include "ipc.h"
32 #include "thread.h"
33
34 static Message *processRequest(Message *request, KDB *handle, uid_t remoteeuid, gid_t remoteegid);
35
36 static Message *processRequest(Message *request, KDB *handle, uid_t remoteeuid, gid_t remoteegid)
37 {
38         Message *reply;
39         int     msgType, procedure;
40
41         msgType = messageGetType(request);
42         if ( msgType != MESSAGE_REQUEST ) {
43                 fprintf(stderr, "processRequest(): Received a non-request message.\n");
44                 return NULL;
45         }
46         
47         procedure = messageGetProcedure(request);
48         switch(procedure) {
49 /*              case KDB_BE_OPEN:
50                         reply = wrapper_kdbOpen(handle, request, remoteeuid, remoteegid);
51                         break;
52                         
53                 case KDB_BE_CLOSE:
54                         reply = wrapper_kdbClose(handle, request);
55                         break;*/
56                         
57                 case KDB_BE_STATKEY:
58                         reply = wrapper_kdbStatKey(handle, request);
59                         break;
60                         
61                 case KDB_BE_GETKEY:
62                         reply = wrapper_kdbGetKey(handle, request);
63                         break;
64                         
65                 case KDB_BE_SETKEY:
66                         reply = wrapper_kdbSetKey(handle, request);
67                         break;
68                         
69                 case KDB_BE_SETKEYS:
70                         reply = wrapper_kdbSetKeys(handle, request);
71                         break;
72                         
73                 case KDB_BE_GETCHILD:
74                         reply = wrapper_kdbGetChild(handle, request);
75                         break;
76                         
77                 default:
78                         reply = NULL;
79         }
80
81         if ( reply == NULL ) {
82                 /* Internat error from wrapper */
83                 fprintf(stderr, "Internal error\n");
84                 reply = messageNew(MESSAGE_REPLY, INTERNAL_ERROR,
85                                         DATATYPE_INTEGER, &errno,
86                                         DATATYPE_LAST);
87                 if ( reply == NULL )
88                         fprintf(stderr, "An internal error caused a fatal error. Client will be confused :-(.\n"); 
89         }
90         
91         return reply;
92 }
93
94 int kdbd(void *pIntThreadHandle)
95 {
96         KDB     *handle;
97         int             threadHandle, socketFd;
98         Message         *request, *reply;
99         uid_t           remoteeuid;
100         gid_t           remoteegid;
101         pid_t           remotepid;
102         int             closed;
103
104         handle = kdbOpen();
105
106         pthread_cleanup_push(threadExit, pIntThreadHandle);
107         
108         threadHandle = *((int *) pIntThreadHandle);
109         
110         if ( (socketFd = threadGetSocket(threadHandle)) == -1 ) {
111                 fprintf(stderr, "Can't get socket :-(\n");
112                 return 1;
113         } 
114
115         if ( ipc_eid(socketFd, &remoteeuid, &remoteegid, &remotepid) == -1 ) {
116                 perror("kdbd");
117                 return 1;
118         }
119         fprintf(stderr, "Thread %ld launched to serve PID %d (euid=%d/egid=%d)\n", pthread_self(), remotepid, remoteeuid, remoteegid);
120
121         closed = 0;
122         while ( !closed ) {
123                 request = protocolReadMessage(socketFd);
124                 if ( request == NULL ) {
125                         if ( (errno == EPIPE) || (errno == EINVAL) ) {
126                                 /* Client closed the connection or
127                                  * malformed request */
128                                 messageDel(request);
129                                 return 1;
130                         } else {
131                                 /* They are probably some usefull errno
132                                  * to check here ...
133                                  */
134                                 continue;
135                         }
136                 }
137                 closed = (messageGetProcedure(request) == KDB_BE_CLOSE);
138                 
139                 reply = processRequest(request, &handle, remoteeuid, remoteegid);
140                 messageDel(request);
141
142                 protocolSendMessage(socketFd, reply);
143                 messageDel(reply);
144         }
145
146         pthread_cleanup_pop(1);
147
148         kdbClose (handle);
149         
150         return 0;
151 }
152