📄 ftp.c
字号:
strcpy(dir, szBuffer); *r = ' '; } } /* * all ok */ return FTPOK;}/* * connects to the ftp server */uerr_t ftp_connect_to_server(int *sock, char *name, int port){ char szBuffer[FTP_BUFFER_SIZE]; uerr_t err; err = connect_to_server(sock, name, port, rt.timeout); if (err != NOCONERROR) { return err; } debug_prz("Entering ftp_get_reply\n"); err = ftp_get_reply(*sock, szBuffer); if (err != FTPOK) { return err; } debug_prz("Exiting ftp_get_reply\n"); if (*szBuffer != '2') { return FTPCONREFUSED; } return FTPOK;}/* * this function will call bind to return a bound socket then the ftp server * will be connected with a port request and asked to connect */uerr_t ftp_get_listen_socket(int control_sock, int *listen_sock){ /* * get a fixed value */ char command[MAX_MSG_SIZE]; int sockfd; socklen_t len; struct sockaddr_in TempAddr; char *port, *ipaddr; struct sockaddr_in serv_addr; uerr_t err; /* * call bind to bind the sock */ if (bind_socket(&sockfd) != BINDOK) { return LISTENERR; } len = sizeof(serv_addr); if (getsockname(sockfd, (struct sockaddr *) &serv_addr, &len) < 0) { perror("getsockname"); close(sockfd); return CONPORTERR; } /* * now get hosts info */ len = sizeof(TempAddr); if (getsockname(control_sock, (struct sockaddr *) &TempAddr, &len) < 0) { perror("getsockname"); close(sockfd); return CONPORTERR; } ipaddr = (char *) &TempAddr.sin_addr; /* * the port we obtained */ port = (char *) &serv_addr.sin_port;#define UC(b) (((int)b)&0xff) snprintf(command, sizeof(command), "PORT %d,%d,%d,%d,%d,%d\r\n", UC(ipaddr[0]), UC(ipaddr[1]), UC(ipaddr[2]), UC(ipaddr[3]), UC(port[0]), UC(port[1])); /* * handle error */ err = ftp_port(control_sock, command); if (err != FTPOK) { return err; } *listen_sock = sockfd; return FTPOK;}uerr_t ftp_login(int control_sock, const char *username, const char *passwd){ uerr_t err; char szBuffer[FTP_BUFFER_SIZE]; if (snprintf(szBuffer, sizeof(szBuffer), "USER %s\r\n", username) >= sizeof(szBuffer)) { return NOTENOUGHMEM; /* FIXME: Better error */ } err = ftp_send_msg(control_sock, szBuffer, strlen(szBuffer)); if (err != FTPOK) { return err; } err = ftp_get_reply(control_sock, szBuffer); if (err != FTPOK) { return err; } /* * An unprobable possibility of logging without a password. */ if (*szBuffer == '2') { return FTPOK; } /* * Else, only response 3 is appropriate. */ if (*szBuffer != '3') { return FTPLOGREFUSED; } /* * send password */ if (snprintf(szBuffer, sizeof(szBuffer), "PASS %s\r\n", passwd) >= sizeof(szBuffer)) { return NOTENOUGHMEM; /* FIXME: Better error */ } err = ftp_send_msg(control_sock, szBuffer, strlen(szBuffer)); if (err != FTPOK) { return err; } err = ftp_get_reply(control_sock, szBuffer); if (err != FTPOK) { return err; } if (*szBuffer != '2') { return FTPLOGREFUSED; } /* * looks like everything is ok */ return FTPOK;}/* * Gets info about the file from the ftp server */uerr_t ftp_get_file_info(int control_sock, char *fname, ftp_stat_t * fs){ char szBuffer[FTP_BUFFER_SIZE]; char *tmp; unsigned char pasv_addr[6]; /* * for PASV */ int listen_sock; /* * this will indicate whether we are using PASV or PORT */ int passive_mode = FALSE; int data_sock; uerr_t err; /* * did we get a filename? */ if (!fname || !(*fname)) { message("No file specified.\n"); return -1; } /* * Lets see whether it really is a file */ err = ftp_cwd(control_sock, fname); if (err == FTPOK) { /* * So fname is a directory and not a file */ fs->fp.flagtrycwd = 1; fs->fp.flagtryretr = 0; return FTPOK; } else fs->fp.flagtrycwd = 0; /* * can't be a directory */ /* * Hmmm.. so fname may be a file or may not exist atl all */ /* * It has allways been hard to get the file size in FTP * lets try the * SIZE command and if the server doesn't support it * we fall back on * the LIST command..... */ if (snprintf(szBuffer, sizeof(szBuffer), "SIZE %s\r\n", fname) >= sizeof(szBuffer)) { return NOTENOUGHMEM; /* FIXME: Better error */ } err = ftp_send_msg(control_sock, szBuffer, strlen(szBuffer)); if (err != FTPOK) { return err; } err = ftp_get_reply(control_sock, szBuffer); if (err != FTPOK) { return err; } /* * Ok lets see what hapenned.. */ if (*szBuffer == '2') /* * everything ok... */ {#if SIZEOF_OFF_T == 4 sscanf(szBuffer + 3, "%ld", &(fs->fp.size));#elif SIZEOF_OFF_T == 8 sscanf(szBuffer + 3, "%Ld", &(fs->fp.size));#else { err = NOTENOUGHMEM; return err; }#endif fs->fp.flagtryretr = 1; return FTPOK; } else if (*szBuffer == '5') /** A error hapenned */ { /* * is it due to the file being not found.... */ if (strstr(szBuffer, "o such file") || strstr(szBuffer, "o Such File") || strstr(szBuffer, "ot found") || strstr(szBuffer, "ot Found")) return FTPNSFOD; } /* * The server did not support the SIZE command, * so lets try to get the * file size through the LIST command */ /* * If enabled lets try PASV */ if (rt.use_pasv == TRUE) { err = ftp_pasv(control_sock, pasv_addr); /* * If the error is due to the server not supporting PASV then * set the * flag and lets try PORT */ if (err == FTPNOPASV || err == FTPINVPASV) { message("Server doesn't seem to support PASV"); passive_mode = FALSE; } else if (err == FTPOK) /* * server supports PASV */ { char dhost[256]; unsigned short dport; snprintf(dhost, sizeof(dhost), "%d.%d.%d.%d", pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]); dport = (pasv_addr[4] << 8) + pasv_addr[5]; err = connect_to_server(&data_sock, dhost, dport, rt.timeout); if (err != NOCONERROR) { return err; } /* * Everything seems to be ok */ passive_mode = TRUE; } else { return err; } } else { /* * Ok..since PASV is not to be used... */ passive_mode = FALSE; } if (passive_mode == FALSE) /* * try to use PORT instead */ { /* * obtain a listen socket */ err = ftp_get_listen_socket(control_sock, &listen_sock); if (err != FTPOK) { return err; } } err = ftp_ascii(control_sock); if (err != FTPOK) { return err; } err = ftp_list(control_sock, fname); if (err != FTPOK) { return err; } if (passive_mode == FALSE) /* * Then we have to accept the connection */ { err = accept_connection(listen_sock, &data_sock); if (err != ACCEPTOK) { return err; } } /* * Clear the data buffer */ memset(szBuffer, 0, sizeof(szBuffer)); if (ftp_read_msg(data_sock, szBuffer, FTP_BUFFER_SIZE) == -1) return FTPERR; while ((tmp = strrchr(szBuffer, '\n')) || (tmp = strrchr(szBuffer, '\r'))) { *tmp = 0; }; /* * close the data_socket */ close(data_sock); if (ftpparse(&(fs->fp), szBuffer, strlen(szBuffer)) == 1) return FTPOK; else return FTPNSFOD;}/* connects to the server and checks wether the file exist * it also checks wether REST is supported * and if everything is OK it stores the length of the file in *len */uerr_t ftp_get_info(urlinfo * u, ftp_stat_t * fs){ int control_sock; uerr_t err; char *user, *passwd; netrc_entry *netrc_ent; memset(fs, 0, sizeof(ftp_stat_t)); err = ftp_connect_to_server(&control_sock, u->host, u->port); if (err != FTPOK) { message("Error connecting to %s", u->host); return err; } message("connect ok"); user = u->user; passwd = u->passwd; /* * Use .netrc if asked to do so. */ if (rt.use_netrc == TRUE) { netrc_ent = search_netrc(rt.netrc_list, u->host); if (netrc_ent != NULL) { user = netrc_ent->account; passwd = netrc_ent->password; } } user = user ? user : DEFAULT_FTP_USER; passwd = passwd ? passwd : DEFAULT_FTP_PASSWD; message("Logging in as user %s password %s", user, passwd); err = ftp_login(control_sock, user, passwd); if (err != FTPOK) { message("login failed"); close(control_sock); return err; } else message("login ok"); err = ftp_binary(control_sock); if (err != FTPOK) { message("binary failed"); close(control_sock); return err; } else message("Type set to binary ok"); /* * De we need to CWD */ if (*u->dir) { err = ftp_cwd(control_sock, u->dir); if (err != FTPOK) { message("CWD failed to change to directory '%s'", u->dir); close(control_sock); return err; } else message("CWD ok"); } else { message("CWD not needed"); } err = ftp_rest(control_sock, 0); if (err != FTPOK) { u->resume_support = FALSE; message("REST failed"); } else { u->resume_support = TRUE; message("REST ok"); } err = ftp_get_file_info(control_sock, u->file, fs); if (err != FTPOK) { message("Get file info failed"); close(control_sock); return err; } u->file_size = fs->fp.size; close(control_sock); return FTPOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -