NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Problems unpacking sets with ftp -o



On Thu, 1 Jul 2021, RVP wrote:

Can you try the patch below?


Well, fixing this in the obvious manner seems to have uncovered
a more serious bug: stream corruption, due to, I suspect, using
stdio functions (snprintf) inside the SIGALRM handler for the
progress-bar:



$ for i in base comp games modules man misc text
  do   sudo mkdir X
       (cd X; ftp -o "| pax -zrvpe" http://localhost:8080/ftp/$i.tar.xz)
       sudo rm -rf X
  done

[...]
./usr/lib/libssl.a
./usr/lib/libssl_p.a
 42% |***********                    | 25504 KiB    3.54 MiB/s    00:09 ETA
gzip: File is corrupt
ftp: Writing `| pax -zrvpe': Broken pipe

pax: End of archive volume 1 reached
pax: ustar vol 1, 2599 files, 186306685 bytes read, 0 bytes written in 7 secs (26615240 bytes/sec)

ATTENTION! pax archive volume change required.
Ready for archive volume: 2
Input archive name or "." to quit pax.



Until that is fixed, either a) disable the progress-bar using
-V, or b) use the hack below. Apply patch to the original ftp
source.

---START---
diff -urN ftp.orig/fetch.c ftp/fetch.c
--- ftp.orig/fetch.c	2020-07-11 00:29:38.000000000 +0000
+++ ftp/fetch.c	2021-07-02 13:36:14.816477000 +0000
@@ -61,6 +61,7 @@
 #include <errno.h>
 #include <netdb.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -1641,6 +1642,9 @@
 				bufrem = MIN(chunksize, bufrem);
 			while (bufrem > 0) {
 				size_t nr = MIN((off_t)bufsize, bufrem);
+				sigset_t sig, osig;
+				sigemptyset(&sig);
+				sigaddset(&sig, SIGALRM);
 				flen = fetch_read(xferbuf, sizeof(char),
 				    nr, fin);
 				if (flen == 0) {
@@ -1650,11 +1654,14 @@
 				}
 				bytes += flen;
 				bufrem -= flen;
+				sigprocmask(SIG_BLOCK, &sig, &osig);
 				if (fwrite(xferbuf, sizeof(char), flen, fout)
 				    != flen) {
 					warn("Writing `%s'", savefile);
+					sigprocmask(SIG_SETMASK, &osig, NULL);
 					goto cleanup_fetch_url;
 				}
+				sigprocmask(SIG_SETMASK, &osig, NULL);
 				if (hash && !progress) {
 					while (bytes >= hashbytes) {
 						(void)putc('#', ttyout);
---END---

-RVP



Home | Main Index | Thread Index | Old Index