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.
20 #include <sys/types.h>
26 #include "SS_Engine_Update.h"
27 #include "SS_Engine_Errors.h"
28 #include "SS_FSUpdate.h"
29 #include "fota_common.h"
33 /* tar Header Block, from POSIX 1003.1-1990. for reference */
37 struct posix_header { /* byte offset */
38 char name[100]; /* 0 */
39 char mode[8]; /* 100 */
40 char uid[8]; /* 108 */
41 char gid[8]; /* 116 */
42 char size[12]; /* 124 */
43 char mtime[12]; /* 136 */
44 char chksum[8]; /* 148 */
45 char typeflag; /* 156 */
46 char linkname[100]; /* 157 */
47 char magic[6]; /* 257 */
48 char version[2]; /* 263 */
49 char uname[32]; /* 265 */
50 char gname[32]; /* 297 */
51 char devmajor[8]; /* 329 */
52 char devminor[8]; /* 337 */
53 char prefix[155]; /* 345 */
58 #define MAX_ITEM_SIZE 0x7FFFFFFF
59 #define TAR_ITEM_SIZE_POSITION 124
60 #define TAR_SIZE_OF_ITEM_SIZE 8
61 #define TAR_SIZE_OF_HEADER 12
62 #define TAR_BLOCK_SIZE 512
63 #define TAR_ITEM_NAME_SIZE 100
64 #define TAR_LONG_NAME_SIZE 256
65 #define TAR_ITEM_TYPE_FLAG_POS 156
67 /*** The byte that indicates whether the prefix is present or not */
68 #define PREFIX_INDICATOR_BYTE 345
69 #define PREFIX_LEN 155
71 /** the rest heavily based on (ie mostly) untgz.c from zlib **/
73 /* Values used in typeflag field. */
75 #define REGTYPE '0' /* regular file */
76 #define AREGTYPE '\0' /* regular file */
77 #define LNKTYPE '1' /* link */
78 #define SYMTYPE '2' /* reserved */
79 #define CHRTYPE '3' /* character special */
80 #define BLKTYPE '4' /* block special */
81 #define DIRTYPE '5' /* directory */
82 #define FIFOTYPE '6' /* FIFO special */
83 #define CONTTYPE '7' /* reserved, for compatibility with gnu tar,
84 treat as regular file, where it represents
85 a regular file, but saved contiguously on disk */
87 /* GNU tar extensions */
89 #define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
90 #define GNUTYPE_LONGLINK 'K' /* long link name */
91 #define GNUTYPE_LONGNAME 'L' /* long file name */
92 #define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
93 #define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
94 #define GNUTYPE_SPARSE 'S' /* sparse file */
95 #define GNUTYPE_VOLHDR 'V' /* tape/volume header */
97 extern void *SS_Malloc(SS_UINT32 size);
99 int gTarFd = -1; // Currenlty this logic supports only one tar file
101 /* Parse an octal number, ignoring leading and trailing nonsense. */
102 static int parseoct(const char *p, size_t n)
106 while (*p < '0' || *p > '7') {
110 while (*p >= '0' && *p <= '7' && n > 0) {
119 /* Verify the tar checksum. */
120 static int verify_checksum(const char *p)
123 for (n = 0; n < 512; ++n) {
124 if (n < 148 || n > 155)
125 /* Standard tar checksum adds unsigned bytes. */
126 u += ((unsigned char *)p)[n];
131 return (u == parseoct(p + 148, 8));
134 static int is_end_of_archive(const char *p)
137 for (n = 511; n >= 0; --n)
143 void create_dir(char *pathname, int mode)
148 /* Strip trailing '/' */
149 if (pathname[strlen(pathname) - 1] == '/')
150 pathname[strlen(pathname) - 1] = '\0';
152 /* Try creating the directory. */
153 r = mkdir(pathname, mode);
156 /* On failure, try creating parent directory. */
157 p = strrchr(pathname, '/');
160 create_dir(pathname, 0755);
162 r = mkdir(pathname, mode);
166 if (r != EEXIST && r != -1)
167 LOG("Could not create directory [%s] Error[%d]\n", pathname, r);
171 /* Create a file, including parent directory as necessary. */
172 static FILE *create_file(char *pathname)
175 f = fopen(pathname, "w+");
177 /* Try creating parent dir and then creating file. */
178 char *p = strrchr(pathname, '/');
181 create_dir(pathname, 0755);
183 f = fopen(pathname, "w+");
189 /*-----------------------------------------------------------------------------
191 ----------------------------------------------------------------------------*/
192 int tar_get_item_offset(char *tar, char *item)
196 char header[TAR_BLOCK_SIZE] = { 0, };
197 char uExtendedName[MAX_FILE_PATH + 1] = { 0, };
198 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
199 unsigned long size_dec = 0;
206 LOG("Invalid params\n");
209 //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it
213 fd = open(tar, O_RDONLY);
215 LOGE("can't open file(%s).\n", tar);
220 tar_len = lseek(fd, 0, SEEK_END);
222 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
225 pos = lseek(fd, 0, SEEK_SET);
227 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
230 while (pos < tar_len) {
231 /* read file header */
232 rdcnt = read(fd, header, sizeof(header));
234 LOG("read failed. (rdcnt=%d)\n", rdcnt);
238 /* get file name and file size */
239 if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) {
240 //rdcnt = read(fd, header, sizeof(header));
241 memset(uExtendedName, 0, sizeof(uExtendedName));
242 rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1);
244 LOG("read failed. (rdcnt=%d)\n", rdcnt);
247 rdcnt = read(fd, header, sizeof(header));
249 LOG("read failed. (rdcnt=%d)\n", rdcnt);
253 memset(uExtendedName, 0, sizeof(uExtendedName));
254 memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE);
256 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
257 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
258 if (size_dec > MAX_ITEM_SIZE) {
259 LOG("ITEM : [%s]\n", item);
260 LOG("size too big. (size_dec=0x%08X)\n", size_dec);
264 /* check if the file is what we are looking for */
265 if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) {
266 ret = (int)lseek(fd, 0, SEEK_CUR);
270 /* move file pointer to next file header */
271 blknum = size_dec / TAR_BLOCK_SIZE;
272 if (size_dec % TAR_BLOCK_SIZE)
275 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
277 LOGE("can't read next block (%s).\n", tar);
290 /*-----------------------------------------------------------------------------
292 ----------------------------------------------------------------------------*/
293 int tar_get_item_size(char *tar, char *item)
297 char header[TAR_BLOCK_SIZE] = { 0, };
298 char uExtendedName[MAX_FILE_PATH + 1] = { 0, };
299 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
300 unsigned long size_dec = 0;
307 LOG("Invalid params\n");
310 LOGL(LOG_SSENGINE, "Tar file Looking for (%s)\n", item);
311 fd = open(tar, O_RDONLY);
313 LOG("can't open file(%s).\n", tar);
317 tar_len = lseek(fd, 0, SEEK_END);
319 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
322 pos = lseek(fd, 0, SEEK_SET);
324 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
328 while (pos < tar_len) {
329 /* read file header */
330 rdcnt = read(fd, header, sizeof(header));
332 LOG("read failed. (rdcnt=%d)\n", rdcnt);
336 /* get file name and file size */
337 if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) {
338 //rdcnt = read(fd, header, sizeof(header));
339 memset(uExtendedName, 0, sizeof(uExtendedName));
340 rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1);
342 LOG("read failed. (rdcnt=%d)\n", rdcnt);
345 rdcnt = read(fd, header, sizeof(header));
347 LOG("read failed. (rdcnt=%d)\n", rdcnt);
351 memset(uExtendedName, 0, sizeof(uExtendedName));
352 memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE);
354 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
355 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
356 if (size_dec > MAX_ITEM_SIZE) {
357 LOG("ITEM : [%s]\n", item);
358 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
362 /* check if the file is what we are looking for */
363 if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) {
365 if ((ret == 0) && (header[TAR_ITEM_TYPE_FLAG_POS] == DIRTYPE))
366 ret = tar_get_folder_size(tar, item);
369 /* move file pointer to next file header */
370 //LOGL(LOG_SSENGINE,"Item in Tar (%s)\n", uExtendedName);
371 blknum = size_dec / TAR_BLOCK_SIZE;
372 if (size_dec % TAR_BLOCK_SIZE)
375 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
377 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
389 /*-----------------------------------------------------------------------------
390 tar_get_item_tye. (Dir/file/link etc)
391 ----------------------------------------------------------------------------*/
393 char tar_get_item_type(char *tar, char *item)
397 char header[TAR_BLOCK_SIZE] = { 0, };
398 char uExtendedName[MAX_FILE_PATH + 1] = { 0, };
399 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
400 unsigned long size_dec = 0;
407 LOG("Invalid params\n");
410 //LOG("Tar file Looking for (%s)\n", item);
411 fd = open(tar, O_RDONLY);
413 LOG("can't open file(%s).\n", tar);
417 tar_len = lseek(fd, 0, SEEK_END);
419 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
422 pos = lseek(fd, 0, SEEK_SET);
424 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
428 while (pos < tar_len) {
429 /* read file header */
430 rdcnt = read(fd, header, sizeof(header));
432 LOG("read failed. (rdcnt=%d)\n", rdcnt);
437 /* get file name and file size */
438 if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) {
439 //rdcnt = read(fd, header, sizeof(header));
440 memset(uExtendedName, 0, sizeof(uExtendedName));
441 rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1);
443 LOG("read failed. (rdcnt=%d)\n", rdcnt);
446 rdcnt = read(fd, header, sizeof(header));
448 LOG("read failed. (rdcnt=%d)\n", rdcnt);
452 memset(uExtendedName, 0, sizeof(uExtendedName));
453 memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE);
455 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
456 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
457 if (size_dec > MAX_ITEM_SIZE) {
458 LOG("ITEM : [%s]\n", item);
459 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
464 /* check if the file is what we are looking for */
465 if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) {
466 ret = header[TAR_ITEM_TYPE_FLAG_POS];
470 /* move file pointer to next file header */
471 blknum = size_dec / TAR_BLOCK_SIZE;
472 if (size_dec % TAR_BLOCK_SIZE)
475 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
477 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
489 /*-----------------------------------------------------------------------------
491 ----------------------------------------------------------------------------*/
492 int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen)
496 int data_offset = -1;
501 LOG("Invalid params\n");
504 data_size = tar_get_item_size(tar, item);
508 if (data_size > buflen)
511 data_offset = tar_get_item_offset(tar, item);
515 fd = open(tar, O_RDONLY);
517 LOG("can't open file(%s).\n", tar);
521 pos = lseek(fd, data_offset, SEEK_SET);
523 LOG("lseek fail (%s offset %d).\n", tar, data_offset);
528 rdcnt = read(fd, buf, data_size);
529 if (rdcnt != (ssize_t) data_size) {
530 LOG("read fail(%s from %s).\n", item, tar);
540 tar_Data_t *tar_build_cfg_table(char *tar)
545 char header[TAR_BLOCK_SIZE] = { 0, };
546 char uExtendedName[MAX_FILE_PATH + 1] = { 0, };
547 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
548 unsigned long size_dec = 0;
556 tar_Data_t *headparam = NULL, *tailparam = NULL, *newnode = NULL;
557 tar_Data_t *local_temp = NULL;
558 tar_Data_t *local_next = NULL;
560 LOGE("Bad param tar\n");
563 //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it
567 fd = open(tar, O_RDONLY);
569 LOG("can't open file(%s).\n", tar);
573 tar_len = lseek(fd, 0, SEEK_END);
575 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
578 pos = lseek(fd, 0, SEEK_SET);
580 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
583 while (pos < tar_len) {
584 /* read file header */
585 rdcnt = read(fd, header, sizeof(header));
587 LOG("read failed. (rdcnt=%d)\n", rdcnt);
591 /* get file name and file size */
592 if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) {
593 //rdcnt = read(fd, header, sizeof(header));
594 memset(uExtendedName, 0, sizeof(uExtendedName));
595 rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1);
597 LOG("read failed. (rdcnt=%d)\n", rdcnt);
601 rdcnt = read(fd, header, sizeof(header));
603 LOG("read failed. (rdcnt=%d)\n", rdcnt);
608 memset(uExtendedName, 0, sizeof(uExtendedName));
609 memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE);
611 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
612 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
613 if (size_dec > MAX_ITEM_SIZE) {
614 LOG("uExtendedName is : [%s]\n", uExtendedName);
615 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
619 //fix WGID : 51254 , size_dec comparison is not required
620 if ((strstr(uExtendedName, "/diff") != NULL)) { //add only delta files from rootfs and csc, hardcoding shd b removed..
622 /* check if the file is what we are looking for */
623 //strncpy(itemName, name,100);
624 itemSize = (int)size_dec;
625 itemOffset = (int)lseek(fd, 0, SEEK_CUR);
626 newnode = (tar_Data_t *) SS_Malloc(sizeof(tar_Data_t));
631 memset(newnode->itemName, 0, sizeof(newnode->itemName));
632 strncpy((char *)newnode->itemName, uExtendedName, sizeof(newnode->itemName) - 1);
633 newnode->itemOffset = itemOffset;
634 newnode->itemSize = itemSize;
635 newnode->nextnode = NULL;
636 if (headparam == NULL) {
640 (tailparam)->nextnode = newnode;
641 (tailparam) = (tailparam)->nextnode;
645 /* move file pointer to next file header */
646 blknum = size_dec / TAR_BLOCK_SIZE;
647 if (size_dec % TAR_BLOCK_SIZE)
650 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
652 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
658 //if gTarFd was opened by tar_open during SS_FSUpdateFile we do not close it
664 if (headparam != newnode && newnode)
667 local_temp = headparam;
669 local_next = local_temp->nextnode;
671 local_temp = local_next;
678 void tar_free_cfg_table(tar_Data_t ** delta_tar)
680 tar_Data_t *local_temp = NULL;
681 tar_Data_t *local_next = NULL;
682 LOGL(LOG_SSENGINE, "Free TAR CFG TABLE\n");
684 local_temp = *delta_tar;
686 local_next = local_temp->nextnode;
687 //LOGL(LOG_SSENGINE,"freeing [%s]\n",local_temp->itemName);
689 local_temp = local_next;
694 void deleteNode(tar_Data_t * head, tar_Data_t * n)
696 tar_Data_t *prev = head;
698 if (head->nextnode == NULL) {
699 LOG("There is only one node. The list can't be made empty\n");
702 strncpy((char *)head->itemName, (const char *)head->nextnode->itemName, TAR_ITEM_NAME_SIZE); //head->itemName = head->nextnode->itemName;
703 head->itemSize = head->nextnode->itemSize;
704 head->itemOffset = head->nextnode->itemOffset;
706 head->nextnode = head->nextnode->nextnode;
710 while (prev->nextnode != NULL && prev->nextnode != n)
711 prev = prev->nextnode;
712 if (prev->nextnode == NULL) {
713 LOG("Given node is not present in Linked List\n");
716 prev->nextnode = prev->nextnode->nextnode;
721 int tar_get_item_size_from_struct(tar_Data_t ** delta_tar, const char *patchname, int *data_size, int *data_offset)
723 tar_Data_t *head = *delta_tar;
724 tar_Data_t *base = *delta_tar;
728 //LOG("fast_tar_get_item_size- looking for [%s] [%s]\n",patchname,head->itemName);
730 if (strstr((const char *)head->itemName, patchname) != 0) {
731 //LOG("fast_tar_get_item_size found [%s] in [%s]\n",patchname, head->itemName);
732 *data_size = head->itemSize;
733 *data_offset = head->itemOffset;
734 deleteNode(base, head);
737 } else if (head->nextnode != NULL) {
738 head = head->nextnode;
739 //LOG("fast_tar_get_item_size current node [%s] \n",head->itemName);
741 LOGE("fast_tar_get_item_size FAILED TO GET [%s] in [%s]\n", patchname, (char *)head->itemName);
749 tar_Data_t *tar_cfg_clear_nodes(tar_Data_t * head)
751 tar_Data_t *local_temp = NULL;
753 LOGL(LOG_SSENGINE, "tar_cfg_delete_node [%s]\n", (char *)head->itemName);
754 local_temp = head->nextnode;
761 int tar_open(char *tar)
765 gTarFd = open(tar, O_RDONLY);
767 LOG("can't open TAR file(%s).\n", tar);
781 int tar_get_folder_size(char *tar, char *item)
785 char header[TAR_BLOCK_SIZE] = { 0, };
786 char name[TAR_LONG_NAME_SIZE + 1] = { 0, };
787 char *lastfolder = NULL;
788 int folderpathlen = 0;
789 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
790 unsigned long size_dec = 0;
797 LOG("Invalid params\n");
800 LOG("Tar folder Looking for (%s)\n", item);
801 fd = open(tar, O_RDONLY);
803 LOG("can't open file(%s).\n", tar);
807 tar_len = lseek(fd, 0, SEEK_END);
809 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
812 pos = lseek(fd, 0, SEEK_SET);
814 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
818 while (pos < tar_len) {
819 /* read file header */
820 rdcnt = read(fd, header, sizeof(header));
822 LOG("read failed. (rdcnt=%d)\n", rdcnt);
827 /* get file name and file size */
828 memcpy(name, header, sizeof(name) - 1);
829 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
830 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
831 if (size_dec > MAX_ITEM_SIZE) {
832 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
835 } else if (size_dec == 0) {
836 LOG("strtoul failed, size_oct is %s\n", size_oct);
841 /* check if the file is what we are looking for */
842 //Get until folder name
844 lastfolder = strrchr(name, '/');
846 folderpathlen = strlen(name) - strlen(lastfolder);
848 if (strncmp(name, item, folderpathlen) == 0) {
849 ret += (int)size_dec;
850 //LOG("Tar Files under folder [%s]\n", name);
854 /* move file pointer to next file header */
855 blknum = size_dec / TAR_BLOCK_SIZE;
856 if (size_dec % TAR_BLOCK_SIZE)
859 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
861 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
869 LOG("ret=%d\n", ret);
871 return ret; //Should return +1?? or Ignore??
874 /*Extract Specific Folder from tar, Taken from Untar.c */
875 int tar_extract_folder(char *tar, char *item, char *path)
877 char buff[MAX_FILE_PATH];
881 int data_offset = -1;
883 char name[512] = { 0, };
884 int folderpathlen = 0;
885 char dirPath[512] = { 0 };
886 int getheader = 1; // Asuming initial header is TAR header
887 char fullname[512] = { 0 };
890 if (!item || !tar || !path){
891 LOG("Invalid params\n");
894 LOG("Extracting Folder from %s %s to %s\n", tar, item, path);
896 data_offset = tar_get_item_offset(tar, item);
897 if (data_offset < 0) {
898 LOGE("data offset for [%s] is [%d]\n", item, data_offset);
902 fd = open(tar, O_RDONLY);
904 LOGE("can't open file(%s).\n", tar);
908 folderpathlen = strlen(item);
911 bytes_read = read(fd, buff, sizeof(buff));
912 if (bytes_read < 512) {
913 LOGE("Short read on %s: expected 512, got %d\n", tar, bytes_read);
917 if (is_end_of_archive(buff)) {
919 LOG("End of %s\n", tar); //Can stop at end of folder.
922 if (!verify_checksum(buff)) {
924 LOGE("Checksum failure\n");
927 filesize = parseoct(buff + 124, 12);
928 if (getheader == 2) {
930 //LOG(" Working on LONG FILE NAME CASE [%s]\n", fullname);
932 memset(fullname, 0, sizeof(fullname));
933 strncpy(fullname, buff, 100);
934 //LOG(" Working on Normal FILE NAME CASE [%s]\n", fullname);
939 LOG(" Ignoring hardlink %s\n", fullname);
943 //LOG(" Creating symlink %s\n", buff);
944 if (strncmp(fullname, item, folderpathlen) == 0) {
945 //LOG("Printing Buffer \n");
946 //for(i=157; buff[i] !='\0' ;i++)
948 //LOG("%c", buff[i]) ;
950 //LOG("\nEnd buffer\n");
951 memset(name, 0, sizeof(name));
952 strncpy(name, buff + 157, 100); //157, target link name will be present
953 memset(dirPath, 0, sizeof(dirPath));
954 snprintf(dirPath, sizeof(dirPath), "%s/%s", path, fullname + folderpathlen);
955 LOG(" Creating Symlink [%s][%s]\n", name, dirPath);
956 ret = symlink(name, dirPath); // use ss_link
958 LOG("Error with symlink: %d\n", errno);
962 LOG(" Ignoring character device %s\n", fullname);
965 LOG(" Ignoring block device %s\n", fullname);
969 //LOG(" Dir [%s] Item [%s] Length [%d]\n", fullname, item, folderpathlen);
970 if (strncmp(fullname, item, folderpathlen) == 0) {
971 //LOG(" Extracting dir %s\n", fullname);
972 memset(dirPath, 0, sizeof(dirPath));
973 snprintf(dirPath, sizeof(dirPath), "%s/%s", path, fullname + folderpathlen);
974 create_dir(dirPath, parseoct(fullname + 100, 8));
980 LOG(" Ignoring FIFO %s\n", fullname);
982 case GNUTYPE_LONGLINK:
983 case GNUTYPE_LONGNAME:
986 memset(fullname, 0, sizeof(fullname));
987 bytes_read = read(fd, fullname, sizeof(fullname));
988 if (bytes_read < 512) {
989 LOGE("Short read on %s: expected 512, got %d\n", tar, bytes_read);
994 //LOG("Entered LONG FILE NAME CASE new NAME is [%s]\n", fullname);
1000 //LOG(" File [%s] Item [%s] Length [%d]\n", fullname, item, folderpathlen);
1001 if (strncmp(fullname, item, folderpathlen) == 0) {
1002 if (buff[PREFIX_INDICATOR_BYTE] != 0) {
1003 memset(name, 0, sizeof(name));
1004 memset(dirPath, 0, sizeof(dirPath));
1005 strncpy(name, buff, 100);
1006 snprintf(name + strlen(name), sizeof(name) - strlen(name),
1007 "%s", buff + PREFIX_INDICATOR_BYTE);
1008 snprintf(dirPath, sizeof(dirPath), "%s/%s", path, name + folderpathlen);
1009 LOG(" File Name is longer than 100 bytes -Remaining Str [%s]\n Full Str[%s]\n", dirPath);
1011 //LOG(" Extracting file %s\n", fullname);
1012 memset(dirPath, 0, sizeof(dirPath));
1013 snprintf(dirPath, sizeof(dirPath), "%s/%s", path, fullname + folderpathlen);
1014 f = create_file(dirPath);
1021 while (filesize > 0) {
1022 bytes_read = read(fd, buff, sizeof(buff));
1023 if (bytes_read < 512) {
1024 LOGE("Short read on %s: Expected 512, got %d\n", tar, bytes_read);
1027 fclose(f);//wgid: 16892
1033 bytes_read = filesize;
1035 if (fwrite(buff, 1, bytes_read, f)
1037 LOG("Failed write\n");
1040 close(fd);//wgid: 59268
1041 return -1;//wgid: 16892
1044 filesize -= bytes_read;
1053 return S_SS_SUCCESS;
1056 int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset)
1059 int data_size = size;
1060 int data_offset = offset;
1063 ssize_t writeCount = 0;
1068 if (!item || !tar || !pathname){
1069 LOG("Invalid params\n");
1075 fd = open(tar, O_RDONLY);
1077 LOG("can't open file(%s).\n", tar);
1081 pos = lseek(fd, data_offset, SEEK_SET);
1083 LOG("lseek fail (%s offset %d).\n", tar, data_offset);
1087 buf = SS_Malloc(data_size + 1);
1090 LOGE("Failed to Allocate Memory\n");
1093 rdcnt = read(fd, buf, data_size);
1094 if (rdcnt != (ssize_t) data_size) {
1095 LOG(" rdcnt read fail(%s from %s).\n", item, tar);
1100 fd2 = open(pathname, O_CREAT | O_WRONLY, S_IRWXU); // Directory where file is required should be created already.
1102 LOG("can't open file(%s).\n", pathname);
1107 writeCount = write(fd2, buf, rdcnt);
1108 if (writeCount != rdcnt) {
1109 LOG("writeCount write fail(%s from %s).\n", item, tar);
1110 strerror_r(errno, err_buf, sizeof(err_buf));
1111 LOG("Oh dear, something went wrong with read()! %s\n", err_buf);
1122 return rdcnt; // or jus return success?
1125 int tar_extract_file(char *tar, char *item, char *pathname)
1129 int data_offset = -1;
1132 ssize_t writeCount = 0;
1137 if (!item || !tar || !pathname){
1138 LOG("Invalid params\n");
1141 data_size = tar_get_item_size(tar, item);
1142 data_offset = tar_get_item_offset(tar, item);
1144 if (data_size <= 0 || data_offset < 0) {
1145 LOGE("Error Not a file , size is [%d], offset [%d] for item [%s]\n", data_size, data_offset, item);
1148 LOGL(LOG_SSENGINE, "extracting file [%s] size [%d]\n", item, data_size);
1149 fd = open(tar, O_RDONLY);
1151 LOG("can't open file(%s).\n", tar);
1154 pos = lseek(fd, data_offset, SEEK_SET);
1156 LOG("lseek fail (%s offset %d).\n", tar, data_offset);
1160 buf = SS_Malloc(data_size + 1);
1163 LOGE("Failed to Allocate Memory\n");
1166 rdcnt = read(fd, buf, data_size);
1167 if (rdcnt != (ssize_t) data_size) {
1168 LOG(" rdcnt read fail(%s from %s).\n", item, tar);
1173 fd2 = open(pathname, O_CREAT | O_WRONLY, S_IRWXU); // Directory where file is required should be created already.
1175 LOG("can't open file(%s).\n", pathname);
1180 writeCount = write(fd2, buf, rdcnt);
1181 if (writeCount != rdcnt) {
1182 LOG("writeCount write fail(%s from %s).\n", item, tar);
1183 strerror_r(errno, err_buf, sizeof(err_buf));
1184 LOG("Oh dear, something went wrong with read()! %s\n", err_buf);
1194 return rdcnt; // or jus return success?