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 "fota_common.h"
32 /* tar Header Block, from POSIX 1003.1-1990. for reference */
36 struct posix_header { /* byte offset */
37 char name[100]; /* 0 */
38 char mode[8]; /* 100 */
39 char uid[8]; /* 108 */
40 char gid[8]; /* 116 */
41 char size[12]; /* 124 */
42 char mtime[12]; /* 136 */
43 char chksum[8]; /* 148 */
44 char typeflag; /* 156 */
45 char linkname[100]; /* 157 */
46 char magic[6]; /* 257 */
47 char version[2]; /* 263 */
48 char uname[32]; /* 265 */
49 char gname[32]; /* 297 */
50 char devmajor[8]; /* 329 */
51 char devminor[8]; /* 337 */
52 char prefix[155]; /* 345 */
57 #define MAX_ITEM_SIZE 0x0FFFFFFF
58 #define TAR_ITEM_SIZE_POSITION 124
59 #define TAR_SIZE_OF_ITEM_SIZE 8
60 #define TAR_SIZE_OF_HEADER 12
61 #define TAR_BLOCK_SIZE 512
62 #define TAR_ITEM_NAME_SIZE 100
63 #define TAR_LONG_NAME_SIZE 256
64 #define TAR_ITEM_TYPE_FLAG_POS 156
66 /*** The byte that indicates whether the prefix is present or not */
67 #define PREFIX_INDICATOR_BYTE 345
68 #define PREFIX_LEN 155
70 /** the rest heavily based on (ie mostly) untgz.c from zlib **/
72 /* Values used in typeflag field. */
74 #define REGTYPE '0' /* regular file */
75 #define AREGTYPE '\0' /* regular file */
76 #define LNKTYPE '1' /* link */
77 #define SYMTYPE '2' /* reserved */
78 #define CHRTYPE '3' /* character special */
79 #define BLKTYPE '4' /* block special */
80 #define DIRTYPE '5' /* directory */
81 #define FIFOTYPE '6' /* FIFO special */
82 #define CONTTYPE '7' /* reserved, for compatibility with gnu tar,
83 treat as regular file, where it represents
84 a regular file, but saved contiguously on disk */
86 /* GNU tar extensions */
88 #define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
89 #define GNUTYPE_LONGLINK 'K' /* long link name */
90 #define GNUTYPE_LONGNAME 'L' /* long file name */
91 #define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
92 #define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
93 #define GNUTYPE_SPARSE 'S' /* sparse file */
94 #define GNUTYPE_VOLHDR 'V' /* tape/volume header */
96 extern void *SS_Malloc(SS_UINT32 size);
98 int gTarFd = -1; // Currenlty this logic supports only one tar file
100 /* Parse an octal number, ignoring leading and trailing nonsense. */
101 static int parseoct(const char *p, size_t n)
105 while (*p < '0' || *p > '7') {
109 while (*p >= '0' && *p <= '7' && n > 0) {
118 /* Verify the tar checksum. */
119 static int verify_checksum(const char *p)
122 for (n = 0; n < 512; ++n) {
123 if (n < 148 || n > 155)
124 /* Standard tar checksum adds unsigned bytes. */
125 u += ((unsigned char *)p)[n];
130 return (u == parseoct(p + 148, 8));
133 static int is_end_of_archive(const char *p)
136 for (n = 511; n >= 0; --n)
142 void create_dir(char *pathname, int mode)
147 /* Strip trailing '/' */
148 if (pathname[strlen(pathname) - 1] == '/')
149 pathname[strlen(pathname) - 1] = '\0';
151 /* Try creating the directory. */
152 r = mkdir(pathname, mode);
155 /* On failure, try creating parent directory. */
156 p = strrchr(pathname, '/');
159 create_dir(pathname, 0755);
161 r = mkdir(pathname, mode);
165 if (r != EEXIST && r != -1)
166 LOG("Could not create directory [%s] Error[%d]\n", pathname, r);
170 /* Create a file, including parent directory as necessary. */
171 static FILE *create_file(char *pathname, int mode)
174 f = fopen(pathname, "w+");
176 /* Try creating parent dir and then creating file. */
177 char *p = strrchr(pathname, '/');
180 create_dir(pathname, 0755);
182 f = fopen(pathname, "w+");
188 /*-----------------------------------------------------------------------------
190 ----------------------------------------------------------------------------*/
191 int tar_get_item_offset(char *tar, char *item)
195 char header[TAR_BLOCK_SIZE] = { 0, };
196 char name[TAR_ITEM_NAME_SIZE + 1] = { 0, };
197 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
204 //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it
208 fd = open(tar, O_RDONLY);
210 LOGE("can't open file(%s).\n", tar);
215 tar_len = lseek(fd, 0, SEEK_END);
217 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
220 pos = lseek(fd, 0, SEEK_SET);
222 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
225 while (pos < tar_len) {
226 /* read file header */
227 rdcnt = read(fd, header, sizeof(header));
229 LOG("read failed. (rdcnt=%d)\n", rdcnt);
233 /* get file name and file size */
234 memcpy(name, header, sizeof(name) - 1);//wgid: 24572
235 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
236 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
237 if (size_dec > MAX_ITEM_SIZE) {
238 LOG("size too big. (size_dec=0x%08X)\n", size_dec);
242 /* check if the file is what we are looking for */
243 if (strncmp(name, item, TAR_ITEM_NAME_SIZE) == 0) {
244 ret = (int)lseek(fd, 0, SEEK_CUR);
248 /* move file pointer to next file header */
249 blknum = size_dec / TAR_BLOCK_SIZE;
250 if (size_dec % TAR_BLOCK_SIZE)
253 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
255 LOGE("can't read next block (%s).\n", tar);
268 /*-----------------------------------------------------------------------------
270 ----------------------------------------------------------------------------*/
271 int tar_get_item_size(char *tar, char *item)
275 char header[TAR_BLOCK_SIZE] = { 0, };
276 char uExtendedName[MAX_FILE_PATH] = { 0, };
277 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
278 unsigned long size_dec = 0;
283 LOGL(LOG_SSENGINE, "Tar file Looking for (%s)\n", item);
284 fd = open(tar, O_RDONLY);
286 LOG("can't open file(%s).\n", tar);
290 tar_len = lseek(fd, 0, SEEK_END);
292 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
295 pos = lseek(fd, 0, SEEK_SET);
297 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
301 while (pos < tar_len) {
302 /* read file header */
303 rdcnt = read(fd, header, sizeof(header));
305 LOG("read failed. (rdcnt=%d)\n", rdcnt);
309 /* get file name and file size */
310 if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) {
311 //rdcnt = read(fd, header, sizeof(header));
312 memset(uExtendedName, 0, sizeof(uExtendedName));
313 rdcnt = read(fd, uExtendedName, sizeof(uExtendedName));
315 LOG("read failed. (rdcnt=%d)\n", rdcnt);
318 rdcnt = read(fd, header, sizeof(header));
320 LOG("read failed. (rdcnt=%d)\n", rdcnt);
324 memset(uExtendedName, 0, sizeof(uExtendedName));
325 memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE);
327 //memcpy(name, header, sizeof(name));
328 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
329 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
330 if (size_dec > MAX_ITEM_SIZE) {
331 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
335 /* check if the file is what we are looking for */
336 if (strcmp(uExtendedName, item) == 0) {
338 if ((ret == 0) && (header[TAR_ITEM_TYPE_FLAG_POS] == DIRTYPE))
339 ret = tar_get_folder_size(tar, item);
342 /* move file pointer to next file header */
343 //LOGL(LOG_SSENGINE,"Item in Tar (%s)\n", uExtendedName);
344 blknum = size_dec / TAR_BLOCK_SIZE;
345 if (size_dec % TAR_BLOCK_SIZE)
348 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
350 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
362 /*-----------------------------------------------------------------------------
363 tar_get_item_tye. (Dir/file/link etc)
364 ----------------------------------------------------------------------------*/
366 char tar_get_item_type(char *tar, char *item)
370 char header[TAR_BLOCK_SIZE] = { 0, };
371 char name[TAR_ITEM_NAME_SIZE + 1] = { 0, };
372 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
373 unsigned long size_dec = 0;
378 //LOG("Tar file Looking for (%s)\n", item);
379 fd = open(tar, O_RDONLY);
381 LOG("can't open file(%s).\n", tar);
385 tar_len = lseek(fd, 0, SEEK_END);
387 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
390 pos = lseek(fd, 0, SEEK_SET);
392 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
396 while (pos < tar_len) {
397 /* read file header */
398 rdcnt = read(fd, header, sizeof(header));
400 LOG("read failed. (rdcnt=%d)\n", rdcnt);
405 /* get file name and file size */
406 memcpy(name, header, sizeof(name) - 1);//wgid: 24573
407 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
408 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
409 if (size_dec > MAX_ITEM_SIZE) {
410 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
415 /* check if the file is what we are looking for */
416 if (strncmp(name, item, TAR_ITEM_NAME_SIZE) == 0) {
417 ret = header[TAR_ITEM_TYPE_FLAG_POS];
421 /* move file pointer to next file header */
422 blknum = size_dec / TAR_BLOCK_SIZE;
423 if (size_dec % TAR_BLOCK_SIZE)
426 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
428 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
440 /*-----------------------------------------------------------------------------
442 ----------------------------------------------------------------------------*/
443 int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen)
447 int data_offset = -1;
451 data_size = tar_get_item_size(tar, item);
452 if (data_size <= 0) {
456 if (data_size > buflen) {
460 data_offset = tar_get_item_offset(tar, item);
461 if (data_offset < 0) {
465 fd = open(tar, O_RDONLY);
467 LOG("can't open file(%s).\n", tar);
471 pos = lseek(fd, data_offset, SEEK_SET);
473 LOG("lseek fail (%s offset %d).\n", tar, data_offset);
478 rdcnt = read(fd, buf, data_size);
479 if (rdcnt != (ssize_t) data_size) {
480 LOG("read fail(%s from %s).\n", item, tar);
490 tar_Data_t *tar_build_cfg_table(char *tar)
495 char header[TAR_BLOCK_SIZE] = { 0, };
496 char uExtendedName[MAX_FILE_PATH] = { 0, };
497 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
498 unsigned long size_dec = 0;
506 tar_Data_t *headparam = NULL, *tailparam = NULL, *newnode = NULL;
507 tar_Data_t *local_temp = NULL;
508 tar_Data_t *local_next = NULL;
510 LOGE("Bad param tar\n");
513 //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it
517 fd = open(tar, O_RDONLY);
519 LOG("can't open file(%s).\n", tar);
523 tar_len = lseek(fd, 0, SEEK_END);
525 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
528 pos = lseek(fd, 0, SEEK_SET);
530 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
533 while (pos < tar_len) {
534 /* read file header */
535 rdcnt = read(fd, header, sizeof(header));
537 LOG("read failed. (rdcnt=%d)\n", rdcnt);
541 /* get file name and file size */
542 //memcpy(name, header, sizeof(name));
543 if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) {
544 //rdcnt = read(fd, header, sizeof(header));
545 memset(uExtendedName, 0, sizeof(uExtendedName));
546 rdcnt = read(fd, uExtendedName, sizeof(uExtendedName));
548 LOG("read failed. (rdcnt=%d)\n", rdcnt);
552 rdcnt = read(fd, header, sizeof(header));
554 LOG("read failed. (rdcnt=%d)\n", rdcnt);
559 memset(uExtendedName, 0, sizeof(uExtendedName));
560 memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE);
562 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
563 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
564 if (size_dec > MAX_ITEM_SIZE) {
565 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
569 //fix WGID : 51254 , size_dec comparison is not required
570 if ((strstr(uExtendedName, "/diff") != NULL)) //add only delta files from rootfs and csc, hardcoding shd b removed..
573 /* check if the file is what we are looking for */
574 //strncpy(itemName, name,100);
575 itemSize = (int)size_dec;
576 itemOffset = (int)lseek(fd, 0, SEEK_CUR);
577 newnode = (tar_Data_t *) SS_Malloc(sizeof(tar_Data_t));
582 strncpy((char *)newnode->itemName, uExtendedName, sizeof(newnode->itemName));
583 newnode->itemOffset = itemOffset;
584 newnode->itemSize = itemSize;
585 newnode->nextnode = NULL;
586 if (headparam == NULL) {
590 (tailparam)->nextnode = newnode;
591 (tailparam) = (tailparam)->nextnode;
595 /* move file pointer to next file header */
596 blknum = size_dec / TAR_BLOCK_SIZE;
597 if (size_dec % TAR_BLOCK_SIZE)
600 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
602 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
608 //if gTarFd was opened by tar_open during SS_FSUpdateFile we do not close it
617 local_temp = headparam;
619 local_next = local_temp->nextnode;
621 local_temp = local_next;
628 void tar_free_cfg_table(tar_Data_t ** delta_tar)
630 tar_Data_t *local_temp = NULL;
631 tar_Data_t *local_next = NULL;
632 LOGL(LOG_SSENGINE, "Free TAR CFG TABLE\n");
634 local_temp = *delta_tar;
636 local_next = local_temp->nextnode;
637 //LOGL(LOG_SSENGINE,"freeing [%s]\n",local_temp->itemName);
639 local_temp = local_next;
644 void deleteNode(tar_Data_t * head, tar_Data_t * n)
646 tar_Data_t *prev = head;
648 if (head->nextnode == NULL) {
649 LOG("There is only one node. The list can't be made empty ");
652 strncpy((char *)head->itemName, (const char *)head->nextnode->itemName, TAR_ITEM_NAME_SIZE); //head->itemName = head->nextnode->itemName;
653 head->itemSize = head->nextnode->itemSize;
654 head->itemOffset = head->nextnode->itemOffset;
656 head->nextnode = head->nextnode->nextnode;
660 while (prev->nextnode != NULL && prev->nextnode != n)
661 prev = prev->nextnode;
662 if (prev->nextnode == NULL) {
663 LOG("\n Given node is not present in Linked List");
666 prev->nextnode = prev->nextnode->nextnode;
671 int tar_get_item_size_from_struct(tar_Data_t ** delta_tar, const char *patchname, int *data_size, int *data_offset)
673 tar_Data_t *head = *delta_tar;
674 tar_Data_t *base = *delta_tar;
678 //LOG("fast_tar_get_item_size- looking for [%s] [%s]\n",patchname,head->itemName);
680 if (strstr((const char *)head->itemName, patchname) != 0) {
681 //LOG("fast_tar_get_item_size found [%s] in [%s]\n",patchname, head->itemName);
682 *data_size = head->itemSize;
683 *data_offset = head->itemOffset;
684 deleteNode(base, head);
687 } else if (head->nextnode != NULL) {
688 head = head->nextnode;
689 //LOG("fast_tar_get_item_size current node [%s] \n",head->itemName);
691 LOGE("fast_tar_get_item_size FAILED TO GET [%s] in [%s]\n", patchname, (char *)head->itemName);
699 tar_Data_t *tar_cfg_clear_nodes(tar_Data_t * head)
701 tar_Data_t *local_temp = NULL;
703 LOGL(LOG_SSENGINE, "tar_cfg_delete_node [%s]", (char *)head->itemName);
704 local_temp = head->nextnode;
711 int tar_open(char *tar)
715 gTarFd = open(tar, O_RDONLY);
717 LOG("can't open TAR file(%s).\n", tar);
731 int tar_get_folder_size(char *tar, char *item)
735 char header[TAR_BLOCK_SIZE] = { 0, };
736 char name[TAR_LONG_NAME_SIZE + 1] = { 0, };
737 char *lastfolder = NULL;
738 int folderpathlen = 0;
739 char size_oct[TAR_SIZE_OF_HEADER] = { 0, };
740 unsigned long size_dec = 0;
745 LOG("Tar folder Looking for (%s)\n", item);
746 fd = open(tar, O_RDONLY);
748 LOG("can't open file(%s).\n", tar);
752 tar_len = lseek(fd, 0, SEEK_END);
754 LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar);
757 pos = lseek(fd, 0, SEEK_SET);
759 LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar);
763 while (pos < tar_len) {
764 /* read file header */
765 rdcnt = read(fd, header, sizeof(header));
767 LOG("read failed. (rdcnt=%d)\n", rdcnt);
772 /* get file name and file size */
773 memcpy(name, header, sizeof(name) - 1);//wgid: 24574
774 memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct));
775 size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE);
776 if (size_dec > MAX_ITEM_SIZE) {
777 LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec);
782 /* check if the file is what we are looking for */
783 //Get until folder name
785 lastfolder = strrchr(name, '/');
787 folderpathlen = strlen(name) - strlen(lastfolder);
789 if (strncmp(name, item, folderpathlen) == 0) {
790 ret += (int)size_dec;
791 //LOG("Tar Files under folder [%s]\n", name);
795 /* move file pointer to next file header */
796 blknum = size_dec / TAR_BLOCK_SIZE;
797 if (size_dec % TAR_BLOCK_SIZE)
800 pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR);
802 LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar);
810 LOG("ret=%d\n", ret);
812 return ret; //Should return +1?? or Ignore??
815 /*Extract Specific Folder from tar, Taken from Untar.c */
816 int tar_extract_folder(char *tar, char *item, char *path)
818 char buff[MAX_FILE_PATH];
822 int data_offset = -1;
824 char name[512] = { 0, };
825 int folderpathlen = 0;
826 char dirPath[512] = { 0 };
827 int getheader = 1; // Asuming initial header is TAR header
828 char fullname[512] = { 0 };
829 LOG("Extracting Folder from %s %s to %s\n", tar, item, path);
831 data_offset = tar_get_item_offset(tar, item);
832 if (data_offset < 0) {
833 LOGE("data offset for [%s] is [%d]\n", item, data_offset);
837 fd = open(tar, O_RDONLY);
839 LOGE("can't open file(%s).\n", tar);
843 folderpathlen = strlen(item);
846 bytes_read = read(fd, buff, sizeof(buff));
847 if (bytes_read < 512) {
848 LOGE("Short read on %s: expected 512, got %d\n", tar, bytes_read);
852 if (is_end_of_archive(buff)) {
854 LOG("End of %s\n", tar); //Can stop at end of folder.
857 if (!verify_checksum(buff)) {
859 LOGE("Checksum failure\n");
862 filesize = parseoct(buff + 124, 12);
863 if (getheader == 2) {
865 //LOG(" Working on LONG FILE NAME CASE [%s]\n", fullname);
867 memset(fullname, 0, sizeof(fullname));
868 strncpy(fullname, buff, 100);
869 //LOG(" Working on Normal FILE NAME CASE [%s]\n", fullname);
874 LOG(" Ignoring hardlink %s\n", fullname);
878 //LOG(" Creating symlink %s\n", buff);
879 if (strncmp(fullname, item, folderpathlen) == 0) {
880 //LOG("Printing Buffer \n");
881 //for(i=157; buff[i] !='\0' ;i++)
883 //LOG("%c", buff[i]) ;
885 //LOG("\nEnd buffer\n");
886 memset(name, 0, sizeof(name));
887 strncpy(name, buff + 157, 100); //157, target link name will be present
888 memset(dirPath, 0, sizeof(dirPath));
889 sprintf(dirPath, "%s/%s", path, fullname + folderpathlen);
890 LOG(" Creating Symlink [%s][%s]\n", name, dirPath);
891 symlink(name, dirPath); // use ss_link
895 LOG(" Ignoring character device %s\n", fullname);
898 LOG(" Ignoring block device %s\n", fullname);
902 //LOG(" Dir [%s] Item [%s] Length [%d]\n", fullname, item, folderpathlen);
903 if (strncmp(fullname, item, folderpathlen) == 0) {
904 //LOG(" Extracting dir %s\n", fullname);
905 memset(dirPath, 0, sizeof(dirPath));
906 sprintf(dirPath, "%s/%s", path, fullname + folderpathlen);
907 create_dir(dirPath, parseoct(fullname + 100, 8));
913 LOG(" Ignoring FIFO %s\n", fullname);
915 case GNUTYPE_LONGLINK:
916 case GNUTYPE_LONGNAME:
919 memset(fullname, 0, sizeof(fullname));
920 bytes_read = read(fd, fullname, sizeof(fullname));
921 if (bytes_read < 512) {
922 LOGE("Short read on %s: expected 512, got %d\n", tar, bytes_read);
927 //LOG("Entered LONG FILE NAME CASE new NAME is [%s]\n", fullname);
933 //LOG(" File [%s] Item [%s] Length [%d]\n", fullname, item, folderpathlen);
934 if (strncmp(fullname, item, folderpathlen) == 0) {
935 if (buff[PREFIX_INDICATOR_BYTE] != 0) {
936 memset(name, 0, sizeof(name));
937 memset(dirPath, 0, sizeof(dirPath));
938 strncpy(name, buff, 100);
939 strcat(name, buff + PREFIX_INDICATOR_BYTE);
940 sprintf(dirPath, "%s/%s", path, name + folderpathlen);
941 LOG(" File Name is longer than 100 bytes -Remaining Str [%s]\n Full Str[%s]", dirPath);
943 //LOG(" Extracting file %s\n", fullname);
944 memset(dirPath, 0, sizeof(dirPath));
945 sprintf(dirPath, "%s/%s", path, fullname + folderpathlen);
946 f = create_file(dirPath, parseoct(fullname + 100, 8));
953 while (filesize > 0) {
954 bytes_read = read(fd, buff, sizeof(buff));
955 if (bytes_read < 512) {
956 LOGE("Short read on %s: Expected 512, got %d\n", tar, bytes_read);
959 fclose(f);//wgid: 16892
965 bytes_read = filesize;
967 if (fwrite(buff, 1, bytes_read, f)
969 LOG("Failed write\n");
972 close(fd);//wgid: 59268
973 return -1;//wgid: 16892
976 filesize -= bytes_read;
988 int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset)
991 int data_size = size;
992 int data_offset = offset;
995 ssize_t writeCount = 0;
1002 fd = open(tar, O_RDONLY);
1004 LOG("can't open file(%s).\n", tar);
1008 pos = lseek(fd, data_offset, SEEK_SET);
1010 LOG("lseek fail (%s offset %d).\n", tar, data_offset);
1014 buf = SS_Malloc(data_size + 1);
1017 LOGE("Failed to Allocate Memory\n");
1020 rdcnt = read(fd, buf, data_size);
1021 if (rdcnt != (ssize_t) data_size) {
1022 LOG(" rdcnt read fail(%s from %s).\n", item, tar);
1027 fd2 = open(pathname, O_CREAT | O_WRONLY, 0777); // Directory where file is required should be created already.
1029 LOG("can't open file(%s).\n", pathname);
1034 writeCount = write(fd2, buf, rdcnt);
1035 if (writeCount != rdcnt) {
1036 LOG("writeCount write fail(%s from %s).\n", item, tar);
1037 LOG("Oh dear, something went wrong with read()! %s\n", strerror(errno));
1048 return rdcnt; // or jus return success?
1051 int tar_extract_file(char *tar, char *item, char *pathname)
1055 int data_offset = -1;
1058 ssize_t writeCount = 0;
1061 data_size = tar_get_item_size(tar, item);
1062 data_offset = tar_get_item_offset(tar, item);
1064 if (data_size <= 0 || data_offset < 0) {
1065 LOGE("Error Not a file , size is [%d], offset [%d] for item [%s]\n", data_size, data_offset, item);
1068 LOGL(LOG_SSENGINE, "extracting file [%s] size [%d]\n", item, data_size);
1069 fd = open(tar, O_RDONLY);
1071 LOG("can't open file(%s).\n", tar);
1074 pos = lseek(fd, data_offset, SEEK_SET);
1076 LOG("lseek fail (%s offset %d).\n", tar, data_offset);
1080 buf = SS_Malloc(data_size + 1);
1083 LOGE("Failed to Allocate Memory\n");
1086 rdcnt = read(fd, buf, data_size);
1087 if (rdcnt != (ssize_t) data_size) {
1088 LOG(" rdcnt read fail(%s from %s).\n", item, tar);
1093 fd2 = open(pathname, O_CREAT | O_WRONLY, 0777); // Directory where file is required should be created already.
1095 LOG("can't open file(%s).\n", pathname);
1100 writeCount = write(fd2, buf, rdcnt);
1101 if (writeCount != rdcnt) {
1102 LOG("writeCount write fail(%s from %s).\n", item, tar);
1103 LOG("Oh dear, something went wrong with read()! %s\n", strerror(errno));
1113 return rdcnt; // or jus return success?