⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftp.c

📁 Wget很好的处理了http和ftp的下载,很值得学习的经典代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* FTPRERR */      switch (err)        {        case FTPRERR:          logputs (LOG_VERBOSE, "\n");          logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));          fd_close (csock);          con->csock = -1;          return err;        case FTPSRVERR :          /* PWD unsupported -- assume "/". */          xfree_null (con->id);          con->id = xstrdup ("/");          break;        case FTPOK:          /* Everything is OK.  */          break;        default:          abort ();        }      /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".         Convert it to "/INITIAL/FOLDER" */       if (con->rs == ST_VMS)        {          char *path = strchr (con->id, '[');          char *pathend = path ? strchr (path + 1, ']') : NULL;          if (!path || !pathend)            DEBUGP (("Initial VMS directory not in the form [...]!\n"));          else            {              char *idir = con->id;              DEBUGP (("Preprocessing the initial VMS directory\n"));              DEBUGP (("  old = '%s'\n", con->id));              /* We do the conversion in-place by copying the stuff                 between [ and ] to the beginning, and changing dots                 to slashes at the same time.  */              *idir++ = '/';              for (++path; path < pathend; path++, idir++)                *idir = *path == '.' ? '/' : *path;              *idir = '\0';              DEBUGP (("  new = '%s'\n\n", con->id));            }        }      if (!opt.server_response)        logputs (LOG_VERBOSE, _("done.\n"));      /* Fifth: Set the FTP type.  */      type_char = ftp_process_type (u->params);      if (!opt.server_response)        logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);      err = ftp_type (csock, type_char);      /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */      switch (err)        {        case FTPRERR:          logputs (LOG_VERBOSE, "\n");          logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));          fd_close (csock);          con->csock = -1;          return err;        case WRITEFAILED:          logputs (LOG_VERBOSE, "\n");          logputs (LOG_NOTQUIET,                   _("Write failed, closing control connection.\n"));          fd_close (csock);          con->csock = -1;          return err;        case FTPUNKNOWNTYPE:          logputs (LOG_VERBOSE, "\n");          logprintf (LOG_NOTQUIET,                     _("Unknown type `%c', closing control connection.\n"),                     type_char);          fd_close (csock);          con->csock = -1;          return err;        case FTPOK:          /* Everything is OK.  */          break;        default:          abort ();        }      if (!opt.server_response)        logputs (LOG_VERBOSE, _("done.  "));    } /* do login */  if (cmd & DO_CWD)    {      if (!*u->dir)        logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));      else        {          char *target = u->dir;          DEBUGP (("changing working directory\n"));          /* Change working directory.  To change to a non-absolute             Unix directory, we need to prepend initial directory             (con->id) to it.  Absolute directories "just work".             A relative directory is one that does not begin with '/'             and, on non-Unix OS'es, one that doesn't begin with             "[a-z]:".             This is not done for OS400, which doesn't use             "/"-delimited directories, nor does it support directory             hierarchies.  "CWD foo" followed by "CWD bar" leaves us             in "bar", not in "foo/bar", as would be customary             elsewhere.  */          if (target[0] != '/'              && !(con->rs != ST_UNIX                   && ISALPHA (target[0])                   && target[1] == ':')              && con->rs != ST_OS400)            {              int idlen = strlen (con->id);              char *ntarget, *p;              /* Strip trailing slash(es) from con->id. */              while (idlen > 0 && con->id[idlen - 1] == '/')                --idlen;              p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);              memcpy (p, con->id, idlen);              p += idlen;              *p++ = '/';              strcpy (p, target);              DEBUGP (("Prepended initial PWD to relative path:\n"));              DEBUGP (("   pwd: '%s'\n   old: '%s'\n  new: '%s'\n",                       con->id, target, ntarget));              target = ntarget;            }          /* If the FTP host runs VMS, we will have to convert the absolute             directory path in UNIX notation to absolute directory path in             VMS notation as VMS FTP servers do not like UNIX notation of             absolute paths.  "VMS notation" is [dir.subdir.subsubdir]. */          if (con->rs == ST_VMS)            {              char *tmpp;              char *ntarget = (char *)alloca (strlen (target) + 2);              /* We use a converted initial dir, so directories in                 TARGET will be separated with slashes, something like                 "/INITIAL/FOLDER/DIR/SUBDIR".  Convert that to                 "[INITIAL.FOLDER.DIR.SUBDIR]".  */              strcpy (ntarget, target);              assert (*ntarget == '/');              *ntarget = '[';              for (tmpp = ntarget + 1; *tmpp; tmpp++)                if (*tmpp == '/')                  *tmpp = '.';              *tmpp++ = ']';              *tmpp = '\0';              DEBUGP (("Changed file name to VMS syntax:\n"));              DEBUGP (("  Unix: '%s'\n  VMS: '%s'\n", target, ntarget));              target = ntarget;            }          if (!opt.server_response)            logprintf (LOG_VERBOSE, "==> CWD %s ... ", escnonprint (target));          err = ftp_cwd (csock, target);          /* FTPRERR, WRITEFAILED, FTPNSFOD */          switch (err)            {            case FTPRERR:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));              fd_close (csock);              con->csock = -1;              return err;            case WRITEFAILED:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET,                       _("Write failed, closing control connection.\n"));              fd_close (csock);              con->csock = -1;              return err;            case FTPNSFOD:              logputs (LOG_VERBOSE, "\n");              logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),                         escnonprint (u->dir));              fd_close (csock);              con->csock = -1;              return err;            case FTPOK:              break;            default:              abort ();            }          if (!opt.server_response)            logputs (LOG_VERBOSE, _("done.\n"));        }    }  else /* do not CWD */    logputs (LOG_VERBOSE, _("==> CWD not required.\n"));  if ((cmd & DO_RETR) && *len == 0)    {      if (opt.verbose)        {          if (!opt.server_response)            logprintf (LOG_VERBOSE, "==> SIZE %s ... ", escnonprint (u->file));        }      err = ftp_size (csock, u->file, len);      /* FTPRERR */      switch (err)        {        case FTPRERR:        case FTPSRVERR:          logputs (LOG_VERBOSE, "\n");          logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));          fd_close (csock);          con->csock = -1;          return err;        case FTPOK:          /* Everything is OK.  */          break;        default:          abort ();        }        if (!opt.server_response)          logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),                     number_to_static_string (*len));    }  /* If anything is to be retrieved, PORT (or PASV) must be sent.  */  if (cmd & (DO_LIST | DO_RETR))    {      if (opt.ftp_pasv)        {          ip_address passive_addr;          int        passive_port;          err = ftp_do_pasv (csock, &passive_addr, &passive_port);          /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */          switch (err)            {            case FTPRERR:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));              fd_close (csock);              con->csock = -1;              return err;            case WRITEFAILED:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET,                       _("Write failed, closing control connection.\n"));              fd_close (csock);              con->csock = -1;              return err;            case FTPNOPASV:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));              break;            case FTPINVPASV:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));              break;            case FTPOK:              break;            default:              abort ();            }   /* switch (err) */          if (err==FTPOK)            {              DEBUGP (("trying to connect to %s port %d\n",                       print_address (&passive_addr), passive_port));              dtsock = connect_to_ip (&passive_addr, passive_port, NULL);              if (dtsock < 0)                {                  int save_errno = errno;                  fd_close (csock);                  con->csock = -1;                  logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),                             print_address (&passive_addr), passive_port,                             strerror (save_errno));                  return (retryable_socket_connect_error (save_errno)                          ? CONERROR : CONIMPOSSIBLE);                }              pasv_mode_open = true;  /* Flag to avoid accept port */              if (!opt.server_response)                logputs (LOG_VERBOSE, _("done.    "));            } /* err==FTP_OK */        }      if (!pasv_mode_open)   /* Try to use a port command if PASV failed */        {          err = ftp_do_port (csock, &local_sock);          /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,             FTPPORTERR */          switch (err)            {            case FTPRERR:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));              fd_close (csock);              con->csock = -1;              fd_close (dtsock);              fd_close (local_sock);              return err;            case WRITEFAILED:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET,                       _("Write failed, closing control connection.\n"));              fd_close (csock);              con->csock = -1;              fd_close (dtsock);              fd_close (local_sock);              return err;            case CONSOCKERR:              logputs (LOG_VERBOSE, "\n");              logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));              fd_close (csock);              con->csock = -1;              fd_close (dtsock);              fd_close (local_sock);              return err;            case FTPSYSERR:              logputs (LOG_VERBOSE, "\n");              logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),                         strerror (errno));              fd_close (dtsock);              return err;            case FTPPORTERR:              logputs (LOG_VERBOSE, "\n");              logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));              fd_close (csock);              con->csock = -1;              fd_close (dtsock);              fd_close (local_sock);              return err;            case FTPOK:              break;            default:              abort ();            } /* port switch */          if (!opt.server_response)            logputs (LOG_VERBOSE, _("done.    "));        } /* dtsock == -1 */    } /* cmd & (DO_LIST | DO_RETR) */  /* Restart if needed.  */  if (restval && (cmd & DO_RETR))    {      if (!opt.server_response)        logprintf (LOG_VERBOSE, "==> REST %s ... ",                   number_to_static_string (restval));      err = ftp_rest (csock, restval);      /* FTPRERR, WRITEFAILED, FTPRESTFAIL */      switch (err)        {        case FTPRERR:          logputs (LOG_VERBOSE, "\n");          logputs (LOG_NOTQUIET, _("\Error in server response, closing control connection.\n"));          fd_close (csock);          con->csock = -1;          fd_close (dtsock);          fd_close (local_sock);          return err;        case WRITEFAILED:          logputs (LOG_VERBOSE, "\n");          logputs (LOG_NOTQUIET,                   _("Write failed, closing control connection.\n"));          fd_close (csock);          con->csock = -1;          fd_close (dtsock);          fd_close (local_sock);          return err;        case FTPRESTFAIL:          logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));          rest_failed = true;          break;        case FTPOK:          break;        default:          abort ();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -