To build snarf on z/OS (formerly KA OS/390 (formerly KA MVS (formerly KA OS/360 (...)))): CC=c89 \ CPPFLAGS="-DALL_SOURCE -D_OE_SOCKETS -D_XOPEN_SOURCE_EXTENDED" \ CFLAGS="$CPPFLAGS -Wl,EDIT=NO" \ ../snarf*/configure gmake -k --jobs 5 gmake install BUGS: o Returned text files are not converted from ASCII to EBCDIC. But I'm primarily interested in binary files, and it's easy enough to pipe through iconv(1) to convert to EBCDIC. o Doesn't work for local ftp:// URLs. Of course it works for FTP through an HTTP proxy. I'll work some more on this. I can't even test it for local GOPHER URLs. o I added an ad-hoc "#if defined (__MVS__)". I know this is anathema to autoconf purists. But I'm not enough of an autoconf wizard to make the changes to the configuration scripts. o Likewise, the excessive parameter list to configure should be handled by autoconf. o I diverted all socket writes to a new function, WrSock. I could have conditionally defined this as a macro that expands simply to write() in the ASCII case and saved a small fraction of execution time and a similar increment in executable size. But I felt it might be useful, even in the ASCII case to have a single point to monitor socket writes for debugging purposes. o WrSock uses an OS/390 specific function, __etoa_l(). This limits portability to other EBCDIC systems such as Siemens BS2000. But I assume that if Martin Kraemer ever wants to port snatch to BS2000 he's clever enought to work around this. The patch: :r ! diff -ru ../orig/src ../src ======================================================================== diff -ru ../orig/src/ftp.c ../src/ftp.c --- ../orig/src/ftp.c Tue Aug 8 17:27:24 2000 +++ ../src/ftp.c Fri Nov 2 13:23:34 2001 @@ -32,7 +32,7 @@ close_quit(int sock) { if(sock) { - write(sock, "QUIT\r\n", 6); + WrSock(sock, "QUIT\r\n", 6); close(sock); } } @@ -77,7 +77,7 @@ } va_end(args); - write(sock, line, strlen(line)); + WrSock(sock, line, strlen(line)); safe_free(line); } diff -ru ../orig/src/gopher.c ../src/gopher.c --- ../orig/src/gopher.c Sun Nov 15 18:29:44 1998 +++ ../src/gopher.c Fri Nov 2 13:23:42 2001 @@ -69,7 +69,7 @@ return 0; } - write(sock, request, strlen(request)); + WrSock(sock, request, strlen(request)); /* never know the size of a gopher file */ return dump_data(rsrc, sock, out); diff -ru ../orig/src/http.c ../src/http.c --- ../orig/src/http.c Tue Aug 8 18:33:30 2000 +++ ../src/http.c Fri Nov 2 13:23:58 2001 @@ -163,13 +163,19 @@ total_read += bytes_read; header = strconcat(header, buf, NULL); + /* Strangely enough, the octal escapes here are more + * portable than "\r\n" because the socket always talks + * ASCII, but the host's character set may be NOT_ASCII. + */ if( total_read > 1) { - if( strcmp(header + (total_read - 2), "\n\n") == 0 ) + if( strcmp(header + (total_read - 2), + "\012\012") == 0 ) break; } if( total_read > 3 ) { - if( strcmp(header + (total_read - 4), "\r\n\r\n") + if( strcmp(header + (total_read - 4), + "\015\012\015\012") == 0 ) break; } @@ -344,7 +350,7 @@ u->file = strdup(u->full_url); request = get_request(rsrc); - write(sock, request, strlen(request)); + WrSock(sock, request, strlen(request)); } else /* no proxy */ { @@ -352,7 +358,7 @@ return 0; request = get_request(rsrc); - write(sock, request, strlen(request)); + WrSock(sock, request, strlen(request)); } @@ -372,8 +378,11 @@ return 0; } - if( ! (buf[0] == 'H' && buf[1] == 'T' - && buf[2] == 'T' && buf[3] == 'P') ) { + /* Strangely enough, the octal escapes here are more + * portable than "HTTP" because the socket always talks + * ASCII, but the host's character set may be NOT_ASCII. + */ + if( memcmp(buf, "\110\124\124\120", 4) ) { if ((rsrc->options & OPT_RESUME) && rsrc->outfile_offset) { report(WARN, diff -ru ../orig/src/util.c ../src/util.c --- ../orig/src/util.c Tue Aug 8 18:12:39 2000 +++ ../src/util.c Fri Nov 2 13:28:51 2001 @@ -207,6 +207,22 @@ int debug_enabled = 0; +int +WrSock(int sock, char *buf, int len) +{ + if (debug_enabled) { + fprintf(stderr, "%s: %d:", __FILE__, __LINE__); + fprintf(stderr, "Request: %s\n", buf); } +#if NOT_ASCII + /* Note: + * This makes MVS the only NOT_ASCII platform supported. + * This destroys the input buffer. + */ + __etoa_l(buf, len); +#endif /* NOT_ASCII */ + write(sock, buf, len); +} + Progress * progress_new(void) { diff -ru ../orig/src/util.h ../src/util.h --- ../orig/src/util.h Tue Aug 8 18:12:25 2000 +++ ../src/util.h Fri Nov 2 13:24:56 2001 @@ -1,5 +1,11 @@ /* -*- mode: C; c-basic-offset: 8; indent-tabs-mode: nil; tab-width: 8 -*- */ +#define NOT_ASCII ( '0' != 48 ) + +#if defined __MVS__ +#include /* for htons() */ +#endif /* __MVS__ */ + #include #include #include "url.h" @@ -26,6 +32,8 @@ enum report_levels { DEBUG, WARN, ERR }; #ifdef PROTOTYPES + +int WrSock(int, char*, int); Progress *progress_new(void); int progress_init(Progress *, UrlResource *, long int); ========================================================================