Update SMACK, Fix a crash of terminating sequence, etc, ...
[apps/livebox/data-provider-master.git] / src / liveinfo.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.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 #include <stdio.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <libgen.h>
22 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26
27 #include <Eina.h>
28
29 #include <dlog.h>
30 #include <livebox-errno.h>
31
32 #include "util.h"
33 #include "debug.h"
34 #include "conf.h"
35
36 int errno;
37
38 static struct info {
39         Eina_List *info_list;
40 } s_info = {
41         .info_list = NULL,
42 };
43
44 struct liveinfo {
45         FILE *fp;
46         char fifo_name[60];
47         pid_t pid;
48         int handle;
49 };
50
51 HAPI int liveinfo_init(void)
52 {
53         return 0;
54 }
55
56 HAPI void liveinfo_fini(void)
57 {
58         struct liveinfo *info;
59
60         EINA_LIST_FREE(s_info.info_list, info) {
61                 if (fclose(info->fp) != 0)
62                         ErrPrint("fclose: %s\n", strerror(errno));
63                 if (unlink(info->fifo_name) < 0)
64                         ErrPrint("unlink: %s\n", strerror(errno));
65                 DbgFree(info);
66         }
67 }
68
69 static inline int valid_requestor(pid_t pid)
70 {
71         char cmdline[60]; /* strlen("/proc/%d/cmdline") + 30 */
72         struct stat target;
73         struct stat src;
74
75         snprintf(cmdline, sizeof(cmdline), "/proc/%d/exe", pid);
76
77         DbgPrint("Open cmdline: %s (%d)\n", cmdline, pid);
78
79         if (stat(cmdline, &target) < 0) {
80                 ErrPrint("Error: %s\n", strerror(errno));
81                 return 0;
82         }
83
84         if (stat("/usr/bin/liveinfo", &src) < 0) {
85                 ErrPrint("Error: %s\n", strerror(errno));
86                 return 0;
87         }
88
89         return target.st_ino == src.st_ino;
90 }
91
92 HAPI struct liveinfo *liveinfo_create(pid_t pid, int handle)
93 {
94         struct liveinfo *info;
95
96         if (!valid_requestor(pid)) {
97                 ErrPrint("Invalid requestor\n");
98                 return NULL;
99         }
100
101         info = calloc(1, sizeof(*info));
102         if (!info) {
103                 ErrPrint("Heap: %s\n", strerror(errno));
104                 return NULL;
105         }
106
107         snprintf(info->fifo_name, sizeof(info->fifo_name), "/tmp/.live_info.%lf", util_timestamp());
108         if (mkfifo(info->fifo_name, 0644) < 0) {
109                 ErrPrint("mkfifo: %s\n", strerror(errno));
110                 if (unlink(info->fifo_name) < 0)
111                         ErrPrint("unlink: %s\n", strerror(errno));
112                 DbgFree(info);
113                 return NULL;
114         }
115
116         info->fp = NULL;
117         info->pid = pid;
118         info->handle = handle;
119
120         DbgPrint("Live info is successfully created\n");
121         s_info.info_list = eina_list_append(s_info.info_list, info);
122         return info;
123 }
124
125 HAPI int liveinfo_open_fifo(struct liveinfo *info)
126 {
127         DbgPrint("FIFO is created (%s)\n", info->fifo_name);
128         info->fp = fopen(info->fifo_name, "w");
129         if (!info->fp) {
130                 ErrPrint("open: %s\n", strerror(errno));
131                 return LB_STATUS_ERROR_IO;
132         }
133
134         return LB_STATUS_SUCCESS;
135 }
136
137 HAPI void liveinfo_close_fifo(struct liveinfo *info)
138 {
139         if (info->fp) {
140                 if (fclose(info->fp) != 0)
141                         ErrPrint("fclose: %s\n", strerror(errno));
142                 info->fp = NULL;
143         }
144 }
145
146 HAPI void liveinfo_destroy(struct liveinfo *info)
147 {
148         s_info.info_list = eina_list_remove(s_info.info_list, info);
149         liveinfo_close_fifo(info);
150         if (unlink(info->fifo_name) < 0)
151                 ErrPrint("unlink: %s\n", strerror(errno));
152         DbgFree(info);
153 }
154
155 HAPI pid_t liveinfo_pid(struct liveinfo *info)
156 {
157         return info ? info->pid : (pid_t)-1;
158 }
159
160 HAPI const char *liveinfo_filename(struct liveinfo *info)
161 {
162         return info ? info->fifo_name : NULL;
163 }
164
165 HAPI FILE *liveinfo_fifo(struct liveinfo *info)
166 {
167         return info ? info->fp : NULL;
168 }
169
170 HAPI struct liveinfo *liveinfo_find_by_pid(pid_t pid)
171 {
172         Eina_List *l;
173         struct liveinfo *info;
174
175         EINA_LIST_FOREACH(s_info.info_list, l, info) {
176                 if (info->pid == pid)
177                         return info;
178         }
179
180         return NULL;
181 }
182
183 HAPI struct liveinfo *liveinfo_find_by_handle(int handle)
184 {
185         Eina_List *l;
186         struct liveinfo *info;
187
188         EINA_LIST_FOREACH(s_info.info_list, l, info) {
189                 if (info->handle == handle)
190                         return info;
191         }
192
193         return NULL;
194 }
195
196 /* End of a file */