2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
21 #include <sys/socket.h>
24 #include "include/ss_data.h"
28 #define SYSNOTI_SOCKET_PATH "/tmp/sn"
35 static void print_sysnoti_msg(const char *title, struct sysnoti *msg)
38 char exe_name[PATH_MAX];
40 if (sysman_get_cmdline_name(msg->pid, exe_name, PATH_MAX) < 0)
41 snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
43 PRT_TRACE_ERR("=====================");
44 PRT_TRACE_ERR("pid : %d", msg->pid);
45 PRT_TRACE_ERR("process name : %s", exe_name);
46 PRT_TRACE_ERR("cmd : %d", msg->cmd);
47 PRT_TRACE_ERR("type : %s", msg->type);
48 PRT_TRACE_ERR("path : %s", msg->path);
49 for (i = 0; i < msg->argc; i++)
50 PRT_TRACE_ERR("arg%d : %s", i, msg->argv[i]);
51 PRT_TRACE_ERR("=====================");
54 static inline int recv_int(int fd)
58 r = read(fd, &val, sizeof(int));
61 PRT_TRACE_ERR("Re-read for error(EINTR)");
65 PRT_TRACE_ERR("Read fail for int");
74 static inline char *recv_str(int fd)
80 r = read(fd, &len, sizeof(int));
83 PRT_TRACE_ERR("Re-read for error(EINTR)");
87 PRT_TRACE_ERR("Read fail for str length");
95 PRT_TRACE_ERR("str is null");
100 PRT_TRACE_ERR("size is over INT_MAX");
104 str = (char *)malloc(len + 1);
106 PRT_TRACE_ERR("Not enough memory");
111 r = read(fd, str, len);
114 PRT_TRACE_ERR("Re-read for error(EINTR)");
118 PRT_TRACE_ERR("Read fail for str");
129 static int read_message(int fd, struct sysnoti *msg)
133 msg->pid = recv_int(fd);
134 msg->cmd = recv_int(fd);
135 msg->type = recv_str(fd);
136 msg->path = recv_str(fd);
137 msg->argc = recv_int(fd);
139 for (i = 0; i < msg->argc; i++)
140 msg->argv[i] = recv_str(fd);
145 static inline void internal_free(char *str)
151 static inline void free_message(struct sysnoti *msg)
153 internal_free(msg->type);
154 internal_free(msg->path);
158 static int sysnoti_cb(void *data, Ecore_Fd_Handler * fd_handler)
163 struct sockaddr_un client_address;
167 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
169 ("ecore_main_fd_handler_active_get error , return\n");
173 fd = ecore_main_fd_handler_fd_get(fd_handler);
175 msg = malloc(sizeof(struct sysnoti));
177 PRT_TRACE_ERR("%s : Not enough memory", __FUNCTION__);
181 client_len = sizeof(client_address);
183 accept(fd, (struct sockaddr *)&client_address,
184 (socklen_t *)&client_len);
185 if(client_sockfd == -1) {
186 PRT_TRACE_ERR("socket accept error");
190 if (read_message(client_sockfd, msg) < 0) {
191 PRT_TRACE_ERR("%s : recv error msg", __FUNCTION__);
193 write(client_sockfd, &ret, sizeof(int));
194 close(client_sockfd);
198 print_sysnoti_msg(__FUNCTION__, msg);
199 if (msg->argc > SYSMAN_MAXARG) {
200 PRT_TRACE_ERR("%s : error argument", __FUNCTION__);
202 write(client_sockfd, &ret, sizeof(int));
203 close(client_sockfd);
208 case CALL_SYSMAN_ACTION:
209 ret = ss_action_entry_call(msg, msg->argc, msg->argv);
215 write(client_sockfd, &ret, sizeof(int));
216 close(client_sockfd);
223 static int ss_sysnoti_server_init(void)
226 struct sockaddr_un serveraddr;
228 if (access(SYSNOTI_SOCKET_PATH, F_OK) == 0)
229 unlink(SYSNOTI_SOCKET_PATH);
231 fd = socket(AF_UNIX, SOCK_STREAM, 0);
233 PRT_ERR("%s: socket create failed\n", __FUNCTION__);
237 if((fsetxattr(fd, "security.SMACK64IPOUT", "@", 2, 0)) < 0 ) {
238 PRT_ERR("%s: Socket SMACK labeling failed\n", __FUNCTION__);
239 if(errno != EOPNOTSUPP)
243 if((fsetxattr(fd, "security.SMACK64IPIN", "*", 2, 0)) < 0 ) {
244 PRT_ERR("%s: Socket SMACK labeling failed\n", __FUNCTION__);
245 if(errno != EOPNOTSUPP)
249 bzero(&serveraddr, sizeof(struct sockaddr_un));
250 serveraddr.sun_family = AF_UNIX;
251 strncpy(serveraddr.sun_path, SYSNOTI_SOCKET_PATH,
252 sizeof(serveraddr.sun_path));
254 if (bind(fd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr)) <
256 PRT_ERR("%s: socket bind failed\n", __FUNCTION__);
260 if (chmod(SYSNOTI_SOCKET_PATH, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) /* 0777 */
261 PRT_ERR("failed to change the socket permission");
265 PRT_INFO("socket create & listen ok\n");
270 int ss_sysnoti_init(void)
273 fd = ss_sysnoti_server_init();
274 ecore_main_fd_handler_add(fd, ECORE_FD_READ, sysnoti_cb, NULL, NULL,