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