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>
40 #define ASCII_PASSWD_CHAR 94
43 ########### Internal APIs ##################
46 /*Note: Don't use any printf statement inside this function*/
47 /*This function is similar to Linux's "system()" for executing a process.*/
48 int _xsystem(const char *argv[])
55 perror("fork failed");
59 execvp(argv[0], (char *const *)argv);
65 if (waitpid(pid, &status, 0) == -1) {
66 perror("waitpid failed");
69 if (WIFSIGNALED(status)) {
73 if (!WIFEXITED(status)) {
74 /* shouldn't happen */
75 perror("should not happen");
78 return WEXITSTATUS(status);
83 * @_app2sd_check_mmc_status
84 * This function checks and returns MMC status
86 int _app2sd_check_mmc_status(void)
90 fp1 = fopen("/etc/mtab", "r");
92 fprintf(stderr, "failed to open file\n");
93 app2ext_print("failed to open file /etc/mtab\n");
94 return APP2EXT_ERROR_MMC_STATUS;
96 while (fgets(line, 512, fp1) != NULL) {
97 if (strstr(line, MMC_PATH) != NULL) {
99 return APP2EXT_SUCCESS;
103 return APP2EXT_ERROR_MMC_STATUS;
107 * @_app2sd_get_available_free_memory
108 * This function returns the available free memory in the SD Card.
109 * param [in]: sd_path: This is sd card access path.
110 * param [out]: free_mem: Result will be available in this.
111 * User has to pass valid memory address.
112 * return: On success, it will return 0.
113 * Else, appropriate error no will be returned.
115 int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem)
119 if (sd_path == NULL || free_mem == NULL) {
120 app2ext_print("App2Sd Error : Invalid input parameter\n");
123 memset((void *)&buf, '\0', sizeof(struct statvfs));
124 ret = statvfs(sd_path, &buf);
127 ("App2SD Error: Unable to get SD Card memory information\n");
128 return APP2EXT_ERROR_MMC_INFORMATION;
130 *free_mem = ((buf.f_bfree * buf.f_bsize) / 1024) / 1024;
134 int _app2sd_delete_directory(char *dirname)
137 struct dirent *ep = NULL;
138 char abs_filename[FILENAME_MAX] = { 0, };
140 dp = opendir(dirname);
142 while ((ep = readdir(dp)) != NULL) {
143 struct stat stFileInfo;
145 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
148 if (lstat(abs_filename, &stFileInfo) < 0) {
149 perror(abs_filename);
153 if (S_ISDIR(stFileInfo.st_mode)) {
154 if (strcmp(ep->d_name, ".")
155 && strcmp(ep->d_name, "..")) {
156 ret = _app2sd_delete_directory(abs_filename);
161 ret = remove(abs_filename);
167 ret = remove(dirname);
171 app2ext_print("Couldn't open the directory\n");
176 int _app2sd_copy_dir(const char *src, const char *dest)
178 int ret = APP2EXT_SUCCESS;
179 const char *argv_bin[] = { "/bin/cp", "-raf", src, dest, NULL };
180 ret = _xsystem(argv_bin);
182 app2ext_print("copy fail\n");
183 return APP2EXT_ERROR_MOVE;
188 int _app2sd_rename_dir(const char *old_name, const char *new_name)
190 int ret = APP2EXT_SUCCESS;
191 const char *argv_bin[] = { "/bin/mv", old_name, new_name, NULL };
192 ret = _xsystem(argv_bin);
194 app2ext_print("mv/rename fail\n");
195 return APP2EXT_ERROR_MOVE;
200 unsigned long long _app2sd_calculate_dir_size(char *dirname)
202 static unsigned long long total = 0;
204 struct dirent *ep = NULL;
205 char abs_filename[FILENAME_MAX] = { 0, };;
206 dp = opendir(dirname);
208 while ((ep = readdir(dp)) != NULL) {
209 struct stat stFileInfo;
211 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
214 if (stat(abs_filename, &stFileInfo) < 0)
215 perror(abs_filename);
217 total += stFileInfo.st_size;
219 if (S_ISDIR(stFileInfo.st_mode)) {
220 if (strcmp(ep->d_name, ".")
221 && strcmp(ep->d_name, "..")) {
222 _app2sd_calculate_dir_size
232 app2ext_print("\n error in opening directory ");
237 unsigned long long _app2sd_calculate_file_size(const char *filename)
239 struct stat stFileInfo;
240 app2ext_print("\n Calculating file size for %s\n", filename);
242 if (stat(filename, &stFileInfo) < 0) {
246 return stFileInfo.st_size;
249 /*Note: Don't use any printf statement inside this function*/
250 char *_app2sd_encrypt_device(const char *device, const char *pkgid,
254 { "/sbin/losetup", "-e", "aes", device, pkgid, "-k", passwd, NULL };
256 int my_pipe[2] = { 0, };
257 char buf[FILENAME_MAX] = { 0, };
258 char *ret_result = NULL;
260 if (pipe(my_pipe) < 0) {
261 fprintf(stderr, "Unable to create pipe\n");
267 perror("fork failed");
273 result = dup(my_pipe[1]);
274 result = dup(my_pipe[1]);
275 if (execvp(argv[0], (char *const *)argv) < 0) {
276 fprintf(stderr, "execvp failed %d....%s\n", errno, strerror(errno)); /*Don't use d_msg_app2sd */
282 result = read(my_pipe[0], buf, FILENAME_MAX);
286 ret_result = (char *)malloc(strlen(buf) + 1);
287 if (ret_result == NULL) {
288 app2ext_print("Malloc failed!\n");
291 memset(ret_result, '\0', strlen(buf) + 1);
292 memcpy(ret_result, buf, strlen(buf));
296 /*Note: Don't use any printf statement inside this function*/
297 char *_app2sd_detach_loop_device(const char *device)
299 const char *argv[] = { "/sbin/losetup", "-d", device, NULL };
301 int my_pipe[2] = { 0, };
302 char buf[FILENAME_MAX] = { 0, };
303 char *ret_result = NULL;
305 if (pipe(my_pipe) < 0) {
306 fprintf(stderr, "Unable to create pipe\n");
312 perror("fork failed");
318 result = dup(my_pipe[1]);
319 result = dup(my_pipe[1]);
320 if (execvp(argv[0], (char *const *)argv) < 0) {
321 fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
327 result = read(my_pipe[0], buf, FILENAME_MAX);
331 ret_result = (char *)malloc(strlen(buf) + 1);
332 if (ret_result == NULL) {
333 app2ext_print("Malloc failed!\n");
336 memset(ret_result, '\0', strlen(buf) + 1);
337 memcpy(ret_result, buf, strlen(buf));
342 /*Note: Don't use any printf statement inside this function*/
343 char *_app2sd_find_associated_device(const char *mmc_app_path)
345 const char *argv[] = { "/sbin/losetup", "-j", mmc_app_path, NULL };
347 int my_pipe[2] = { 0, };
348 char buf[FILENAME_MAX] = { 0, };
349 char *ret_result = NULL;
351 if (pipe(my_pipe) < 0) {
352 fprintf(stderr, "Unable to create pipe\n");
358 perror("fork failed");
364 result = dup(my_pipe[1]);
365 result = dup(my_pipe[1]);
366 if (execvp(argv[0], (char *const *)argv) < 0) {
367 fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
373 result = read(my_pipe[0], buf, FILENAME_MAX);
377 ret_result = (char *)malloc(strlen(buf) + 1);
378 if (ret_result == NULL) {
379 app2ext_print("Malloc failed!\n");
382 memset(ret_result, '\0', strlen(buf) + 1);
383 memcpy(ret_result, buf, strlen(buf));
388 /*Note: Don't use any printf statement inside this function*/
389 char *_app2sd_find_free_device(void)
391 const char *argv[] = { "/sbin/losetup", "-f", NULL };
393 int my_pipe[2] = { 0, };
394 char buf[FILENAME_MAX+1] = { 0, };
395 char *ret_result = NULL;
397 if (pipe(my_pipe) < 0) {
398 fprintf(stderr, "Unable to create pipe\n");
404 perror("fork failed");
410 result = dup(my_pipe[1]);
411 result = dup(my_pipe[1]);
412 if (execvp(argv[0], (char *const *)argv) < 0) {
413 fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
419 result = read(my_pipe[0], buf, FILENAME_MAX);
423 ret_result = (char *)malloc(strlen(buf) + 1);
424 if (ret_result == NULL) {
425 app2ext_print("Malloc failed!\n");
428 memset(ret_result, '\0', strlen(buf) + 1);
429 memcpy(ret_result, buf, strlen(buf));
434 /*@_app2sd_generate_password
435 * This is a simple password generator
436 * return: On success, it will return the password, else NULL.
438 char *_app2sd_generate_password(const char *pkgid)
440 char passwd[PASSWD_LEN+1] = { 0, };
441 char *ret_result = NULL;
442 char set[ASCII_PASSWD_CHAR+1] = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
443 unsigned char char_1;
444 unsigned char char_2;
446 int appname_len = strlen(pkgid);
449 /* Length of the password */
450 ret_result = (char*)malloc(PASSWD_LEN+1);
451 if (NULL == ret_result) {
452 app2ext_print("Unable to Allocate memory\n");
455 memset((void *)ret_result, '\0', PASSWD_LEN+1);
457 while(i < PASSWD_LEN) {
458 char_1 = (rand()+pkgid[j--])%ASCII_PASSWD_CHAR;
459 char_2 = rand()%ASCII_PASSWD_CHAR;
460 passwd[i] = set[char_1];
461 passwd[i+1] = set[(pkgid[j--])*2];
463 passwd[i+2] = set[char_2];
467 app2ext_print("Password is %s\n", passwd);
468 memcpy(ret_result, passwd, PASSWD_LEN+1);