4 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #define _XOPEN_SOURCE 600
20 #define _POSIX_C_SOURCE 200809L
27 #include <sys/types.h>
35 #include <sys/xattr.h>
36 #include "SS_Common.h"
38 #include "fota_common.h"
41 static int feature_support_capability;
43 enum smack_label_type {
47 SMACK_LABEL_TRANSMUTE,
52 #define SMACK_LABEL_LEN 255
54 /************************************************************
56 ************************************************************/
57 void SS_create_dir(char *pathname, int mode)
62 /* Strip trailing '/' */
63 if (pathname[strlen(pathname) - 1] == '/')
64 pathname[strlen(pathname) - 1] = '\0';
66 /* Try creating the directory. */
67 r = mkdir(pathname, mode);
70 /* On failure, try creating parent directory. */
71 p = strrchr(pathname, '/');
74 SS_create_dir(pathname, 0755);
76 r = mkdir(pathname, mode);
80 if (r != EEXIST && r != -1)
81 LOG("Could not create directory [%s] Error[%d]\n", pathname, r);
86 void SS_unicode_to_char(const char *src, char *dest, int size)
91 strncpy(dest, src, size);
94 void SS_char_to_unicode(const char *src, char *dest, int size)
99 strncpy(dest, src, size);
102 long SS_recursive_folder_creater(const char *path, const mode_t mode)
106 char temppath[MAX_PATH] = { '\0' };
108 LOGL(LOG_SSENGINE, "path: %s\n", path);
110 if ((offset = strlen(path)) == 0) // For counting back until the '/' delimiter
111 return -1; //if from some reason we got to the end return error!!!.
113 while (path[offset] != '/') // get to the next '/' place
116 strncpy(temppath, path, offset); // copy one depth below till and without the char '/'
117 LOGL(LOG_SSENGINE, " temppath: %s\n", temppath);
118 ret = mkdir(temppath, mode);
119 LOGL(LOG_SSENGINE, " mkdir result: %d errno: %d\n", ret, errno);
121 if (ret == 0 || ((ret == -1) && (errno == EEXIST))) {
122 return 0; //meaning the depth creation is success.
123 } else if ((ret == -1) && (errno == ENOENT)) {
124 if ((ret = SS_recursive_folder_creater(temppath, mode)) == 0)
125 ret = mkdir(temppath, mode);
133 SS_CopyFile(const char *strFromPath, const char *strToPath)
136 int readCount = 0, writeCount = 0;
137 char buf[1 << 15]; // copy 32KB wise
140 char path1[MAX_PATH] = { '\0' };
141 char path2[MAX_PATH] = { '\0' };
143 if (!strFromPath || !strToPath) {
144 LOGE("NULL file name find. Abort.\n");
148 SS_unicode_to_char((const char *)strFromPath, (char *)path1, MAX_PATH - 1);
149 SS_unicode_to_char((const char *)strToPath, (char *)path2, MAX_PATH - 1);
151 //LOGL(LOG_SSENGINE, "%s -> %s \n", path1, path2);
153 fd1 = open(path1, O_RDONLY);
155 return E_SS_OPENFILE_ONLYR;
156 ret = SS_OpenFile(strToPath, ONLY_W, (long *)&fd2);
157 if (ret != S_SS_SUCCESS || fd2 < 0) {
159 LOGE(" SS_OpenFile fail leaved path1:%s | path2:%s\n", path1, path1);
160 return E_SS_WRITE_ERROR;
163 while ((readCount = read(fd1, buf, sizeof(buf))) > 0) {
164 writeCount = write(fd2, buf, readCount);
165 if (writeCount != readCount) {
166 LOGE(" read %d, but write %d, abort.\n", readCount,
168 ret = E_SS_WRITE_ERROR;
176 //LOGL(LOG_INFO, " leaved path1:%s | path2:%s\n", path1, path2);
181 long SS_DeleteFile(const char *strPath)
183 char path[MAX_PATH] = { '\0' };
186 SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1);
187 //LOGL(LOG_SSENGINE, "%s\n", path);
192 LOGE("failed to delete path [%s] unlink value: %d, errno: %d\n", path, ret, errno);
193 if (ret < 0 && errno == ENOENT)
195 return E_SS_DELETEFILE;
198 int SS_unlink_cbf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
200 int rv = remove(fpath);//returns zero on success and -1 on failure
204 LOGE("path : %s, remove value: %d, errno: %d\n", fpath, rv, errno);
208 long SS_DeleteFolder(const char *strPath)
210 //runs till either tree is exhausted or when unlink_cbf returns non zero value.
211 return ((long)nftw(strPath, SS_unlink_cbf, 64, FTW_DEPTH | FTW_PHYS) == 0) ? S_SS_SUCCESS : E_SS_FAILURE;
214 long SS_DeleteFolderEmpty(const char *strPath)
218 char path[MAX_PATH] = { '\0' };
220 SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1);
221 //LOGL(LOG_SSENGINE, "%s\n", path);
224 || ((ret < 0) && ((errno == ENOENT) || (errno == ENOTEMPTY)))) {
225 LOGL(LOG_SSENGINE, "rmdir value: %d, errno: %d\n", ret, errno);
228 LOGE("rmdir value: %d, errno: %d\n", ret, errno);
232 long SS_CreateFolder(const char *strPath)
236 char path[MAX_PATH] = { '\0' };
238 SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1);
239 mode = S_IRUSR /*Read by owner */ |
240 S_IWUSR /*Write by owner */ |
241 S_IXUSR /*Execute by owner */ |
242 S_IRGRP /*Read by group */ |
243 S_IWGRP /*Write by group */ |
244 S_IXGRP /*Execute by group */ |
245 S_IROTH /*Read by others */ |
246 S_IWOTH /*Write by others */ |
247 S_IXOTH /*Execute by others */ ;
249 LOGL(LOG_SSENGINE, "%s, mode:0x%x\n", path, mode);
251 ret = mkdir(path, mode);
253 if (ret == 0 || ((ret == -1) && (errno == EEXIST))) {
255 } else if ((ret == -1) && (errno == ENOENT)) { //maybe multi directory problem
256 //do//Recursive Function
258 ret = SS_recursive_folder_creater(path, mode);
259 if (ret == S_SS_SUCCESS) {
260 ret = mkdir(path, mode); //After creating all the depth Directories we try to create the Original one again.
276 mode_t SS_get_mode(E_RW_TYPE wFlag)
280 //LOGL(LOG_SSENGINE, " RDONLY \n");
283 //LOGL(LOG_SSENGINE, " WRONLY \n");
284 return O_WRONLY | O_CREAT;
286 //LOGL(LOG_SSENGINE, " RDWR \n");
287 return O_RDWR | O_CREAT;
289 //LOGL(LOG_SSENGINE, " Unknown \n");
295 SS_OpenFile(const char *strPath, E_RW_TYPE wFlag, long *pwHandle)
298 char path[MAX_PATH] = { '\0' };
300 SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1);
302 mode = SS_get_mode(wFlag);
303 //LOGL(LOG_SSENGINE, "Path:%s wFlag:%d Mode:%d\n", path, wFlag, mode);
305 if (mode & O_CREAT) {
306 //LOGL(LOG_SSENGINE, " open() S_IRWXU\n");
307 *pwHandle = open(path, mode, S_IRWXU);
309 //LOGL(LOG_SSENGINE, " open() %d\n", mode);
310 *pwHandle = open(path, mode);
312 if (*pwHandle == -1) {
314 LOGE(" First open() with error %d\n", errno);
315 if (wFlag == ONLY_R) {
316 LOGE(" error in ONLY_R return E_SS_OPENFILE_ONLYR\n");
317 return E_SS_OPENFILE_ONLYR;
320 //if we need to open the file for write or read/write then we need to create the folder (in case it does not exist)
321 if ((wFlag != ONLY_R) && (errno == ENOENT)) {
322 char dir[MAX_PATH] = { '\0' };
323 char dirShort[MAX_PATH] = { '\0' };
325 //copy the full file path to directory path variable
326 while (path[i] != '\0') {
330 LOGL(LOG_SSENGINE, " copy dir[]=%s\n", dir);
331 //search for the last '/' char
332 while (dir[i--] != '/') ;
335 SS_char_to_unicode((const char *)dir,
336 (char *)dirShort, MAX_PATH - 1);
338 if (SS_CreateFolder(dirShort)) {
339 LOGE(" Fail create folder, Leave SS_OpenFile\n");
340 return E_SS_OPENFILE_WRITE;
343 *pwHandle = open(path, mode);
344 if (*pwHandle == -1) {
346 LOGE(" After successful creating folder, fail open() with error %d\n", errno);
347 return E_SS_OPENFILE_WRITE;
350 LOG(" fail open() *pwHandle:%ld\n", *pwHandle);
351 return E_SS_OPENFILE_WRITE;
355 //LOGL(LOG_SSENGINE, " Successful open() *pwHandle:%ld\n", *pwHandle);
360 long SS_ResizeFile(long wHandle, SS_UINT32 dwSize)
364 LOGL(LOG_SSENGINE, "handle %ld, dwSize %d\n", wHandle, errno);
367 ret = ftruncate(wHandle, dwSize);
369 ret = E_SS_RESIZEFILE;
371 LOGL(LOG_SSENGINE, "ret %d handle %ld %d\n", ret, wHandle, errno);
376 long SS_CloseFile(long wHandle)
379 LOGL(LOG_SSENGINE, "wHandle = %ld\n", wHandle);
382 ret = fsync(wHandle);
384 LOG(" fsync Failed with return value: %d\n", ret);
385 return E_SS_WRITE_ERROR;
387 LOG(" fsync after write: %d\n", ret);
388 ret = close(wHandle);
394 return E_SS_CLOSEFILE_ERROR;
398 SS_WriteFile(long wHandle,
399 SS_UINT32 dwPosition,
400 unsigned char *pbBuffer, SS_UINT32 dwSize)
404 LOGL(LOG_SSENGINE, "Handle:%ld , Pos:%u , Size: %u\n", wHandle,
407 ret = lseek(wHandle, dwPosition, SEEK_SET);
409 LOGE(" lseek failed with return value: %d\n", ret);
410 LOGL(LOG_SSENGINE, "lseek errno=%d\n", errno);
411 return E_SS_WRITE_ERROR;
414 ret = write(wHandle, pbBuffer, dwSize);
415 if (ret < 0 || ret != dwSize) {
416 LOGE(" Failed with return value: %d\n", ret);
417 LOGL(LOG_SSENGINE, "ret=%d, dwSize=%u write errno=%d\n",
418 ret, (unsigned int)dwSize, errno);
419 return E_SS_WRITE_ERROR;
421 LOGL(LOG_SSENGINE, "leave Bytes Write: %d\n", ret);
426 long SS_MoveFile(const char *strFromPath, const char *strToPath)
430 char path1[MAX_PATH] = { '\0' };
431 char path2[MAX_PATH] = { '\0' };
433 if (!strFromPath || !strToPath)
434 return -1; //should never happen
436 SS_unicode_to_char(strFromPath, (char *)path1, MAX_PATH - 1);
437 SS_unicode_to_char(strToPath, (char *)path2, MAX_PATH - 1);
439 LOGL(LOG_INFO, "entered path1:%s | path2:%s\n", path1, path2);
440 ret = stat(path1, &sbuf);
442 LOGE("stat failed with return value: %d errno: %d\n", ret, errno);
445 ret = rename(path1, path2);
447 LOGL(LOG_INFO, "rename fail with code [%d], try to create dir if errno is 2\n", errno);
449 char * file_name = strrchr(path2, '/');
451 SS_create_dir(path2, 0755);
453 ret = rename(path1, path2);
455 LOGE("Move failed, error code [%d]", errno);
456 return E_SS_WRITE_ERROR;
458 } else if (errno == 18) { //EXDEV 18 /* Cross-device link */
459 //Moving file across partitions if mount point is different (Extremely rare)
460 ret = (int)SS_CopyFile(path1, path2);
461 if (ret != S_SS_SUCCESS) {
462 LOGE("failed to copy file [%s] result [%d]\n", path1, ret);
463 return E_SS_WRITE_ERROR;
467 LOGE("failed to unlink [%s] code [%d]\n", path1, errno);
468 return E_SS_WRITE_ERROR;
471 LOGE("Move failed, error code [%d]", errno);
472 return E_SS_WRITE_ERROR;
475 LOGL(LOG_INFO, "leaved path1:%s | path2:%s\n", path1, path2);
478 long SS_SyncFile(long wHandle)
480 return (-1 == fsync(wHandle)) ? E_SS_FAILURE : S_SS_SUCCESS;
484 SS_ReadFile(long wHandle,
485 SS_UINT32 dwPosition,
486 unsigned char *pbBuffer, SS_UINT32 dwSize)
491 LOG(" %s: Handle:%ld , Pos:%u , Size: %u", __func__, wHandle,
494 ret = lseek(wHandle, dwPosition, SEEK_SET);
496 LOGE("Handle:%ld , Pos:%u , Size: %u", wHandle, dwPosition,
498 LOGE("lseek failed with return value: %d\n", ret);
499 return E_SS_READ_ERROR;
501 ret = read(wHandle, pbBuffer, dwSize);
503 LOGE("Handle:%ld , Pos:%u , Size: %u", wHandle, dwPosition,
505 LOGE("read failed with return value: %d\n", ret);
506 return E_SS_READ_ERROR;
509 if (ret != dwSize && ((ret + dwPosition) != (unsigned long)SS_GetFileSize(wHandle)))
510 return E_SS_READ_ERROR;
513 LOGL(LOG_DEBUG, "Bytes Read: %d\n", ret);
518 long SS_GetFileSize(long wHandle)
523 ret = lseek(wHandle, 0, SEEK_END);
526 LOGE(" lseek errno: %d\n", errno);
527 return E_SS_READFILE_SIZE;
529 LOGL(LOG_SSENGINE, "handle=%d Returning Size = %ld(0x%x)\n",
530 (int)wHandle, (long int)ret, ret);
535 long SS_Unlink(char *pLinkName)
538 char path[MAX_PATH] = { '\0' };
539 //enumFileType fileType = FT_REGULAR_FILE;
542 SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1);
545 if (ret < 0 && errno != ENOENT) {
546 LOGE("unlink failed with return value: %d\n", ret);
549 LOGL(LOG_SSENGINE, "unlink with return value: %d\n", ret);
555 SS_VerifyLinkReference(char *pLinkName, char *pReferenceFileName)
558 char path[MAX_PATH] = { '\0' };
559 char linkedpath[MAX_PATH] = { '\0' };
560 char refpath[MAX_PATH] = { '\0' };
563 SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1);
564 SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath, MAX_PATH - 1);
566 ret = readlink(path, linkedpath, MAX_PATH);
568 LOGE("readlink failed with return value: %d\n", ret);
572 if ((memcmp(&linkedpath, &refpath, ret)) != 0) {
573 LOGE("not same linked path\n");
576 LOGL(LOG_SSENGINE, "same linked path\n");
582 SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName)
585 char sympath[MAX_PATH] = { '\0' };
586 char refpath[MAX_PATH] = { '\0' };
587 //enumFileType fileType = FT_SYMBOLIC_LINK;
590 SS_unicode_to_char((const char *)pLinkName, (char *)sympath, MAX_PATH - 1);
591 SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath, MAX_PATH - 1);
593 ret = symlink(refpath, sympath);
595 LOGE(" symlink failed with return value: %d, errno: %d\n", ret, errno);
597 if (errno == EEXIST) {
598 ret = lstat(sympath, &sbuf);
599 LOGL(LOG_SSENGINE, "symlink LSTAT with return value: %d\n", ret);
601 if (S_ISREG(sbuf.st_mode)) {
602 LOGL(LOG_SSENGINE, " stat->st_mode = regular file, To be deleted and create a LINK \n");
603 SS_DeleteFile(sympath);
604 SS_Link(pbUserData, pLinkName, pReferenceFileName);
607 if (SS_VerifyLinkReference(pLinkName
608 , pReferenceFileName) == S_SS_SUCCESS) {
613 } else if (errno == ENOENT) {//to handle cases where new symlink points to a new symlink yet to be created
619 //LOGL(LOG_SSENGINE, "symlink with return value: %d\n", ret);
624 long SS_GetFileType(char *pLinkName, enumFileType * fileType)
627 char path[MAX_PATH] = { '\0' };
630 //LOGL(LOG_SSENGINE, "\n");
631 SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1);
633 ret = lstat(path, &sbuf);
635 ret = stat(path, &sbuf);
637 LOGE("stat failed with return value: %d errno: %d\n",
639 *fileType = FT_MISSING;
643 //LOGL(LOG_SSENGINE, " sbuf.st_mode: %d\n", sbuf.st_mode);
644 //LOGL(LOG_SSENGINE, " S_ISREG(sbuf.st_mode): %d\n", S_ISREG(sbuf.st_mode));
645 //LOGL(LOG_SSENGINE, " S_ISLNK(sbuf.st_mode): %d\n", S_ISLNK(sbuf.st_mode));
647 if (S_ISLNK(sbuf.st_mode)) {
648 //LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n");
649 *fileType = FT_SYMBOLIC_LINK;
653 if (S_ISREG(sbuf.st_mode)) {
654 //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n");
655 *fileType = FT_REGULAR_FILE;
659 if (S_ISDIR(sbuf.st_mode)) {
660 //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n");
661 *fileType = FT_FOLDER;
664 LOGE("failed to lstat, err : %d\n", ret);
668 char SS_a2ch(int value)
672 LOGL(LOG_SSENGINE, "%d\n", value);
706 LOGL(LOG_SSENGINE, "Wrong attribute value: %d\n", value);
709 LOGL(LOG_SSENGINE, "SS_a2ch : %c\n", set_value);
714 void SS_chtoa(int value, char *str)
718 LOGL(LOG_SSENGINE, "%d\n", value);
752 LOGL(LOG_SSENGINE, "Wrong attribute value: %d\n", value);
756 static inline char *SS_get_xattr_name(enum smack_label_type type)
759 case SMACK_LABEL_ACCESS:
760 return "security.SMACK64";
761 case SMACK_LABEL_EXEC:
762 return "security.SMACK64EXEC";
763 case SMACK_LABEL_MMAP:
764 return "security.SMACK64MMAP";
765 case SMACK_LABEL_TRANSMUTE:
766 return "security.SMACK64TRANSMUTE";
767 case SMACK_LABEL_IPIN:
768 return "security.SMACK64IPIN";
769 case SMACK_LABEL_IPOUT:
770 return "security.SMACK64IPOUT";
772 /* Should not reach this point */
777 int SS_smack_lsetlabel(const char *path, const char *label, enum smack_label_type type)
780 LOGE("Path is NULL\n");
784 char *xattr_name = SS_get_xattr_name(type);
785 if (xattr_name == NULL) {
786 LOGE("Failed get xattr name\n");
790 /* Check validity of labels for LABEL_TRANSMUTE */
791 if (type == SMACK_LABEL_TRANSMUTE && label != NULL) {
792 if (!strncmp(label, "0", strlen("0"))) {
794 } else if (!strncmp(label, "1", strlen("0"))) {
801 if (label == NULL || label[0] == '\0') {
802 return lremovexattr(path, xattr_name);
804 int len = strnlen(label, SMACK_LABEL_LEN + 1);
805 if (len > SMACK_LABEL_LEN) {
808 return lsetxattr(path, xattr_name, label, len, 0);
813 *******************************************************************************
814 * Set file attributes.<p>
816 * The file attributes token (\a ui8pAttribs) is defined at generation time.
817 * If attributes are not defined explicitly, they are given the following,
818 * OS-dependent values:
819 * \li Windows: _foo_ro_ for R/O files, _foo_rw_ for R/W files
820 * \li Linux: _foo_oooooo:xxxx:yyyy indicating the file mode, uid, and gid
821 * (uid and gid use capitalized hex digits as required)
823 * \param pbUserData Optional opaque data-structure to pass to IPL
825 * \param ui16pFilePath File path
826 * \param ui32AttribSize Size of \a ui8pAttribs
827 * \param ui8pAttribs Attributes to set
829 * \return S_SS_SUCCESS on success or < 0 on error
830 *******************************************************************************
833 long SS_SetFileAttributes(const char *ui16pFilePath,
834 const SS_UINT32 ui32AttribSize,
835 const unsigned char *ui8pAttribs)
837 static char tmpAttribs[512];
838 static char tmpSmackAttribs[512];
842 char *smack_value, *psmack;
844 gid_t setGroupID = 0;
845 mode_t setFileMode = 0;
846 const char attrDelim[2] = ":";
848 char setFilePath[MAX_PATH] = { '\0' };
851 char *smack_attr_pos = NULL;
860 if (NULL == ui16pFilePath) {
861 LOGL(LOG_SSENGINE, "ui16pFilePath NULL [error]\n");
862 return E_SS_BAD_PARAMS;
863 } else if (NULL == ui8pAttribs) {
864 LOGL(LOG_SSENGINE, "ui8pAttribs NULL [error]\n");
865 return E_SS_BAD_PARAMS;
866 } else if (0 == ui32AttribSize) {
867 LOGL(LOG_SSENGINE, "ui32AttribSize 0\n");
871 SS_unicode_to_char((const char *)ui16pFilePath, (char *)setFilePath, MAX_PATH - 1);
873 ret = lstat(setFilePath, &sbuf);
875 ret = stat(setFilePath, &sbuf);
877 LOGL(LOG_SSENGINE, " stat failed with return value: %d\n", ret);
880 if (S_ISLNK(sbuf.st_mode)) {
881 LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n");
882 // return S_RB_SUCCESS; // sybolic link should be set mode.
884 if (S_ISREG(sbuf.st_mode))
885 LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n");
886 if (S_ISDIR(sbuf.st_mode))
887 LOGL(LOG_SSENGINE, " stat->st_mode = directory\n");
890 LOGL(LOG_SSENGINE, "ui16pFilePath = %s\n", setFilePath);
891 LOGL(LOG_SSENGINE, "ui32AttribSize = %u\n", ui32AttribSize);
892 LOGL(LOG_SSENGINE, "ui8pAttribs = %s\n", ui8pAttribs);
895 memset(tmpAttribs, 0x0, sizeof(tmpAttribs));
896 memcpy(tmpAttribs, ui8pAttribs, (size_t) ui32AttribSize-1);
897 smack_attr_pos = tmpAttribs;
898 tp = strtok_r(tmpAttribs, attrDelim, &saveptr);
902 smack_attr_pos += strlen(tp);
904 setFileMode = strtol(tp, &endstr, 8);
905 tp = strtok_r(NULL, attrDelim, &saveptr);
909 smack_attr_pos += strlen(tp);
911 setUserID = (uid_t) strtol(tp, &endstr, 10);
912 tp = strtok_r(NULL, attrDelim, &saveptr);
916 smack_attr_pos += strlen(tp);
918 setGroupID = (gid_t) strtol(tp, &endstr, 10);
921 if (feature_support_capability) {
924 if (*smack_attr_pos != '\0') {
925 char *cap_mark = "capability=0x";
926 int cap_mark_len = strlen(cap_mark);
927 psmack = strstr(smack_attr_pos, cap_mark);
934 tp = strstr(psmack, ":");
935 smack_attr_pos = tp + 1;
936 memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
937 memcpy(tmpSmackAttribs, psmack+cap_mark_len,
938 (int)tp - (int)psmack - cap_mark_len);
940 // convert hexadecimal into raw data
941 cap_hex_len = strlen(tmpSmackAttribs);
942 cap_len = cap_hex_len/2;
943 memset(cap_raw, 0x00, sizeof(cap_raw));
944 for (i = 0; i < cap_len; i++) {
945 ch1 = tmpSmackAttribs[i*2];
946 ch2 = tmpSmackAttribs[i*2+1];
947 if ((ch1 >= '0') && (ch1 <= '9')) raw1 = ch1 - '0';
948 else if ((ch1 >= 'a') && (ch1 <= 'f')) raw1 = ch1 - 'a' + 10;
949 else if ((ch1 >= 'A') && (ch1 <= 'F')) raw1 = ch1 - 'A' + 10;
951 if ((ch2 >= '0') && (ch2 <= '9')) raw2 = ch2 - '0';
952 else if ((ch2 >= 'a') && (ch2 <= 'f')) raw2 = ch2 - 'a' + 10;
953 else if ((ch2 >= 'A') && (ch2 <= 'F')) raw2 = ch2 - 'A' + 10;
956 cap_raw[i] = raw1*16 + raw2;
958 LOGL(LOG_SSENGINE, "[Cap] %s (cap_len=%d)\n", tmpSmackAttribs, cap_len);
965 if (*smack_attr_pos != '\0') {
966 char *acl_mark = "acl_access=0x";
967 int acl_mark_len = strlen(acl_mark);
968 psmack = strstr(smack_attr_pos, acl_mark);
975 tp = strstr(psmack, ":");
976 smack_attr_pos = tp + 1;
977 memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
978 memcpy(tmpSmackAttribs, psmack+acl_mark_len,
979 (int)tp - (int)psmack - acl_mark_len);
981 // convert hexadecimal into raw data
982 acl_hex_len = strlen(tmpSmackAttribs);
983 acl_len = acl_hex_len/2;
984 memset(acl_raw, 0x00, sizeof(acl_raw));
985 for (i = 0; i < acl_len; i++) {
986 ch1 = tmpSmackAttribs[i*2];
987 ch2 = tmpSmackAttribs[i*2+1];
988 if ((ch1 >= '0') && (ch1 <= '9')) raw1 = ch1 - '0';
989 else if ((ch1 >= 'a') && (ch1 <= 'f')) raw1 = ch1 - 'a' + 10;
990 else if ((ch1 >= 'A') && (ch1 <= 'F')) raw1 = ch1 - 'A' + 10;
992 if ((ch2 >= '0') && (ch2 <= '9')) raw2 = ch2 - '0';
993 else if ((ch2 >= 'a') && (ch2 <= 'f')) raw2 = ch2 - 'a' + 10;
994 else if ((ch2 >= 'A') && (ch2 <= 'F')) raw2 = ch2 - 'A' + 10;
997 acl_raw[i] = raw1*16 + raw2;
999 LOG("[ACL] %s (acl_len=%d)\n", tmpSmackAttribs, acl_len);
1006 // Get Smack value -> Set Smack value
1007 if (*smack_attr_pos != '\0') {
1008 SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_ACCESS);
1009 SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_EXEC);
1010 SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_MMAP);
1011 SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_TRANSMUTE);
1013 psmack = strstr(smack_attr_pos, "access=\"");
1015 memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
1016 memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1);
1017 smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr);
1019 smack_value = strtok_r(NULL, "\"", &saveptr);
1020 //LOGL(LOG_SSENGINE, "[SMACK_LABEL_ACCESS] smack_value=%s\n", smack_value);
1022 ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_ACCESS);
1024 LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n");
1028 psmack = strstr(smack_attr_pos, "execute=\"");
1030 memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
1031 memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1);
1032 smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr);
1034 smack_value = strtok_r(NULL, "\"", &saveptr);
1035 //LOGL(LOG_SSENGINE, "[SMACK_LABEL_EXEC] smack_value=%s\n", smack_value);
1037 ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_EXEC);
1039 LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n");
1043 psmack = strstr(smack_attr_pos, "mmap=\"");
1045 memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
1046 memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1);
1047 smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr);
1049 smack_value = strtok_r(NULL, "\"", &saveptr);
1050 //LOGL(LOG_SSENGINE, "[SMACK_LABEL_MMAP] smack_value=%s\n", smack_value);
1052 ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_MMAP);
1054 LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n");
1058 psmack = strstr(smack_attr_pos, "transmute=\"");
1060 memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
1061 memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1);
1062 smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr);
1064 smack_value = strtok_r(NULL, "\"", &saveptr);
1065 //LOGL(LOG_SSENGINE, "[SMACK_LABEL_TRANSMUTE] smack_value=%s\n", smack_value);
1067 if (strcasecmp(smack_value, "TRUE") == 0)
1068 ret = SS_smack_lsetlabel(setFilePath, "1", SMACK_LABEL_TRANSMUTE);
1070 ret = SS_smack_lsetlabel(setFilePath, "0", SMACK_LABEL_TRANSMUTE);
1072 LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n");
1078 // Set UserID,GroupID
1079 if (lchown(setFilePath, setUserID, setGroupID)) {
1081 LOGL(LOG_SSENGINE, "%s chown error\n", __func__);
1082 LOGL(LOG_SSENGINE, "%s setUserID = %d\n", __func__, setUserID);
1083 LOGL(LOG_SSENGINE, "%s setGroupID = %d\n", __func__, setGroupID);
1084 LOGL(LOG_SSENGINE, "%s chown errno = %d\n", __func__, errno);
1087 return E_SS_FAILURE;
1090 // mode is always 0777 at symlink file. It doesn't need to call chmod().
1091 if (S_ISLNK(sbuf.st_mode)) {
1092 LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n");
1093 return S_SS_SUCCESS;
1096 if (chmod(setFilePath, setFileMode)) {
1097 LOGL(LOG_SSENGINE, "%s chmod error\n", __func__);
1098 return E_SS_FAILURE;
1101 if (feature_support_capability) {
1104 if (setxattr(setFilePath, "security.capability", (void*)cap_raw, cap_len, 0) < 0) {
1105 strerror_r(errno, buf, sizeof(buf));
1106 LOGL(LOG_SSENGINE, "cap setxattr() failed: %s\n", buf);
1111 if (setxattr(setFilePath, "system.posix_acl_access", (void*)acl_raw, acl_len, 0) < 0) {
1112 strerror_r(errno, buf, sizeof(buf));
1113 LOGL(LOG_SSENGINE, "Acl setxattr() failed: %s\n", buf);
1115 //LOG("Acl setxattr() :")asfd
1119 //LOGL(LOG_SSENGINE, "%s SUCCESS\n", __func__);
1121 return S_SS_SUCCESS;
1125 long SS_CompareFileAttributes(void)
1127 return S_SS_SUCCESS;
1132 #define MAX_INT 0xefffffff
1136 SS_GetAvailableFreeSpace(const char *partition_name,
1137 SS_UINT32 *available_flash_size)
1139 // *available_flash_size = MAX_INT;
1141 #define IDENT_SBL "sbl"
1142 #define IDENT_PLATFORM "platform"
1143 #define IDENT_BOOT "boot"
1146 char path[MAX_PATH] = { '\0' };
1148 SS_unicode_to_char(partition_name, (char *)path, MAX_PATH - 1);
1149 //LOGL(LOG_SSENGINE, "Enter %s path=%s\n", __func__, path);
1152 //LOGL(LOG_SSENGINE, "path=%s\n", path);
1153 result = statfs(path, &vfs);
1155 LOGE("failed to fstatfs, err : %d errno: %d\n", result, errno);
1159 *available_flash_size = vfs.f_bsize * vfs.f_bavail;
1160 if (*available_flash_size == 0) {
1161 *available_flash_size = 0x80000; //Same as Legecy RB
1162 LOGE("available_flash_size=%u(vfs.f_bsize=%d vfs.f_bavail=%d\n",
1163 (unsigned int)*available_flash_size, (int)vfs.f_bsize, (int)vfs.f_bavail);
1164 return 0; // Same as Legecy RB
1169 #ifdef HEAP_PROFILING
1173 /*******[ Multiprocess API sample implementation ]******/
1174 void *SS_Malloc(SS_UINT32 size)
1176 void *p = malloc(size);
1180 #ifdef HEAP_PROFILING
1182 if (cur_mem > max_mem) {
1184 LOGL(LOG_SSENGINE, "New chunk [%d] assigned making heap [%d]\n", size, cur_mem);
1191 void SS_Free(void *pMemBlock)
1193 #ifdef HEAP_PROFILING
1194 cur_mem -= malloc_usable_size(pMemBlock);
1195 LOGL(LOG_SSENGINE, "Old chunk [%d] removed making heap [%d]\n", malloc_usable_size(pMemBlock), cur_mem);
1201 SS_UINT32 SS_GetMaxNumProcess(void)
1203 return SAMPLE_PROCS_NUM;
1206 void* SS_WaitForProcess(const void *handle, SS_UINT32* process_exit_code)
1209 *process_exit_code = 0;
1214 pid = waitpid((pid_t)handle, (int *)process_exit_code, 0);
1216 pid = wait((int*)process_exit_code);
1220 pid = wait((int*)process_exit_code);
1225 if (!WIFEXITED(*process_exit_code)) {
1226 *process_exit_code = (char)WTERMSIG(*process_exit_code);
1227 LOG("Wait Error\n");
1229 *process_exit_code = (char)WEXITSTATUS(*process_exit_code);
1234 unsigned long SS_GetMaxProcRamSize(void)
1239 void* SS_RunProcess(void)
1246 child_pid = vfork();
1249 if (child_pid == -1) {
1250 LOG("Fork failed.\n");
1254 // This is the child
1255 if (child_pid == 0) {
1257 #ifdef _TIZEN_SSENGINE//bota
1258 SS_HandleProcessRequest(pbUserData, argc, argv);
1260 LOGL(LOG_SSENGINE, "SS_RunProcess was called - SS_HandleProcessRequest\n");
1264 char **params = NULL;
1267 params = (char **)SS_Malloc((argc+EXTRA_ARGS) *sizeof(char*));
1269 LOG("params allocation failed\n");
1272 // prepare child data, as it's forbidden to change data after vfork
1273 params[0] = strdup(((sample_userdata*)user)->exec_path);
1274 params[1] = strdup("handle_run_process");
1275 params[2] = strdup(((sample_userdata*)user)->delta_path);
1277 for (i = 0; i < argc; i++)
1278 params[i+EXTRA_ARGS] = strdup(argv[i]);
1280 // no need to free allocated memory - execv takes care of it
1281 execv(params[0], (char**)params);
1282 _exit(-1); // if we're here, execv has failed
1285 return (void *)child_pid;
1289 int SS_get_feature_support_capability(void)
1291 return feature_support_capability;
1294 void SS_set_feature_support_capability(int val)
1296 feature_support_capability = val;