📄 sftp.cpp
字号:
// sftp.cpp// code for sftp.h// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#include "sftp.h" // this module#include "xassert.h" // xfailure#include "datablok.h" // DataBlock#include "sockutil.h" // recvAll, recvAllToEOF#include <ctype.h> // isdigit#include <stdlib.h> // strtoul// parse a reply to a PASV requestvoid parsePasvArgument(char const *text, IPAddress &addr, int &port){ char const *p = text; // scan for the first digit while (*p && !isdigit(*p)) { p++; } if (!*p) { xfailure(stringb("reply to PASV was malformed (no digits): " << text)); } // parse the address and port string whyFail; if (!parsePortArgument(p, addr, port, whyFail)) { xfailure(stringb("reply to PASV was malformed, " << whyFail << ": " << text)); }}// PORT command argument, PASV reply argumentstring constructPortArg(IPAddress addr, int port){ return stringb( ((addr >> 24) & 0xff) << "," << ((addr >> 16) & 0xff) << "," << ((addr >> 8) & 0xff) << "," << (addr & 0xff) << "," << ((port >> 8) & 0xff) << "," << (port & 0xff) );}// parse a PORT command argument, returning false (and setting 'whyFail')// if there is a problem (also works for PASV replies, as long as 'p'// is already set to the first digit)bool parsePortArgument(char const *p, IPAddress &clientAddress, int &clientPort, string &whyFail){ clientAddress = 0; clientPort = 0; for (int i=0; i<6; i++) { if (!isdigit(*p)) { if (isprint(*p)) { whyFail = stringb("Character '" << *p << "' is not a valid digit."); } else { whyFail = "Unprintable character in input."; } return false; } char *endptr; unsigned long val = strtoul(p, &endptr, 10 /*decimal*/); if (val > 0xFF) { whyFail = stringb((i < 4 ? "Address byte " : "Host byte ") << (i%4) << " (" << val << "), must be between 0 and 255."); return false; } if (i < 4) { clientAddress |= (val << (24 - i*8)); } else { clientPort |= (val << (8 - (i-4)*8)); } // advance to next while (isdigit(*p)) { p++; } if (*p == ',') { p++; } // if not, either we're at end (ok) or is bad, and first test // at loop start will catch error } #if 0 // for testing parsing code diagnostic("parsePort: ip address = 0x%lX (%d,%d,%d,%d), " "port = 0x%X (%d)\n", clientAddress, (clientAddress >> 24) & 0xff, (clientAddress >> 16) & 0xff, (clientAddress >> 8) & 0xff, clientAddress & 0xff, clientPort, clientPort); #endif // 0 return true;}void recvAllBlock(SOCKET s, DataBlock &block, int lenToRead){ xassert(lenToRead <= block.getAllocated()); recvAll(s, (char*)block.getData(), lenToRead); block.setDataLen(lenToRead);}int recvAllToEOFBlock(SOCKET s, DataBlock &block, int lenToRead){ xassert(lenToRead <= block.getAllocated()); int len = recvAllToEOF(s, (char*)block.getData(), lenToRead); block.setDataLen(len); return len;}// ---------------- test code --------------------#ifdef TEST_SFTP#include "test.h" // USUAL_MAINvoid entry(){ struct S { // input char const *text; // expected output IPAddress addr; int port; bool ok; }; #define IP(a,b,c,d) ( ((a)<<24)|((b)<<16)|((c)<<8)|(d) ) #define PORT(a,b) IP(0,0,a,b) static S const T[] = { { "136,152,99,6,21,179", IP(136,152,99,6), PORT(21,179), true }, { "1,2,3,4,5,6", IP(1,2,3,4), PORT(5,6), true }, { "1,2,3,4,5,6,7", IP(1,2,3,4), PORT(5,6), true }, { "1,2,3,4,5", 0, 0, false }, { "1,2,3,4,5,", 0, 0, false }, { "256,0,0,0,1,2", 0, 0, false }, { " 1,2,3,4,5,6", 0, 0, false }, { "1,2,3, 4,5,6", 0, 0, false }, }; #undef PORT #undef IP loopi(TABLESIZE(T)) { // parse entry T[i] IPAddress addr; int port; string whyFail; bool result = parsePortArgument(T[i].text, addr, port, whyFail); // check for correct return value (will use debugger to see why) if (result != T[i].ok) { xfailure("entry with wrong return value"); } if (result && (addr != T[i].addr || port != T[i].port)) { xfailure("entry with wrong addr/port"); } }}USUAL_MAIN#endif // TEST_SFTP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -