📄 ftpget.bin.c
字号:
*t = 0; Debug(26, 1, ("read_reply: %s\n", buf)); } fclose(fp); code = atoi(buf); server_reply_msg = xstrdup(&buf[4]); return code;}/* * send_cmd() * Write a command string * * Returns # bytes written */int send_cmd(fd, buf) int fd; char *buf;{ char *xbuf = NULL; int len; int x; len = strlen(buf) + 2; xbuf = (char *) xmalloc(len + 1); sprintf(xbuf, "%s\r\n", buf); Debug(26, 1, ("send_cmd: %s\n", buf)); x = write(fd, xbuf, len); if (x < 0) log_errno2(__FILE__, __LINE__, "write"); alarm(timeout); /* reset timeout timer */ xfree(xbuf); return x;}#define ASCII_DIGIT(c) ((c)-48)time_t parse_iso3307_time(buf) char *buf;{/* buf is an ISO 3307 style time: YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx */ struct tm tms; time_t t; while (*buf == ' ' || *buf == '\t') buf++; if ((int) strlen(buf) < 14) return 0; memset(&tms, '\0', sizeof(struct tm)); tms.tm_year = (ASCII_DIGIT(buf[2]) * 10) + ASCII_DIGIT(buf[3]); tms.tm_mon = (ASCII_DIGIT(buf[4]) * 10) + ASCII_DIGIT(buf[5]) - 1; tms.tm_mday = (ASCII_DIGIT(buf[6]) * 10) + ASCII_DIGIT(buf[7]); tms.tm_hour = (ASCII_DIGIT(buf[8]) * 10) + ASCII_DIGIT(buf[9]); tms.tm_min = (ASCII_DIGIT(buf[10]) * 10) + ASCII_DIGIT(buf[11]); tms.tm_sec = (ASCII_DIGIT(buf[12]) * 10) + ASCII_DIGIT(buf[13]);#ifdef HAVE_TIMEGM t = timegm(&tms);#elif defined(_HARVEST_SYSV_) || defined(_HARVEST_LINUX_) || defined(_HARVEST_HPUX_) || defined(_HARVEST_AIX_) t = mktime(&tms);#else t = (time_t) 0;#endif Debug(26, 1, ("parse_iso3307_time: %d\n", t)); return t;}#undef ASCII_DIGIT#define SEND_CBUF \ if (send_cmd(r->sfd, cbuf) < 0) { \ r->errmsg = (char *) xmalloc (BUFSIZ); \ sprintf(r->errmsg, "Failed to send '%s'", cbuf); \ r->rc = 4; \ return FAIL_SOFT; \ }/* * parse_request() * Perform validity checks on request parameters. * - lookup hostname * * Returns states: * FAIL_HARD * PARSE_OK */state_t parse_request(r) request_t *r;{ Debug(26, 1, ("parse_request: looking up '%s'\n", r->host)); if (get_host(r->host) == (Host *) NULL) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "Unknown host: %s", r->host); r->rc = 10; return FAIL_HARD; } return PARSE_OK;}/* * do_connect() * Connect to the FTP server r->host on port 21. * * Returns states: * FAIL_SOFT * CONNECTED * r->state ( retry ) */state_t do_connect(r) request_t *r;{ Host *h = NULL; int sock; struct sockaddr_in S; int len; ++r->connect_attempts; Debug(26, 1, ("do_connect: connect attempt #%d to '%s'\n", r->connect_attempts, r->host)); if (r->connect_attempts > connect_retries) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "%s: Giving up after %d connect attempts", r->host, connect_retries); r->rc = 3; return FAIL_SOFT; } if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "socket: %s", strerror(errno)); r->rc = 2; return FAIL_SOFT; } h = get_host(r->host); memcpy(&(S.sin_addr.s_addr), h->ipaddr, h->addrlen); S.sin_family = AF_INET; S.sin_port = htons(FTP_PORT); if (connect(sock, (struct sockaddr *) &S, sizeof(S)) < 0) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "%s (port %d): %s", r->host, FTP_PORT, strerror(errno)); r->rc = 3; return r->state; } r->sfd = sock; alarm(timeout); /* reset timeout timer */ /* get the address of whatever interface we're using so we know */ /* what to use in the PORT command. */ len = sizeof(ifc_addr); if (getsockname(sock, (struct sockaddr *) &ifc_addr, &len) < 0) { log_errno2(__FILE__, __LINE__, "getsockname"); exit(1); } return CONNECTED;}/* * read_welcome() * Parse the ``welcome'' message from the FTP server * * Returns states: * FAIL_SOFT * SERVICE_READY * PARSE_OK ( retry ) */state_t read_welcome(r) request_t *r;{ int code; if ((code = read_reply(r->sfd)) > 0) { if (code == 220) return SERVICE_READY; } close(r->sfd); r->sfd = -1; if (code < 0) { r->errmsg = xstrdup(server_reply_msg); r->rc = 4; return FAIL_SOFT; } if (r->connect_attempts >= connect_retries) { r->errmsg = xstrdup(server_reply_msg); r->rc = 5; return FAIL_SOFT; } return PARSE_OK; /* retry */}/* * do_user() * Send the USER command to the FTP server * * Returns states: * FAIL_SOFT * LOGGED_IN * NEED_PASSWD * PARSE_OK ( retry ) */state_t do_user(r) request_t *r;{ int code; r->login_attempts++; sprintf(cbuf, "USER %s", r->user); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 230) return LOGGED_IN; if (code == 331) return NEED_PASSWD; } close(r->sfd); r->sfd = -1; if (code < 0) { r->errmsg = xstrdup(server_reply_msg); r->rc = 4; return FAIL_SOFT; } if (r->login_attempts >= login_retries) { r->errmsg = xstrdup(server_reply_msg); r->rc = 5; return FAIL_SOFT; } return PARSE_OK; /* retry */}/* * do_passwd() * Send the USER command to the FTP server * * Returns states: * FAIL_SOFT * LOGGED_IN * PARSE_OK ( retry ) */state_t do_passwd(r) request_t *r;{ int code; sprintf(cbuf, "PASS %s", r->pass); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 230) return LOGGED_IN; } close(r->sfd); r->sfd = -1; if (code < 0) { r->errmsg = xstrdup(server_reply_msg); r->rc = 4; return FAIL_SOFT; } if (r->login_attempts >= login_retries) { r->errmsg = xstrdup(server_reply_msg); r->rc = 5; return FAIL_SOFT; } return PARSE_OK; /* retry */}state_t do_type(r) request_t *r;{ int code; sprintf(cbuf, "TYPE %c", *(r->type)); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 200) return TYPE_OK; } r->errmsg = xstrdup(server_reply_msg); r->rc = code < 0 ? 4 : 5; return FAIL_SOFT;}state_t do_mdtm(r) request_t *r;{ int code; sprintf(cbuf, "MDTM %s", r->path); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 213) r->mdtm = parse_iso3307_time(server_reply_msg); } if (code < 0) { r->errmsg = xstrdup(server_reply_msg); r->rc = 4; return FAIL_SOFT; } return MDTM_OK;}state_t do_size(r) request_t *r;{ int code; sprintf(cbuf, "SIZE %s", r->path); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 213) r->size = atoi(server_reply_msg); } if (code < 0) { r->errmsg = xstrdup(server_reply_msg); r->rc = 4; return FAIL_SOFT; } return SIZE_OK;}state_t do_port(r) request_t *r;{ int code; int sock; struct sockaddr_in S; unsigned int naddr; int tries = 0; int port = 0; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "socket: %s", strerror(errno)); r->rc = 2; return FAIL_SOFT; } S = ifc_addr; S.sin_family = AF_INET;#if defined(HAVE_SRAND48) srand48(time(NULL));#else srand(time(NULL));#endif while (1) {#if defined(HAVE_LRAND48) port = (lrand48() & 0x3FFF) | 0x4000;#else port = (rand() & 0x3FFF) | 0x4000;#endif S.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &S, sizeof(S)) >= 0) break; if (++tries < 10) continue; r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "bind: %s", strerror(errno)); r->rc = 2; return FAIL_SOFT; } if (listen(sock, 1) < 0) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "listen: %s", strerror(errno)); r->rc = 2; return FAIL_SOFT; } naddr = ntohl(ifc_addr.sin_addr.s_addr); sprintf(cbuf, "PORT %d,%d,%d,%d,%d,%d", (naddr >> 24) & 0xFF, (naddr >> 16) & 0xFF, (naddr >> 8) & 0xFF, naddr & 0xFF, (port >> 8) & 0xFF, port & 0xFF); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 200) { r->dfd = sock; return PORT_OK; } } r->errmsg = xstrdup(server_reply_msg); r->rc = code < 0 ? 4 : 5; return FAIL_SOFT;}state_t do_cwd(r) request_t *r;{ int code; sprintf(cbuf, "CWD %s", r->path); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code >= 200 && code < 300) return CWD_OK; return CWD_FAIL; } r->errmsg = xstrdup(server_reply_msg); r->rc = code < 0 ? 4 : 5; return FAIL_SOFT;}state_t do_retr(r) request_t *r;{ int code; sprintf(cbuf, "RETR %s", r->path); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 125) return TRANSFER_BEGIN; if (code == 150) return TRANSFER_BEGIN; if (code == 550) { r->errmsg = xstrdup(server_reply_msg); r->rc = 10; return FAIL_HARD; } } r->errmsg = xstrdup(server_reply_msg); r->rc = code < 0 ? 4 : 5; return FAIL_SOFT;}state_t do_list(r) request_t *r;{ int code; sprintf(cbuf, "LIST -l"); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 125) return TRANSFER_BEGIN; if (code == 150) return TRANSFER_BEGIN; if (code == 450) { r->errmsg = xstrdup(server_reply_msg); r->rc = 10; return FAIL_HARD; } } sprintf(cbuf, "NLST -l"); SEND_CBUF; if ((code = read_reply(r->sfd)) > 0) { if (code == 125) return TRANSFER_BEGIN; if (code == 150) return TRANSFER_BEGIN; if (code == 450) { r->errmsg = xstrdup(server_reply_msg); r->rc = 10; return FAIL_HARD; } } r->errmsg = xstrdup(server_reply_msg); r->rc = code < 0 ? 4 : 5; return FAIL_SOFT;}state_t do_accept(r) request_t *r;{ int sock; struct sockaddr S; int len; len = sizeof(S); memset(&S, '\0', len); if ((sock = accept(r->dfd, &S, &len)) < 0) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "accept: %s", strerror(errno)); r->rc = 3; return FAIL_SOFT; } alarm(timeout); /* reset timeout timer */ close(r->dfd); r->dfd = sock; return DATA_TRANSFER;}state_t read_data(r) request_t *r;{ int code; int n; char buf[8192]; n = read(r->dfd, buf, 8192); alarm(timeout); /* reset timeout timer */ if (n < 0) { r->errmsg = (char *) xmalloc(BUFSIZ); sprintf(r->errmsg, "read: %s", strerror(errno)); r->rc = 4; return FAIL_SOFT; } if (n == 0) { if ((code = read_reply(r->sfd)) > 0) { if (code == 226) return TRANSFER_DONE; } r->errmsg = xstrdup(server_reply_msg); r->rc = code < 0 ? 4 : 5; return FAIL_SOFT; } write(r->cfd, buf, n); return r->state;}static char *Month[] ={ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};int is_month(buf) char *buf;{ int i; for (i = 0; i < 12; i++) if (!strcasecmp(buf, Month[i])) return 1; return 0;}#define MAX_TOKENS 64parts_t *parse_entry(buf) char *buf;{ parts_t *p = NULL; char *t = NULL; char *tokens[MAX_TOKENS]; int i, n; char WS[] = " \t\n"; char sbuf[128]; char *xbuf = NULL; if (buf == NULL) return NULL; p = (parts_t *) xmalloc(sizeof(parts_t)); memset(p, '\0', sizeof(parts_t)); n = 0; xbuf = xstrdup(buf); for (t = strtok(xbuf, WS); t && n < MAX_TOKENS; t = strtok(NULL, WS)) tokens[n++] = xstrdup(t); xfree(xbuf); /* locate the Month field */ for (i = 3; i < n - 3; i++) { if (!is_month(tokens[i])) /* Month */ continue; if (!sscanf(tokens[i - 1], "%[0-9]", sbuf)) /* Size */ continue; if (!sscanf(tokens[i + 1], "%[0-9]", sbuf)) /* Day */ continue; if (!sscanf(tokens[i + 2], "%[0-9:]", sbuf)) /* Yr | hh:mm */ continue; p->type = *tokens[0]; p->size = atoi(tokens[i - 1]); sprintf(sbuf, "%s %2s %5s",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -