void execSTOR(session* ses, list<string> args) { int fd = 0; char buf[BUF_SIZE] = {0}; int bytesRead = 0; string path(ses->currentDir); if (path[path.size()] != '/') { path += "/"; } path += args.front(); string dataChunk; int pos = 0; // open data connection openDataConnection(ses); if (ses->dsck <= 0) { cerr << "Data connection closed.\n"; } string resp("125 Data connection opened."); respond(ses, resp); // read data switch (ses->t) { case ASCII: fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); while ((bytesRead = read(ses->dsck, buf, BUF_SIZE)) != 0 && bytesRead != -1) { // convert new line characters dataChunk.assign(buf); while ((pos = dataChunk.find("\r\n")) != string::npos) { dataChunk.replace(pos, 2, "\n"); } write(fd, dataChunk.c_str(), dataChunk.size()); } close(fd); break; case IMAGE: fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); cerr << "desc: " << fd << "\n"; while ((bytesRead = read(ses->dsck, buf, BUF_SIZE)) != 0 && bytesRead != -1) { write(fd, buf, bytesRead); } close(fd); break; default: printEvent(ses, "Undefined session type"); break; } closeDataConnection(ses); resp.assign("226 Closing data connection. Requested file action successful."); respond(ses, resp); }
void Session::handleLIST(const std::string& arg) { Path path = m_root / m_path; // @fixme don't allow going below root. if (arg.size() > 0) { if (arg != "-aL" && arg != "-la") { path = getAbsolutePath(arg); } } // Check if we're trying to go below root. if (String::startsWith(m_root.str(), path.str())) path = m_root; Path::Type type = path.type(); if (type == Path::PT_INVALID) { sendReply(450, "Requested file action not taken."); return; } sendReply(150, "File status okay; about to open data connection."); Time::BrokenDown time_ref; TCPSocket* data = openDataConnection(); if (type == Path::PT_FILE) { sendFileInfo(path, data, time_ref); } else { Directory dir(path); const char* entry = NULL; while ((entry = dir.readEntry(Directory::RD_FULL_NAME))) { sendFileInfo(entry, data, time_ref); } } closeDataConnection(data); }
void execLIST(session* ses, list<string> args) { openDataConnection(ses); if (ses->dsck <= 0) { cerr << "Data connection closed.\n"; } string listing = runLs(ses, args); string resp("125 Data connection already open; transfer starting."); respond(ses, resp); // send listing through data connection write(ses->dsck, listing.c_str(), listing.length()); string resp2("250 Requested file action okay, completed."); respond(ses, resp2); closeDataConnection(ses); }
void Session::handleRETR(const std::string& arg) { int64_t rest_offset = m_rest_offset; m_rest_offset = -1; Path path = getAbsolutePath(arg); if (!path.isFile()) { sendReply(450, "Requested file action not taken."); return; } sendReply(150, "File status okay; about to open data connection."); TCPSocket* data = openDataConnection(); if (!data->writeFile(path.c_str(), path.size() - 1, rest_offset)) return; closeDataConnection(data); m_rest_offset = 0; }
void execRETR(session* ses, list<string> args) { int fd = 0; string path(ses->currentDir); if (path[path.size()] != '/') { path += "/"; } path += args.front(); fd = open(path.c_str(), O_RDONLY); if (fd == -1) { cerr << "cant open file\n"; } char buf[BUF_SIZE] = {0}; int readBytes = 0; openDataConnection(ses); if (ses->dsck <= 0) { cerr << "Data connection closed.\n"; } string resp("125 Data connection opened."); respond(ses, resp); while ((readBytes = read(fd, buf, BUF_SIZE)) != 0) { write(ses->dsck, buf, readBytes); } resp.assign("226 Closing data connection. Requested file action successful."); respond(ses, resp); closeDataConnection(ses); close(fd); }