[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.39 and 1.40

version 1.39, 2002/05/30 06:51:46 version 1.40, 2002/11/08 03:30:17
Line 66 
Line 66 
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   #include <util.h>
   
 #include "ftp_var.h"  #include "ftp_var.h"
   
Line 102 
Line 103 
 {  {
         struct addrinfo hints, *res0, *res;          struct addrinfo hints, *res0, *res;
         int error;          int error;
         int i, isftpurl, isfileurl;          int i, isftpurl, isfileurl, isredirect;
         volatile int s, out;          volatile int s, out;
         size_t len;          size_t len;
         char c, *cp, *ep, *portnum, *path, buf[4096];          char *cp, *ep, *portnum, *path;
         char pbuf[NI_MAXSERV];          char pbuf[NI_MAXSERV];
         const char * volatile savefile;          const char * volatile savefile;
         char *line, *host, *port;          char *line, *host, *port, *buf;
         char * volatile proxy;          char * volatile proxy;
         char *hosttail;          char *hosttail;
         volatile sig_t oldintr;          volatile sig_t oldintr;
         off_t hashbytes;          off_t hashbytes;
         char *cause = "unknown";          char *cause = "unknown";
           FILE *fin;
           int rval;
   
         s = -1;          s = -1;
         proxy = NULL;          proxy = NULL;
           fin = NULL;
           buf = NULL;
         isftpurl = 0;          isftpurl = 0;
         isfileurl = 0;          isfileurl = 0;
           isredirect = 0;
           rval = -1;
   
         line = strdup(origline);          line = strdup(origline);
         if (line == NULL)          if (line == NULL)
Line 224 
Line 231 
                 bytes = 0;                  bytes = 0;
                 hashbytes = mark;                  hashbytes = mark;
                 progressmeter(-1);                  progressmeter(-1);
   
                   if ((buf = malloc(4096)) == NULL)
                           errx(1, "Can't allocate memory for transfer buffer\n");
   
                 /* Finally, suck down the file. */                  /* Finally, suck down the file. */
                 i = 0;                  i = 0;
                 while ((len = read(s, buf, sizeof(buf))) > 0) {                  while ((len = read(s, buf, 4096)) > 0) {
                         bytes += len;                          bytes += len;
                         for (cp = buf; len > 0; len -= i, cp += i) {                          for (cp = buf; len > 0; len -= i, cp += i) {
                                 if ((i = write(out, cp, len)) == -1) {                                  if ((i = write(out, cp, len)) == -1) {
Line 260 
Line 270 
                         fputs("Successfully retrieved file.\n", ttyout);                          fputs("Successfully retrieved file.\n", ttyout);
                 (void)signal(SIGINT, oldintr);                  (void)signal(SIGINT, oldintr);
   
                 close(s);                  rval = 0;
                 if (out != fileno(stdout))                  goto cleanup_url_get;
                         close(out);  
                 if (proxy)  
                         free(proxy);  
                 free(line);  
                 return (0);  
         }          }
   
         if (*host == '[' && (hosttail = strrchr(host, ']')) != NULL &&          if (*host == '[' && (hosttail = strrchr(host, ']')) != NULL &&
Line 294 
Line 299 
                  * If the services file is corrupt/missing, fall back                   * If the services file is corrupt/missing, fall back
                  * on our hard-coded defines.                   * on our hard-coded defines.
                  */                   */
                 char pbuf[NI_MAXSERV];  
   
                 snprintf(pbuf, sizeof(pbuf), "%d", HTTP_PORT);                  snprintf(pbuf, sizeof(pbuf), "%d", HTTP_PORT);
                 error = getaddrinfo(host, pbuf, &hints, &res0);                  error = getaddrinfo(host, pbuf, &hints, &res0);
         }          }
Line 306 
Line 309 
   
         s = -1;          s = -1;
         for (res = res0; res; res = res->ai_next) {          for (res = res0; res; res = res->ai_next) {
                 getnameinfo(res->ai_addr, res->ai_addrlen, buf, sizeof(buf),                  getnameinfo(res->ai_addr, res->ai_addrlen, pbuf, sizeof(pbuf),
                         NULL, 0, NI_NUMERICHOST);                          NULL, 0, NI_NUMERICHOST);
                 fprintf(ttyout, "Trying %s...\n", buf);                  fprintf(ttyout, "Trying %s...\n", pbuf);
   
                 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);                  s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
                 if (s == -1) {                  if (s == -1) {
Line 341 
Line 344 
                 goto cleanup_url_get;                  goto cleanup_url_get;
         }          }
   
           fin = fdopen(s, "r+");
   
         /*          /*
          * Construct and send the request.  We're expecting a return           * Construct and send the request. Proxy requests don't want leading /.
          * status of "200". Proxy requests don't want leading /.  
          */           */
         if (proxy) {          if (proxy) {
                 /*                  /*
Line 353 
Line 357 
                 if (verbose)                  if (verbose)
                         fprintf(ttyout, "Requesting %s (via %s)\n",                          fprintf(ttyout, "Requesting %s (via %s)\n",
                             origline, proxyenv);                              origline, proxyenv);
                 snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n%s\r\n\r\n", path, HTTP_USER_AGENT);                  fprintf(fin, "GET %s HTTP/1.0\r\n%s\r\n\r\n", path, HTTP_USER_AGENT);
         } else {          } else {
                 if (verbose)                  if (verbose)
                         fprintf(ttyout, "Requesting %s\n", origline);                          fprintf(ttyout, "Requesting %s\n", origline);
Line 372 
Line 376 
                          * send them the port number.                           * send them the port number.
                          */                           */
                         if (port && strcmp(port, "80") != 0)                          if (port && strcmp(port, "80") != 0)
                                 snprintf(buf, sizeof(buf),                                  fprintf(fin, "GET /%s HTTP/1.0\r\nHost: [%s]:%s\r\n%s\r\n\r\n",
                                     "GET /%s HTTP/1.0\r\nHost: [%s]:%s\r\n%s\r\n\r\n",  
                                     path, h, port, HTTP_USER_AGENT);                                      path, h, port, HTTP_USER_AGENT);
                         else                          else
                                 snprintf(buf, sizeof(buf),                                  fprintf(fin, "GET /%s HTTP/1.0\r\nHost: [%s]\r\n%s\r\n\r\n",
                                     "GET /%s HTTP/1.0\r\nHost: [%s]\r\n%s\r\n\r\n",  
                                     path, h, HTTP_USER_AGENT);                                      path, h, HTTP_USER_AGENT);
                         free(h);                          free(h);
                 } else {                  } else {
                         if (port && strcmp(port, "80") != 0)                          if (port && strcmp(port, "80") != 0)
                                 snprintf(buf, sizeof(buf),                                  fprintf(fin, "GET /%s HTTP/1.0\r\nHost: %s:%s\r\n%s\r\n\r\n",
                                     "GET /%s HTTP/1.0\r\nHost: %s:%s\r\n%s\r\n\r\n",  
                                     path, host, port, HTTP_USER_AGENT);                                      path, host, port, HTTP_USER_AGENT);
                         else                          else
                                 snprintf(buf, sizeof(buf),                                  fprintf(fin, "GET /%s HTTP/1.0\r\nHost: %s\r\n%s\r\n\r\n",
                                     "GET /%s HTTP/1.0\r\nHost: %s\r\n%s\r\n\r\n",  
                                     path, host, HTTP_USER_AGENT);                                      path, host, HTTP_USER_AGENT);
                 }                  }
         }          }
         len = strlen(buf);          if (fflush(fin) == EOF) {
         if (debug)  
                 fprintf(ttyout, "Sending request:\n%s", buf);  
         if (write(s, buf, len) < len) {  
                 warn("Writing HTTP request");                  warn("Writing HTTP request");
                 goto cleanup_url_get;                  goto cleanup_url_get;
         }          }
         memset(buf, 0, sizeof(buf));  
         for (cp = buf; cp < buf + sizeof(buf); ) {          if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0)) == NULL) {
                 if (read(s, cp, 1) != 1)                  warn("Receiving HTTP reply");
                         goto improper;                  goto cleanup_url_get;
                 if (*cp == '\r')  
                         continue;  
                 if (*cp == '\n')  
                         break;  
                 cp++;  
         }          }
         buf[sizeof(buf) - 1] = '\0';            /* sanity */  
           while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
                   buf[--len] = '\0';
           if (debug)
                   fprintf(ttyout, "received '%s'\n", buf);
   
         cp = strchr(buf, ' ');          cp = strchr(buf, ' ');
         if (cp == NULL)          if (cp == NULL)
                 goto improper;                  goto improper;
         else          else
                 cp++;                  cp++;
         if (strncmp(cp, "200", 3)) {          if (strncmp(cp, "301", 3) == 0 || strncmp(cp, "302", 3) == 0) {
                   isredirect++;
           } else if (strncmp(cp, "200", 3)) {
                 warnx("Error retrieving file: %s", cp);                  warnx("Error retrieving file: %s", cp);
                 goto cleanup_url_get;                  goto cleanup_url_get;
         }          }
Line 422 
Line 421 
         /*          /*
          * Read the rest of the header.           * Read the rest of the header.
          */           */
         memset(buf, 0, sizeof(buf));          free(buf);
         c = '\0';          filesize = -1;
         for (cp = buf; cp < buf + sizeof(buf); ) {  
                 if (read(s, cp, 1) != 1)          while (1) {
                         goto improper;                  if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0)) == NULL) {
                 if (*cp == '\r')                          warn("Receiving HTTP reply");
                         continue;                          goto cleanup_url_get;
                 if (*cp == '\n' && c == '\n')                  }
                   while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
                           buf[--len] = '\0';
                   if (len == 0)
                         break;                          break;
                 c = *cp;                  if (debug)
                 cp++;                          fprintf(ttyout, "received '%s'\n", buf);
         }  
         buf[sizeof(buf) - 1] = '\0';            /* sanity */  
   
         /* Look for the "Content-length: " header.  */                  /* Look for some headers */
                   cp = buf;
 #define CONTENTLEN "Content-Length: "  #define CONTENTLEN "Content-Length: "
         for (cp = buf; *cp != '\0'; cp++) {                  if (strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0) {
                 if (tolower(*cp) == 'c' &&                          cp += sizeof(CONTENTLEN) - 1;
                     strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0)                          filesize = strtol(cp, &ep, 10);
                         break;                          if (filesize < 1 || *ep != '\0')
                                   goto improper;
   #define LOCATION "Location: "
                   } else if (isredirect &&
                       strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) {
                           cp += sizeof(LOCATION) - 1;
                           if (verbose)
                                   fprintf(ttyout, "Redirected to %s\n", cp);
                           if (fin != NULL)
                                   fclose(fin);
                           else if (s != -1)
                                   close(s);
                           if (proxy)
                                   free(proxy);
                           free(line);
                           rval = url_get(cp, proxyenv, outfile);
                           if (buf)
                                   free(buf);
                           return (rval);
                   }
         }          }
         if (*cp != '\0') {          free(buf);
                 cp += sizeof(CONTENTLEN) - 1;  
                 ep = strchr(cp, '\n');  
                 if (ep == NULL)  
                         goto improper;  
                 else  
                         *ep = '\0';  
                 filesize = strtol(cp, &ep, 10);  
                 if (filesize < 1 || *ep != '\0')  
                         goto improper;  
         } else  
                 filesize = -1;  
   
         /* Open the output file.  */          /* Open the output file.  */
         if (strcmp(savefile, "-") != 0) {          if (strcmp(savefile, "-") != 0) {
Line 480 
Line 489 
         progressmeter(-1);          progressmeter(-1);
   
         /* Finally, suck down the file. */          /* Finally, suck down the file. */
           if ((buf = malloc(4096)) == NULL)
                   errx(1, "Can't allocate memory for transfer buffer\n");
         i = 0;          i = 0;
         while ((len = read(s, buf, sizeof(buf))) > 0) {          while ((len = fread(buf, sizeof(char), 4096, fin)) > 0) {
                 bytes += len;                  bytes += len;
                 for (cp = buf; len > 0; len -= i, cp += i) {                  for (cp = buf; len > 0; len -= i, cp += i) {
                         if ((i = write(out, cp, len)) == -1) {                          if ((i = write(out, cp, len)) == -1) {
Line 520 
Line 531 
                 fputs("Successfully retrieved file.\n", ttyout);                  fputs("Successfully retrieved file.\n", ttyout);
         (void)signal(SIGINT, oldintr);          (void)signal(SIGINT, oldintr);
   
         close(s);          rval = 0;
         if (out != fileno(stdout))          goto cleanup_url_get;
                 close(out);  
         if (proxy)  
                 free(proxy);  
         free(line);  
         return (0);  
   
 noftpautologin:  noftpautologin:
         warnx(          warnx(
Line 537 
Line 543 
         warnx("Improper response from %s", host);          warnx("Improper response from %s", host);
   
 cleanup_url_get:  cleanup_url_get:
         if (s != -1)          if (fin != NULL)
                   fclose(fin);
           else if (s != -1)
                 close(s);                  close(s);
           if (buf)
                   free(buf);
         if (proxy)          if (proxy)
                 free(proxy);                  free(proxy);
         free(line);          free(line);
         return (-1);          return (rval);
 }  }
   
 /*  /*
Line 781 
Line 791 
                         setpeer(xargc, xargv);                          setpeer(xargc, xargv);
                         autologin = oautologin;                          autologin = oautologin;
                         if ((connected == 0) ||                          if ((connected == 0) ||
                             ((connected == 1) && !login(host, user, pass))) {                              ((connected == 1) && !ftp_login(host, user, pass))) {
                                 warnx("Can't connect or login to host `%s'",                                  warnx("Can't connect or login to host `%s'",
                                     host);                                      host);
                                 rval = argpos + 1;                                  rval = argpos + 1;

Legend:
Removed from v.1.39  
changed lines
  Added in v.1.40