2 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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.
18 #define _XOPEN_SOURCE 500
26 #include <sys/types.h>
30 #include "pkgmgrinfo_type.h"
31 #include "pkgmgr-info.h"
32 #include "pkgmgr-server.h"
35 #define BACKEND_DIR "/etc/package-manager/backend"
38 struct backend_queue {
45 static GHashTable *queue_type_table;
46 static GHashTable *queue_slot_table;
50 int _is_queue_empty(int pos)
52 struct backend_queue *queue;
54 queue = (struct backend_queue *)g_hash_table_lookup(queue_slot_table,
57 ERR("cannot find queue of slot %d", pos);
61 if (queue->job_list == NULL)
67 struct backend_job *_pop_queue(int pos)
69 struct backend_queue *queue;
70 struct backend_job *job;
73 queue = (struct backend_queue *)g_hash_table_lookup(queue_slot_table,
76 ERR("cannot find queue of slot %d", pos);
80 tmp = g_list_first(queue->job_list);
83 job = (struct backend_job *)tmp->data;
84 queue->job_list = g_list_delete_link(queue->job_list, tmp);
89 int _push_queue(uid_t target_uid, uid_t caller_uid, const char *req_id,
90 int req_type, const char *queue_type, const char *pkgid,
91 const char *args, void *extra_data)
93 struct backend_queue *queue;
94 struct backend_job *job;
96 queue = (struct backend_queue *)g_hash_table_lookup(queue_type_table,
97 (gconstpointer)queue_type);
99 ERR("no such queue: %s", queue_type);
103 job = calloc(1, sizeof(struct backend_job));
105 ERR("Out of memory");
109 job->target_uid = target_uid;
110 job->caller_uid = caller_uid;
112 job->req_id = strdup(req_id);
113 job->req_type = req_type;
115 job->pkgid = strdup(pkgid);
117 job->args = strdup(args);
118 /* just assign pointer value */
119 job->backend_slot = queue->slot;
120 job->backend_type = queue->type;
121 job->backend_path = queue->path;
123 job->extra_data = extra_data;
125 queue->job_list = g_list_append(queue->job_list, (gpointer)job);
130 static int __init_backends(const char *fpath, const struct stat *sb,
131 int typeflag, struct FTW *ftwbuf)
134 struct backend_queue *queue;
136 if (typeflag != FTW_F && typeflag != FTW_SL)
139 queue = calloc(1, sizeof(struct backend_queue));
141 ERR("Out of memory");
145 if (typeflag == FTW_F) {
146 queue->path = strdup(fpath);
147 } else if (typeflag == FTW_SL) {
148 queue->path = malloc(sb->st_size + 1);
149 if (queue->path == NULL) {
150 ERR("Out of memory");
155 r = readlink(fpath, queue->path, sb->st_size + 1);
156 if (r < 0 || r > sb->st_size) {
157 ERR("failed to readlink for %s", fpath);
162 queue->path[r] = '\0';
164 queue->type = strdup(fpath + ftwbuf->base);
165 queue->slot = num_of_backends++;
166 g_hash_table_insert(queue_type_table, (gpointer)queue->type,
168 g_hash_table_insert(queue_slot_table, (gpointer)queue->slot,
171 DBG("backend detected: %s(%s)", queue->type, queue->path);
176 static gboolean __str_equal(gconstpointer v1, gconstpointer v2)
178 const char *str1 = (const char *)v1;
179 const char *str2 = (const char *)v2;
182 return strcasecmp(str1, str2) == 0;
185 void __free_extra_info(struct backend_job *job)
187 struct getsize_sync_extra_info *getsize_sync_data;
188 pkgmgrinfo_updateinfo_h update_info;
190 switch (job->req_type) {
191 case REQUEST_TYPE_GETSIZE_SYNC:
192 getsize_sync_data = (struct getsize_sync_extra_info *)job->extra_data;
193 if (!getsize_sync_data)
195 if (getsize_sync_data->getsize_io)
196 g_io_channel_unref(getsize_sync_data->getsize_io);
197 if (getsize_sync_data->getsize_fd)
198 close(getsize_sync_data->getsize_fd);
199 if (getsize_sync_data->getsize_fifo) {
200 unlink(getsize_sync_data->getsize_fifo);
201 free(getsize_sync_data->getsize_fifo);
203 free(getsize_sync_data);
204 job->extra_data = NULL;
206 case REQUEST_TYPE_REGISTER_PKG_UPDATE_INFO:
207 update_info = (pkgmgrinfo_updateinfo_h)job->extra_data;
210 pkgmgrinfo_updateinfo_destroy(update_info);
211 job->extra_data = NULL;
216 void _free_backend_job(struct backend_job *job)
218 __free_extra_info(job);
226 static void __free_backend_queue(gpointer data)
228 struct backend_queue *queue = (struct backend_queue *)data;
230 g_list_free_full(queue->job_list, (GDestroyNotify)_free_backend_job);
236 void _fini_backend_queue(void)
238 g_hash_table_destroy(queue_slot_table);
239 g_hash_table_destroy(queue_type_table);
242 int _init_backend_queue(void)
244 queue_type_table = g_hash_table_new_full(g_str_hash, __str_equal,
245 NULL, __free_backend_queue);
246 queue_slot_table = g_hash_table_new(g_direct_hash, g_direct_equal);
248 if (nftw(BACKEND_DIR, __init_backends, NOPENFD, FTW_PHYS))
251 DBG("number of backends: %d", num_of_backends);