[BACK]Return to fetch.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ftp

Diff for /src/usr.bin/ftp/fetch.c between version 1.175 and 1.176

version 1.175, 2019/10/23 16:47:53 version 1.176, 2019/11/03 19:26:15
Line 74 
Line 74 
 char            hextochar(const char *);  char            hextochar(const char *);
 char            *urldecode(const char *);  char            *urldecode(const char *);
 char            *recode_credentials(const char *_userinfo);  char            *recode_credentials(const char *_userinfo);
 int             ftp_printf(FILE *, struct tls *, const char *, ...) __attribute__((format(printf, 3, 4)));  char            *ftp_readline(FILE *, size_t *);
 char            *ftp_readline(FILE *, struct tls *, size_t *);  
 size_t          ftp_read(FILE *, struct tls *, char *, size_t);  
 void            ftp_close(FILE **fin, struct tls **tls, volatile int *fd);  void            ftp_close(FILE **fin, struct tls **tls, volatile int *fd);
   const char      *sockerror(struct tls *);
 #ifndef NOSSL  #ifndef NOSSL
 int             proxy_connect(int, char *, char *);  int             proxy_connect(int, char *, char *);
 int             SSL_vprintf(struct tls *, const char *, va_list);  int             stdio_tls_write_wrapper(void *, const char *, int);
 char            *SSL_readline(struct tls *, size_t *);  int             stdio_tls_read_wrapper(void *, char *, int);
 #endif /* !NOSSL */  #endif /* !NOSSL */
   
 #define FTP_URL         "ftp://"        /* ftp URL prefix */  #define FTP_URL         "ftp://"        /* ftp URL prefix */
Line 638 
Line 637 
                         fprintf(ttyout, "SSL failure: %s\n", tls_error(tls));                          fprintf(ttyout, "SSL failure: %s\n", tls_error(tls));
                         goto cleanup_url_get;                          goto cleanup_url_get;
                 }                  }
                   if (tls_handshake(tls) != 0) {
                           fprintf(ttyout, "SSL failure: %s\n", tls_error(tls));
                           goto cleanup_url_get;
                   }
                   fin = funopen(tls, stdio_tls_read_wrapper,
                       stdio_tls_write_wrapper, NULL, NULL);
         } else {          } else {
                 fin = fdopen(fd, "r+");                  fin = fdopen(fd, "r+");
                 fd = -1;                  fd = -1;
Line 682 
Line 687 
                  * the original URI (path).                   * the original URI (path).
                  */                   */
                 if (credentials)                  if (credentials)
                         ftp_printf(fin, tls, "GET %s HTTP/1.0\r\n"                          fprintf(fin, "GET %s HTTP/1.0\r\n"
                             "Proxy-Authorization: Basic %s\r\n"                              "Proxy-Authorization: Basic %s\r\n"
                             "Host: %s\r\n%s%s\r\n\r\n",                              "Host: %s\r\n%s%s\r\n\r\n",
                             epath, credentials,                              epath, credentials,
                             proxyhost, buf ? buf : "", httpuseragent);                              proxyhost, buf ? buf : "", httpuseragent);
                 else                  else
                         ftp_printf(fin, tls, "GET %s HTTP/1.0\r\n"                          fprintf(fin, "GET %s HTTP/1.0\r\n"
                             "Host: %s\r\n%s%s\r\n\r\n",                              "Host: %s\r\n%s%s\r\n\r\n",
                             epath, proxyhost, buf ? buf : "", httpuseragent);                              epath, proxyhost, buf ? buf : "", httpuseragent);
         } else {          } else {
Line 706 
Line 711 
 #endif  /* SMALL */  #endif  /* SMALL */
 #ifndef NOSSL  #ifndef NOSSL
                 if (credentials) {                  if (credentials) {
                         ftp_printf(fin, tls,                          fprintf(fin,
                             "GET /%s %s\r\nAuthorization: Basic %s\r\nHost: ",                              "GET /%s %s\r\nAuthorization: Basic %s\r\nHost: ",
                             epath, restart_point ?                              epath, restart_point ?
                             "HTTP/1.1\r\nConnection: close" : "HTTP/1.0",                              "HTTP/1.1\r\nConnection: close" : "HTTP/1.0",
Line 715 
Line 720 
                         credentials = NULL;                          credentials = NULL;
                 } else                  } else
 #endif  /* NOSSL */  #endif  /* NOSSL */
                         ftp_printf(fin, tls, "GET /%s %s\r\nHost: ", epath,                          fprintf(fin, "GET /%s %s\r\nHost: ", epath,
 #ifndef SMALL  #ifndef SMALL
                             restart_point ? "HTTP/1.1\r\nConnection: close" :                              restart_point ? "HTTP/1.1\r\nConnection: close" :
 #endif /* !SMALL */  #endif /* !SMALL */
                             "HTTP/1.0");                              "HTTP/1.0");
                 if (proxyhost) {                  if (proxyhost) {
                         ftp_printf(fin, tls, "%s", proxyhost);                          fprintf(fin, "%s", proxyhost);
                         port = NULL;                          port = NULL;
                 } else if (strchr(host, ':')) {                  } else if (strchr(host, ':')) {
                         /*                          /*
Line 733 
Line 738 
                                 errx(1, "Can't allocate memory.");                                  errx(1, "Can't allocate memory.");
                         if ((p = strchr(h, '%')) != NULL)                          if ((p = strchr(h, '%')) != NULL)
                                 *p = '\0';                                  *p = '\0';
                         ftp_printf(fin, tls, "[%s]", h);                          fprintf(fin, "[%s]", h);
                         free(h);                          free(h);
                 } else                  } else
                         ftp_printf(fin, tls, "%s", host);                          fprintf(fin, "%s", host);
   
                 /*                  /*
                  * Send port number only if it's specified and does not equal                   * Send port number only if it's specified and does not equal
Line 745 
Line 750 
                  */                   */
 #ifndef NOSSL  #ifndef NOSSL
                 if (port && strcmp(port, (ishttpsurl ? "443" : "80")) != 0)                  if (port && strcmp(port, (ishttpsurl ? "443" : "80")) != 0)
                         ftp_printf(fin, tls, ":%s", port);                          fprintf(fin, ":%s", port);
                 if (restart_point)                  if (restart_point)
                         ftp_printf(fin, tls, "\r\nRange: bytes=%lld-",                          fprintf(fin, "\r\nRange: bytes=%lld-",
                                 (long long)restart_point);                                  (long long)restart_point);
 #else /* !NOSSL */  #else /* !NOSSL */
                 if (port && strcmp(port, "80") != 0)                  if (port && strcmp(port, "80") != 0)
                         ftp_printf(fin, tls, ":%s", port);                          fprintf(fin, ":%s", port);
 #endif /* !NOSSL */  #endif /* !NOSSL */
                 ftp_printf(fin, tls, "\r\n%s%s\r\n\r\n",                  fprintf(fin, "\r\n%s%s\r\n\r\n",
                     buf ? buf : "", httpuseragent);                      buf ? buf : "", httpuseragent);
         }          }
         free(epath);          free(epath);
Line 763 
Line 768 
 #endif /* !NOSSL */  #endif /* !NOSSL */
         buf = NULL;          buf = NULL;
   
         if (fin != NULL && fflush(fin) == EOF) {          if (fflush(fin) == EOF) {
                 warn("Writing HTTP request");                  warnx("Writing HTTP request: %s", sockerror(tls));
                 goto cleanup_url_get;                  goto cleanup_url_get;
         }          }
         if ((buf = ftp_readline(fin, tls, &len)) == NULL) {          if ((buf = ftp_readline(fin, &len)) == NULL) {
                 warn("Receiving HTTP reply");                  warnx("Receiving HTTP reply: %s", sockerror(tls));
                 goto cleanup_url_get;                  goto cleanup_url_get;
         }          }
   
Line 842 
Line 847 
         filesize = -1;          filesize = -1;
   
         for (;;) {          for (;;) {
                 if ((buf = ftp_readline(fin, tls, &len)) == NULL) {                  if ((buf = ftp_readline(fin, &len)) == NULL) {
                         warn("Receiving HTTP reply");                          warnx("Receiving HTTP reply: %s", sockerror(tls));
                         goto cleanup_url_get;                          goto cleanup_url_get;
                 }                  }
   
Line 1004 
Line 1009 
         len = 1;          len = 1;
         oldinti = signal(SIGINFO, psummary);          oldinti = signal(SIGINFO, psummary);
         while (len > 0) {          while (len > 0) {
                 len = ftp_read(fin, tls, buf, buflen);                  len = fread(buf, 1, buflen, fin);
                 bytes += len;                  bytes += len;
                 for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) {                  for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) {
                         if ((i = write(out, cp, wlen)) == -1) {                          if ((i = write(out, cp, wlen)) == -1) {
Line 1031 
Line 1036 
                 (void)fflush(ttyout);                  (void)fflush(ttyout);
         }          }
         if (len != 0) {          if (len != 0) {
                 warn("Reading from socket");                  warnx("Reading from socket: %s", sockerror(tls));
                 goto cleanup_url_get;                  goto cleanup_url_get;
         }          }
         progressmeter(1, NULL);          progressmeter(1, NULL);
Line 1514 
Line 1519 
 }  }
   
 char *  char *
 ftp_readline(FILE *fp, struct tls *tls, size_t *lenp)  ftp_readline(FILE *fp, size_t *lenp)
 {  {
         if (fp != NULL)          return fparseln(fp, lenp, NULL, "\0\0\0", 0);
                 return fparseln(fp, lenp, NULL, "\0\0\0", 0);  
 #ifndef NOSSL  
         else if (tls != NULL)  
                 return SSL_readline(tls, lenp);  
 #endif /* !NOSSL */  
         else  
                 return NULL;  
 }  }
   
 size_t  
 ftp_read(FILE *fp, struct tls *tls, char *buf, size_t len)  
 {  
 #ifndef NOSSL  
         ssize_t tret;  
 #endif  
         size_t ret = 0;  
   
         if (fp != NULL)  
                 ret = fread(buf, sizeof(char), len, fp);  
 #ifndef NOSSL  
         else if (tls != NULL) {  
                 do {  
                         tret = tls_read(tls, buf, len);  
                 } while (tret == TLS_WANT_POLLIN || tret == TLS_WANT_POLLOUT);  
                 if (tret == -1)  
                         errx(1, "SSL read error: %s", tls_error(tls));  
                 ret = (size_t)tret;  
         }  
 #endif /* !NOSSL */  
         return (ret);  
 }  
   
 int  
 ftp_printf(FILE *fp, struct tls *tls, const char *fmt, ...)  
 {  
         int ret;  
         va_list ap;  
   
         va_start(ap, fmt);  
   
         if (fp != NULL)  
                 ret = vfprintf(fp, fmt, ap);  
 #ifndef NOSSL  
         else if (tls != NULL)  
                 ret = SSL_vprintf(tls, fmt, ap);  
 #endif /* !NOSSL */  
         else  
                 ret = 0;  
   
         va_end(ap);  
 #ifndef SMALL  
         if (debug) {  
                 va_start(ap, fmt);  
                 ret = vfprintf(ttyout, fmt, ap);  
                 va_end(ap);  
         }  
 #endif /* !SMALL */  
         return (ret);  
 }  
   
 void  void
 ftp_close(FILE **fin, struct tls **tls, volatile int *fd)  ftp_close(FILE **fin, struct tls **tls, volatile int *fd)
 {  {
Line 1593 
Line 1540 
                 tls_free(*tls);                  tls_free(*tls);
                 *tls = NULL;                  *tls = NULL;
         }          }
           if (*fd != -1) {
                   close(*fd);
                   *fd = -1;
           }
 #endif  #endif
         if (*fin != NULL) {          if (*fin != NULL) {
                 fclose(*fin);                  fclose(*fin);
                 *fin = NULL;                  *fin = NULL;
         }          }
         if (*fd != -1) {  
                 close(*fd);  
                 *fd = -1;  
         }  
 }  }
   
 #ifndef NOSSL  const char *
 int  sockerror(struct tls *tls)
 SSL_vprintf(struct tls *tls, const char *fmt, va_list ap)  
 {  {
         char *string, *buf;          int     save_errno = errno;
         size_t len;  #ifndef NOSSL
         int ret;          if (tls != NULL) {
                   const char *tlserr = tls_error(tls);
         if ((ret = vasprintf(&string, fmt, ap)) == -1)                  if (tlserr != NULL)
                 return ret;                          return tlserr;
         buf = string;  
         len = ret;  
         while (len > 0) {  
                 ret = tls_write(tls, buf, len);  
                 if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)  
                         continue;  
                 if (ret == -1)  
                         errx(1, "SSL write error: %s", tls_error(tls));  
                 buf += ret;  
                 len -= ret;  
         }          }
         free(string);  #endif
         return ret;          return strerror(save_errno);
 }  }
   
 char *  #ifndef NOSSL
 SSL_readline(struct tls *tls, size_t *lenp)  
 {  
         size_t i, len;  
         char *buf, *q, c;  
         int ret;  
   
         len = 128;  
         if ((buf = malloc(len)) == NULL)  
                 errx(1, "Can't allocate memory for transfer buffer");  
         for (i = 0; ; i++) {  
                 if (i >= len - 1) {  
                         if ((q = reallocarray(buf, len, 2)) == NULL)  
                                 errx(1, "Can't expand transfer buffer");  
                         buf = q;  
                         len *= 2;  
                 }  
                 do {  
                         ret = tls_read(tls, &c, 1);  
                 } while (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT);  
                 if (ret == -1)  
                         errx(1, "SSL read error: %s", tls_error(tls));  
   
                 buf[i] = c;  
                 if (c == '\n') {  
                         buf[i] = '\0';  
                         break;  
                 }  
         }  
         *lenp = i;  
         return (buf);  
 }  
   
 int  int
 proxy_connect(int socket, char *host, char *cookie)  proxy_connect(int socket, char *host, char *cookie)
 {  {
Line 1702 
Line 1606 
         read(socket, &buf, sizeof(buf)); /* only proxy header XXX: error handling? */          read(socket, &buf, sizeof(buf)); /* only proxy header XXX: error handling? */
         free(connstr);          free(connstr);
         return(200);          return(200);
   }
   
   int
   stdio_tls_write_wrapper(void *arg, const char *buf, int len)
   {
           struct tls *tls = arg;
           ssize_t ret;
   
           do {
                   ret = tls_write(tls, buf, len);
           } while (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT);
   
           return ret;
   }
   
   int
   stdio_tls_read_wrapper(void *arg, char *buf, int len)
   {
           struct tls *tls = arg;
           ssize_t ret;
   
           do {
                   ret = tls_read(tls, buf, len);
           } while (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT);
   
           return ret;
 }  }
 #endif /* !NOSSL */  #endif /* !NOSSL */

Legend:
Removed from v.1.175  
changed lines
  Added in v.1.176