void do_cmd_appe(session_t *pses) { //打开文件 int fd = open(pses->arg, O_CREAT | O_WRONLY, 0666); if(fd < 0) { ftp_reply(pses->ctrl_fd, FTP_UPLOADFAIL, "Could not create file."); return; } //给文件加写锁 if(lock_file_write(fd) == -1) { ftp_reply(pses->ctrl_fd, FTP_UPLOADFAIL, "Could not create file."); return; } int flag = upload_common(pses, fd, 1); //关闭数据套接字 close(pses->data_fd); pses->data_fd = -1; //关闭文件 unlock_file(fd); close(fd); if(flag == 0) { //226 ftp_reply(pses->ctrl_fd, FTP_TRANSFEROK, "Transfer complete."); } else if(flag == -1) { ftp_reply(pses->ctrl_fd, FTP_BADSENDNET, "Failure writting to local file."); } else if(flag == -2) { //451 ftp_reply(pses->ctrl_fd, FTP_BADSENDNET, "Failure reading from network stream."); } }
void upload_common(session_t* sess, int is_append) { if(get_transfer_fd(sess) == 0) return; int fd = open(sess->arg, O_CREAT | O_WRONLY, 0666); if(fd == -1) { ftp_reply(sess, FTP_UPLOADFAIL, "Could not creat file."); return; } int ret = 0; ret = lock_file_write(fd); if(ret == -1) { ftp_reply(sess, FTP_UPLOADFAIL, "Could not creat file."); return; } long long offset = sess->restart_pos; sess->restart_pos = 0; if(!is_append && offset == 0) //STOR { ftruncate(fd, 0); if(lseek(fd, 0, SEEK_SET) < 0) { ftp_reply(sess, FTP_UPLOADFAIL, "Could not creat file."); return; } } else if(!is_append && offset != 0) //REST + STOR { if(lseek(fd, offset, SEEK_SET) < 0) { ftp_reply(sess, FTP_UPLOADFAIL, "Could not creat file."); return; } } else if(is_append) { if(lseek(fd, 0, SEEK_END) < 0) { ftp_reply(sess, FTP_UPLOADFAIL, "Could not creat file."); return; } } struct stat sbuf; fstat(fd, &sbuf); char text[1024] = {0}; if(sess->is_ascii) { sprintf(text, "Opening ASCII mode data conection for %s (%lld bytes).", sess->arg, (long long)sbuf.st_size); } else { sprintf(text, "Opening BINARY mode data conection for %s (%lld bytes).", sess->arg, (long long)sbuf.st_size); } ftp_reply(sess, FTP_DATACONN, text); int flag = 0; char buf[65536] = {0}; sess->bw_transfer_start_sec = get_time_sec(); sess->bw_transfer_start_usec = get_time_usec(); while(1) { ret = read(sess->data_fd, buf, sizeof(buf)); if(ret == -1) { if(errno == EINTR) continue; flag = 2; break; } else if(ret == 0) { flag = 0; break; } limit_rate(sess, ret, 1); if(sess->abor_received) { flag = 2; break; } if(writen(fd, buf, ret) != ret) { flag = 1; break; } } close(sess->data_fd); sess->data_fd = -1; close(fd); if(flag == 0) ftp_reply(sess, FTP_TRANSFEROK, "Transfer complete."); else if(flag == 1) ftp_reply(sess, FTP_BADSENDFILE, "Failure to write file."); else if(flag == 2) ftp_reply(sess, FTP_BADSENDNET, "Failure read from network stream."); check_abor(sess); start_cmdio_alarm(); }