e52ac8058fb8ef873dd3960f70b56a223f308a19
[framework/system/system-server.git] / ss_bs.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  *      http://www.tizenopensource.org/license
9  *
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.
15 */
16
17
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <limits.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <sysman.h>
26 #include <Ecore_File.h>
27
28 #include "ss_log.h"
29 #include "ss_launch.h"
30
31 #define BSNOTI_DIR              "/opt/bs"
32 #define BSNOTI_FILE             "curbs.log"
33 #define BSNOTI_FULL_PATH        BSNOTI_DIR"/"BSNOTI_FILE
34 #define CRASH_WORKER_PATH       "/usr/bin/crash-worker"
35
36 static int noti_fd;
37 static int add_noti(void);
38
39 static int make_noti_file(const char *path, const char *file)
40 {
41         PRT_TRACE("Make Noti File");
42         int fd;
43         char buf[PATH_MAX];
44
45         /* make a directory */
46         if (access(path, F_OK) == -1) {
47                 snprintf(buf, sizeof(buf), "mkdir -p %s", path);
48                 system(buf);
49                 snprintf(buf, sizeof(buf), "chown root:app %s", path);
50                 system(buf);
51         }
52
53         snprintf(buf, sizeof(buf), "%s/%s", path, file);
54
55         if (access(buf, F_OK) == 0)
56                 return -1;
57
58         fd = open(buf, O_CREAT, S_IRUSR | S_IWUSR);
59         close(fd);
60         snprintf(buf, sizeof(buf), "chmod 666 %s/%s", path, file);
61         system(buf);
62         snprintf(buf, sizeof(buf), "chown root:app %s/%s", path, file);
63         system(buf);
64
65         return 0;
66 }
67
68 static void launch_crash_worker(void *data)
69 {
70         FILE *fp;
71         char bsfile_name[NAME_MAX], bs_color[MAX_INPUT];
72         char args[NAME_MAX + MAX_INPUT];
73         int ret = -1, i;
74
75         fp = fopen((char *)data, "r");
76         if (fp == NULL) {
77                 return;
78         }
79         /* launch bs process */
80         while (fgets(args, NAME_MAX + MAX_INPUT, fp) != NULL) {
81                 /* add rule for log */
82                 if (args[strlen(args) - 1] != '\n') {
83                         PRT_TRACE_ERR("bsfile log must be terminated with new line character\n");
84                         break;
85                 }
86                 /* change last caracter from \n to \0 */
87                 args[strlen(args) - 1] = '\0';
88                 for (i = 0; i < NAME_MAX + MAX_INPUT; i++) {
89                         if (args[i] == ' ') {
90                                 if (i >= NAME_MAX - 1) {
91                                         PRT_TRACE_ERR("bsfile name is over 254. 255(NAME_MAX) - 1(NULL Termination)\n");
92                                         break;
93                                 }
94                                 strncpy(bsfile_name, args, i);
95                                 bsfile_name[i] = '\0';
96                                 strncpy(bs_color, args + i + 1, MAX_INPUT);
97                                 bs_color[MAX_INPUT - 1] = '\0';
98                                 snprintf(args, sizeof(args), "%s %s",
99                                          bsfile_name, bs_color);
100                                 PRT_TRACE("bsfile_name(size %d): %s\nargs: %s\n", i, bsfile_name, bs_color, args);
101                                 ret = ss_launch_evenif_exist(CRASH_WORKER_PATH, args);
102                                 break;
103                         }
104                 }
105                 if (ret < 0)
106                         break;
107         }
108         fclose(fp);
109
110         if (ret != -1) {
111                 fp = fopen((char *)data, "w");
112                 if (fp == NULL) {
113                         return;
114                 }
115                 fclose(fp);
116         }
117
118         return;
119 }
120
121 static Ecore_File_Monitor *bs_file_monitor;
122
123 static Ecore_File_Monitor_Cb __bs_file_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
124 {
125         switch (event) {
126                 case ECORE_FILE_EVENT_DELETED_DIRECTORY:
127                 case ECORE_FILE_EVENT_DELETED_SELF:
128                         if (0 > make_noti_file(BSNOTI_DIR, BSNOTI_FILE)) {
129                                 launch_crash_worker((void *)path);
130                         }
131                         break;
132                 case ECORE_FILE_EVENT_MODIFIED:
133                 default:
134                         launch_crash_worker((void *)path);
135                         break;
136         }
137          
138         return;
139 }
140
141 int ss_bs_init(void)
142 {
143         if (0 > make_noti_file(BSNOTI_DIR, BSNOTI_FILE)) {
144                 PRT_TRACE_ERR("make_noti_file() failed");
145                 launch_crash_worker((void *)BSNOTI_FULL_PATH);
146         }
147                     
148         if (0 == ecore_file_init()) {
149                 PRT_TRACE_ERR("ecore_file_init() failed");
150                 launch_crash_worker((void *)BSNOTI_FULL_PATH);
151         }
152                             
153         bs_file_monitor = ecore_file_monitor_add(BSNOTI_FULL_PATH,(void *) __bs_file_cb, NULL);
154         if (!bs_file_monitor) {
155                 PRT_TRACE_ERR("ecore_file_monitor_add() failed");
156                 launch_crash_worker((void *)BSNOTI_FULL_PATH);
157                 return -1;
158         }
159
160         return 0;
161 }