tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / module / xdbg_module_main.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <windowstr.h>
39 #include <xacestr.h>
40 #include <xdbg.h>
41
42 #include "xdbg_dbus_server.h"
43 #include "xdbg_module.h"
44 #include "xdbg_module_command.h"
45 #include "xdbg_module_evlog.h"
46 #include "xdbg_module_clist.h"
47
48 #define __USE_GNU
49 #include <sys/socket.h>
50
51 DevPrivateKeyRec debug_client_key;
52
53 static XDbgDbusServerMethod method;
54
55 static void
56 _debugClientInfo (ClientPtr client)
57 {
58     int fd = XaceGetConnectionNumber (client);
59     ModuleClientInfo *info = GetClientInfo (client);
60
61     /* For local clients, try and determine the executable name */
62     if (XaceIsLocal (client))
63     {
64         struct ucred creds;
65         socklen_t len = sizeof (creds);
66         char path[PATH_MAX + 1] = {0,};
67         int bytes;
68
69         memset (&creds, 0, sizeof (creds));
70         if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
71             goto finish;
72
73         snprintf (path, PATH_MAX + 1, "/proc/%d/cmdline", creds.pid);
74         fd = open (path, O_RDONLY);
75         if (fd < 0)
76             goto finish;
77
78         bytes = read (fd, path, PATH_MAX + 1);
79         close (fd);
80         if (bytes <= 0)
81             goto finish;
82
83         strncpy (info->command, path, PATH_MAX);
84         info->command[PATH_MAX] = '\0';
85
86         info->pid = creds.pid;
87         info->uid = creds.uid;
88         info->gid = creds.gid;
89         info->conn_fd = fd;
90         info->index = client->index;
91     }
92     else
93     {
94         info->pid = -1;
95         info->index = client->index;
96         strncpy (info->command, "REMOTE", PATH_MAX);
97         info->command[PATH_MAX] = '\0';
98     }
99
100     return;
101
102 finish:
103     XDBG_ERROR (MXDBG, "Failed to make client info(index:%d)\n",
104                  client->index);
105     return;
106 }
107
108 static void
109 _traceClientState (CallbackListPtr *list, pointer closure, pointer calldata)
110 {
111     NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
112     ClientPtr client = clientinfo->client;
113     ModuleClientInfo *info = GetClientInfo (client);
114     XDbgModule *pMod = (XDbgModule *)closure;
115     static char* clientState[]=
116     {
117         "ClientStateInitial",
118         "ClientStateAuthenticating",
119         "ClientStateRunning",
120         "ClientStateRetained",
121         "ClientStateGone",
122         "ClientStateCheckingDebug",
123         "ClientStateCheckedDebug"
124     };
125
126     if (!info)
127         return;
128
129     if ((client->clientState == ClientStateInitial) || (client->clientState == ClientStateGone))
130     {
131         if (client->clientState == ClientStateInitial)
132         {
133               _debugClientInfo (client);
134
135               if (pMod->trace_cnt)
136                   xDbgModuleClistTraceAdd (pMod, info);
137         }
138
139         if (client->clientState == ClientStateGone)
140         {
141               if (pMod->trace_cnt)
142                 xDbgModuleClistTraceRemove (pMod, info);
143         }
144
145         XDBG_SECURE (MXDBG, "id:%d, conn_fd:%d, pid:%d, uid:%d, name:%s (%s)\n",
146               info->index, info->conn_fd, info->pid, info->uid, info->command,
147               clientState[client->clientState]);
148         return;
149     }
150
151     XDBG_DEBUG (MXDBG, "id:%d, conn_fd:%d, pid:%d, uid:%d, name:%s (%s)\n",
152                  info->index, info->conn_fd, info->pid, info->uid, info->command,
153                  clientState[client->clientState]);
154 }
155
156 Bool
157 xDbgModuleMain (XDbgModule *pMod)
158 {
159     Bool ret = TRUE;
160
161     if (!dixRegisterPrivateKey (DebugClientKey, PRIVATE_CLIENT, sizeof (ModuleClientInfo)))
162     {
163         XDBG_ERROR (MXDBG, "failed: dixRegisterPrivateKey\n");
164         return FALSE;
165     }
166
167     if (pMod->trace_cnt)
168         xDbgModuleClistTraceInit (pMod);
169
170     ret &= AddCallback (&ClientStateCallback, _traceClientState, pMod);
171
172     if (!ret)
173     {
174         XDBG_ERROR (MXDBG, "failed: AddCallback\n");
175         return FALSE;
176     }
177
178     xDbgModuleEvlogInstallHooks (pMod);
179
180     if (!xDbgDBusServerConnect ())
181     {
182         XDBG_ERROR (MXDBG, "failed: xDbgDBusServerConnect\n");
183         return FALSE;
184     }
185
186     snprintf (method.name, sizeof (method.name), "%s", XDBG_DBUS_METHOD);
187     method.func = xDbgModuleCommand;
188     method.data = pMod;
189
190     xDbgDBusServerAddMethod (&method);
191
192     return TRUE;
193 }
194
195 void
196 xDbgModuleMainExit (XDbgModule *pMod)
197 {
198     DeleteCallback (&ClientStateCallback, _traceClientState, pMod);
199
200     xDbgModuleEvlogUninstallHooks (pMod);
201
202     xDbgDBusServerRemoveMethod (&method);
203
204     free (pMod->trace_options);
205
206     xDbgDBusServerDisconnect ();
207 }