Changeset 24fda5e in mainline
- Timestamp:
- 2018-06-05T16:05:16Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 18ad56a8, 8404342
- Parents:
- 04051b8e
- Location:
- uspace
- Files:
-
- 3 added
- 3 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/Makefile
r04051b8e r24fda5e 214 214 lib/c \ 215 215 lib/softint \ 216 lib/softfloat 216 lib/softfloat \ 217 lib/untar 217 218 218 219 LIBS = \ -
uspace/app/untar/Makefile
r04051b8e r24fda5e 30 30 BINARY = untar 31 31 32 LIBS = untar 33 32 34 SOURCES = \ 33 main.c \ 34 tar.c 35 main.c 35 36 36 37 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/untar/main.c
r04051b8e r24fda5e 34 34 35 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <errno.h> 38 #include <str_error.h> 39 #include <vfs/vfs.h> 40 #include "tar.h" 36 #include <stdarg.h> 37 #include <untar.h> 41 38 42 static size_t get_block_count(size_t bytes) 39 const char *filename; 40 41 static int tar_open(tar_file_t *tar) 43 42 { 44 return (bytes + TAR_BLOCK_SIZE - 1) / TAR_BLOCK_SIZE; 45 } 43 FILE *file = fopen(filename, "rb"); 44 if (file == NULL) 45 return errno; 46 46 47 static errno_t skip_blocks(FILE *tarfile, size_t valid_data_size) 48 { 49 size_t blocks_to_read = get_block_count(valid_data_size); 50 while (blocks_to_read > 0) { 51 uint8_t block[TAR_BLOCK_SIZE]; 52 size_t actually_read = fread(block, TAR_BLOCK_SIZE, 1, tarfile); 53 if (actually_read != 1) { 54 return errno; 55 } 56 blocks_to_read--; 57 } 47 tar->data = (void *) file; 58 48 return EOK; 59 49 } 60 50 61 static errno_t handle_normal_file(const tar_header_t *header, FILE *tarfile)51 static void tar_close(tar_file_t *tar) 62 52 { 63 // FIXME: create the directory first 64 65 FILE *file = fopen(header->filename, "wb"); 66 if (file == NULL) { 67 fprintf(stderr, "Failed to create %s: %s.\n", header->filename, 68 str_error(errno)); 69 return errno; 70 } 71 72 errno_t rc = EOK; 73 size_t bytes_remaining = header->size; 74 size_t blocks = get_block_count(bytes_remaining); 75 while (blocks > 0) { 76 uint8_t block[TAR_BLOCK_SIZE]; 77 size_t actually_read = fread(block, 1, TAR_BLOCK_SIZE, tarfile); 78 if (actually_read != TAR_BLOCK_SIZE) { 79 rc = errno; 80 fprintf(stderr, "Failed to read block for %s: %s.\n", 81 header->filename, str_error(rc)); 82 break; 83 } 84 size_t to_write = TAR_BLOCK_SIZE; 85 if (bytes_remaining < TAR_BLOCK_SIZE) { 86 to_write = bytes_remaining; 87 } 88 size_t actually_written = fwrite(block, 1, to_write, file); 89 if (actually_written != to_write) { 90 rc = errno; 91 fprintf(stderr, "Failed to write to %s: %s.\n", 92 header->filename, str_error(rc)); 93 break; 94 } 95 blocks--; 96 bytes_remaining -= TAR_BLOCK_SIZE; 97 } 98 53 FILE *file = (FILE *) tar->data; 99 54 fclose(file); 100 101 return rc;102 55 } 103 56 104 static errno_t handle_directory(const tar_header_t *header, FILE *tarfile)57 static size_t tar_read(tar_file_t *tar, void *data, size_t size) 105 58 { 106 errno_t rc; 59 FILE *file = (FILE *) tar->data; 60 return fread(data, 1, size, file); 61 } 107 62 108 rc = vfs_link_path(header->filename, KIND_DIRECTORY, NULL); 109 if (rc != EOK) { 110 if (rc != EEXIST) { 111 fprintf(stderr, "Failed to create directory %s: %s.\n", 112 header->filename, str_error(rc)); 113 return rc; 114 } 115 } 63 static void tar_vreport(tar_file_t *tar, const char *fmt, va_list args) 64 { 65 vfprintf(stderr, fmt, args); 66 } 116 67 117 return skip_blocks(tarfile, header->size); 118 } 68 tar_file_t tar = { 69 .open = tar_open, 70 .close = tar_close, 71 72 .read = tar_read, 73 .vreport = tar_vreport 74 }; 119 75 120 76 int main(int argc, char *argv[]) … … 125 81 } 126 82 127 const char *filename = argv[1]; 128 129 FILE *tarfile = fopen(filename, "rb"); 130 if (tarfile == NULL) { 131 fprintf(stderr, "Failed to open `%s': %s.\n", filename, str_error(errno)); 132 return 2; 133 } 134 135 while (true) { 136 size_t header_ok; 137 tar_header_raw_t header_raw; 138 tar_header_t header; 139 header_ok = fread(&header_raw, sizeof(header_raw), 1, tarfile); 140 if (header_ok != 1) { 141 break; 142 } 143 errno_t rc = tar_header_parse(&header, &header_raw); 144 if (rc == EEMPTY) { 145 continue; 146 } 147 if (rc != EOK) { 148 fprintf(stderr, "Failed parsing TAR header: %s.\n", str_error(rc)); 149 break; 150 } 151 152 //printf(" ==> %s (%zuB, type %s)\n", header.filename, 153 // header.size, tar_type_str(header.type)); 154 155 switch (header.type) { 156 case TAR_TYPE_DIRECTORY: 157 rc = handle_directory(&header, tarfile); 158 break; 159 case TAR_TYPE_NORMAL: 160 rc = handle_normal_file(&header, tarfile); 161 break; 162 default: 163 rc = skip_blocks(tarfile, header.size); 164 break; 165 } 166 if (rc != EOK) { 167 break; 168 } 169 170 } 171 172 fclose(tarfile); 173 174 return 0; 83 filename = argv[1]; 84 return untar(&tar); 175 85 } 176 86 -
uspace/lib/untar/private/tar.h
r04051b8e r24fda5e 27 27 */ 28 28 29 /** @addtogroup untar29 /** @addtogroup libuntar 30 30 * @{ 31 31 */ 32 32 /** @file 33 33 */ 34 #ifndef TAR_H_GUARD 35 #define TAR_H_GUARD 34 35 #ifndef TAR_H_ 36 #define TAR_H_ 36 37 37 38 #define TAR_BLOCK_SIZE 512 … … 69 70 } tar_header_t; 70 71 71 72 72 extern errno_t tar_header_parse(tar_header_t *, const tar_header_raw_t *); 73 73 extern tar_type_t tar_type_parse(const char); -
uspace/lib/untar/tar.c
r04051b8e r24fda5e 27 27 */ 28 28 29 /** @addtogroup untar29 /** @addtogroup libuntar 30 30 * @{ 31 31 */ … … 38 38 #include <errno.h> 39 39 #include <assert.h> 40 41 #include "tar.h" 40 #include "private/tar.h" 42 41 43 42 tar_type_t tar_type_parse(const char type) … … 71 70 errno_t tar_header_parse(tar_header_t *parsed, const tar_header_raw_t *raw) 72 71 { 73 errno_t rc;74 75 72 if (str_length(raw->filename) == 0) { 76 73 return EEMPTY; … … 78 75 79 76 size_t size; 80 rc = str_size_t(raw->size, NULL, 8, true, &size);77 errno_t rc = str_size_t(raw->size, NULL, 8, true, &size); 81 78 if (rc != EOK) { 82 79 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.