add xevlog_analyze function
[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
47 #define __USE_GNU
48 #include <sys/socket.h>
49
50 DevPrivateKeyRec debug_client_key;
51
52 static XDbgDbusServerMethod method;
53
54 static void
55 _debugClientInfo (ClientPtr client)
56 {
57     int fd = XaceGetConnectionNumber (client);
58     ModuleClientInfo *info = GetClientInfo (client);
59
60     /* For local clients, try and determine the executable name */
61     if (XaceIsLocal (client))
62     {
63         struct ucred creds;
64         socklen_t len = sizeof (creds);
65         char path[PATH_MAX + 1] = {0,};
66         int bytes;
67
68         memset (&creds, 0, sizeof (creds));
69         if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
70             goto finish;
71
72         snprintf (path, PATH_MAX + 1, "/proc/%d/cmdline", creds.pid);
73         fd = open (path, O_RDONLY);
74         if (fd < 0)
75             goto finish;
76
77         bytes = read (fd, path, PATH_MAX + 1);
78         close (fd);
79         if (bytes <= 0)
80             goto finish;
81
82         strncpy (info->command, path, PATH_MAX);
83
84         info->pid = creds.pid;
85         info->uid = creds.uid;
86         info->gid = creds.gid;
87         info->conn_fd = fd;
88         info->index = client->index;
89     }
90     else
91     {
92         info->pid = -1;
93         info->index = client->index;
94         strncpy (info->command, "REMOTE", PATH_MAX);
95     }
96
97     return;
98
99 finish:
100     XDBG_ERROR (MXDBG, "Failed to make client info(index:%d)\n",
101                  client->index);
102     return;
103 }
104
105 static void
106 _traceClientState (CallbackListPtr *list, pointer closure, pointer calldata)
107 {
108     NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
109     ClientPtr client = clientinfo->client;
110     ModuleClientInfo *info = GetClientInfo (client);
111     static char* clientState[]=
112     {
113         "ClientStateInitial",
114         "ClientStateAuthenticating",
115         "ClientStateRunning",
116         "ClientStateRetained",
117         "ClientStateGone",
118         "ClientStateCheckingDebug",
119         "ClientStateCheckedDebug"
120     };
121
122     if (!info)
123         return;
124
125     if ((client->clientState == ClientStateInitial) || (client->clientState == ClientStateGone))
126     {
127         if (client->clientState == ClientStateInitial)
128               _debugClientInfo (client);
129
130         XDBG_INFO (MXDBG, "id:%d, conn_fd:%d, pid:%d, uid:%d, name:%s (%s)\n",
131               info->index, info->conn_fd, info->pid, info->uid, info->command,
132               clientState[client->clientState]);
133         return;
134     }
135
136     XDBG_DEBUG (MXDBG, "id:%d, conn_fd:%d, pid:%d, uid:%d, name:%s (%s)\n",
137                  info->index, info->conn_fd, info->pid, info->uid, info->command,
138                  clientState[client->clientState]);
139 }
140
141 Bool
142 xDbgModuleMain (XDbgModule *pMod)
143 {
144     Bool ret = TRUE;
145
146     if (!dixRegisterPrivateKey (DebugClientKey, PRIVATE_CLIENT, sizeof (ModuleClientInfo)))
147     {
148         XDBG_ERROR (MXDBG, "failed: dixRegisterPrivateKey\n");
149         return FALSE;
150     }
151
152     ret &= AddCallback (&ClientStateCallback, _traceClientState, pMod);
153
154     if (!ret)
155     {
156         XDBG_ERROR (MXDBG, "failed: AddCallback\n");
157         return FALSE;
158     }
159
160     xDbgModuleEvlogInstallHooks (pMod);
161
162     if (!xDbgDBusServerConnect ())
163     {
164         XDBG_ERROR (MXDBG, "failed: xDbgDBusServerConnect\n");
165         return FALSE;
166     }
167
168     if (!xDbgModuleCommandInitLogPath (pMod))
169     {
170         XDBG_ERROR (MXDBG, "failed: xDbgModuleInitLogPath\n");
171         return FALSE;
172     }
173
174     snprintf (method.name, sizeof (method.name), "%s", XDBG_DBUS_METHOD);
175     method.func = xDbgModuleCommand;
176     method.data = pMod;
177
178     xDbgDBusServerAddMethod (&method);
179
180     return TRUE;
181 }
182
183 void
184 xDbgModuleMainExit (XDbgModule *pMod)
185 {
186     DeleteCallback (&ClientStateCallback, _traceClientState, pMod);
187
188     xDbgModuleEvlogUninstallHooks (pMod);
189
190     xDbgDBusServerRemoveMethod (&method);
191
192     xDbgDBusServerDisconnect ();
193 }