6657e61c0746a1f681a1704f6a976c3cf536b585
[platform/core/appfw/ail.git] / src / ail_package.c
1 /*
2  * ail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23
24 #include <string.h>
25 #include <stdlib.h>
26 #include <db-util.h>
27 #include <tzplatform_config.h>
28 #include <vconf.h>
29 #include "ail.h"
30 #include "ail_private.h"
31 #include "ail_convert.h"
32 #include "ail_db.h"
33 #include "ail_sql.h"
34 #include "ail_package.h"
35 #include <assert.h>
36 #include <unistd.h>
37
38 #define LANGUAGE_LENGTH 2
39 #define DEFAULT_LOCALE          "No Locale"
40 #define MAX_QUERY_LEN   4096
41 #define PKG_SD_PATH tzplatform_mkpath(TZ_SYS_STORAGE, "sdcard/app2sd/")
42 #define QUERY_GET_LOCALNAME "select name from localname where package='%s' and locale='%s'"
43
44 struct ail_appinfo {
45         char **values;
46         sqlite3_stmt *stmt;
47 };
48
49 typedef struct _pkgmgr_locale_x {
50         char *locale;
51 } pkgmgr_locale_x;
52
53
54 /* get the first locale value*/
55 static int __fallback_locale_cb(void *data, int ncols, char **coltxt, char **colname)
56 {
57         pkgmgr_locale_x *info = (pkgmgr_locale_x *)data;
58
59         if (ncols >= 1)
60                 info->locale = strdup(coltxt[0]);
61         else
62                 info->locale = NULL;
63
64         return 0;
65 }
66
67 static int __check_validation_of_query_cb(void *data, int ncols, char **coltxt, char **colname)
68 {
69         int *p = (int*)data;
70         *p = atoi(coltxt[0]);
71         return 0;
72 }
73
74 static int __check_app_locale_from_app_localized_info_by_exact(const char *appid, const char *locale)
75 {
76         int result_query = -1;
77         char query[MAX_QUERY_LEN];
78
79         snprintf(query, MAX_QUERY_LEN, "select exists(select locale from localname where package='%s' and locale='%s')", appid, locale);
80         db_exec_sqlite_query(query, __check_validation_of_query_cb, (void *)&result_query);
81
82         return result_query;
83 }
84
85 static int __check_app_locale_from_app_localized_info_by_fallback(const char *appid, const char *locale)
86 {
87         int result_query = -1;
88         char wildcard[2] = {'%','\0'};
89         char query[MAX_QUERY_LEN];
90         char lang[3] = {'\0'};
91         strncpy(lang, locale, LANGUAGE_LENGTH);
92
93         snprintf(query, MAX_QUERY_LEN, "select exists(select locale from localname where package='%s' and locale like '%s%s')", appid, lang, wildcard);
94         db_exec_sqlite_query(query, __check_validation_of_query_cb, (void *)&result_query);
95
96         return result_query;
97 }
98
99 static char* __get_app_locale_from_app_localized_info_by_fallback(const char *appid, const char *locale)
100 {
101         char wildcard[2] = {'%','\0'};
102         char lang[3] = {'\0'};
103         char query[MAX_QUERY_LEN];
104         char *locale_new = NULL;
105         pkgmgr_locale_x *info = NULL;
106
107         info = (pkgmgr_locale_x *)malloc(sizeof(pkgmgr_locale_x));
108         if (info == NULL) {
109                 _E("Out of Memory!!!\n");
110                 return NULL;
111         }
112         memset(info, NULL, sizeof(*info));
113
114         strncpy(lang, locale, 2);
115         snprintf(query, MAX_QUERY_LEN, "select locale from localname where package='%s' and locale like '%s%s'", appid, lang, wildcard);
116         db_exec_sqlite_query(query, __fallback_locale_cb, (void *)info);
117         locale_new = info->locale;
118         free(info);
119
120         return locale_new;
121 }
122
123 static char* __convert_syslocale_to_manifest_locale(char *syslocale)
124 {
125         char *locale = malloc(6);
126         if (!locale) {
127                 _E("Malloc Failed\n");
128                 return NULL;
129         }
130
131         snprintf(locale, 6, "%c%c_%c%c", syslocale[0], syslocale[1], toupper(syslocale[3]), toupper(syslocale[4]));
132         return locale;
133 }
134
135 static char* __get_app_locale_by_fallback(const char *appid, const char *syslocale)
136 {
137         assert(appid);
138         assert(syslocale);
139
140         char *locale = NULL;
141         char *locale_new = NULL;
142         int check_result = 0;
143
144         locale = __convert_syslocale_to_manifest_locale(syslocale);
145
146         /*check exact matching */
147         check_result = __check_app_locale_from_app_localized_info_by_exact(appid, locale);
148
149         /* Exact found */
150         if (check_result == 1) {
151                 _D("%s find exact locale(%s)\n", appid, locale);
152                 return locale;
153         }
154
155         /* fallback matching */
156         check_result = __check_app_locale_from_app_localized_info_by_fallback(appid, locale);
157         if(check_result == 1) {
158                    locale_new = __get_app_locale_from_app_localized_info_by_fallback(appid, locale);
159                    _D("%s found (%s) language-locale in DB by fallback!\n", appid, locale_new);
160                    free(locale);
161                    if (locale_new == NULL)
162                            locale_new =  strdup(DEFAULT_LOCALE);
163                    return locale_new;
164         }
165
166         /* default locale */
167         free(locale);
168         _D("%s DEFAULT_LOCALE)\n", appid);
169         return  strdup(DEFAULT_LOCALE);
170 }
171
172 static ail_error_e __retrieve_all_column(ail_appinfo_h ai)
173 {
174         int i, j;
175         ail_error_e err;
176         char *col;
177
178         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
179         retv_if(!ai->stmt, AIL_ERROR_INVALID_PARAMETER);
180
181         ai->values = calloc(NUM_OF_PROP, sizeof(char *));
182         retv_if(!ai->values, AIL_ERROR_OUT_OF_MEMORY);
183
184         for (i = 0; i < NUM_OF_PROP; i++) {
185                 err = db_column_str(ai->stmt, i, &col);
186                 if (AIL_ERROR_OK != err) 
187                         break;
188
189                 if (!col) {
190                         ai->values[i] = NULL;
191                 } else {
192                         ai->values[i] = strdup(col);
193                         if (!ai->values[i]) {
194                                 err = AIL_ERROR_OUT_OF_MEMORY;
195                                 break;
196                         }
197                 }
198         }
199
200         if (err < 0) {
201                 for (j = 0; j < i; ++j) {
202                         if (ai->values[j])
203                                 free(ai->values[j]);
204                 }
205                 if (ai->values)
206                         free(ai->values);
207                 return err;
208         } else
209                 return AIL_ERROR_OK;
210 }
211
212 int _appinfo_check_installed_storage(ail_appinfo_h ai)
213 {
214         int index = 0;
215         ail_prop_str_e prop = -1;
216         char *pkgid = NULL;
217         char *installed_storage = NULL;
218         char buf[AIL_SQL_QUERY_MAX_LEN] = {'\0'};
219
220         retv_if(!ai, AIL_ERROR_OK);
221
222         if (ai->stmt) {
223                 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR);
224                 index = sql_get_app_info_idx(prop);
225                 if (db_column_str(ai->stmt, index, &installed_storage) < 0){
226                         return AIL_ERROR_OK;
227                 }
228
229                 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_PKGID_STR);
230                 index = sql_get_app_info_idx(prop);
231                 if (db_column_str(ai->stmt, index, &pkgid) < 0){
232                         return AIL_ERROR_OK;
233                 }
234         } else {
235                 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR);
236                 installed_storage = ai->values[prop];
237
238                 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_PKGID_STR);
239                 pkgid = ai->values[prop];
240         }
241
242         if (strcmp(installed_storage, "installed_external") == 0) {
243                 snprintf(buf, AIL_SQL_QUERY_MAX_LEN - 1, "%s%s", PKG_SD_PATH, pkgid);
244                 if (access(buf, R_OK) != 0) {
245                         _E("can not access [%s]", buf);
246                         return AIL_ERROR_OK;//tmep, it will be fixed to ::  return AIL_ERROR_FAIL;
247                 }
248         }
249
250         return AIL_ERROR_OK;
251 }
252
253 void appinfo_set_stmt(ail_appinfo_h ai, sqlite3_stmt *stmt)
254 {
255         ai->stmt = stmt;
256 }
257
258 ail_appinfo_h appinfo_create(void)
259 {
260         ail_appinfo_h ai;
261         ai = calloc(1, sizeof(struct ail_appinfo));
262         retv_if (NULL == ai, NULL);
263         ai->stmt = NULL;
264
265         return ai;
266 }
267
268 void appinfo_destroy(ail_appinfo_h ai)
269 {
270         if (ai)
271                 free(ai);
272 }
273
274 EXPORT_API ail_error_e ail_package_destroy_appinfo(ail_appinfo_h ai)
275 {
276         return ail_destroy_appinfo(ai);
277 }
278
279 EXPORT_API ail_error_e ail_destroy_appinfo(ail_appinfo_h ai)
280 {
281         int i;
282
283         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
284         retv_if(!ai->values, AIL_ERROR_INVALID_PARAMETER);
285
286         for (i = 0; i < NUM_OF_PROP; i++) {
287                 if (ai->values[i]) {
288                         free(ai->values[i]);
289                 }
290         }
291
292         free(ai->values);
293         free(ai);
294         db_close();
295
296         return AIL_ERROR_OK;
297 }
298
299 EXPORT_API ail_error_e ail_package_get_appinfo(const char *package, ail_appinfo_h *ai)
300 {
301         return ail_get_appinfo(package, ai);
302 }
303
304 EXPORT_API ail_error_e ail_package_get_usr_appinfo(const char *package, uid_t uid, ail_appinfo_h *ai)
305 {
306         return ail_get_usr_appinfo(package, uid, ai);
307 }
308
309 EXPORT_API ail_error_e ail_get_appinfo(const char *appid, ail_appinfo_h *ai)
310 {
311         ail_error_e ret;
312         char query[AIL_SQL_QUERY_MAX_LEN];
313         sqlite3_stmt *stmt = NULL;
314         char w[AIL_SQL_QUERY_MAX_LEN];
315         const char *filter;
316
317         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
318         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
319
320         *ai = appinfo_create();
321         retv_if(!*ai, AIL_ERROR_OUT_OF_MEMORY);
322
323         filter = sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR);
324         if (filter == NULL) {
325                 appinfo_destroy(*ai);
326                 return AIL_ERROR_FAIL;
327         }
328
329         snprintf(w, sizeof(w), filter, appid);
330         snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",
331                                         SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
332
333         do {
334                 ret = db_open(DB_OPEN_RO, GLOBAL_USER);
335                 if (ret < 0)
336                         break;
337
338                 /* is_admin */
339                 ret = db_prepare_globalro(query, &stmt);
340                 if (ret < 0)
341                         break;
342
343                 ret = db_step(stmt);
344                 if (ret < 0) {
345                         db_finalize(stmt);
346                         break;
347                 }
348
349                 (*ai)->stmt = stmt;
350
351                 ret = _appinfo_check_installed_storage(*ai);
352                 if (ret < 0) {
353                         db_finalize((*ai)->stmt);
354                         break;
355                 }
356
357                 ret = __retrieve_all_column(*ai);
358                 if (ret < 0) {
359                         db_finalize((*ai)->stmt);
360                         break;
361                 }
362
363                 ret = db_finalize((*ai)->stmt);
364                 if (ret < 0)
365                         break;
366
367                 (*ai)->stmt = NULL;
368
369                 return AIL_ERROR_OK;
370         } while (0);
371
372         appinfo_destroy(*ai);
373
374         return ret;
375 }
376
377 EXPORT_API ail_error_e ail_get_usr_appinfo(const char *appid, uid_t uid, ail_appinfo_h *ai)
378 {
379         ail_error_e ret;
380         char query[AIL_SQL_QUERY_MAX_LEN];
381         sqlite3_stmt *stmt = NULL;
382         char w[AIL_SQL_QUERY_MAX_LEN];
383         const char *filter;
384
385         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
386         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
387
388         *ai = appinfo_create();
389         retv_if(!*ai, AIL_ERROR_OUT_OF_MEMORY);
390
391         filter = sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR);
392         if (filter == NULL) {
393                 appinfo_destroy(*ai);
394                 return AIL_ERROR_FAIL;
395         }
396
397         snprintf(w, sizeof(w), filter, appid);
398         snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",
399                                         SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
400
401         do {
402                 ret = db_open(DB_OPEN_RO, uid);
403                 if (ret < 0)
404                         break;
405
406                 /* is_admin */
407                 ret = db_prepare(query, &stmt);
408                 if (ret < 0)
409                         break;
410
411                 ret = db_step(stmt);
412                 if (ret < 0) {
413                         db_finalize(stmt);
414                         break;
415                 }
416
417                 (*ai)->stmt = stmt;
418
419                 ret = _appinfo_check_installed_storage(*ai);
420                 if (ret < 0) {
421                         db_finalize((*ai)->stmt);
422                         break;
423                 }
424
425                 ret = __retrieve_all_column(*ai);
426                 if (ret < 0) {
427                         db_finalize((*ai)->stmt);
428                         break;
429                 }
430
431                 ret = db_finalize((*ai)->stmt);
432                 if (ret < 0)
433                         break;
434
435                 (*ai)->stmt = NULL;
436
437                 return AIL_ERROR_OK;
438         } while (0);
439
440         appinfo_destroy(*ai);
441
442         return ret;
443 }
444
445 EXPORT_API ail_error_e ail_appinfo_get_bool(const ail_appinfo_h ai, const char *property, bool *value)
446 {
447         ail_prop_bool_e prop;
448         int val;
449
450         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
451         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
452         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
453
454         prop = _ail_convert_to_prop_bool(property);
455
456         if (prop < E_AIL_PROP_BOOL_MIN || prop > E_AIL_PROP_BOOL_MAX)
457                 return AIL_ERROR_INVALID_PARAMETER;
458
459         if (ai->stmt) {
460                 int index;
461                 index = sql_get_app_info_idx(prop);
462                 if (db_column_bool(ai->stmt, index, value) < 0)
463                         return AIL_ERROR_DB_FAILED;
464         } else {
465                 val = atoi(ai->values[prop]);
466                 *value = (val == 0? false : true);
467         }
468         return AIL_ERROR_OK;
469 }
470
471 EXPORT_API ail_error_e ail_appinfo_get_int(const ail_appinfo_h ai, const char *property, int *value)
472 {
473         ail_prop_int_e prop;
474
475         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
476         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
477         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
478
479         prop = _ail_convert_to_prop_int(property);
480
481         if (prop < E_AIL_PROP_INT_MIN || prop > E_AIL_PROP_INT_MAX)
482                 return AIL_ERROR_INVALID_PARAMETER;
483
484         if (ai->stmt) {
485                 int index;
486                 index = sql_get_app_info_idx(prop);
487                 if (db_column_int(ai->stmt, index, value) < 0)
488                         return AIL_ERROR_DB_FAILED;
489         } else
490                 *value = atoi(ai->values[prop]);
491
492         return AIL_ERROR_OK;
493 }
494
495 char *appinfo_get_localname(const char *package, char *locale, uid_t uid)
496 {
497         db_open(DB_OPEN_RO, uid);
498         sqlite3_stmt *stmt;
499         char *str = NULL;
500         char *localname;
501         char query[512];
502
503         snprintf(query, sizeof(query), QUERY_GET_LOCALNAME, package, locale);
504
505         if (uid != GLOBAL_USER)
506                 retv_if (db_prepare(query, &stmt) < 0, NULL);
507         else
508                 retv_if (db_prepare_globalro(query, &stmt) < 0, NULL);
509
510         do {
511                 if (db_step(stmt) < 0)
512                         break;
513                 if (db_column_str(stmt, 0, &str) < 0)
514                         break;
515                 if (str)
516                         localname = strdup(str);
517                 else
518                         localname = NULL;
519
520                 db_finalize(stmt);
521
522                 return localname;
523         } while(0);
524
525         db_finalize(stmt);
526         return NULL;
527 }
528
529 EXPORT_API ail_error_e ail_appinfo_get_str(const ail_appinfo_h ai, const char *property, char **str)
530 {
531         int index;
532         char *value;
533         char *pkg;
534         char *pkg_type;
535         char *locale, *localname;
536         ail_prop_str_e prop;
537         char *locale_new;
538
539         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
540         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
541         retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
542
543         prop = _ail_convert_to_prop_str(property);
544
545         if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
546                 return AIL_ERROR_INVALID_PARAMETER;
547
548         localname = NULL;
549
550         if (E_AIL_PROP_NAME_STR == prop) {
551                 if (ai->stmt) {
552                         if (db_column_str(ai->stmt, E_AIL_PROP_X_SLP_PACKAGETYPE_STR, &pkg_type) < 0)
553                                 return AIL_ERROR_DB_FAILED;
554                         if(pkg_type && (strcasecmp(pkg_type, "tpk") ==0))
555                         {
556                                 locale = sql_get_locale();
557                                 retv_if (NULL == locale, AIL_ERROR_FAIL);
558
559                                 if (db_column_str(ai->stmt, E_AIL_PROP_PACKAGE_STR, &pkg) < 0){
560                                         free(locale);
561                                         return AIL_ERROR_DB_FAILED;
562                                 }
563                                 if (pkg == NULL){
564                                         free(locale);
565                                         return AIL_ERROR_DB_FAILED;
566                                 }
567
568                                 locale_new = __get_app_locale_by_fallback(pkg, locale);
569                                 localname = (char *)appinfo_get_localname(pkg, locale_new, GLOBAL_USER);
570                                 free(locale);
571                                 free(locale_new);
572                         } else {
573                                 if (db_column_str(ai->stmt, SQL_LOCALNAME_IDX, &localname) < 0)
574                                         return AIL_ERROR_DB_FAILED;
575                         }
576                 } else {
577                         pkg_type = ai->values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR];
578                         pkg = ai->values[E_AIL_PROP_PACKAGE_STR];
579                         retv_if (NULL == pkg, AIL_ERROR_FAIL);
580
581                         locale = sql_get_locale();
582                         retv_if (NULL == locale, AIL_ERROR_FAIL);
583
584                         if(pkg_type && (strcasecmp(pkg_type, "tpk") ==0))
585                         {
586                                 locale_new = __get_app_locale_by_fallback(pkg, locale);
587                                 localname = (char *)appinfo_get_localname(pkg, locale_new, GLOBAL_USER);
588                                 free(locale);
589                                 free(locale_new);
590                         } else {
591                                 localname = (char *)appinfo_get_localname(pkg, locale, GLOBAL_USER);
592                                 free(locale);
593                         }
594                 }
595
596                 if (localname) {
597                         if (!ai->stmt) {
598                                 if (ai->values) {
599                                         if (ai->values[prop])
600                                                 free(ai->values[prop]);
601                                         ai->values[prop] = localname;
602                                 }
603                         }
604                         *str = localname;
605                         return AIL_ERROR_OK;
606                 }
607         }
608
609         if (ai->stmt) {
610                 index = sql_get_app_info_idx(prop);
611                 if (db_column_str(ai->stmt, index, &value) < 0){
612                         return AIL_ERROR_DB_FAILED;
613                 }
614                 *str = value;
615         } else
616                 *str = ai->values[prop];
617
618         return AIL_ERROR_OK;
619 }
620 EXPORT_API ail_error_e ail_appinfo_get_usr_str(const ail_appinfo_h ai, const char *property, uid_t uid, char **str)
621 {
622         int index;
623         char *value;
624         char *pkg;
625         char *pkg_type;
626         char *locale, *localname;
627         ail_prop_str_e prop;
628         char *locale_new;
629
630         retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
631         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
632         retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
633
634         prop = _ail_convert_to_prop_str(property);
635
636         if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
637                 return AIL_ERROR_INVALID_PARAMETER;
638
639         localname = NULL;
640
641         if (E_AIL_PROP_NAME_STR == prop) {
642                 if (ai->stmt) {
643                         if (db_column_str(ai->stmt, E_AIL_PROP_X_SLP_PACKAGETYPE_STR, &pkg_type) < 0)
644                                 return AIL_ERROR_DB_FAILED;
645                         if(pkg_type && (strcasecmp(pkg_type, "tpk") ==0))
646                         {
647                                 locale = sql_get_locale();
648                                 retv_if (NULL == locale, AIL_ERROR_FAIL);
649
650                                 if (db_column_str(ai->stmt, E_AIL_PROP_PACKAGE_STR, &pkg) < 0){
651                                         free(locale);
652                                         return AIL_ERROR_DB_FAILED;
653                                 }
654                                 if (pkg == NULL){
655                                         free(locale);
656                                         return AIL_ERROR_DB_FAILED;
657                                 }
658
659                                 locale_new = __get_app_locale_by_fallback(pkg, locale);
660                                 localname = (char *)appinfo_get_localname(pkg, locale_new, uid);
661                                 free(locale);
662                                 free(locale_new);
663                         } else {
664                                 if (db_column_str(ai->stmt, SQL_LOCALNAME_IDX, &localname) < 0)
665                                         return AIL_ERROR_DB_FAILED;
666                         }
667                 } else {
668                         pkg_type = ai->values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR];
669                         pkg = ai->values[E_AIL_PROP_PACKAGE_STR];
670                         retv_if (NULL == pkg, AIL_ERROR_FAIL);
671
672                         locale = sql_get_locale();
673                         retv_if (NULL == locale, AIL_ERROR_FAIL);
674
675                         if(pkg_type && (strcasecmp(pkg_type, "tpk") ==0))
676                         {
677                                 locale_new = __get_app_locale_by_fallback(pkg, locale);
678                                 localname = (char *)appinfo_get_localname(pkg, locale_new, uid);
679                                 free(locale);
680                                 free(locale_new);
681                         } else {
682                                 localname = (char *)appinfo_get_localname(pkg, locale, uid);
683                                 free(locale);
684                         }
685                 }
686
687                 if (localname) {
688                         if (!ai->stmt) {
689                                 if (ai->values) {
690                                         if (ai->values[prop])
691                                                 free(ai->values[prop]);
692                                         ai->values[prop] = localname;
693                                 }
694                         }
695                         *str = localname;
696                         return AIL_ERROR_OK;
697                 }
698         }
699
700         if (ai->stmt) {
701                 index = sql_get_app_info_idx(prop);
702                 if (db_column_str(ai->stmt, index, &value) < 0){
703                         return AIL_ERROR_DB_FAILED;
704                 }
705                 *str = value;
706         } else
707                 *str = ai->values[prop];
708
709         return AIL_ERROR_OK;
710 }
711
712
713 EXPORT_API ail_error_e ail_close_appinfo_db(void)
714 {
715         return db_close();
716 }
717
718 // End of file