📄 staffsservice.cpp
字号:
fDirectoryCopyStateClass->addKey("name", "Name"); fDirectoryCopyStateClass->addKey("mode", "Mode"); fDirectoryCopyStateClass->addKey("fileSize", "File Size"); fDirectoryCopyStateClass->addKey("bytesCopied", "Bytes Copied"); // Construct map class for LIST SETTINGS information fSettingsClass = STAFMapClassDefinition::create( "STAF/Service/FS/Settings"); fSettingsClass->addKey("strictFSCopyTrust", "Strict FS Copy Trust"); // Construct map-class for GET ENTRY SIZE information fEntrySizeInfoClass = STAFMapClassDefinition::create( "STAF/Service/FS/SizeInfo"); fEntrySizeInfoClass->addKey("upperSize", "Upper 32-bit Size"); fEntrySizeInfoClass->addKey("lowerSize", "Lower 32-bit Size"); // Construct map-class for QUERY ENTRY information fQueryInfoClass = STAFMapClassDefinition::create( "STAF/Service/FS/QueryInfo"); fQueryInfoClass->addKey("name", "Name"); fQueryInfoClass->addKey("type", "Type"); fQueryInfoClass->addKey("upperSize", "Upper 32-bit Size"); fQueryInfoClass->addKey("lowerSize", "Lower 32-bit Size"); fQueryInfoClass->addKey("lastModifiedTimestamp", "Modified Date-Time"); // Construct map-class for error information on a copy/delete fErrorInfoClass = STAFMapClassDefinition::create( "STAF/Service/FS/ErrorInfo"); fErrorInfoClass->addKey("name", "Name"); fErrorInfoClass->addKey("rc", "RC"); fErrorInfoClass->addKey("osRC", "OS RC");}STAFFSService::~STAFFSService(){ /* Do Nothing */}STAFString STAFFSService::info(unsigned int) const{ return name() + ": Internal";}STAFServiceResult STAFFSService::acceptRequest( const STAFServiceRequest &requestInfo){ STAFString action = requestInfo.fRequest.subWord(0, 1).toLowerCase(); STAFString subAction = requestInfo.fRequest.subWord(1, 1).toLowerCase(); if (action == "copy") { if (subAction == "file") return handleCopyFile(requestInfo); else if (subAction == "directory") return handleCopyDir(requestInfo); else return STAFServiceResult(kSTAFInvalidRequestString, ""); } else if (action == "get") return handleGet(requestInfo); else if (action == "list") { if (subAction == "copyrequests") return handleListCopyRequests(requestInfo); else return handleList(requestInfo); } else if (action == "create") return handleCreate(requestInfo); else if (action == "delete") return handleDelete(requestInfo); else if (action == "query") return handleQuery(requestInfo); else if (action == "set") return handleSet(requestInfo); else if (action == "help") return handleHelp(requestInfo); else return STAFServiceResult(kSTAFInvalidRequestString, "");}STAFServiceResult STAFFSService::handleCopyFile( const STAFServiceRequest &requestInfo){ // Verify that the requesting machine/user has at least trust level 4 IVALIDATE_TRUST(4, "COPY"); // Parse the request STAFCommandParseResultPtr parsedResult = fCopyFileParser.parse( requestInfo.fRequest); if (parsedResult->rc != kSTAFOk) { return STAFServiceResult(kSTAFInvalidRequestString, parsedResult->errorBuffer, 0); } DEFINE_VAR_POOL_LIST(varPoolList, varPoolListSize, requestInfo); STAFString fromMachine = requestInfo.fEndpoint; STAFHandle_t handle = requestInfo.fHandle; STAFString request = requestInfo.fRequest; STAFRC_t rc = kSTAFOk; STAFString toMachine = fromMachine; STAFString toFile; STAFString fromFile; STAFString errorBuffer; rc = RESOLVE_STRING_OPTION("FILE", fromFile); if (!rc) rc = RESOLVE_OPTIONAL_STRING_OPTION("TOMACHINE", toMachine); if (rc) return STAFServiceResult(rc, errorBuffer); // if user specified TOFILE value if (parsedResult->optionTimes("TOFILE") != 0) { toFile = parsedResult->optionValue("TOFILE"); } else if (parsedResult->optionTimes("TODIRECTORY") != 0) { // Copy the file to this directory using the same file name as // the "from" file name toFile = parsedResult->optionValue("TODIRECTORY"); } else { toFile = parsedResult->optionValue("FILE"); } if (requestInfo.fIsLocalRequest && isLocalMachine(toMachine, 1)) { // XXX: I'm not sure this next comment is still true as of STAF V3.0 // If we are copying to and from ourself then we need to resolve // any handle specific variables here. STAFProc is only responsible // for resolving variables in the case where the file came from // a different machine. STAFString unresToFile = toFile; rc = RESOLVE_STRING(unresToFile, toFile); if (rc) return STAFServiceResult(rc, errorBuffer); } // Check if the from file exists STAFFSPath fromPath(fromFile); try { if (!fromPath.exists()) return STAFServiceResult( kSTAFDoesNotExist, "File " + fromFile + " does not exist"); } catch (STAFBaseOSErrorException &e) { STAFString errMsg = "Error on From File: " + fromFile + "\n" + e.getText() + STAFString(": ") + e.getErrorCode(); return STAFServiceResult(kSTAFBaseOSError, errMsg); } // Remove trailing slashes, if any, in the file name fromFile = fromPath.setRoot(fromPath.root()).asString(); // If TODIRECTORY is specified, need to add the from file name to the path if (parsedResult->optionTimes("TODIRECTORY") != 0) { toFile = toFile + "/" + fromPath.name(); if (fromPath.extension() != "") toFile = toFile + "." + fromPath.extension(); } // determine if transfer is text or binary bool doText = false; bool doCodepage = false; STAFString newEOL = "Native"; if (parsedResult->optionTimes("TEXT") > 0) { doText = true; doCodepage = true; rc = RESOLVE_OPTIONAL_STRING_OPTION("FORMAT", newEOL); if (rc) return STAFServiceResult(rc, errorBuffer); // If enable NOCONVERT option, uncomment the following line //doCodepage = (parsedResult->optionTimes("NOCONVERT") == 0); } fstream inFile; // open the file as binary inFile.open(fromFile.toCurrentCodePage()->buffer(), ios::in | STAF_ios_binary); if (!inFile) return STAFServiceResult(kSTAFFileOpenError, fromFile); // Get the size of the file (upperSize and lowerSize). // If the file size is < 4G, upperSize will be zero. STAFFSEntryPtr entry; try { entry = fromPath.getEntry(); } catch (STAFBaseOSErrorException &e) { STAFString errMsg = "Error on From File: " + fromFile + "\n" + e.getText() + STAFString(": ") + e.getErrorCode(); return STAFServiceResult(kSTAFBaseOSError, errMsg); } unsigned int upperSize = entry->size().first; unsigned int lowerSize = entry->size().second; // Check if file size exceeds the maximum that the FS service handles if ((upperSize > 0) || (lowerSize > UINT_MAX)) { STAFString errMsg = STAFString( "File size exceeds the maximum size (") + UINT_MAX + ") supported. File name: " + fromFile; return STAFServiceResult(kSTAFFileReadError, errMsg); } unsigned int fileLength = lowerSize; unsigned char fileBuffer[4000] = { 0 }; unsigned int writeLength = 0; STAFConnectionPtr connection; STAFString result; unsigned int useNewAPI = 1; unsigned int levelToUse = 0; unsigned int flags = 0; if (parsedResult->optionTimes("FAILIFEXISTS") != 0) flags |= 0x00000001; else if (parsedResult->optionTimes("FAILIFNEW") != 0) flags |= 0x00000002; // If interface cycling is not enabled, and toMachine is not 'local', // and neither interface nor port are specified in toMachine, get the // originator's interface and prepend to the toMachine value so that // the connection to the toMachine will use the orginator's interface. if ((!gConnectionManagerPtr->getAutoInterfaceCycling()) && (!isLocalMachine(toMachine, 1)) && (toMachine.find(gSpecSeparator == STAFString::kNPos)) && (toMachine.find(kUTF8_AT) == STAFString::kNPos)) { unsigned int specSepPos = requestInfo.fEndpoint.find(gSpecSeparator); if (specSepPos != STAFString::kNPos) { STAFString interface = requestInfo.fEndpoint.subString( 0, specSepPos); if (interface != "local") { // Prepend the interface from the originator's endpoint toMachine = interface + gSpecSeparator + toMachine; } } } STAFFSCopyManager::FSCopyDataPtr copyDataPtr; try { // Make a connection to the toMachine try { rc = gConnectionManagerPtr->makeConnection( toMachine, connection, result); } catch (STAFConnectionProviderConnectException &e) { rc = kSTAFNoPathToMachine; result = e.getText() + STAFString(": ") + STAFString(e.getErrorCode()); } if ((rc == kSTAFNoPathToMachine) && (toMachine.find(kUTF8_AT) == STAFString::kNPos)) { // Retry connecting to the toMachine, this time using the // originator's port unsigned int atPos = requestInfo.fEndpoint.find(kUTF8_AT); if (atPos != STAFString::kNPos) { toMachine = toMachine + requestInfo.fEndpoint.subString(atPos); rc = gConnectionManagerPtr->makeConnection( toMachine, connection, result); } } if (rc) return STAFServiceResult(rc, result); // First, lets try the new API connection->writeUInt(kSTAFFileTransferAPI2); // New API number connection->writeUInt(0); // Dummy level STAFRC_t ack = connection->readUInt(); if (ack != kSTAFOk) { // They don't support the new API, so try the old API useNewAPI = 0; rc = gConnectionManagerPtr->makeConnection( toMachine, connection, result); if (rc) return STAFServiceResult(rc, result); connection->writeUInt(kSTAFFileTransferAPI); // Old API Number connection->writeUInt(0); // API Level ack = connection->readUInt(); if (ack != kSTAFOk) return ack; } else { // Now find out the specific level to use unsigned int minLevel = 1; unsigned int maxLevel = 3; connection->writeUInt(minLevel); connection->writeUInt(maxLevel); levelToUse = connection->readUInt(); if (levelToUse == 0) return kSTAFInvalidAPILevel; } // If the other machine can do a text transfer, specify text or binary if (useNewAPI && (levelToUse > 1)) if (doText) { if (doCodepage) connection->writeUInt(kSTAFFSTextConvert); e
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -