diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-22 00:21:07 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-22 00:21:07 +0000 |
| commit | 714701c890b5f03253c5ecdb7367c4258ce78715 (patch) | |
| tree | 7ddaf73cf2deda0f357b21802dab4d42798dd778 | |
| parent | 0a8a7741795880201bcf78231d1eab0e2538bb0b (diff) | |
| download | busybox-w32-714701c890b5f03253c5ecdb7367c4258ce78715.tar.gz busybox-w32-714701c890b5f03253c5ecdb7367c4258ce78715.tar.bz2 busybox-w32-714701c890b5f03253c5ecdb7367c4258ce78715.zip | |
tar et al: die if bb_copyfd_size copies less than asked for.
(we have bb_copyfd_exact_size now for that kind of usage)
| -rw-r--r-- | archival/libunarchive/data_extract_all.c | 4 | ||||
| -rw-r--r-- | archival/libunarchive/data_extract_to_buffer.c | 3 | ||||
| -rw-r--r-- | archival/libunarchive/data_extract_to_stdout.c | 6 | ||||
| -rw-r--r-- | archival/libunarchive/get_header_ar.c | 3 | ||||
| -rw-r--r-- | archival/libunarchive/get_header_tar.c | 2 | ||||
| -rw-r--r-- | archival/libunarchive/seek_by_read.c | 5 | ||||
| -rw-r--r-- | archival/tar.c | 32 | ||||
| -rw-r--r-- | archival/unzip.c | 23 | ||||
| -rw-r--r-- | coreutils/cat.c | 3 | ||||
| -rw-r--r-- | include/libbb.h | 7 | ||||
| -rw-r--r-- | include/unarchive.h | 2 | ||||
| -rw-r--r-- | libbb/copyfd.c | 32 | ||||
| -rw-r--r-- | networking/ftpgetput.c | 29 |
13 files changed, 85 insertions, 66 deletions
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index 67f8f3534..25bf028d2 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c | |||
| @@ -67,10 +67,10 @@ void data_extract_all(archive_handle_t *archive_handle) | |||
| 67 | /* Regular file */ | 67 | /* Regular file */ |
| 68 | dst_fd = xopen3(file_header->name, O_WRONLY | O_CREAT | O_EXCL, | 68 | dst_fd = xopen3(file_header->name, O_WRONLY | O_CREAT | O_EXCL, |
| 69 | file_header->mode); | 69 | file_header->mode); |
| 70 | bb_copyfd_size(archive_handle->src_fd, dst_fd, file_header->size); | 70 | bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); |
| 71 | close(dst_fd); | 71 | close(dst_fd); |
| 72 | break; | 72 | break; |
| 73 | } | 73 | } |
| 74 | case S_IFDIR: | 74 | case S_IFDIR: |
| 75 | res = mkdir(file_header->name, file_header->mode); | 75 | res = mkdir(file_header->name, file_header->mode); |
| 76 | if ((errno != EISDIR) && (res == -1) | 76 | if ((errno != EISDIR) && (res == -1) |
diff --git a/archival/libunarchive/data_extract_to_buffer.c b/archival/libunarchive/data_extract_to_buffer.c index 95cb8f576..d8fcdf3d3 100644 --- a/archival/libunarchive/data_extract_to_buffer.c +++ b/archival/libunarchive/data_extract_to_buffer.c | |||
| @@ -10,9 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | void data_extract_to_buffer(archive_handle_t *archive_handle) | 11 | void data_extract_to_buffer(archive_handle_t *archive_handle) |
| 12 | { | 12 | { |
| 13 | const unsigned int size = archive_handle->file_header->size; | 13 | unsigned int size = archive_handle->file_header->size; |
| 14 | 14 | ||
| 15 | archive_handle->buffer = xzalloc(size + 1); | 15 | archive_handle->buffer = xzalloc(size + 1); |
| 16 | |||
| 17 | xread(archive_handle->src_fd, archive_handle->buffer, size); | 16 | xread(archive_handle->src_fd, archive_handle->buffer, size); |
| 18 | } | 17 | } |
diff --git a/archival/libunarchive/data_extract_to_stdout.c b/archival/libunarchive/data_extract_to_stdout.c index 788246ce7..2e266c046 100644 --- a/archival/libunarchive/data_extract_to_stdout.c +++ b/archival/libunarchive/data_extract_to_stdout.c | |||
| @@ -4,9 +4,11 @@ | |||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include "unarchive.h" | 6 | #include "unarchive.h" |
| 7 | #include <unistd.h> | 7 | //#include <unistd.h> |
| 8 | 8 | ||
| 9 | void data_extract_to_stdout(archive_handle_t *archive_handle) | 9 | void data_extract_to_stdout(archive_handle_t *archive_handle) |
| 10 | { | 10 | { |
| 11 | bb_copyfd_size(archive_handle->src_fd, STDOUT_FILENO, archive_handle->file_header->size); | 11 | bb_copyfd_exact_size(archive_handle->src_fd, |
| 12 | STDOUT_FILENO, | ||
| 13 | archive_handle->file_header->size); | ||
| 12 | } | 14 | } |
diff --git a/archival/libunarchive/get_header_ar.c b/archival/libunarchive/get_header_ar.c index 7f8c81ca0..6638c65aa 100644 --- a/archival/libunarchive/get_header_ar.c +++ b/archival/libunarchive/get_header_ar.c | |||
| @@ -96,7 +96,8 @@ char get_header_ar(archive_handle_t *archive_handle) | |||
| 96 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { | 96 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { |
| 97 | archive_handle->action_header(typed); | 97 | archive_handle->action_header(typed); |
| 98 | if (archive_handle->sub_archive) { | 98 | if (archive_handle->sub_archive) { |
| 99 | while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS); | 99 | while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) |
| 100 | /* repeat */; | ||
| 100 | } else { | 101 | } else { |
| 101 | archive_handle->action_data(archive_handle); | 102 | archive_handle->action_data(archive_handle); |
| 102 | } | 103 | } |
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 66c3314a1..beb8687c7 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
| @@ -251,7 +251,7 @@ char get_header_tar(archive_handle_t *archive_handle) | |||
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | /* Strip trailing '/' in directories */ | 253 | /* Strip trailing '/' in directories */ |
| 254 | /* Must be done after mode is set as '/' is used to check if its a directory */ | 254 | /* Must be done after mode is set as '/' is used to check if it's a directory */ |
| 255 | cp = last_char_is(file_header->name, '/'); | 255 | cp = last_char_is(file_header->name, '/'); |
| 256 | 256 | ||
| 257 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { | 257 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { |
diff --git a/archival/libunarchive/seek_by_read.c b/archival/libunarchive/seek_by_read.c index d56f94b21..e46af4842 100644 --- a/archival/libunarchive/seek_by_read.c +++ b/archival/libunarchive/seek_by_read.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | */ | 13 | */ |
| 14 | void seek_by_read(const archive_handle_t *archive_handle, const unsigned int jump_size) | 14 | void seek_by_read(const archive_handle_t *archive_handle, const unsigned int jump_size) |
| 15 | { | 15 | { |
| 16 | if (jump_size) { | 16 | if (jump_size) |
| 17 | bb_copyfd_size(archive_handle->src_fd, -1, jump_size); | 17 | bb_copyfd_exact_size(archive_handle->src_fd, -1, jump_size); |
| 18 | } | ||
| 19 | } | 18 | } |
diff --git a/archival/tar.c b/archival/tar.c index 7465e881b..ee9007c47 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
| @@ -452,26 +452,28 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, | |||
| 452 | 452 | ||
| 453 | /* If it was a regular file, write out the body */ | 453 | /* If it was a regular file, write out the body */ |
| 454 | if (inputFileFd >= 0) { | 454 | if (inputFileFd >= 0) { |
| 455 | off_t readSize = 0; | 455 | size_t readSize; |
| 456 | 456 | /* Wwrite the file to the archive. */ | |
| 457 | /* write the file to the archive */ | 457 | /* We record size into header first, */ |
| 458 | readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size); | 458 | /* and then write out file. If file shrinks in between, */ |
| 459 | /* readSize < 0 means that error was already reported */ | 459 | /* tar will be corrupted. So we don't allow for that. */ |
| 460 | if (readSize != statbuf->st_size && readSize >= 0) { | 460 | /* NB: GNU tar 1.16 warns and pads with zeroes */ |
| 461 | /* Deadly. We record size into header first, */ | 461 | /* or even seeks back and updates header */ |
| 462 | /* and then write out file. If file shrinks in between, */ | 462 | bb_copyfd_exact_size(inputFileFd, tbInfo->tarFd, statbuf->st_size); |
| 463 | /* tar will be corrupted. So bail out. */ | 463 | ////off_t readSize; |
| 464 | /* NB: GNU tar 1.16 warns and pads with zeroes */ | 464 | ////readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size); |
| 465 | /* or even seeks back and updates header */ | 465 | ////if (readSize != statbuf->st_size && readSize >= 0) { |
| 466 | bb_error_msg_and_die("short read from %s, aborting", fileName); | 466 | //// bb_error_msg_and_die("short read from %s, aborting", fileName); |
| 467 | } | 467 | ////} |
| 468 | |||
| 468 | /* Check that file did not grow in between? */ | 469 | /* Check that file did not grow in between? */ |
| 469 | /* if (safe_read(inputFileFd,1) == 1) warn but continue? */ | 470 | /* if (safe_read(inputFileFd, 1) == 1) warn but continue? */ |
| 471 | |||
| 470 | close(inputFileFd); | 472 | close(inputFileFd); |
| 471 | 473 | ||
| 472 | /* Pad the file up to the tar block size */ | 474 | /* Pad the file up to the tar block size */ |
| 473 | /* (a few tricks here in the name of code size) */ | 475 | /* (a few tricks here in the name of code size) */ |
| 474 | readSize = (-(int)readSize) & (TAR_BLOCK_SIZE-1); | 476 | readSize = (-(int)statbuf->st_size) & (TAR_BLOCK_SIZE-1); |
| 475 | memset(bb_common_bufsiz1, 0, readSize); | 477 | memset(bb_common_bufsiz1, 0, readSize); |
| 476 | xwrite(tbInfo->tarFd, bb_common_bufsiz1, readSize); | 478 | xwrite(tbInfo->tarFd, bb_common_bufsiz1, readSize); |
| 477 | } | 479 | } |
diff --git a/archival/unzip.c b/archival/unzip.c index f553eefa2..1c03a4c47 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
| @@ -54,9 +54,9 @@ typedef union { | |||
| 54 | static void unzip_skip(int fd, off_t skip) | 54 | static void unzip_skip(int fd, off_t skip) |
| 55 | { | 55 | { |
| 56 | if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { | 56 | if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { |
| 57 | if ((errno != ESPIPE) || (bb_copyfd_size(fd, -1, skip) != skip)) { | 57 | if (errno != ESPIPE) |
| 58 | bb_error_msg_and_die("seek failure"); | 58 | bb_error_msg_and_die("seek failure"); |
| 59 | } | 59 | bb_copyfd_exact_size(fd, -1, skip); |
| 60 | } | 60 | } |
| 61 | } | 61 | } |
| 62 | 62 | ||
| @@ -75,10 +75,8 @@ static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) | |||
| 75 | if (zip_header->formatted.method == 0) { | 75 | if (zip_header->formatted.method == 0) { |
| 76 | /* Method 0 - stored (not compressed) */ | 76 | /* Method 0 - stored (not compressed) */ |
| 77 | off_t size = zip_header->formatted.ucmpsize; | 77 | off_t size = zip_header->formatted.ucmpsize; |
| 78 | if (size && (bb_copyfd_size(src_fd, dst_fd, size) != size)) { | 78 | if (size) |
| 79 | bb_error_msg_and_die("cannot complete extraction"); | 79 | bb_copyfd_exact_size(src_fd, dst_fd, size); |
| 80 | } | ||
| 81 | |||
| 82 | } else { | 80 | } else { |
| 83 | /* Method 8 - inflate */ | 81 | /* Method 8 - inflate */ |
| 84 | inflate_init(zip_header->formatted.cmpsize); | 82 | inflate_init(zip_header->formatted.cmpsize); |
| @@ -249,8 +247,8 @@ int unzip_main(int argc, char **argv) | |||
| 249 | unzip_skip(src_fd, zip_header.formatted.extra_len); | 247 | unzip_skip(src_fd, zip_header.formatted.extra_len); |
| 250 | 248 | ||
| 251 | if ((verbosity == v_list) && !list_header_done){ | 249 | if ((verbosity == v_list) && !list_header_done){ |
| 252 | printf(" Length Date Time Name\n" | 250 | puts(" Length Date Time Name\n" |
| 253 | " -------- ---- ---- ----\n"); | 251 | " -------- ---- ---- ----"); |
| 254 | list_header_done = 1; | 252 | list_header_done = 1; |
| 255 | } | 253 | } |
| 256 | 254 | ||
| @@ -274,10 +272,8 @@ int unzip_main(int argc, char **argv) | |||
| 274 | dst_fn); | 272 | dst_fn); |
| 275 | total_entries++; | 273 | total_entries++; |
| 276 | i = 'n'; | 274 | i = 'n'; |
| 277 | |||
| 278 | } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ | 275 | } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ |
| 279 | i = -1; | 276 | i = -1; |
| 280 | |||
| 281 | } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ | 277 | } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ |
| 282 | if (stat(dst_fn, &stat_buf) == -1) { | 278 | if (stat(dst_fn, &stat_buf) == -1) { |
| 283 | if (errno != ENOENT) { | 279 | if (errno != ENOENT) { |
| @@ -298,17 +294,15 @@ int unzip_main(int argc, char **argv) | |||
| 298 | i = 'n'; | 294 | i = 'n'; |
| 299 | 295 | ||
| 300 | } else { /* Extract file */ | 296 | } else { /* Extract file */ |
| 301 | _check_file: | 297 | _check_file: |
| 302 | if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ | 298 | if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ |
| 303 | if (errno != ENOENT) { | 299 | if (errno != ENOENT) { |
| 304 | bb_perror_msg_and_die("cannot stat '%s'",dst_fn); | 300 | bb_perror_msg_and_die("cannot stat '%s'",dst_fn); |
| 305 | } | 301 | } |
| 306 | i = 'y'; | 302 | i = 'y'; |
| 307 | |||
| 308 | } else { /* File already exists */ | 303 | } else { /* File already exists */ |
| 309 | if (overwrite == o_never) { | 304 | if (overwrite == o_never) { |
| 310 | i = 'n'; | 305 | i = 'n'; |
| 311 | |||
| 312 | } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ | 306 | } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ |
| 313 | if (overwrite == o_always) { | 307 | if (overwrite == o_always) { |
| 314 | i = 'y'; | 308 | i = 'y'; |
| @@ -319,7 +313,6 @@ int unzip_main(int argc, char **argv) | |||
| 319 | } | 313 | } |
| 320 | i = key_buf[0]; | 314 | i = key_buf[0]; |
| 321 | } | 315 | } |
| 322 | |||
| 323 | } else { /* File is not regular file */ | 316 | } else { /* File is not regular file */ |
| 324 | bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn); | 317 | bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn); |
| 325 | } | 318 | } |
| @@ -338,7 +331,7 @@ int unzip_main(int argc, char **argv) | |||
| 338 | printf(" inflating: %s\n", dst_fn); | 331 | printf(" inflating: %s\n", dst_fn); |
| 339 | } | 332 | } |
| 340 | if (unzip_extract(&zip_header, src_fd, dst_fd)) { | 333 | if (unzip_extract(&zip_header, src_fd, dst_fd)) { |
| 341 | failed = 1; | 334 | failed = 1; |
| 342 | } | 335 | } |
| 343 | if (dst_fd != STDOUT_FILENO) { | 336 | if (dst_fd != STDOUT_FILENO) { |
| 344 | /* closing STDOUT is potentially bad for future business */ | 337 | /* closing STDOUT is potentially bad for future business */ |
diff --git a/coreutils/cat.c b/coreutils/cat.c index d828b86ec..2b7c6035f 100644 --- a/coreutils/cat.c +++ b/coreutils/cat.c | |||
| @@ -25,9 +25,8 @@ int bb_cat(char **argv) | |||
| 25 | if (f) { | 25 | if (f) { |
| 26 | off_t r = bb_copyfd_eof(fileno(f), STDOUT_FILENO); | 26 | off_t r = bb_copyfd_eof(fileno(f), STDOUT_FILENO); |
| 27 | fclose_if_not_stdin(f); | 27 | fclose_if_not_stdin(f); |
| 28 | if (r >= 0) { | 28 | if (r >= 0) |
| 29 | continue; | 29 | continue; |
| 30 | } | ||
| 31 | } | 30 | } |
| 32 | retval = EXIT_FAILURE; | 31 | retval = EXIT_FAILURE; |
| 33 | } while (*++argv); | 32 | } while (*++argv); |
diff --git a/include/libbb.h b/include/libbb.h index 2fd54e789..2bfeba4e1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -203,8 +203,13 @@ extern int recursive_action(const char *fileName, int recurse, | |||
| 203 | extern int device_open(const char *device, int mode); | 203 | extern int device_open(const char *device, int mode); |
| 204 | extern int get_console_fd(void); | 204 | extern int get_console_fd(void); |
| 205 | extern char *find_block_device(char *path); | 205 | extern char *find_block_device(char *path); |
| 206 | extern off_t bb_copyfd_size(int fd1, int fd2, off_t size); | 206 | /* bb_copyfd_XX print read/write errors and return -1 if they occur */ |
| 207 | extern off_t bb_copyfd_eof(int fd1, int fd2); | 207 | extern off_t bb_copyfd_eof(int fd1, int fd2); |
| 208 | extern off_t bb_copyfd_size(int fd1, int fd2, off_t size); | ||
| 209 | extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size); | ||
| 210 | /* "short" copy can be detected by return value < size */ | ||
| 211 | /* this helper yells "short read!" if param is not -1 */ | ||
| 212 | extern void complain_copyfd_and_die(off_t sz) ATTRIBUTE_NORETURN; | ||
| 208 | extern char bb_process_escape_sequence(const char **ptr); | 213 | extern char bb_process_escape_sequence(const char **ptr); |
| 209 | extern char *bb_get_last_path_component(char *path); | 214 | extern char *bb_get_last_path_component(char *path); |
| 210 | extern int ndelay_on(int fd); | 215 | extern int ndelay_on(int fd); |
diff --git a/include/unarchive.h b/include/unarchive.h index 7de6a63fe..88c00882c 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
| @@ -24,7 +24,7 @@ typedef struct file_headers_s { | |||
| 24 | } file_header_t; | 24 | } file_header_t; |
| 25 | 25 | ||
| 26 | typedef struct archive_handle_s { | 26 | typedef struct archive_handle_s { |
| 27 | /* define if the header and data component should processed */ | 27 | /* define if the header and data component should be processed */ |
| 28 | char (*filter)(struct archive_handle_s *); | 28 | char (*filter)(struct archive_handle_s *); |
| 29 | llist_t *accept; | 29 | llist_t *accept; |
| 30 | /* List of files that have been rejected */ | 30 | /* List of files that have been rejected */ |
diff --git a/libbb/copyfd.c b/libbb/copyfd.c index c6b886647..17bf4fbc2 100644 --- a/libbb/copyfd.c +++ b/libbb/copyfd.c | |||
| @@ -39,7 +39,7 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) | |||
| 39 | 39 | ||
| 40 | rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size); | 40 | rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size); |
| 41 | 41 | ||
| 42 | if (!rd) { /* eof - all done. */ | 42 | if (!rd) { /* eof - all done */ |
| 43 | status = 0; | 43 | status = 0; |
| 44 | break; | 44 | break; |
| 45 | } | 45 | } |
| @@ -56,22 +56,31 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) | |||
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | total += rd; | 58 | total += rd; |
| 59 | if (status < 0) { | 59 | if (status < 0) { /* if we aren't copying till EOF... */ |
| 60 | size -= rd; | 60 | size -= rd; |
| 61 | if (!size) { | 61 | if (!size) { |
| 62 | status = 0; | 62 | /* 'size' bytes copied - all done */ |
| 63 | status = 0; | ||
| 63 | break; | 64 | break; |
| 64 | } | 65 | } |
| 65 | } | 66 | } |
| 66 | } | 67 | } |
| 67 | 68 | out: | |
| 68 | out: | ||
| 69 | RELEASE_CONFIG_BUFFER(buffer); | 69 | RELEASE_CONFIG_BUFFER(buffer); |
| 70 | |||
| 71 | return status ? -1 : total; | 70 | return status ? -1 : total; |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | 73 | ||
| 74 | #if 0 | ||
| 75 | void complain_copyfd_and_die(off_t sz) | ||
| 76 | { | ||
| 77 | if (sz != -1) | ||
| 78 | bb_error_msg_and_die("short read"); | ||
| 79 | /* if sz == -1, bb_copyfd_XX already complained */ | ||
| 80 | exit(xfunc_error_retval); | ||
| 81 | } | ||
| 82 | #endif | ||
| 83 | |||
| 75 | off_t bb_copyfd_size(int fd1, int fd2, off_t size) | 84 | off_t bb_copyfd_size(int fd1, int fd2, off_t size) |
| 76 | { | 85 | { |
| 77 | if (size) { | 86 | if (size) { |
| @@ -80,6 +89,17 @@ off_t bb_copyfd_size(int fd1, int fd2, off_t size) | |||
| 80 | return 0; | 89 | return 0; |
| 81 | } | 90 | } |
| 82 | 91 | ||
| 92 | void bb_copyfd_exact_size(int fd1, int fd2, off_t size) | ||
| 93 | { | ||
| 94 | off_t sz = bb_copyfd_size(fd1, fd2, size); | ||
| 95 | if (sz == size) | ||
| 96 | return; | ||
| 97 | if (sz != -1) | ||
| 98 | bb_error_msg_and_die("short read"); | ||
| 99 | /* if sz == -1, bb_copyfd_XX already complained */ | ||
| 100 | exit(xfunc_error_retval); | ||
| 101 | } | ||
| 102 | |||
| 83 | off_t bb_copyfd_eof(int fd1, int fd2) | 103 | off_t bb_copyfd_eof(int fd1, int fd2) |
| 84 | { | 104 | { |
| 85 | return bb_full_fd_action(fd1, fd2, 0); | 105 | return bb_full_fd_action(fd1, fd2, 0); |
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index dff894468..9d054428f 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c | |||
| @@ -22,8 +22,8 @@ typedef struct ftp_host_info_s { | |||
| 22 | struct sockaddr_in *s_in; | 22 | struct sockaddr_in *s_in; |
| 23 | } ftp_host_info_t; | 23 | } ftp_host_info_t; |
| 24 | 24 | ||
| 25 | static char verbose_flag = 0; | 25 | static char verbose_flag; |
| 26 | static char do_continue = 0; | 26 | static char do_continue; |
| 27 | 27 | ||
| 28 | static int ftpcmd(const char *s1, const char *s2, FILE *stream, char *buf) | 28 | static int ftpcmd(const char *s1, const char *s2, FILE *stream, char *buf) |
| 29 | { | 29 | { |
| @@ -112,7 +112,9 @@ int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |||
| 112 | const char *local_path, char *server_path) | 112 | const char *local_path, char *server_path) |
| 113 | { | 113 | { |
| 114 | char buf[512]; | 114 | char buf[512]; |
| 115 | off_t filesize = 0; | 115 | /* I think 'filesize' usage here is bogus. Let's see... */ |
| 116 | //off_t filesize = -1; | ||
| 117 | #define filesize ((off_t)-1) | ||
| 116 | int fd_data; | 118 | int fd_data; |
| 117 | int fd_local = -1; | 119 | int fd_local = -1; |
| 118 | off_t beg_range = 0; | 120 | off_t beg_range = 0; |
| @@ -124,11 +126,10 @@ int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |||
| 124 | fd_data = xconnect_ftpdata(server, buf); | 126 | fd_data = xconnect_ftpdata(server, buf); |
| 125 | 127 | ||
| 126 | if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) { | 128 | if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) { |
| 127 | filesize = BB_STRTOOFF(buf + 4, NULL, 10); | 129 | //filesize = BB_STRTOOFF(buf + 4, NULL, 10); |
| 128 | if (errno || filesize < 0) | 130 | //if (errno || filesize < 0) |
| 129 | bb_error_msg_and_die("SIZE error: %s", buf + 4); | 131 | // bb_error_msg_and_die("SIZE error: %s", buf + 4); |
| 130 | } else { | 132 | } else { |
| 131 | filesize = -1; | ||
| 132 | do_continue = 0; | 133 | do_continue = 0; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| @@ -154,7 +155,8 @@ int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |||
| 154 | if (ftpcmd(buf, NULL, control_stream, buf) != 350) { | 155 | if (ftpcmd(buf, NULL, control_stream, buf) != 350) { |
| 155 | do_continue = 0; | 156 | do_continue = 0; |
| 156 | } else { | 157 | } else { |
| 157 | filesize -= beg_range; | 158 | //if (filesize != -1) |
| 159 | // filesize -= beg_range; | ||
| 158 | } | 160 | } |
| 159 | } | 161 | } |
| 160 | 162 | ||
| @@ -173,11 +175,11 @@ int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |||
| 173 | 175 | ||
| 174 | /* Copy the file */ | 176 | /* Copy the file */ |
| 175 | if (filesize != -1) { | 177 | if (filesize != -1) { |
| 176 | if (-1 == bb_copyfd_size(fd_data, fd_local, filesize)) | 178 | if (bb_copyfd_size(fd_data, fd_local, filesize) == -1) |
| 177 | exit(EXIT_FAILURE); | 179 | return EXIT_FAILURE; |
| 178 | } else { | 180 | } else { |
| 179 | if (-1 == bb_copyfd_eof(fd_data, fd_local)) | 181 | if (bb_copyfd_eof(fd_data, fd_local) == -1) |
| 180 | exit(EXIT_FAILURE); | 182 | return EXIT_FAILURE; |
| 181 | } | 183 | } |
| 182 | 184 | ||
| 183 | /* close it all down */ | 185 | /* close it all down */ |
| @@ -277,14 +279,11 @@ int ftpgetput_main(int argc, char **argv) | |||
| 277 | /* content-length of the file */ | 279 | /* content-length of the file */ |
| 278 | unsigned opt; | 280 | unsigned opt; |
| 279 | char *port = "ftp"; | 281 | char *port = "ftp"; |
| 280 | |||
| 281 | /* socket to ftp server */ | 282 | /* socket to ftp server */ |
| 282 | FILE *control_stream; | 283 | FILE *control_stream; |
| 283 | struct sockaddr_in s_in; | 284 | struct sockaddr_in s_in; |
| 284 | |||
| 285 | /* continue a prev transfer (-c) */ | 285 | /* continue a prev transfer (-c) */ |
| 286 | ftp_host_info_t *server; | 286 | ftp_host_info_t *server; |
| 287 | |||
| 288 | int (*ftp_action)(ftp_host_info_t *, FILE *, const char *, char *) = NULL; | 287 | int (*ftp_action)(ftp_host_info_t *, FILE *, const char *, char *) = NULL; |
| 289 | 288 | ||
| 290 | /* Check to see if the command is ftpget or ftput */ | 289 | /* Check to see if the command is ftpget or ftput */ |
