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://floralicense.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.
21 #include <Elementary.h>
23 #include <Ecore_File.h>
25 #include <sys/inotify.h>
27 #include <sys/ioctl.h>
32 #include "pkg_event.h"
36 #define CONF_FILE "/usr/share/install-info/desktop.conf"
47 struct desktop_notifier s_desktop_notifier = {
55 struct inotify_path paths[CONF_PATH_NUMBER];
59 directory_notify(void* data, Ecore_Fd_Handler* fd_handler)
62 ssize_t read_size, len, i = 0;
65 fd = ecore_main_fd_handler_fd_get(fd_handler);
66 _D("There are some modification, ifd [%d]", fd);
68 _E("Failed to get fd");
69 return ECORE_CALLBACK_CANCEL;
72 if (ioctl(fd, FIONREAD, &read_size) < 0) {
73 _E("Failed to get q size");
74 return ECORE_CALLBACK_CANCEL;
78 _E("Buffer is not ready!!!");
79 return ECORE_CALLBACK_RENEW;
82 buf = malloc(read_size);
84 _E("Failed to allocate heap for event handling");
85 return ECORE_CALLBACK_RENEW;
88 len = read(fd, buf, read_size);
91 return ECORE_CALLBACK_CANCEL;
93 buf[read_size - 1] = '\0';
96 struct inotify_event* event = (struct inotify_event*) &buf[i];
97 char *str_potksed = "potksed.";
102 nev_name = strlen(event->name) - 1;
103 for (idx = 0; nev_name >= 0 && str_potksed[idx]; idx++) {
104 if (event->name[nev_name] != str_potksed[idx]) {
110 if (str_potksed[idx] != '\0' || nev_name < 0) {
111 _D("This is not a desktop file : %s", event->name);
112 i += sizeof(struct inotify_event) + event->len;
116 package = strdup(event->name);
117 break_if(NULL == package);
119 package[nev_name + 1] = '\0';
120 _D("Package : %s", package);
122 if (event->mask & IN_CLOSE_WRITE || event->mask & IN_MOVED_TO) {
123 ail_appinfo_h ai = NULL;
126 ret = ail_get_appinfo(package, &ai);
127 if (AIL_ERROR_OK == ret || AIL_ERROR_NO_DATA == ret) {
128 if (ai) ail_destroy_appinfo(ai);
130 if (AIL_ERROR_NO_DATA == ret) {
131 if (ail_desktop_add(package) < 0) {
132 _D("Failed to add a new package (%s)", event->name);
134 } else if (AIL_ERROR_OK == ret) {
135 if (ail_desktop_update(package) < 0) {
136 _D("Failed to add a new package (%s)", event->name);
140 _E("Failed to get appinfo");
142 } else if (event->mask & IN_DELETE) {
143 if (ail_desktop_remove(package) < 0)
144 _D("Failed to remove a package (%s)", event->name);
146 _D("this event is not dealt with inotify");
151 i += sizeof(struct inotify_event) + event->len;
155 return ECORE_CALLBACK_RENEW;
160 static inline char *_ltrim(char *str)
162 retv_if(NULL == str, NULL);
163 while (*str && (*str == ' ' || *str == '\t' || *str == '\n')) str ++;
169 static inline int _rtrim(char *str)
173 retv_if(NULL == str, 0);
176 while (--len >= 0 && (str[len] == ' ' || str[len] == '\n' || str[len] == '\t')) {
185 static int _retrieve_conf_path(struct inotify_path* paths)
193 fp = fopen(CONF_FILE, "r");
199 while ((read = getline(&line, &size, fp)) != -1 && i < CONF_PATH_NUMBER - 1) {
202 if (size <= 0) break;
204 begin = _ltrim(line);
207 if (*begin == '#' || *begin == '\0') continue;
209 paths[i].path = strdup(begin);
213 if (line) free(line);
214 paths[i].path = NULL;
222 static void _unretrieve_conf_path(struct inotify_path* paths, int number)
226 for (i = 0; i < number; i ++) {
229 paths[i].path = NULL;
236 void pkg_event_init()
241 s_desktop_notifier.ifd = inotify_init();
242 if (s_desktop_notifier.ifd == -1) {
243 _E("inotify_init error: %s", strerror(errno));
247 s_desktop_notifier.number = _retrieve_conf_path(paths);
249 for (i = 0; i < CONF_PATH_NUMBER && paths[i].path; i++)
251 _D("Configuration file for desktop file monitoring [%s] is added", paths[i].path);
252 if (access(paths[i].path, R_OK) != 0)
254 ecore_file_mkpath(paths[i].path);
255 if (chmod(paths[i].path, 0777) == -1) {
256 _E("cannot chmod %s", paths[i].path);
260 wd = inotify_add_watch(s_desktop_notifier.ifd, paths[i].path, IN_CLOSE_WRITE | IN_MOVED_TO | IN_DELETE);
262 _E("inotify_add_watch error: %s", strerror(errno));
263 close(s_desktop_notifier.ifd);
270 s_desktop_notifier.handler = ecore_main_fd_handler_add(s_desktop_notifier.ifd, ECORE_FD_READ, directory_notify, NULL, NULL, NULL);
271 if (!s_desktop_notifier.handler) {
272 _E("cannot add handler for inotify");
278 void pkg_event_fini(void)
282 if (s_desktop_notifier.handler) {
283 ecore_main_fd_handler_del(s_desktop_notifier.handler);
286 for (i = 0; i < CONF_PATH_NUMBER; i ++) {
288 if (inotify_rm_watch(s_desktop_notifier.ifd, paths[i].wd) < 0) {
289 _E("Error: %s", strerror(errno));
295 _unretrieve_conf_path(paths, s_desktop_notifier.number);
297 if (s_desktop_notifier.ifd) {
298 close(s_desktop_notifier.ifd);
299 s_desktop_notifier.ifd = 0;