4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Garima Shrivastava<garima.s@samsung.com>
7 * Jyotsna Dhumale <jyotsna.a@samsung.com>
8 * Venkatesha Sarpangala <sarpangala.v@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
24 #include <app2sd_internals.h>
25 #include <app2sd_interface.h>
27 #include <sys/types.h>
31 #include <sys/types.h>
36 #include <sys/statvfs.h>
41 #define ASCII_PASSWD_CHAR 93
42 #define LIB_PRIVILEGE_CONTROL "libprivilege-control.so.0"
45 ########### Internal APIs ##################
48 /*Note: Don't use any printf statement inside this function*/
49 /*This function is similar to Linux's "system()" for executing a process.*/
50 int _xsystem(const char *argv[])
57 perror("fork failed");
61 execvp(argv[0], (char *const *)argv);
67 if (waitpid(pid, &status, 0) == -1) {
68 perror("waitpid failed");
71 if (WIFSIGNALED(status)) {
75 if (!WIFEXITED(status)) {
76 /* shouldn't happen */
77 perror("should not happen");
80 return WEXITSTATUS(status);
85 * @_app2sd_check_mmc_status
86 * This function checks and returns MMC status
88 int _app2sd_check_mmc_status(void)
92 fp1 = fopen("/etc/mtab", "r");
94 fprintf(stderr, "failed to open file\n");
95 app2ext_print("failed to open file /etc/mtab\n");
96 return APP2EXT_ERROR_MMC_STATUS;
98 while (fgets(line, 512, fp1) != NULL) {
99 if (strstr(line, MMC_PATH) != NULL) {
101 return APP2EXT_SUCCESS;
105 return APP2EXT_ERROR_MMC_STATUS;
109 * @_app2sd_get_available_free_memory
110 * This function returns the available free memory in the SD Card.
111 * param [in]: sd_path: This is sd card access path.
112 * param [out]: free_mem: Result will be available in this.
113 * User has to pass valid memory address.
114 * return: On success, it will return 0.
115 * Else, appropriate error no will be returned.
117 int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem)
121 if (sd_path == NULL || free_mem == NULL) {
122 app2ext_print("App2Sd Error : Invalid input parameter\n");
125 memset((void *)&buf, '\0', sizeof(struct statvfs));
126 ret = statvfs(sd_path, &buf);
129 ("App2SD Error: Unable to get SD Card memory information\n");
130 return APP2EXT_ERROR_MMC_INFORMATION;
132 *free_mem = ((buf.f_bfree * buf.f_bsize) / 1024) / 1024;
136 int _app2sd_delete_directory(char *dirname)
139 struct dirent *ep = NULL;
140 char abs_filename[FILENAME_MAX] = { 0, };
142 dp = opendir(dirname);
144 while ((ep = readdir(dp)) != NULL) {
145 struct stat stFileInfo;
147 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
150 if (lstat(abs_filename, &stFileInfo) < 0) {
151 perror(abs_filename);
155 if (S_ISDIR(stFileInfo.st_mode)) {
156 if (strcmp(ep->d_name, ".")
157 && strcmp(ep->d_name, "..")) {
158 ret = _app2sd_delete_directory(abs_filename);
163 ret = remove(abs_filename);
169 ret = remove(dirname);
173 app2ext_print("Couldn't open the directory[%s]\n", dirname);
178 int _app2sd_copy_dir(const char *src, const char *dest)
180 int ret = APP2EXT_SUCCESS;
181 const char *argv_bin[] = { "/bin/cp", "-raf", src, dest, NULL };
182 ret = _xsystem(argv_bin);
184 app2ext_print("copy fail\n");
185 return APP2EXT_ERROR_MOVE;
190 int _app2sd_rename_dir(const char *old_name, const char *new_name)
192 int ret = APP2EXT_SUCCESS;
193 const char *argv_bin[] = { "/bin/mv", old_name, new_name, NULL };
194 ret = _xsystem(argv_bin);
196 app2ext_print("mv/rename fail\n");
197 return APP2EXT_ERROR_MOVE;
202 unsigned long long _app2sd_calculate_dir_size(char *dirname)
204 static unsigned long long total = 0;
206 struct dirent *ep = NULL;
207 char abs_filename[FILENAME_MAX] = { 0, };;
208 dp = opendir(dirname);
210 while ((ep = readdir(dp)) != NULL) {
211 struct stat stFileInfo;
213 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
216 if (stat(abs_filename, &stFileInfo) < 0)
217 perror(abs_filename);
219 total += stFileInfo.st_size;
221 if (S_ISDIR(stFileInfo.st_mode)) {
222 if (strcmp(ep->d_name, ".")
223 && strcmp(ep->d_name, "..")) {
224 _app2sd_calculate_dir_size
234 app2ext_print("\n error in opening directory ");
239 unsigned long long _app2sd_calculate_file_size(const char *filename)
241 struct stat stFileInfo;
242 app2ext_print("\n Calculating file size for %s\n", filename);
244 if (stat(filename, &stFileInfo) < 0) {
248 return stFileInfo.st_size;
251 /*Note: Don't use any printf statement inside this function*/
252 char *_app2sd_encrypt_device(const char *device, const char *pkgid,
256 { "/sbin/losetup", "-e", "aes", device, pkgid, "-k", passwd, NULL };
258 int my_pipe[2] = { 0, };
259 char buf[FILENAME_MAX] = { 0, };
260 char *ret_result = NULL;
262 if (pipe(my_pipe) < 0) {
263 fprintf(stderr, "Unable to create pipe\n");
269 perror("fork failed");
275 result = dup(my_pipe[1]);
277 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
280 result = dup(my_pipe[1]);
282 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
285 if (execvp(argv[0], (char *const *)argv) < 0) {
286 fprintf(stderr, "execvp failed %d....%s\n", errno, strerror(errno)); /*Don't use d_msg_app2sd */
292 result = read(my_pipe[0], buf, FILENAME_MAX);
294 fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
298 ret_result = (char *)malloc(strlen(buf) + 1);
299 if (ret_result == NULL) {
300 app2ext_print("Malloc failed!\n");
303 memset(ret_result, '\0', strlen(buf) + 1);
304 memcpy(ret_result, buf, strlen(buf));
308 /*Note: Don't use any printf statement inside this function*/
309 char *_app2sd_detach_loop_device(const char *device)
311 const char *argv[] = { "/sbin/losetup", "-d", device, NULL };
313 int my_pipe[2] = { 0, };
314 char buf[FILENAME_MAX] = { 0, };
315 char *ret_result = NULL;
317 if (pipe(my_pipe) < 0) {
318 fprintf(stderr, "Unable to create pipe\n");
324 perror("fork failed");
330 result = dup(my_pipe[1]);
332 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
335 result = dup(my_pipe[1]);
337 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
340 if (execvp(argv[0], (char *const *)argv) < 0) {
341 fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
347 result = read(my_pipe[0], buf, FILENAME_MAX);
349 fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
353 ret_result = (char *)malloc(strlen(buf) + 1);
354 if (ret_result == NULL) {
355 app2ext_print("Malloc failed!\n");
358 memset(ret_result, '\0', strlen(buf) + 1);
359 memcpy(ret_result, buf, strlen(buf));
364 /*Note: Don't use any printf statement inside this function*/
365 char *_app2sd_find_associated_device(const char *mmc_app_path)
367 const char *argv[] = { "/sbin/losetup", "-j", mmc_app_path, NULL };
369 int my_pipe[2] = { 0, };
370 char buf[FILENAME_MAX] = { 0, };
371 char *ret_result = NULL;
373 if (pipe(my_pipe) < 0) {
374 fprintf(stderr, "Unable to create pipe\n");
380 perror("fork failed");
386 result = dup(my_pipe[1]);
388 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
391 result = dup(my_pipe[1]);
393 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
396 if (execvp(argv[0], (char *const *)argv) < 0) {
397 fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
403 result = read(my_pipe[0], buf, FILENAME_MAX);
405 fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
409 ret_result = (char *)malloc(strlen(buf) + 1);
410 if (ret_result == NULL) {
411 app2ext_print("Malloc failed!\n");
414 memset(ret_result, '\0', strlen(buf) + 1);
415 memcpy(ret_result, buf, strlen(buf));
420 /*Note: Don't use any printf statement inside this function*/
421 char *_app2sd_find_free_device(void)
423 const char *argv[] = { "/sbin/losetup", "-f", NULL };
425 int my_pipe[2] = { 0, };
426 char buf[FILENAME_MAX+1] = { 0, };
427 char *ret_result = NULL;
429 if (pipe(my_pipe) < 0) {
430 fprintf(stderr, "Unable to create pipe\n");
436 perror("fork failed");
442 result = dup(my_pipe[1]);
444 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
447 result = dup(my_pipe[1]);
449 fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
452 if (execvp(argv[0], (char *const *)argv) < 0) {
453 fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
459 result = read(my_pipe[0], buf, FILENAME_MAX);
461 fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
465 ret_result = (char *)malloc(strlen(buf) + 1);
466 if (ret_result == NULL) {
467 app2ext_print("Malloc failed!\n");
470 memset(ret_result, '\0', strlen(buf) + 1);
471 memcpy(ret_result, buf, strlen(buf));
476 /*@_app2sd_generate_password
477 * This is a simple password generator
478 * return: On success, it will return the password, else NULL.
480 char *_app2sd_generate_password(const char *pkgid)
482 char passwd[PASSWD_LEN+1] = { 0, };
483 char *ret_result = NULL;
484 char set[ASCII_PASSWD_CHAR+1] = "!\"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
485 unsigned char char_1;
486 unsigned char char_2;
488 int appname_len = strlen(pkgid);
491 /* Length of the password */
492 ret_result = (char*)malloc(PASSWD_LEN+1);
493 if (NULL == ret_result) {
494 app2ext_print("Unable to Allocate memory\n");
497 memset((void *)ret_result, '\0', PASSWD_LEN+1);
499 while(i < PASSWD_LEN) {
500 char_1 = (rand()+pkgid[j--])%ASCII_PASSWD_CHAR;
501 char_2 = rand()%ASCII_PASSWD_CHAR;
502 passwd[i] = set[char_1];
503 passwd[i+1] = set[(pkgid[j--])*2];
505 passwd[i+2] = set[char_2];
509 app2ext_print("Password is %s\n", passwd);
510 memcpy(ret_result, passwd, PASSWD_LEN+1);
514 /*@_app2sd_setup_path
515 * change smack label given groupid
516 * return: On success, it will return the password, else NULL.
518 int _app2sd_setup_path(const char *pkgid, const char *dirpath,
519 int apppathtype, const char *groupid)
524 int (*perm_app_setup_path)(const char*, const char*, int, ...) = NULL;
526 if (pkgid == NULL || dirpath == NULL)
529 handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
531 app2ext_print( "setup path: dlopen() failed. [%s]", dlerror());
535 perm_app_setup_path = dlsym(handle, "perm_app_setup_path");
537 if ((errmsg != NULL) || (perm_app_setup_path == NULL)) {
538 app2ext_print( "setup path: dlsym() failed. [%s]", errmsg);
543 if (groupid == NULL) {
544 app2ext_print( "[smack] perm_app_setup_path(%s, %s, %d)", pkgid, dirpath, apppathtype);
545 ret = perm_app_setup_path(pkgid, dirpath, apppathtype);
546 app2ext_print( "[smack] perm_app_setup_path(), result = [%d]", ret);
548 app2ext_print( "[smack] perm_app_setup_path(%s, %s, %d, %s)", pkgid, dirpath, apppathtype, groupid);
549 ret = perm_app_setup_path(pkgid, dirpath, apppathtype, groupid);
550 app2ext_print( "[smack] perm_app_setup_path(), result = [%d]", ret);