Documentation
+For now, all I have is the + API docs. I'll have to work up a + tutorial and a manual at some point.
+Last updated: April 8, 2009.
diff --git a/html/tftpy-doc/api-objects.txt b/html/tftpy-doc/api-objects.txt new file mode 100644 index 0000000..30745e5 --- /dev/null +++ b/html/tftpy-doc/api-objects.txt @@ -0,0 +1,272 @@ +tftpy tftpy-module.html +tftpy.verlist tftpy-module.html#verlist +tftpy.TftpClient' tftpy.TftpClient%27-module.html +tftpy.TftpClient'.MAX_BLKSIZE tftpy.TftpClient%27-module.html#MAX_BLKSIZE +tftpy.TftpClient'.TIMEOUT_RETRIES tftpy.TftpClient%27-module.html#TIMEOUT_RETRIES +tftpy.TftpClient'.LOG_LEVEL tftpy.TftpClient%27-module.html#LOG_LEVEL +tftpy.TftpClient'.log tftpy.TftpClient%27-module.html#log +tftpy.TftpClient'.DEF_TFTP_PORT tftpy.TftpClient%27-module.html#DEF_TFTP_PORT +tftpy.TftpClient'.MAX_DUPS tftpy.TftpClient%27-module.html#MAX_DUPS +tftpy.TftpClient'.MIN_BLKSIZE tftpy.TftpClient%27-module.html#MIN_BLKSIZE +tftpy.TftpClient'.SOCK_TIMEOUT tftpy.TftpClient%27-module.html#SOCK_TIMEOUT +tftpy.TftpClient'.DEF_BLKSIZE tftpy.TftpClient%27-module.html#DEF_BLKSIZE +tftpy.TftpPacketFactory' tftpy.TftpPacketFactory%27-module.html +tftpy.TftpPacketFactory'.MAX_BLKSIZE tftpy.TftpPacketFactory%27-module.html#MAX_BLKSIZE +tftpy.TftpPacketFactory'.MAX_DUPS tftpy.TftpPacketFactory%27-module.html#MAX_DUPS +tftpy.TftpPacketFactory'.TIMEOUT_RETRIES tftpy.TftpPacketFactory%27-module.html#TIMEOUT_RETRIES +tftpy.TftpPacketFactory'.LOG_LEVEL tftpy.TftpPacketFactory%27-module.html#LOG_LEVEL +tftpy.TftpPacketFactory'.log tftpy.TftpPacketFactory%27-module.html#log +tftpy.TftpPacketFactory'.DEF_TFTP_PORT tftpy.TftpPacketFactory%27-module.html#DEF_TFTP_PORT +tftpy.TftpPacketFactory'.MIN_BLKSIZE tftpy.TftpPacketFactory%27-module.html#MIN_BLKSIZE +tftpy.TftpPacketFactory'.SOCK_TIMEOUT tftpy.TftpPacketFactory%27-module.html#SOCK_TIMEOUT +tftpy.TftpPacketFactory'.DEF_BLKSIZE tftpy.TftpPacketFactory%27-module.html#DEF_BLKSIZE +tftpy.TftpPacketTypes tftpy.TftpPacketTypes-module.html +tftpy.TftpPacketTypes.tftpassert tftpy.TftpShared-module.html#tftpassert +tftpy.TftpPacketTypes.setLogLevel tftpy.TftpShared-module.html#setLogLevel +tftpy.TftpServer' tftpy.TftpServer%27-module.html +tftpy.TftpServer'.MAX_BLKSIZE tftpy.TftpServer%27-module.html#MAX_BLKSIZE +tftpy.TftpServer'.TIMEOUT_RETRIES tftpy.TftpServer%27-module.html#TIMEOUT_RETRIES +tftpy.TftpServer'.LOG_LEVEL tftpy.TftpServer%27-module.html#LOG_LEVEL +tftpy.TftpServer'.log tftpy.TftpServer%27-module.html#log +tftpy.TftpServer'.DEF_TFTP_PORT tftpy.TftpServer%27-module.html#DEF_TFTP_PORT +tftpy.TftpServer'.MAX_DUPS tftpy.TftpServer%27-module.html#MAX_DUPS +tftpy.TftpServer'.MIN_BLKSIZE tftpy.TftpServer%27-module.html#MIN_BLKSIZE +tftpy.TftpServer'.SOCK_TIMEOUT tftpy.TftpServer%27-module.html#SOCK_TIMEOUT +tftpy.TftpServer'.DEF_BLKSIZE tftpy.TftpServer%27-module.html#DEF_BLKSIZE +tftpy.TftpShared tftpy.TftpShared-module.html +tftpy.TftpShared.DEF_BLKSIZE tftpy.TftpShared-module.html#DEF_BLKSIZE +tftpy.TftpShared.MAX_BLKSIZE tftpy.TftpShared-module.html#MAX_BLKSIZE +tftpy.TftpShared.setLogLevel tftpy.TftpShared-module.html#setLogLevel +tftpy.TftpShared.MIN_BLKSIZE tftpy.TftpShared-module.html#MIN_BLKSIZE +tftpy.TftpShared.log tftpy.TftpShared-module.html#log +tftpy.TftpShared.tftpassert tftpy.TftpShared-module.html#tftpassert +tftpy.TftpShared.MAX_DUPS tftpy.TftpShared-module.html#MAX_DUPS +tftpy.TftpShared.TIMEOUT_RETRIES tftpy.TftpShared-module.html#TIMEOUT_RETRIES +tftpy.TftpShared.SOCK_TIMEOUT tftpy.TftpShared-module.html#SOCK_TIMEOUT +tftpy.TftpShared.LOG_LEVEL tftpy.TftpShared-module.html#LOG_LEVEL +tftpy.TftpShared.DEF_TFTP_PORT tftpy.TftpShared-module.html#DEF_TFTP_PORT +tftpy.TftpStates tftpy.TftpStates-module.html +tftpy.TftpClient'.TftpClient tftpy.TftpClient%27.TftpClient-class.html +tftpy.TftpClient'.TftpClient.upload tftpy.TftpClient%27.TftpClient-class.html#upload +tftpy.TftpClient'.TftpClient.download tftpy.TftpClient%27.TftpClient-class.html#download +tftpy.TftpClient'.TftpClient.__init__ tftpy.TftpClient%27.TftpClient-class.html#__init__ +tftpy.TftpPacketFactory'.TftpPacketFactory tftpy.TftpPacketFactory%27.TftpPacketFactory-class.html +tftpy.TftpPacketFactory'.TftpPacketFactory.parse tftpy.TftpPacketFactory%27.TftpPacketFactory-class.html#parse +tftpy.TftpPacketFactory'.TftpPacketFactory.__create tftpy.TftpPacketFactory%27.TftpPacketFactory-class.html#__create +tftpy.TftpPacketFactory'.TftpPacketFactory.__init__ tftpy.TftpPacketFactory%27.TftpPacketFactory-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacket tftpy.TftpPacketTypes.TftpPacket-class.html +tftpy.TftpPacketTypes.TftpPacket.decode tftpy.TftpPacketTypes.TftpPacket-class.html#decode +tftpy.TftpPacketTypes.TftpPacket.encode tftpy.TftpPacketTypes.TftpPacket-class.html#encode +tftpy.TftpPacketTypes.TftpPacket.__init__ tftpy.TftpPacketTypes.TftpPacket-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketACK tftpy.TftpPacketTypes.TftpPacketACK-class.html +tftpy.TftpPacketTypes.TftpPacketACK.__str__ tftpy.TftpPacketTypes.TftpPacketACK-class.html#__str__ +tftpy.TftpPacketTypes.TftpPacketACK.decode tftpy.TftpPacketTypes.TftpPacketACK-class.html#decode +tftpy.TftpPacketTypes.TftpPacketACK.encode tftpy.TftpPacketTypes.TftpPacketACK-class.html#encode +tftpy.TftpPacketTypes.TftpPacketACK.__init__ tftpy.TftpPacketTypes.TftpPacketACK-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketDAT tftpy.TftpPacketTypes.TftpPacketDAT-class.html +tftpy.TftpPacketTypes.TftpPacketDAT.__str__ tftpy.TftpPacketTypes.TftpPacketDAT-class.html#__str__ +tftpy.TftpPacketTypes.TftpPacketDAT.decode tftpy.TftpPacketTypes.TftpPacketDAT-class.html#decode +tftpy.TftpPacketTypes.TftpPacketDAT.encode tftpy.TftpPacketTypes.TftpPacketDAT-class.html#encode +tftpy.TftpPacketTypes.TftpPacketDAT.__init__ tftpy.TftpPacketTypes.TftpPacketDAT-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketERR tftpy.TftpPacketTypes.TftpPacketERR-class.html +tftpy.TftpPacketTypes.TftpPacketERR.__str__ tftpy.TftpPacketTypes.TftpPacketERR-class.html#__str__ +tftpy.TftpPacketTypes.TftpPacketERR.decode tftpy.TftpPacketTypes.TftpPacketERR-class.html#decode +tftpy.TftpPacketTypes.TftpPacketERR.encode tftpy.TftpPacketTypes.TftpPacketERR-class.html#encode +tftpy.TftpPacketTypes.TftpPacketERR.__init__ tftpy.TftpPacketTypes.TftpPacketERR-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketInitial tftpy.TftpPacketTypes.TftpPacketInitial-class.html +tftpy.TftpPacketTypes.TftpPacketWithOptions.setoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#setoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.decode_options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#decode_options +tftpy.TftpPacketTypes.TftpPacketInitial.decode tftpy.TftpPacketTypes.TftpPacketInitial-class.html#decode +tftpy.TftpPacketTypes.TftpPacketInitial.encode tftpy.TftpPacketTypes.TftpPacketInitial-class.html#encode +tftpy.TftpPacketTypes.TftpPacketWithOptions.getoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#getoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#options +tftpy.TftpPacketTypes.TftpPacketInitial.__init__ tftpy.TftpPacketTypes.TftpPacketInitial-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketOACK tftpy.TftpPacketTypes.TftpPacketOACK-class.html +tftpy.TftpPacketTypes.TftpPacketWithOptions.setoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#setoptions +tftpy.TftpPacketTypes.TftpPacketOACK.__str__ tftpy.TftpPacketTypes.TftpPacketOACK-class.html#__str__ +tftpy.TftpPacketTypes.TftpPacketWithOptions.decode_options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#decode_options +tftpy.TftpPacketTypes.TftpPacketOACK.decode tftpy.TftpPacketTypes.TftpPacketOACK-class.html#decode +tftpy.TftpPacketTypes.TftpPacketOACK.match_options tftpy.TftpPacketTypes.TftpPacketOACK-class.html#match_options +tftpy.TftpPacketTypes.TftpPacketOACK.encode tftpy.TftpPacketTypes.TftpPacketOACK-class.html#encode +tftpy.TftpPacketTypes.TftpPacketWithOptions.getoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#getoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#options +tftpy.TftpPacketTypes.TftpPacketOACK.__init__ tftpy.TftpPacketTypes.TftpPacketOACK-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketRRQ tftpy.TftpPacketTypes.TftpPacketRRQ-class.html +tftpy.TftpPacketTypes.TftpPacketWithOptions.setoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#setoptions +tftpy.TftpPacketTypes.TftpPacketRRQ.__str__ tftpy.TftpPacketTypes.TftpPacketRRQ-class.html#__str__ +tftpy.TftpPacketTypes.TftpPacketWithOptions.decode_options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#decode_options +tftpy.TftpPacketTypes.TftpPacketInitial.decode tftpy.TftpPacketTypes.TftpPacketInitial-class.html#decode +tftpy.TftpPacketTypes.TftpPacketInitial.encode tftpy.TftpPacketTypes.TftpPacketInitial-class.html#encode +tftpy.TftpPacketTypes.TftpPacketWithOptions.getoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#getoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#options +tftpy.TftpPacketTypes.TftpPacketRRQ.__init__ tftpy.TftpPacketTypes.TftpPacketRRQ-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketWRQ tftpy.TftpPacketTypes.TftpPacketWRQ-class.html +tftpy.TftpPacketTypes.TftpPacketWithOptions.setoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#setoptions +tftpy.TftpPacketTypes.TftpPacketWRQ.__str__ tftpy.TftpPacketTypes.TftpPacketWRQ-class.html#__str__ +tftpy.TftpPacketTypes.TftpPacketWithOptions.decode_options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#decode_options +tftpy.TftpPacketTypes.TftpPacketInitial.decode tftpy.TftpPacketTypes.TftpPacketInitial-class.html#decode +tftpy.TftpPacketTypes.TftpPacketInitial.encode tftpy.TftpPacketTypes.TftpPacketInitial-class.html#encode +tftpy.TftpPacketTypes.TftpPacketWithOptions.getoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#getoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#options +tftpy.TftpPacketTypes.TftpPacketWRQ.__init__ tftpy.TftpPacketTypes.TftpPacketWRQ-class.html#__init__ +tftpy.TftpPacketTypes.TftpPacketWithOptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html +tftpy.TftpPacketTypes.TftpPacketWithOptions.decode_options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#decode_options +tftpy.TftpPacketTypes.TftpPacketWithOptions.setoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#setoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.getoptions tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#getoptions +tftpy.TftpPacketTypes.TftpPacketWithOptions.options tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#options +tftpy.TftpPacketTypes.TftpPacketWithOptions.__init__ tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html#__init__ +tftpy.TftpPacketTypes.TftpSession tftpy.TftpPacketTypes.TftpSession-class.html +tftpy.TftpServer'.TftpServer tftpy.TftpServer%27.TftpServer-class.html +tftpy.TftpServer'.TftpServer.__init__ tftpy.TftpServer%27.TftpServer-class.html#__init__ +tftpy.TftpServer'.TftpServer.listen tftpy.TftpServer%27.TftpServer-class.html#listen +tftpy.TftpShared.TftpErrors tftpy.TftpShared.TftpErrors-class.html +tftpy.TftpShared.TftpErrors.IllegalTftpOp tftpy.TftpShared.TftpErrors-class.html#IllegalTftpOp +tftpy.TftpShared.TftpErrors.DiskFull tftpy.TftpShared.TftpErrors-class.html#DiskFull +tftpy.TftpShared.TftpErrors.UnknownTID tftpy.TftpShared.TftpErrors-class.html#UnknownTID +tftpy.TftpShared.TftpErrors.FileAlreadyExists tftpy.TftpShared.TftpErrors-class.html#FileAlreadyExists +tftpy.TftpShared.TftpErrors.NoSuchUser tftpy.TftpShared.TftpErrors-class.html#NoSuchUser +tftpy.TftpShared.TftpErrors.FailedNegotiation tftpy.TftpShared.TftpErrors-class.html#FailedNegotiation +tftpy.TftpShared.TftpErrors.NotDefined tftpy.TftpShared.TftpErrors-class.html#NotDefined +tftpy.TftpShared.TftpErrors.AccessViolation tftpy.TftpShared.TftpErrors-class.html#AccessViolation +tftpy.TftpShared.TftpErrors.FileNotFound tftpy.TftpShared.TftpErrors-class.html#FileNotFound +tftpy.TftpShared.TftpException tftpy.TftpShared.TftpException-class.html +tftpy.TftpStates.TftpContext tftpy.TftpStates.TftpContext-class.html +tftpy.TftpStates.TftpContext.end tftpy.TftpStates.TftpContext-class.html#end +tftpy.TftpStates.TftpContext.checkTimeout tftpy.TftpStates.TftpContext-class.html#checkTimeout +tftpy.TftpStates.TftpContext.sethost tftpy.TftpStates.TftpContext-class.html#sethost +tftpy.TftpStates.TftpContext.setNextBlock tftpy.TftpStates.TftpContext-class.html#setNextBlock +tftpy.TftpStates.TftpContext.start tftpy.TftpStates.TftpContext-class.html#start +tftpy.TftpStates.TftpContext.host tftpy.TftpStates.TftpContext-class.html#host +tftpy.TftpStates.TftpContext.getNextBlock tftpy.TftpStates.TftpContext-class.html#getNextBlock +tftpy.TftpStates.TftpContext.cycle tftpy.TftpStates.TftpContext-class.html#cycle +tftpy.TftpStates.TftpContext.gethost tftpy.TftpStates.TftpContext-class.html#gethost +tftpy.TftpStates.TftpContext.__init__ tftpy.TftpStates.TftpContext-class.html#__init__ +tftpy.TftpStates.TftpContext.next_block tftpy.TftpStates.TftpContext-class.html#next_block +tftpy.TftpStates.TftpContextClientDownload tftpy.TftpStates.TftpContextClientDownload-class.html +tftpy.TftpStates.TftpContextClientDownload.end tftpy.TftpStates.TftpContextClientDownload-class.html#end +tftpy.TftpStates.TftpContext.checkTimeout tftpy.TftpStates.TftpContext-class.html#checkTimeout +tftpy.TftpStates.TftpContext.sethost tftpy.TftpStates.TftpContext-class.html#sethost +tftpy.TftpStates.TftpContext.setNextBlock tftpy.TftpStates.TftpContext-class.html#setNextBlock +tftpy.TftpStates.TftpContextClientDownload.start tftpy.TftpStates.TftpContextClientDownload-class.html#start +tftpy.TftpStates.TftpContext.host tftpy.TftpStates.TftpContext-class.html#host +tftpy.TftpStates.TftpContext.getNextBlock tftpy.TftpStates.TftpContext-class.html#getNextBlock +tftpy.TftpStates.TftpContext.next_block tftpy.TftpStates.TftpContext-class.html#next_block +tftpy.TftpStates.TftpContext.gethost tftpy.TftpStates.TftpContext-class.html#gethost +tftpy.TftpStates.TftpContextClientDownload.__init__ tftpy.TftpStates.TftpContextClientDownload-class.html#__init__ +tftpy.TftpStates.TftpContext.cycle tftpy.TftpStates.TftpContext-class.html#cycle +tftpy.TftpStates.TftpContextClientUpload tftpy.TftpStates.TftpContextClientUpload-class.html +tftpy.TftpStates.TftpContextClientUpload.end tftpy.TftpStates.TftpContextClientUpload-class.html#end +tftpy.TftpStates.TftpContext.checkTimeout tftpy.TftpStates.TftpContext-class.html#checkTimeout +tftpy.TftpStates.TftpContext.sethost tftpy.TftpStates.TftpContext-class.html#sethost +tftpy.TftpStates.TftpContext.setNextBlock tftpy.TftpStates.TftpContext-class.html#setNextBlock +tftpy.TftpStates.TftpContextClientUpload.start tftpy.TftpStates.TftpContextClientUpload-class.html#start +tftpy.TftpStates.TftpContext.host tftpy.TftpStates.TftpContext-class.html#host +tftpy.TftpStates.TftpContext.getNextBlock tftpy.TftpStates.TftpContext-class.html#getNextBlock +tftpy.TftpStates.TftpContext.next_block tftpy.TftpStates.TftpContext-class.html#next_block +tftpy.TftpStates.TftpContext.gethost tftpy.TftpStates.TftpContext-class.html#gethost +tftpy.TftpStates.TftpContextClientUpload.__init__ tftpy.TftpStates.TftpContextClientUpload-class.html#__init__ +tftpy.TftpStates.TftpContext.cycle tftpy.TftpStates.TftpContext-class.html#cycle +tftpy.TftpStates.TftpContextServer tftpy.TftpStates.TftpContextServer-class.html +tftpy.TftpStates.TftpContextServer.end tftpy.TftpStates.TftpContextServer-class.html#end +tftpy.TftpStates.TftpContext.checkTimeout tftpy.TftpStates.TftpContext-class.html#checkTimeout +tftpy.TftpStates.TftpContext.sethost tftpy.TftpStates.TftpContext-class.html#sethost +tftpy.TftpStates.TftpContext.setNextBlock tftpy.TftpStates.TftpContext-class.html#setNextBlock +tftpy.TftpStates.TftpContextServer.start tftpy.TftpStates.TftpContextServer-class.html#start +tftpy.TftpStates.TftpContext.host tftpy.TftpStates.TftpContext-class.html#host +tftpy.TftpStates.TftpContext.getNextBlock tftpy.TftpStates.TftpContext-class.html#getNextBlock +tftpy.TftpStates.TftpContext.next_block tftpy.TftpStates.TftpContext-class.html#next_block +tftpy.TftpStates.TftpContext.gethost tftpy.TftpStates.TftpContext-class.html#gethost +tftpy.TftpStates.TftpContextServer.__init__ tftpy.TftpStates.TftpContextServer-class.html#__init__ +tftpy.TftpStates.TftpContext.cycle tftpy.TftpStates.TftpContext-class.html#cycle +tftpy.TftpStates.TftpMetrics tftpy.TftpStates.TftpMetrics-class.html +tftpy.TftpStates.TftpMetrics.compute tftpy.TftpStates.TftpMetrics-class.html#compute +tftpy.TftpStates.TftpMetrics.add_dup tftpy.TftpStates.TftpMetrics-class.html#add_dup +tftpy.TftpStates.TftpMetrics.__init__ tftpy.TftpStates.TftpMetrics-class.html#__init__ +tftpy.TftpStates.TftpState tftpy.TftpStates.TftpState-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpState.handle tftpy.TftpStates.TftpState-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpStateExpectACK tftpy.TftpStates.TftpStateExpectACK-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateExpectACK.handle tftpy.TftpStates.TftpStateExpectACK-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpStateExpectDAT tftpy.TftpStates.TftpStateExpectDAT-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateExpectDAT.handle tftpy.TftpStates.TftpStateExpectDAT-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpStateSentRRQ tftpy.TftpStates.TftpStateSentRRQ-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateSentRRQ.handle tftpy.TftpStates.TftpStateSentRRQ-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpStateSentWRQ tftpy.TftpStates.TftpStateSentWRQ-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateSentWRQ.handle tftpy.TftpStates.TftpStateSentWRQ-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpStateServerRecvRRQ tftpy.TftpStates.TftpStateServerRecvRRQ-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateServerRecvRRQ.handle tftpy.TftpStates.TftpStateServerRecvRRQ-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpStateServerRecvWRQ tftpy.TftpStates.TftpStateServerRecvWRQ-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateServerRecvWRQ.handle tftpy.TftpStates.TftpStateServerRecvWRQ-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT +tftpy.TftpStates.TftpStateServerStart tftpy.TftpStates.TftpStateServerStart-class.html +tftpy.TftpStates.TftpState.sendError tftpy.TftpStates.TftpState-class.html#sendError +tftpy.TftpStates.TftpStateServerStart.handle tftpy.TftpStates.TftpStateServerStart-class.html#handle +tftpy.TftpStates.TftpState.handleOACK tftpy.TftpStates.TftpState-class.html#handleOACK +tftpy.TftpStates.TftpState.handleDat tftpy.TftpStates.TftpState-class.html#handleDat +tftpy.TftpStates.TftpState.serverInitial tftpy.TftpStates.TftpState-class.html#serverInitial +tftpy.TftpStates.TftpState.returnSupportedOptions tftpy.TftpStates.TftpState-class.html#returnSupportedOptions +tftpy.TftpStates.TftpState.__init__ tftpy.TftpStates.TftpState-class.html#__init__ +tftpy.TftpStates.TftpState.sendACK tftpy.TftpStates.TftpState-class.html#sendACK +tftpy.TftpStates.TftpState.sendOACK tftpy.TftpStates.TftpState-class.html#sendOACK +tftpy.TftpStates.TftpState.sendDAT tftpy.TftpStates.TftpState-class.html#sendDAT diff --git a/html/tftpy-doc/class-tree.html b/html/tftpy-doc/class-tree.html new file mode 100644 index 0000000..c22662e --- /dev/null +++ b/html/tftpy-doc/class-tree.html @@ -0,0 +1,245 @@ + + + + +Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ |
+ |
+
+
Class Hierarchy
+-
+
- object:
+ The most base type
+
-
+
- exceptions.BaseException:
+ Common base class for all exceptions
+
-
+
- exceptions.Exception:
+ Common base class for all non-exit exceptions.
+
-
+
- tftpy.TftpShared.TftpException: + This class is the parent class of all exceptions regarding the + handling of the TFTP protocol. + +
+
+ - exceptions.Exception:
+ Common base class for all non-exit exceptions.
+
- tftpy.TftpStates.TftpContext:
+ The base class of the contexts.
+
-
+
- tftpy.TftpStates.TftpContextClientDownload: + The download context for the client during a download. + +
- tftpy.TftpStates.TftpContextClientUpload: + The upload context for the client during an upload. + +
- tftpy.TftpStates.TftpContextServer: + The context for the server. + +
+ - tftpy.TftpShared.TftpErrors: + This class is a convenience for defining the common tftp error + codes, and making them more readable in the code. + +
- tftpy.TftpStates.TftpMetrics: + A class representing metrics of the transfer. + +
- tftpy.TftpPacketTypes.TftpPacket:
+ This class is the parent class of all tftp packet classes.
+
-
+
- tftpy.TftpPacketTypes.TftpPacketACK: + 2 bytes 2 bytes... + +
- tftpy.TftpPacketTypes.TftpPacketDAT: + 2 bytes 2 bytes n bytes... + +
- tftpy.TftpPacketTypes.TftpPacketERR: + 2 bytes 2 bytes string 1 byte + ---------------------------------------- +ERROR | 05 | ErrorCode | ErrMsg | 0 | + ---------------------------------------- + Error Codes + +
- tftpy.TftpPacketTypes.TftpPacketInitial:
+ This class is a common parent class for the RRQ and WRQ packets, as
+ they share quite a bit of code.
+
-
+
- tftpy.TftpPacketTypes.TftpPacketRRQ: + 2 bytes string 1 byte string 1 byte... + +
- tftpy.TftpPacketTypes.TftpPacketWRQ: + 2 bytes string 1 byte string 1 byte... + +
+ - tftpy.TftpPacketTypes.TftpPacketOACK: + # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ # + | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | # + +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + +
+ - tftpy.TftpPacketFactory'.TftpPacketFactory: + This class generates TftpPacket objects. + +
- tftpy.TftpPacketTypes.TftpPacketWithOptions:
+ This class exists to permit some TftpPacket subclasses to share
+ code regarding options handling.
+
-
+
- tftpy.TftpPacketTypes.TftpPacketInitial:
+ This class is a common parent class for the RRQ and WRQ packets, as
+ they share quite a bit of code.
+
-
+
- tftpy.TftpPacketTypes.TftpPacketRRQ: + 2 bytes string 1 byte string 1 byte... + +
- tftpy.TftpPacketTypes.TftpPacketWRQ: + 2 bytes string 1 byte string 1 byte... + +
+ - tftpy.TftpPacketTypes.TftpPacketOACK: + # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ # + | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | # + +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + +
+ - tftpy.TftpPacketTypes.TftpPacketInitial:
+ This class is a common parent class for the RRQ and WRQ packets, as
+ they share quite a bit of code.
+
- tftpy.TftpPacketTypes.TftpSession:
+ This class is the base class for the tftp client and server.
+
-
+
- tftpy.TftpClient'.TftpClient: + This class is an implementation of a tftp client. + +
- tftpy.TftpServer'.TftpServer: + This class implements a tftp server object. + +
+ - tftpy.TftpStates.TftpState:
+ The base class for the states.
+
-
+
- tftpy.TftpStates.TftpStateExpectACK: + This class represents the state of the transfer when a DAT was just + sent, and we are waiting for an ACK from the server. + +
- tftpy.TftpStates.TftpStateExpectDAT: + Just sent an ACK packet. + +
- tftpy.TftpStates.TftpStateSentRRQ: + Just sent an RRQ packet. + +
- tftpy.TftpStates.TftpStateSentWRQ: + Just sent an WRQ packet for an upload. + +
- tftpy.TftpStates.TftpStateServerRecvRRQ: + This class represents the state of the TFTP server when it has just + received an RRQ packet. + +
- tftpy.TftpStates.TftpStateServerRecvWRQ: + This class represents the state of the TFTP server when it has just + received a WRQ packet. + +
- tftpy.TftpStates.TftpStateServerStart: + The start state for the server. + +
+
+ - exceptions.BaseException:
+ Common base class for all exceptions
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
). The page title may be followed by a link to the
+ * corresponding source code (using 'span.codelink').
+ * - The footer consists of a navigation bar, a timestamp, and a
+ * pointer to epydoc's homepage.
+ */
+h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; }
+h2.epydoc { font-size: +130%; font-weight: bold; }
+h3.epydoc { font-size: +115%; font-weight: bold;
+ margin-top: 0.2em; }
+td h3.epydoc { font-size: +115%; font-weight: bold;
+ margin-bottom: 0; }
+table.navbar { background: #a0c0ff; color: #000000;
+ border: 2px groove #c0d0d0; }
+table.navbar table { color: #000000; }
+th.navbar-select { background: #70b0ff;
+ color: #000000; }
+table.navbar a { text-decoration: none; }
+table.navbar a:link { color: #0000ff; }
+table.navbar a:visited { color: #204080; }
+span.breadcrumbs { font-size: 85%; font-weight: bold; }
+span.options { font-size: 70%; }
+span.codelink { font-size: 85%; }
+td.footer { font-size: 85%; }
+
+/* Table Headers
+ * - Each summary table and details section begins with a 'header'
+ * row. This row contains a section title (marked by
+ * 'span.table-header') as well as a show/hide private link
+ * (marked by 'span.options', defined above).
+ * - Summary tables that contain user-defined groups mark those
+ * groups using 'group header' rows.
+ */
+td.table-header { background: #70b0ff; color: #000000;
+ border: 1px solid #608090; }
+td.table-header table { color: #000000; }
+td.table-header table a:link { color: #0000ff; }
+td.table-header table a:visited { color: #204080; }
+span.table-header { font-size: 120%; font-weight: bold; }
+th.group-header { background: #c0e0f8; color: #000000;
+ text-align: left; font-style: italic;
+ font-size: 115%;
+ border: 1px solid #608090; }
+
+/* Summary Tables (functions, variables, etc)
+ * - Each object is described by a single row of the table with
+ * two cells. The left cell gives the object's type, and is
+ * marked with 'code.summary-type'. The right cell gives the
+ * object's name and a summary description.
+ * - CSS styles for the table's header and group headers are
+ * defined above, under 'Table Headers'
+ */
+table.summary { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090;
+ margin-bottom: 0.5em; }
+td.summary { border: 1px solid #608090; }
+code.summary-type { font-size: 85%; }
+table.summary a:link { color: #0000ff; }
+table.summary a:visited { color: #204080; }
+
+
+/* Details Tables (functions, variables, etc)
+ * - Each object is described in its own div.
+ * - A single-row summary table w/ table-header is used as
+ * a header for each details section (CSS style for table-header
+ * is defined above, under 'Table Headers').
+ */
+table.details { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090;
+ margin: .2em 0 0 0; }
+table.details table { color: #000000; }
+table.details a:link { color: #0000ff; }
+table.details a:visited { color: #204080; }
+
+/* Fields */
+dl.fields { margin-left: 2em; margin-top: 1em;
+ margin-bottom: 1em; }
+dl.fields dd ul { margin-left: 0em; padding-left: 0em; }
+dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; }
+div.fields { margin-left: 2em; }
+div.fields p { margin-bottom: 0.5em; }
+
+/* Index tables (identifier index, term index, etc)
+ * - link-index is used for indices containing lists of links
+ * (namely, the identifier index & term index).
+ * - index-where is used in link indices for the text indicating
+ * the container/source for each link.
+ * - metadata-index is used for indices containing metadata
+ * extracted from fields (namely, the bug index & todo index).
+ */
+table.link-index { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090; }
+td.link-index { border-width: 0px; }
+table.link-index a:link { color: #0000ff; }
+table.link-index a:visited { color: #204080; }
+span.index-where { font-size: 70%; }
+table.metadata-index { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090;
+ margin: .2em 0 0 0; }
+td.metadata-index { border-width: 1px; border-style: solid; }
+table.metadata-index a:link { color: #0000ff; }
+table.metadata-index a:visited { color: #204080; }
+
+/* Function signatures
+ * - sig* is used for the signature in the details section.
+ * - .summary-sig* is used for the signature in the summary
+ * table, and when listing property accessor functions.
+ * */
+.sig-name { color: #006080; }
+.sig-arg { color: #008060; }
+.sig-default { color: #602000; }
+.summary-sig { font-family: monospace; }
+.summary-sig-name { color: #006080; font-weight: bold; }
+table.summary a.summary-sig-name:link
+ { color: #006080; font-weight: bold; }
+table.summary a.summary-sig-name:visited
+ { color: #006080; font-weight: bold; }
+.summary-sig-arg { color: #006040; }
+.summary-sig-default { color: #501800; }
+
+/* Subclass list
+ */
+ul.subclass-list { display: inline; }
+ul.subclass-list li { display: inline; }
+
+/* To render variables, classes etc. like functions */
+table.summary .summary-name { color: #006080; font-weight: bold;
+ font-family: monospace; }
+table.summary
+ a.summary-name:link { color: #006080; font-weight: bold;
+ font-family: monospace; }
+table.summary
+ a.summary-name:visited { color: #006080; font-weight: bold;
+ font-family: monospace; }
+
+/* Variable values
+ * - In the 'variable details' sections, each varaible's value is
+ * listed in a 'pre.variable' box. The width of this box is
+ * restricted to 80 chars; if the value's repr is longer than
+ * this it will be wrapped, using a backslash marked with
+ * class 'variable-linewrap'. If the value's repr is longer
+ * than 3 lines, the rest will be ellided; and an ellipsis
+ * marker ('...' marked with 'variable-ellipsis') will be used.
+ * - If the value is a string, its quote marks will be marked
+ * with 'variable-quote'.
+ * - If the variable is a regexp, it is syntax-highlighted using
+ * the re* CSS classes.
+ */
+pre.variable { padding: .5em; margin: 0;
+ background: #dce4ec; color: #000000;
+ border: 1px solid #708890; }
+.variable-linewrap { color: #604000; font-weight: bold; }
+.variable-ellipsis { color: #604000; font-weight: bold; }
+.variable-quote { color: #604000; font-weight: bold; }
+.variable-group { color: #008000; font-weight: bold; }
+.variable-op { color: #604000; font-weight: bold; }
+.variable-string { color: #006030; }
+.variable-unknown { color: #a00000; font-weight: bold; }
+.re { color: #000000; }
+.re-char { color: #006030; }
+.re-op { color: #600000; }
+.re-group { color: #003060; }
+.re-ref { color: #404040; }
+
+/* Base tree
+ * - Used by class pages to display the base class hierarchy.
+ */
+pre.base-tree { font-size: 80%; margin: 0; }
+
+/* Frames-based table of contents headers
+ * - Consists of two frames: one for selecting modules; and
+ * the other listing the contents of the selected module.
+ * - h1.toc is used for each frame's heading
+ * - h2.toc is used for subheadings within each frame.
+ */
+h1.toc { text-align: center; font-size: 105%;
+ margin: 0; font-weight: bold;
+ padding: 0; }
+h2.toc { font-size: 100%; font-weight: bold;
+ margin: 0.5em 0 0 -0.3em; }
+
+/* Syntax Highlighting for Source Code
+ * - doctest examples are displayed in a 'pre.py-doctest' block.
+ * If the example is in a details table entry, then it will use
+ * the colors specified by the 'table pre.py-doctest' line.
+ * - Source code listings are displayed in a 'pre.py-src' block.
+ * Each line is marked with 'span.py-line' (used to draw a line
+ * down the left margin, separating the code from the line
+ * numbers). Line numbers are displayed with 'span.py-lineno'.
+ * The expand/collapse block toggle button is displayed with
+ * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not
+ * modify the font size of the text.)
+ * - If a source code page is opened with an anchor, then the
+ * corresponding code block will be highlighted. The code
+ * block's header is highlighted with 'py-highlight-hdr'; and
+ * the code block's body is highlighted with 'py-highlight'.
+ * - The remaining py-* classes are used to perform syntax
+ * highlighting (py-string for string literals, py-name for names,
+ * etc.)
+ */
+pre.py-doctest { padding: .5em; margin: 1em;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #708890; }
+table pre.py-doctest { background: #dce4ec;
+ color: #000000; }
+pre.py-src { border: 2px solid #000000;
+ background: #f0f0f0; color: #000000; }
+.py-line { border-left: 2px solid #000000;
+ margin-left: .2em; padding-left: .4em; }
+.py-lineno { font-style: italic; font-size: 90%;
+ padding-left: .5em; }
+a.py-toggle { text-decoration: none; }
+div.py-highlight-hdr { border-top: 2px solid #000000;
+ border-bottom: 2px solid #000000;
+ background: #d8e8e8; }
+div.py-highlight { border-bottom: 2px solid #000000;
+ background: #d0e0e0; }
+.py-prompt { color: #005050; font-weight: bold;}
+.py-more { color: #005050; font-weight: bold;}
+.py-string { color: #006030; }
+.py-comment { color: #003060; }
+.py-keyword { color: #600000; }
+.py-output { color: #404040; }
+.py-name { color: #000050; }
+.py-name:link { color: #000050 !important; }
+.py-name:visited { color: #000050 !important; }
+.py-number { color: #005000; }
+.py-defname { color: #000060; font-weight: bold; }
+.py-def-name { color: #000060; font-weight: bold; }
+.py-base-class { color: #000060; }
+.py-param { color: #000060; }
+.py-docstring { color: #006030; }
+.py-decorator { color: #804020; }
+/* Use this if you don't want links to names underlined: */
+/*a.py-name { text-decoration: none; }*/
+
+/* Graphs & Diagrams
+ * - These CSS styles are used for graphs & diagrams generated using
+ * Graphviz dot. 'img.graph-without-title' is used for bare
+ * diagrams (to remove the border created by making the image
+ * clickable).
+ */
+img.graph-without-title { border: none; }
+img.graph-with-title { border: 1px solid #000000; }
+span.graph-title { font-weight: bold; }
+span.graph-caption { }
+
+/* General-purpose classes
+ * - 'p.indent-wrapped-lines' defines a paragraph whose first line
+ * is not indented, but whose subsequent lines are.
+ * - The 'nomargin-top' class is used to remove the top margin (e.g.
+ * from lists). The 'nomargin' class is used to remove both the
+ * top and bottom margin (but not the left or right margin --
+ * for lists, that would cause the bullets to disappear.)
+ */
+p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em;
+ margin: 0; }
+.nomargin-top { margin-top: 0; }
+.nomargin { margin-top: 0; margin-bottom: 0; }
+
+/* HTML Log */
+div.log-block { padding: 0; margin: .5em 0 .5em 0;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #000000; }
+div.log-error { padding: .1em .3em .1em .3em; margin: 4px;
+ background: #ffb0b0; color: #000000;
+ border: 1px solid #000000; }
+div.log-warning { padding: .1em .3em .1em .3em; margin: 4px;
+ background: #ffffb0; color: #000000;
+ border: 1px solid #000000; }
+div.log-info { padding: .1em .3em .1em .3em; margin: 4px;
+ background: #b0ffb0; color: #000000;
+ border: 1px solid #000000; }
+h2.log-hdr { background: #70b0ff; color: #000000;
+ margin: 0; padding: 0em 0.5em 0em 0.5em;
+ border-bottom: 1px solid #000000; font-size: 110%; }
+p.log { font-weight: bold; margin: .5em 0 .5em 0; }
+tr.opt-changed { color: #000000; font-weight: bold; }
+tr.opt-default { color: #606060; }
+pre.log { margin: 0; padding: 0; padding-left: 1em; }
diff --git a/html/tftpy-doc/epydoc.js b/html/tftpy-doc/epydoc.js
new file mode 100644
index 0000000..e787dbc
--- /dev/null
+++ b/html/tftpy-doc/epydoc.js
@@ -0,0 +1,293 @@
+function toggle_private() {
+ // Search for any private/public links on this page. Store
+ // their old text in "cmd," so we will know what action to
+ // take; and change their text to the opposite action.
+ var cmd = "?";
+ var elts = document.getElementsByTagName("a");
+ for(var i=0; i";
+ s += " ";
+ for (var i=0; i...
";
+ elt.innerHTML = s;
+ }
+}
+
+function toggle(id) {
+ elt = document.getElementById(id+"-toggle");
+ if (elt.innerHTML == "-")
+ collapse(id);
+ else
+ expand(id);
+ return false;
+}
+
+function highlight(id) {
+ var elt = document.getElementById(id+"-def");
+ if (elt) elt.className = "py-highlight-hdr";
+ var elt = document.getElementById(id+"-expanded");
+ if (elt) elt.className = "py-highlight";
+ var elt = document.getElementById(id+"-collapsed");
+ if (elt) elt.className = "py-highlight";
+}
+
+function num_lines(s) {
+ var n = 1;
+ var pos = s.indexOf("\n");
+ while ( pos > 0) {
+ n += 1;
+ pos = s.indexOf("\n", pos+1);
+ }
+ return n;
+}
+
+// Collapse all blocks that mave more than `min_lines` lines.
+function collapse_all(min_lines) {
+ var elts = document.getElementsByTagName("div");
+ for (var i=0; i 0)
+ if (elt.id.substring(split, elt.id.length) == "-expanded")
+ if (num_lines(elt.innerHTML) > min_lines)
+ collapse(elt.id.substring(0, split));
+ }
+}
+
+function expandto(href) {
+ var start = href.indexOf("#")+1;
+ if (start != 0 && start != href.length) {
+ if (href.substring(start, href.length) != "-") {
+ collapse_all(4);
+ pos = href.indexOf(".", start);
+ while (pos != -1) {
+ var id = href.substring(start, pos);
+ expand(id);
+ pos = href.indexOf(".", pos+1);
+ }
+ var id = href.substring(start, href.length);
+ expand(id);
+ highlight(id);
+ }
+ }
+}
+
+function kill_doclink(id) {
+ var parent = document.getElementById(id);
+ parent.removeChild(parent.childNodes.item(0));
+}
+function auto_kill_doclink(ev) {
+ if (!ev) var ev = window.event;
+ if (!this.contains(ev.toElement)) {
+ var parent = document.getElementById(this.parentID);
+ parent.removeChild(parent.childNodes.item(0));
+ }
+}
+
+function doclink(id, name, targets_id) {
+ var elt = document.getElementById(id);
+
+ // If we already opened the box, then destroy it.
+ // (This case should never occur, but leave it in just in case.)
+ if (elt.childNodes.length > 1) {
+ elt.removeChild(elt.childNodes.item(0));
+ }
+ else {
+ // The outer box: relative + inline positioning.
+ var box1 = document.createElement("div");
+ box1.style.position = "relative";
+ box1.style.display = "inline";
+ box1.style.top = 0;
+ box1.style.left = 0;
+
+ // A shadow for fun
+ var shadow = document.createElement("div");
+ shadow.style.position = "absolute";
+ shadow.style.left = "-1.3em";
+ shadow.style.top = "-1.3em";
+ shadow.style.background = "#404040";
+
+ // The inner box: absolute positioning.
+ var box2 = document.createElement("div");
+ box2.style.position = "relative";
+ box2.style.border = "1px solid #a0a0a0";
+ box2.style.left = "-.2em";
+ box2.style.top = "-.2em";
+ box2.style.background = "white";
+ box2.style.padding = ".3em .4em .3em .4em";
+ box2.style.fontStyle = "normal";
+ box2.onmouseout=auto_kill_doclink;
+ box2.parentID = id;
+
+ // Get the targets
+ var targets_elt = document.getElementById(targets_id);
+ var targets = targets_elt.getAttribute("targets");
+ var links = "";
+ target_list = targets.split(",");
+ for (var i=0; i" +
+ target[0] + "";
+ }
+
+ // Put it all together.
+ elt.insertBefore(box1, elt.childNodes.item(0));
+ //box1.appendChild(box2);
+ box1.appendChild(shadow);
+ shadow.appendChild(box2);
+ box2.innerHTML =
+ "Which "+name+" do you want to see documentation for?" +
+ "" +
+ links +
+ "- "+
+ "None of the above
";
+ }
+ return false;
+}
+
+function get_anchor() {
+ var href = location.href;
+ var start = href.indexOf("#")+1;
+ if ((start != 0) && (start != href.length))
+ return href.substring(start, href.length);
+ }
+function redirect_url(dottedName) {
+ // Scan through each element of the "pages" list, and check
+ // if "name" matches with any of them.
+ for (var i=0; i-m" or "-c";
+ // extract the portion & compare it to dottedName.
+ var pagename = pages[i].substring(0, pages[i].length-2);
+ if (pagename == dottedName.substring(0,pagename.length)) {
+
+ // We've found a page that matches `dottedName`;
+ // construct its URL, using leftover `dottedName`
+ // content to form an anchor.
+ var pagetype = pages[i].charAt(pages[i].length-1);
+ var url = pagename + ((pagetype=="m")?"-module.html":
+ "-class.html");
+ if (dottedName.length > pagename.length)
+ url += "#" + dottedName.substring(pagename.length+1,
+ dottedName.length);
+ return url;
+ }
+ }
+ }
diff --git a/html/tftpy-doc/frames.html b/html/tftpy-doc/frames.html
new file mode 100644
index 0000000..17cf982
--- /dev/null
+++ b/html/tftpy-doc/frames.html
@@ -0,0 +1,17 @@
+
+
+
+
+ API Documentation
+
+
+
diff --git a/html/tftpy-doc/help.html b/html/tftpy-doc/help.html
new file mode 100644
index 0000000..f073451
--- /dev/null
+++ b/html/tftpy-doc/help.html
@@ -0,0 +1,268 @@
+
+
+
+
+ Help
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ API Documentation
+
+ This document contains the API (Application Programming Interface)
+documentation for this project. Documentation for the Python
+objects defined by the project is divided into separate pages for each
+package, module, and class. The API documentation also includes two
+pages containing information about the project as a whole: a trees
+page, and an index page.
+
+ Object Documentation
+
+ Each Package Documentation page contains:
+
+ - A description of the package.
+ - A list of the modules and sub-packages contained by the
+ package.
+ - A summary of the classes defined by the package.
+ - A summary of the functions defined by the package.
+ - A summary of the variables defined by the package.
+ - A detailed description of each function defined by the
+ package.
+ - A detailed description of each variable defined by the
+ package.
+
+
+ Each Module Documentation page contains:
+
+ - A description of the module.
+ - A summary of the classes defined by the module.
+ - A summary of the functions defined by the module.
+ - A summary of the variables defined by the module.
+ - A detailed description of each function defined by the
+ module.
+ - A detailed description of each variable defined by the
+ module.
+
+
+ Each Class Documentation page contains:
+
+ - A class inheritance diagram.
+ - A list of known subclasses.
+ - A description of the class.
+ - A summary of the methods defined by the class.
+ - A summary of the instance variables defined by the class.
+ - A summary of the class (static) variables defined by the
+ class.
+ - A detailed description of each method defined by the
+ class.
+ - A detailed description of each instance variable defined by the
+ class.
+ - A detailed description of each class (static) variable defined
+ by the class.
+
+
+ Project Documentation
+
+ The Trees page contains the module and class hierarchies:
+
+ - The module hierarchy lists every package and module, with
+ modules grouped into packages. At the top level, and within each
+ package, modules and sub-packages are listed alphabetically.
+ - The class hierarchy lists every class, grouped by base
+ class. If a class has more than one base class, then it will be
+ listed under each base class. At the top level, and under each base
+ class, classes are listed alphabetically.
+
+
+ The Index page contains indices of terms and
+ identifiers:
+
+ - The term index lists every term indexed by any object's
+ documentation. For each term, the index provides links to each
+ place where the term is indexed.
+ - The identifier index lists the (short) name of every package,
+ module, class, method, function, variable, and parameter. For each
+ identifier, the index provides a short description, and a link to
+ its documentation.
+
+
+ The Table of Contents
+
+ The table of contents occupies the two frames on the left side of
+the window. The upper-left frame displays the project
+contents, and the lower-left frame displays the module
+contents:
+
+
+
+
+ Project
Contents
...
+
+ API
Documentation
Frame
+
+
+
+
+ Module
Contents
...
+
+
+
+
+ The project contents frame contains a list of all packages
+and modules that are defined by the project. Clicking on an entry
+will display its contents in the module contents frame. Clicking on a
+special entry, labeled "Everything," will display the contents of
+the entire project.
+
+ The module contents frame contains a list of every
+submodule, class, type, exception, function, and variable defined by a
+module or package. Clicking on an entry will display its
+documentation in the API documentation frame. Clicking on the name of
+the module, at the top of the frame, will display the documentation
+for the module itself.
+
+ The "frames" and "no frames" buttons below the top
+navigation bar can be used to control whether the table of contents is
+displayed or not.
+
+ The Navigation Bar
+
+ A navigation bar is located at the top and bottom of every page.
+It indicates what type of page you are currently viewing, and allows
+you to go to related pages. The following table describes the labels
+on the navigation bar. Note that not some labels (such as
+[Parent]) are not displayed on all pages.
+
+
+
+ Label
+ Highlighted when...
+ Links to...
+
+ [Parent]
+ (never highlighted)
+ the parent of the current package
+ [Package]
+ viewing a package
+ the package containing the current object
+
+ [Module]
+ viewing a module
+ the module containing the current object
+
+ [Class]
+ viewing a class
+ the class containing the current object
+ [Trees]
+ viewing the trees page
+ the trees page
+ [Index]
+ viewing the index page
+ the index page
+ [Help]
+ viewing the help page
+ the help page
+
+
+ The "show private" and "hide private" buttons below
+the top navigation bar can be used to control whether documentation
+for private objects is displayed. Private objects are usually defined
+as objects whose (short) names begin with a single underscore, but do
+not end with an underscore. For example, "_x
",
+"__pprint
", and "epydoc.epytext._tokenize
"
+are private objects; but "re.sub
",
+"__init__
", and "type_
" are not. However,
+if a module defines the "__all__
" variable, then its
+contents are used to decide which objects are private.
+
+ A timestamp below the bottom navigation bar indicates when each
+page was last updated.
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/identifier-index.html b/html/tftpy-doc/identifier-index.html
new file mode 100644
index 0000000..d7bc961
--- /dev/null
+++ b/html/tftpy-doc/identifier-index.html
@@ -0,0 +1,711 @@
+
+
+
+
+ Identifier Index
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Identifier Index
+
+[
+ A
+ B
+ C
+ D
+ E
+ F
+ G
+ H
+ I
+ J
+ K
+ L
+ M
+ N
+ O
+ P
+ Q
+ R
+ S
+ T
+ U
+ V
+ W
+ X
+ Y
+ Z
+ _
+]
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/index.html b/html/tftpy-doc/index.html
new file mode 100644
index 0000000..17cf982
--- /dev/null
+++ b/html/tftpy-doc/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+ API Documentation
+
+
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/module-tree.html b/html/tftpy-doc/module-tree.html
new file mode 100644
index 0000000..aa1a209
--- /dev/null
+++ b/html/tftpy-doc/module-tree.html
@@ -0,0 +1,117 @@
+
+
+
+
+ Module Hierarchy
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [ Module Hierarchy
+ | Class Hierarchy ]
+
+Module Hierarchy
+
+ - tftpy: This library implements the tftp protocol, based on rfc 1350.
+
+ - tftpy.TftpClient
+ - tftpy.TftpClient'
+ - tftpy.TftpPacketFactory
+ - tftpy.TftpPacketFactory'
+ - tftpy.TftpPacketTypes
+ - tftpy.TftpServer
+ - tftpy.TftpServer'
+ - tftpy.TftpShared
+ - tftpy.TftpStates
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/redirect.html b/html/tftpy-doc/redirect.html
new file mode 100644
index 0000000..db5e3c0
--- /dev/null
+++ b/html/tftpy-doc/redirect.html
@@ -0,0 +1,38 @@
+Epydoc Redirect Page
+
+
+
+
+
+
+
+
+Epydoc Auto-redirect page
+
+When javascript is enabled, this page will redirect URLs of
+the form redirect.html#dotted.name to the
+documentation for the object with the given fully-qualified
+dotted name.
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy-module.html b/html/tftpy-doc/tftpy-module.html
new file mode 100644
index 0000000..56850de
--- /dev/null
+++ b/html/tftpy-doc/tftpy-module.html
@@ -0,0 +1,165 @@
+
+
+
+
+ tftpy
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Package tftpy
+This library implements the tftp protocol, based on rfc 1350.
+ http://www.faqs.org/rfcs/rfc1350.html At the moment it implements only a
+ client class, but will include a server, with support for variable block
+ sizes.
+
+
+
+
+
+
+
+
+ Submodules
+
+
+
+
+
+
+
+ - tftpy.TftpClient
+ - tftpy.TftpClient'
+ - tftpy.TftpPacketFactory
+ - tftpy.TftpPacketFactory'
+ - tftpy.TftpPacketTypes
+ - tftpy.TftpServer
+ - tftpy.TftpServer'
+ - tftpy.TftpShared
+ - tftpy.TftpStates
+
+
+
+
+
+
+
+
+
+
+
+ Variables
+
+
+
+
+
+
+
+
+
+ verlist = (
2,
5,
2,
'
final
'
,
0)
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy-pysrc.html b/html/tftpy-doc/tftpy-pysrc.html
new file mode 100644
index 0000000..2d1bc55
--- /dev/null
+++ b/html/tftpy-doc/tftpy-pysrc.html
@@ -0,0 +1,128 @@
+
+
+
+
+ tftpy
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Package tftpy
+
+ 1 """This library implements the tftp protocol, based on rfc 1350.
+ 2 http://www.faqs.org/rfcs/rfc1350.html
+ 3 At the moment it implements only a client class, but will include a server,
+ 4 with support for variable block sizes.
+ 5 """
+ 6
+ 7 import sys
+ 8
+ 9 # Make sure that this is at least Python 2.3
+10 verlist = sys.version_info
+11 if not verlist[0] >= 2 or not verlist[1] >= 3:
+12 raise AssertionError, "Requires at least Python 2.3"
+13
+14 from TftpShared import *
+15 from TftpPacketTypes import *
+16 from TftpPacketFactory import *
+17 from TftpClient import *
+18 from TftpServer import *
+19
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpClient'-module.html b/html/tftpy-doc/tftpy.TftpClient'-module.html
new file mode 100644
index 0000000..7cfca4c
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpClient'-module.html
@@ -0,0 +1,211 @@
+
+
+
+
+ tftpy.TftpClient'
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Module TftpClient'
+
+
+
+
+
+
+
+ Classes
+
+
+
+
+
+
+
+
+
+ TftpClient
+ This class is an implementation of a tftp client.
+
+
+
+
+
+
+
+
+
+
+ Variables
+
+
+
+
+
+
+
+
+
+ DEF_BLKSIZE = 512
+
+
+
+
+
+
+ DEF_TFTP_PORT = 69
+
+
+
+
+
+
+ LOG_LEVEL = 0
+
+
+
+
+
+
+ MAX_BLKSIZE = 65536
+
+
+
+
+
+
+ MAX_DUPS = 20
+
+
+
+
+
+
+ MIN_BLKSIZE = 8
+
+
+
+
+
+
+ SOCK_TIMEOUT = 5
+
+
+
+
+
+
+ TIMEOUT_RETRIES = 5
+
+
+
+
+
+
+ log = logging.getLogger('tftpy')
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpClient'-pysrc.html b/html/tftpy-doc/tftpy.TftpClient'-pysrc.html
new file mode 100644
index 0000000..bb2b65f
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpClient'-pysrc.html
@@ -0,0 +1,297 @@
+
+
+
+
+ tftpy.TftpClient'
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Module tftpy.TftpClient'
+
+ 1 import time, types
+ 2 from TftpShared import *
+ 3 from TftpPacketFactory import *
+ 4 from TftpStates import TftpContextClientDownload, TftpContextClientUpload
+ 5
+ 7 """This class is an implementation of a tftp client. Once instantiated, a
+ 8 download can be initiated via the download() method."""
+10 """This constructor returns an instance of TftpClient, taking the
+11 remote host, the remote port, and the filename to fetch."""
+12 TftpSession.__init__(self)
+13 self.context = None
+14 self.host = host
+15 self.iport = port
+16 self.filename = None
+17 self.options = options
+18 # FIXME: If the blksize is DEF_BLKSIZE, we should just skip sending
+19 # it.
+20 if self.options.has_key('blksize'):
+21 size = self.options['blksize']
+22 tftpassert(types.IntType == type(size), "blksize must be an int")
+23 if size < MIN_BLKSIZE or size > MAX_BLKSIZE:
+24 raise TftpException, "Invalid blksize: %d" % size
+25 else:
+26 self.options['blksize'] = DEF_BLKSIZE
+27
+29 """This method initiates a tftp download from the configured remote
+30 host, requesting the filename passed. It saves the file to a local
+31 file specified in the output parameter. If a packethook is provided,
+32 it must be a function that takes a single parameter, which will be a
+33 copy of each DAT packet received in the form of a TftpPacketDAT
+34 object. The timeout parameter may be used to override the default
+35 SOCK_TIMEOUT setting, which is the amount of time that the client will
+36 wait for a receive packet to arrive."""
+37 # We're downloading.
+38 log.debug("Creating download context with the following params:")
+39 log.debug("host = %s, port = %s, filename = %s, output = %s"
+40 % (self.host, self.iport, filename, output))
+41 log.debug("options = %s, packethook = %s, timeout = %s"
+42 % (self.options, packethook, timeout))
+43 self.context = TftpContextClientDownload(self.host,
+44 self.iport,
+45 filename,
+46 output,
+47 self.options,
+48 packethook,
+49 timeout)
+50 self.context.start()
+51 # Download happens here
+52 self.context.end()
+53
+54 metrics = self.context.metrics
+55
+56 log.info('')
+57 log.info("Download complete.")
+58 if metrics.duration == 0:
+59 log.info("Duration too short, rate undetermined")
+60 else:
+61 log.info("Downloaded %.2f bytes in %.2f seconds" % (metrics.bytes, metrics.duration))
+62 log.info("Average rate: %.2f kbps" % metrics.kbps)
+63 log.info("%.2f bytes in resent data" % metrics.resent_bytes)
+64 log.info("Received %d duplicate packets" % metrics.dupcount)
+65
+67 # Open the input file.
+68 # FIXME: As of the state machine, this is now broken. Need to
+69 # implement with new state machine.
+70 self.context = TftpContextClientUpload(self.host,
+71 self.iport,
+72 filename,
+73 input,
+74 self.options,
+75 packethook,
+76 timeout)
+77 self.context.start()
+78 # Upload happens here
+79 self.context.end()
+80
+81 metrics = self.context.metrics
+82
+83 log.info('')
+84 log.info("Upload complete.")
+85 if metrics.duration == 0:
+86 log.info("Duration too short, rate undetermined")
+87 else:
+88 log.info("Uploaded %.2f bytes in %.2f seconds" % (metrics.bytes, metrics.duration))
+89 log.info("Average rate: %.2f kbps" % metrics.kbps)
+90 log.info("%.2f bytes in resent data" % metrics.resent_bytes)
+91 log.info("Resent %d packets" % metrics.dupcount)
+92
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpClient'.TftpClient-class.html b/html/tftpy-doc/tftpy.TftpClient'.TftpClient-class.html
new file mode 100644
index 0000000..3ccee38
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpClient'.TftpClient-class.html
@@ -0,0 +1,314 @@
+
+
+
+
+ tftpy.TftpClient'.TftpClient
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpClient
+
+ object --+
+ |
+TftpPacketTypes.TftpSession --+
+ |
+ TftpClient
+
+
+
+This class is an implementation of a tftp client. Once instantiated, a
+ download can be initiated via the download() method.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ options={
}
)
+ This constructor returns an instance of TftpClient, taking the remote
+ host, the remote port, and the filename to fetch.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ download(self,
+ filename,
+ output,
+ packethook=None,
+ timeout=5)
+ This method initiates a tftp download from the configured remote
+ host, requesting the filename passed.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ upload(self,
+ filename,
+ input,
+ packethook=None,
+ timeout=5)
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ options={
}
)
+
(Constructor)
+
+ source code
+
+
+
+ This constructor returns an instance of TftpClient, taking the remote
+ host, the remote port, and the filename to fetch.
+
+ - Overrides:
+ object.__init__
+
+
+
+
+
+
+
+
+
+
+ download(self,
+ filename,
+ output,
+ packethook=None,
+ timeout=5)
+
+ source code
+
+
+
+ This method initiates a tftp download from the configured remote host,
+ requesting the filename passed. It saves the file to a local file
+ specified in the output parameter. If a packethook is provided, it must
+ be a function that takes a single parameter, which will be a copy of each
+ DAT packet received in the form of a TftpPacketDAT object. The timeout
+ parameter may be used to override the default SOCK_TIMEOUT setting, which
+ is the amount of time that the client will wait for a receive packet to
+ arrive.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketFactory'-module.html b/html/tftpy-doc/tftpy.TftpPacketFactory'-module.html
new file mode 100644
index 0000000..ad5bba1
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketFactory'-module.html
@@ -0,0 +1,211 @@
+
+
+
+
+ tftpy.TftpPacketFactory'
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Module TftpPacketFactory'
+
+
+
+
+
+
+
+ Classes
+
+
+
+
+
+
+
+
+
+ TftpPacketFactory
+ This class generates TftpPacket objects.
+
+
+
+
+
+
+
+
+
+
+ Variables
+
+
+
+
+
+
+
+
+
+ DEF_BLKSIZE = 512
+
+
+
+
+
+
+ DEF_TFTP_PORT = 69
+
+
+
+
+
+
+ LOG_LEVEL = 0
+
+
+
+
+
+
+ MAX_BLKSIZE = 65536
+
+
+
+
+
+
+ MAX_DUPS = 20
+
+
+
+
+
+
+ MIN_BLKSIZE = 8
+
+
+
+
+
+
+ SOCK_TIMEOUT = 5
+
+
+
+
+
+
+ TIMEOUT_RETRIES = 5
+
+
+
+
+
+
+ log = logging.getLogger('tftpy')
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketFactory'-pysrc.html b/html/tftpy-doc/tftpy.TftpPacketFactory'-pysrc.html
new file mode 100644
index 0000000..8c3452c
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketFactory'-pysrc.html
@@ -0,0 +1,159 @@
+
+
+
+
+ tftpy.TftpPacketFactory'
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Module tftpy.TftpPacketFactory'
+
+ 1 from TftpShared import *
+ 2 from TftpPacketTypes import *
+ 3
+ 5 """This class generates TftpPacket objects. It is responsible for parsing
+ 6 raw buffers off of the wire and returning objects representing them, via
+ 7 the parse() method."""
+ 9 self.classes = {
+10 1: TftpPacketRRQ,
+11 2: TftpPacketWRQ,
+12 3: TftpPacketDAT,
+13 4: TftpPacketACK,
+14 5: TftpPacketERR,
+15 6: TftpPacketOACK
+16 }
+17
+19 """This method is used to parse an existing datagram into its
+20 corresponding TftpPacket object. The buffer is the raw bytes off of
+21 the network."""
+22 log.debug("parsing a %d byte packet" % len(buffer))
+23 (opcode,) = struct.unpack("!H", buffer[:2])
+24 log.debug("opcode is %d" % opcode)
+25 packet = self.__create(opcode)
+26 packet.buffer = buffer
+27 return packet.decode()
+28
+30 """This method returns the appropriate class object corresponding to
+31 the passed opcode."""
+32 tftpassert(self.classes.has_key(opcode),
+33 "Unsupported opcode: %d" % opcode)
+34
+35 packet = self.classes[opcode]()
+36
+37 return packet
+38
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketFactory'.TftpPacketFactory-class.html b/html/tftpy-doc/tftpy.TftpPacketFactory'.TftpPacketFactory-class.html
new file mode 100644
index 0000000..0955ad5
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketFactory'.TftpPacketFactory-class.html
@@ -0,0 +1,295 @@
+
+
+
+
+ tftpy.TftpPacketFactory'.TftpPacketFactory
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketFactory
+
+object --+
+ |
+ TftpPacketFactory
+
+
+
+This class generates TftpPacket objects. It is responsible for parsing
+ raw buffers off of the wire and returning objects representing them, via
+ the parse() method.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __create(self,
+ opcode)
+ This method returns the appropriate class object corresponding to the
+ passed opcode.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ parse(self,
+ buffer)
+ This method is used to parse an existing datagram into its
+ corresponding TftpPacket object.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ parse(self,
+ buffer)
+
+ source code
+
+
+
+ This method is used to parse an existing datagram into its
+ corresponding TftpPacket object. The buffer is the raw bytes off of the
+ network.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes-module.html b/html/tftpy-doc/tftpy.TftpPacketTypes-module.html
new file mode 100644
index 0000000..e971d36
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes-module.html
@@ -0,0 +1,210 @@
+
+
+
+
+ tftpy.TftpPacketTypes
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Module TftpPacketTypes
+
+
+
+
+
+
+
+ Classes
+
+
+
+
+
+
+
+
+
+ TftpSession
+ This class is the base class for the tftp client and server.
+
+
+
+
+
+
+ TftpPacketWithOptions
+ This class exists to permit some TftpPacket subclasses to share
+ code regarding options handling.
+
+
+
+
+
+
+ TftpPacket
+ This class is the parent class of all tftp packet classes.
+
+
+
+
+
+
+ TftpPacketInitial
+ This class is a common parent class for the RRQ and WRQ packets, as
+ they share quite a bit of code.
+
+
+
+
+
+
+ TftpPacketRRQ
+ 2 bytes string 1 byte string 1 byte...
+
+
+
+
+
+
+ TftpPacketWRQ
+ 2 bytes string 1 byte string 1 byte...
+
+
+
+
+
+
+ TftpPacketDAT
+ 2 bytes 2 bytes n bytes...
+
+
+
+
+
+
+ TftpPacketACK
+ 2 bytes 2 bytes...
+
+
+
+
+
+
+ TftpPacketERR
+ 2 bytes 2 bytes string 1 byte
+ ----------------------------------------
+ERROR | 05 | ErrorCode | ErrMsg | 0 |
+ ----------------------------------------
+ Error Codes
+
+
+
+
+
+
+ TftpPacketOACK
+ # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ #
+ | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | #
+ +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes-pysrc.html b/html/tftpy-doc/tftpy.TftpPacketTypes-pysrc.html
new file mode 100644
index 0000000..2f2f34f
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes-pysrc.html
@@ -0,0 +1,833 @@
+
+
+
+
+ tftpy.TftpPacketTypes
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Module tftpy.TftpPacketTypes
+
+ 1 import struct
+ 2 from TftpShared import *
+ 3
+ 5 """This class is the base class for the tftp client and server. Any shared
+ 6 code should be in this class."""
+ 7 # FIXME: do we need this anymore?
+ 8 pass
+ 9
+ 11 """This class exists to permit some TftpPacket subclasses to share code
+ 12 regarding options handling. It does not inherit from TftpPacket, as the
+ 13 goal is just to share code here, and not cause diamond inheritance."""
+ 14
+ 16 self.options = {}
+ 17
+ 19 log.debug("in TftpPacketWithOptions.setoptions")
+ 20 log.debug("options: " + str(options))
+ 21 myoptions = {}
+ 22 for key in options:
+ 23 newkey = str(key)
+ 24 myoptions[newkey] = str(options[key])
+ 25 log.debug("populated myoptions with %s = %s"
+ 26 % (newkey, myoptions[newkey]))
+ 27
+ 28 log.debug("setting options hash to: " + str(myoptions))
+ 29 self._options = myoptions
+ 30
+ 34
+ 35 # Set up getter and setter on options to ensure that they are the proper
+ 36 # type. They should always be strings, but we don't need to force the
+ 37 # client to necessarily enter strings if we can avoid it.
+ 38 options = property(getoptions, setoptions)
+ 39
+ 41 """This method decodes the section of the buffer that contains an
+ 42 unknown number of options. It returns a dictionary of option names and
+ 43 values."""
+ 44 nulls = 0
+ 45 format = "!"
+ 46 options = {}
+ 47
+ 48 log.debug("decode_options: buffer is: " + repr(buffer))
+ 49 log.debug("size of buffer is %d bytes" % len(buffer))
+ 50 if len(buffer) == 0:
+ 51 log.debug("size of buffer is zero, returning empty hash")
+ 52 return {}
+ 53
+ 54 # Count the nulls in the buffer. Each one terminates a string.
+ 55 log.debug("about to iterate options buffer counting nulls")
+ 56 length = 0
+ 57 for c in buffer:
+ 58 #log.debug("iterating this byte: " + repr(c))
+ 59 if ord(c) == 0:
+ 60 log.debug("found a null at length %d" % length)
+ 61 if length > 0:
+ 62 format += "%dsx" % length
+ 63 length = -1
+ 64 else:
+ 65 raise TftpException, "Invalid options in buffer"
+ 66 length += 1
+ 67
+ 68 log.debug("about to unpack, format is: %s" % format)
+ 69 mystruct = struct.unpack(format, buffer)
+ 70
+ 71 tftpassert(len(mystruct) % 2 == 0,
+ 72 "packet with odd number of option/value pairs")
+ 73
+ 74 for i in range(0, len(mystruct), 2):
+ 75 log.debug("setting option %s to %s" % (mystruct[i], mystruct[i+1]))
+ 76 options[mystruct[i]] = mystruct[i+1]
+ 77
+ 78 return options
+ 79
+ 81 """This class is the parent class of all tftp packet classes. It is an
+ 82 abstract class, providing an interface, and should not be instantiated
+ 83 directly."""
+ 87
+ 89 """The encode method of a TftpPacket takes keyword arguments specific
+ 90 to the type of packet, and packs an appropriate buffer in network-byte
+ 91 order suitable for sending over the wire.
+ 92
+ 93 This is an abstract method."""
+ 94 raise NotImplementedError, "Abstract method"
+ 95
+ 97 """The decode method of a TftpPacket takes a buffer off of the wire in
+ 98 network-byte order, and decodes it, populating internal properties as
+ 99 appropriate. This can only be done once the first 2-byte opcode has
+100 already been decoded, but the data section does include the entire
+101 datagram.
+102
+103 This is an abstract method."""
+104 raise NotImplementedError, "Abstract method"
+105
+107 """This class is a common parent class for the RRQ and WRQ packets, as
+108 they share quite a bit of code."""
+110 TftpPacket.__init__(self)
+111 TftpPacketWithOptions.__init__(self)
+112 self.filename = None
+113 self.mode = None
+114
+116 """Encode the packet's buffer from the instance variables."""
+117 tftpassert(self.filename, "filename required in initial packet")
+118 tftpassert(self.mode, "mode required in initial packet")
+119
+120 ptype = None
+121 if self.opcode == 1: ptype = "RRQ"
+122 else: ptype = "WRQ"
+123 log.debug("Encoding %s packet, filename = %s, mode = %s"
+124 % (ptype, self.filename, self.mode))
+125 for key in self.options:
+126 log.debug(" Option %s = %s" % (key, self.options[key]))
+127
+128 format = "!H"
+129 format += "%dsx" % len(self.filename)
+130 if self.mode == "octet":
+131 format += "5sx"
+132 else:
+133 raise AssertionError, "Unsupported mode: %s" % mode
+134 # Add options.
+135 options_list = []
+136 if self.options.keys() > 0:
+137 log.debug("there are options to encode")
+138 for key in self.options:
+139 # Populate the option name
+140 format += "%dsx" % len(key)
+141 options_list.append(key)
+142 # Populate the option value
+143 format += "%dsx" % len(str(self.options[key]))
+144 options_list.append(str(self.options[key]))
+145
+146 log.debug("format is %s" % format)
+147 log.debug("options_list is %s" % options_list)
+148 log.debug("size of struct is %d" % struct.calcsize(format))
+149
+150 self.buffer = struct.pack(format,
+151 self.opcode,
+152 self.filename,
+153 self.mode,
+154 *options_list)
+155
+156 log.debug("buffer is " + repr(self.buffer))
+157 return self
+158
+160 tftpassert(self.buffer, "Can't decode, buffer is empty")
+161
+162 # FIXME - this shares a lot of code with decode_options
+163 nulls = 0
+164 format = ""
+165 nulls = length = tlength = 0
+166 log.debug("in decode: about to iterate buffer counting nulls")
+167 subbuf = self.buffer[2:]
+168 for c in subbuf:
+169 log.debug("iterating this byte: " + repr(c))
+170 if ord(c) == 0:
+171 nulls += 1
+172 log.debug("found a null at length %d, now have %d"
+173 % (length, nulls))
+174 format += "%dsx" % length
+175 length = -1
+176 # At 2 nulls, we want to mark that position for decoding.
+177 if nulls == 2:
+178 break
+179 length += 1
+180 tlength += 1
+181
+182 log.debug("hopefully found end of mode at length %d" % tlength)
+183 # length should now be the end of the mode.
+184 tftpassert(nulls == 2, "malformed packet")
+185 shortbuf = subbuf[:tlength+1]
+186 log.debug("about to unpack buffer with format: %s" % format)
+187 log.debug("unpacking buffer: " + repr(shortbuf))
+188 mystruct = struct.unpack(format, shortbuf)
+189
+190 tftpassert(len(mystruct) == 2, "malformed packet")
+191 log.debug("setting filename to %s" % mystruct[0])
+192 log.debug("setting mode to %s" % mystruct[1])
+193 self.filename = mystruct[0]
+194 self.mode = mystruct[1]
+195
+196 self.options = self.decode_options(subbuf[tlength+1:])
+197 return self
+198
+200 """
+201 2 bytes string 1 byte string 1 byte
+202 -----------------------------------------------
+203 RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
+204 WRQ -----------------------------------------------
+205 """
+209
+216
+218 """
+219 2 bytes string 1 byte string 1 byte
+220 -----------------------------------------------
+221 RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
+222 WRQ -----------------------------------------------
+223 """
+227
+234
+236 """
+237 2 bytes 2 bytes n bytes
+238 ---------------------------------
+239 DATA | 03 | Block # | Data |
+240 ---------------------------------
+241 """
+243 TftpPacket.__init__(self)
+244 self.opcode = 3
+245 self.blocknumber = 0
+246 self.data = None
+247
+249 s = 'DAT packet: block %s' % self.blocknumber
+250 if self.data:
+251 s += '\n data: %d bytes' % len(self.data)
+252 return s
+253
+255 """Encode the DAT packet. This method populates self.buffer, and
+256 returns self for easy method chaining."""
+257 if len(self.data) == 0:
+258 log.debug("Encoding an empty DAT packet")
+259 format = "!HH%ds" % len(self.data)
+260 self.buffer = struct.pack(format,
+261 self.opcode,
+262 self.blocknumber,
+263 self.data)
+264 return self
+265
+267 """Decode self.buffer into instance variables. It returns self for
+268 easy method chaining."""
+269 # We know the first 2 bytes are the opcode. The second two are the
+270 # block number.
+271 (self.blocknumber,) = struct.unpack("!H", self.buffer[2:4])
+272 log.debug("decoding DAT packet, block number %d" % self.blocknumber)
+273 log.debug("should be %d bytes in the packet total"
+274 % len(self.buffer))
+275 # Everything else is data.
+276 self.data = self.buffer[4:]
+277 log.debug("found %d bytes of data"
+278 % len(self.data))
+279 return self
+280
+282 """
+283 2 bytes 2 bytes
+284 -------------------
+285 ACK | 04 | Block # |
+286 --------------------
+287 """
+292
+295
+297 log.debug("encoding ACK: opcode = %d, block = %d"
+298 % (self.opcode, self.blocknumber))
+299 self.buffer = struct.pack("!HH", self.opcode, self.blocknumber)
+300 return self
+301
+303 self.opcode, self.blocknumber = struct.unpack("!HH", self.buffer)
+304 log.debug("decoded ACK packet: opcode = %d, block = %d"
+305 % (self.opcode, self.blocknumber))
+306 return self
+307
+309 """
+310 2 bytes 2 bytes string 1 byte
+311 ----------------------------------------
+312 ERROR | 05 | ErrorCode | ErrMsg | 0 |
+313 ----------------------------------------
+314 Error Codes
+315
+316 Value Meaning
+317
+318 0 Not defined, see error message (if any).
+319 1 File not found.
+320 2 Access violation.
+321 3 Disk full or allocation exceeded.
+322 4 Illegal TFTP operation.
+323 5 Unknown transfer ID.
+324 6 File already exists.
+325 7 No such user.
+326 8 Failed to negotiate options
+327 """
+329 TftpPacket.__init__(self)
+330 self.opcode = 5
+331 self.errorcode = 0
+332 # FIXME: We don't encode the errmsg...
+333 self.errmsg = None
+334 # FIXME - integrate in TftpErrors references?
+335 self.errmsgs = {
+336 1: "File not found",
+337 2: "Access violation",
+338 3: "Disk full or allocation exceeded",
+339 4: "Illegal TFTP operation",
+340 5: "Unknown transfer ID",
+341 6: "File already exists",
+342 7: "No such user",
+343 8: "Failed to negotiate options"
+344 }
+345
+347 s = 'ERR packet: errorcode = %d' % self.errorcode
+348 s += '\n msg = %s' % self.errmsgs.get(self.errorcode, '')
+349 return s
+350
+352 """Encode the DAT packet based on instance variables, populating
+353 self.buffer, returning self."""
+354 format = "!HH%dsx" % len(self.errmsgs[self.errorcode])
+355 log.debug("encoding ERR packet with format %s" % format)
+356 self.buffer = struct.pack(format,
+357 self.opcode,
+358 self.errorcode,
+359 self.errmsgs[self.errorcode])
+360 return self
+361
+363 "Decode self.buffer, populating instance variables and return self."
+364 buflen = len(self.buffer)
+365 tftpassert(buflen >= 4, "malformed ERR packet, too short")
+366 log.debug("Decoding ERR packet, length %s bytes" % buflen)
+367 if buflen == 4:
+368 log.debug("Allowing this affront to the RFC of a 4-byte packet")
+369 format = "!HH"
+370 log.debug("Decoding ERR packet with format: %s" % format)
+371 self.opcode, self.errorcode = struct.unpack(format,
+372 self.buffer)
+373 else:
+374 log.debug("Good ERR packet > 4 bytes")
+375 format = "!HH%dsx" % (len(self.buffer) - 5)
+376 log.debug("Decoding ERR packet with format: %s" % format)
+377 self.opcode, self.errorcode, self.errmsg = struct.unpack(format,
+378 self.buffer)
+379 log.error("ERR packet - errorcode: %d, message: %s"
+380 % (self.errorcode, self.errmsg))
+381 return self
+382
+384 """
+385 # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+386 # | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 |
+387 # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+388 """
+393
+395 return 'OACK packet:\n options = %s' % self.options
+396
+398 format = "!H" # opcode
+399 options_list = []
+400 log.debug("in TftpPacketOACK.encode")
+401 for key in self.options:
+402 log.debug("looping on option key %s" % key)
+403 log.debug("value is %s" % self.options[key])
+404 format += "%dsx" % len(key)
+405 format += "%dsx" % len(self.options[key])
+406 options_list.append(key)
+407 options_list.append(self.options[key])
+408 self.buffer = struct.pack(format, self.opcode, *options_list)
+409 return self
+410
+414
+416 """This method takes a set of options, and tries to match them with
+417 its own. It can accept some changes in those options from the server as
+418 part of a negotiation. Changed or unchanged, it will return a dict of
+419 the options so that the session can update itself to the negotiated
+420 options."""
+421 for name in self.options:
+422 if options.has_key(name):
+423 if name == 'blksize':
+424 # We can accept anything between the min and max values.
+425 size = self.options[name]
+426 if size >= MIN_BLKSIZE and size <= MAX_BLKSIZE:
+427 log.debug("negotiated blksize of %d bytes" % size)
+428 options[blksize] = size
+429 else:
+430 raise TftpException, "Unsupported option: %s" % name
+431 return True
+432
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacket-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacket-class.html
new file mode 100644
index 0000000..8e3af49
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacket-class.html
@@ -0,0 +1,325 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacket
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacket
+
+object --+
+ |
+ TftpPacket
+
+
+- Known Subclasses:
+-
+
+
+
+
+This class is the parent class of all tftp packet classes. It is an
+ abstract class, providing an interface, and should not be instantiated
+ directly.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+ The encode method of a TftpPacket takes keyword arguments specific to
+ the type of packet, and packs an appropriate buffer in network-byte
+ order suitable for sending over the wire.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+
+ source code
+
+
+
+ The encode method of a TftpPacket takes keyword arguments specific to
+ the type of packet, and packs an appropriate buffer in network-byte order
+ suitable for sending over the wire.
+ This is an abstract method.
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+
+ source code
+
+
+
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate. This can only be done once the first 2-byte opcode has
+ already been decoded, but the data section does include the entire
+ datagram.
+ This is an abstract method.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketACK-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketACK-class.html
new file mode 100644
index 0000000..053d14f
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketACK-class.html
@@ -0,0 +1,375 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketACK
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketACK
+
+object --+
+ |
+TftpPacket --+
+ |
+ TftpPacketACK
+
+
+
+
+
+ 2 bytes 2 bytes
+ -------------------
+ACK | 04 | Block # |
+ --------------------
+
+
+
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+ str(x)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+ The encode method of a TftpPacket takes keyword arguments specific to
+ the type of packet, and packs an appropriate buffer in network-byte
+ order suitable for sending over the wire.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+
(Informal representation operator)
+
+ source code
+
+
+
+ str(x)
+
+ - Overrides:
+ object.__str__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+
+ source code
+
+
+
+ The encode method of a TftpPacket takes keyword arguments specific to
+ the type of packet, and packs an appropriate buffer in network-byte order
+ suitable for sending over the wire.
+ This is an abstract method.
+
+ - Overrides:
+ TftpPacket.encode
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+
+ source code
+
+
+
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate. This can only be done once the first 2-byte opcode has
+ already been decoded, but the data section does include the entire
+ datagram.
+ This is an abstract method.
+
+ - Overrides:
+ TftpPacket.decode
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketDAT-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketDAT-class.html
new file mode 100644
index 0000000..81aec79
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketDAT-class.html
@@ -0,0 +1,363 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketDAT
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketDAT
+
+object --+
+ |
+TftpPacket --+
+ |
+ TftpPacketDAT
+
+
+
+
+
+ 2 bytes 2 bytes n bytes
+ ---------------------------------
+DATA | 03 | Block # | Data |
+ ---------------------------------
+
+
+
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+ str(x)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+ Encode the DAT packet.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+ Decode self.buffer into instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+
(Informal representation operator)
+
+ source code
+
+
+
+ str(x)
+
+ - Overrides:
+ object.__str__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+
+ source code
+
+
+
+ Encode the DAT packet. This method populates self.buffer, and returns
+ self for easy method chaining.
+
+ - Overrides:
+ TftpPacket.encode
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+
+ source code
+
+
+
+ Decode self.buffer into instance variables. It returns self for easy
+ method chaining.
+
+ - Overrides:
+ TftpPacket.decode
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketERR-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketERR-class.html
new file mode 100644
index 0000000..aab44e1
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketERR-class.html
@@ -0,0 +1,376 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketERR
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketERR
+
+object --+
+ |
+TftpPacket --+
+ |
+ TftpPacketERR
+
+
+
+
+
+ 2 bytes 2 bytes string 1 byte
+ ----------------------------------------
+ERROR | 05 | ErrorCode | ErrMsg | 0 |
+ ----------------------------------------
+ Error Codes
+
+ Value Meaning
+
+ 0 Not defined, see error message (if any).
+ 1 File not found.
+ 2 Access violation.
+ 3 Disk full or allocation exceeded.
+ 4 Illegal TFTP operation.
+ 5 Unknown transfer ID.
+ 6 File already exists.
+ 7 No such user.
+ 8 Failed to negotiate options
+
+
+
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+ str(x)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+ Encode the DAT packet based on instance variables, populating
+ self.buffer, returning self.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+ Decode self.buffer, populating instance variables and return self.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+
(Informal representation operator)
+
+ source code
+
+
+
+ str(x)
+
+ - Overrides:
+ object.__str__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+
+ source code
+
+
+
+ Encode the DAT packet based on instance variables, populating
+ self.buffer, returning self.
+
+ - Overrides:
+ TftpPacket.encode
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+
+ source code
+
+
+
+ Decode self.buffer, populating instance variables and return self.
+
+ - Overrides:
+ TftpPacket.decode
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketInitial-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketInitial-class.html
new file mode 100644
index 0000000..d6315dd
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketInitial-class.html
@@ -0,0 +1,340 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketInitial
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketInitial
+
+ object --+
+ |
+ TftpPacket --+
+ |
+ object --+ |
+ | |
+TftpPacketWithOptions --+
+ |
+ TftpPacketInitial
+
+
+- Known Subclasses:
+-
+
+
+
+
+This class is a common parent class for the RRQ and WRQ packets, as
+ they share quite a bit of code.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+ Encode the packet's buffer from the instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpPacketWithOptions
:
+ decode_options
,
+ getoptions
,
+ setoptions
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpPacketWithOptions
:
+ options
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+
+ source code
+
+
+
+ Encode the packet's buffer from the instance variables.
+
+ - Overrides:
+ TftpPacket.encode
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+
+ source code
+
+
+
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate. This can only be done once the first 2-byte opcode has
+ already been decoded, but the data section does include the entire
+ datagram.
+ This is an abstract method.
+
+ - Overrides:
+ TftpPacket.decode
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketOACK-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketOACK-class.html
new file mode 100644
index 0000000..cb1b5e6
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketOACK-class.html
@@ -0,0 +1,424 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketOACK
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketOACK
+
+ object --+
+ |
+ TftpPacket --+
+ |
+ object --+ |
+ | |
+TftpPacketWithOptions --+
+ |
+ TftpPacketOACK
+
+
+
+# +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ # |
+ opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | #
+ +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+ str(x)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+ The encode method of a TftpPacket takes keyword arguments specific to
+ the type of packet, and packs an appropriate buffer in network-byte
+ order suitable for sending over the wire.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ match_options(self,
+ options)
+ This method takes a set of options, and tries to match them with its
+ own.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpPacketWithOptions
:
+ decode_options
,
+ getoptions
,
+ setoptions
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpPacketWithOptions
:
+ options
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+
(Informal representation operator)
+
+ source code
+
+
+
+ str(x)
+
+ - Overrides:
+ object.__str__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ encode(self)
+
+ source code
+
+
+
+ The encode method of a TftpPacket takes keyword arguments specific to
+ the type of packet, and packs an appropriate buffer in network-byte order
+ suitable for sending over the wire.
+ This is an abstract method.
+
+ - Overrides:
+ TftpPacket.encode
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ decode(self)
+
+ source code
+
+
+
+ The decode method of a TftpPacket takes a buffer off of the wire in
+ network-byte order, and decodes it, populating internal properties as
+ appropriate. This can only be done once the first 2-byte opcode has
+ already been decoded, but the data section does include the entire
+ datagram.
+ This is an abstract method.
+
+ - Overrides:
+ TftpPacket.decode
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ match_options(self,
+ options)
+
+ source code
+
+
+
+ This method takes a set of options, and tries to match them with its
+ own. It can accept some changes in those options from the server as part
+ of a negotiation. Changed or unchanged, it will return a dict of the
+ options so that the session can update itself to the negotiated
+ options.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketRRQ-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketRRQ-class.html
new file mode 100644
index 0000000..7277114
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketRRQ-class.html
@@ -0,0 +1,301 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketRRQ
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketRRQ
+
+ object --+
+ |
+ TftpPacket --+
+ |
+ object --+ |
+ | |
+TftpPacketWithOptions --+
+ |
+ TftpPacketInitial --+
+ |
+ TftpPacketRRQ
+
+
+
+
+
+ 2 bytes string 1 byte string 1 byte
+ -----------------------------------------------
+RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
+WRQ -----------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+ str(x)
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpPacketInitial
:
+ decode
,
+ encode
+
+ Inherited from TftpPacketWithOptions
:
+ decode_options
,
+ getoptions
,
+ setoptions
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpPacketWithOptions
:
+ options
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+
(Informal representation operator)
+
+ source code
+
+
+
+ str(x)
+
+ - Overrides:
+ object.__str__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketWRQ-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketWRQ-class.html
new file mode 100644
index 0000000..0d5d7c8
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketWRQ-class.html
@@ -0,0 +1,301 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketWRQ
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketWRQ
+
+ object --+
+ |
+ TftpPacket --+
+ |
+ object --+ |
+ | |
+TftpPacketWithOptions --+
+ |
+ TftpPacketInitial --+
+ |
+ TftpPacketWRQ
+
+
+
+
+
+ 2 bytes string 1 byte string 1 byte
+ -----------------------------------------------
+RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
+WRQ -----------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+ str(x)
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpPacketInitial
:
+ decode
,
+ encode
+
+ Inherited from TftpPacketWithOptions
:
+ decode_options
,
+ getoptions
,
+ setoptions
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpPacketWithOptions
:
+ options
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ __str__(self)
+
(Informal representation operator)
+
+ source code
+
+
+
+ str(x)
+
+ - Overrides:
+ object.__str__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html
new file mode 100644
index 0000000..d7736e0
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpPacketWithOptions-class.html
@@ -0,0 +1,359 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpPacketWithOptions
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpPacketWithOptions
+
+object --+
+ |
+ TftpPacketWithOptions
+
+
+- Known Subclasses:
+-
+
+
+
+
+This class exists to permit some TftpPacket subclasses to share code
+ regarding options handling. It does not inherit from TftpPacket, as the
+ goal is just to share code here, and not cause diamond inheritance.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setoptions(self,
+ options)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getoptions(self)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ decode_options(self,
+ buffer)
+ This method decodes the section of the buffer that contains an
+ unknown number of options.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+
+
+ options
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ decode_options(self,
+ buffer)
+
+ source code
+
+
+
+ This method decodes the section of the buffer that contains an unknown
+ number of options. It returns a dictionary of option names and
+ values.
+
+
+
+
+
+
+
+
+
+
+
+
+ Property Details
+
+
+
+
+
+
+
+
+
+
+ options
+
+
+ - Get Method:
+ - getoptions(self)
+
+ - Set Method:
+ - setoptions(self,
+ options)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpPacketTypes.TftpSession-class.html b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpSession-class.html
new file mode 100644
index 0000000..5387d0a
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpPacketTypes.TftpSession-class.html
@@ -0,0 +1,180 @@
+
+
+
+
+ tftpy.TftpPacketTypes.TftpSession
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpSession
+
+object --+
+ |
+ TftpSession
+
+
+- Known Subclasses:
+-
+
+
+
+
+This class is the base class for the tftp client and server. Any
+ shared code should be in this class.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __init__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpServer'-module.html b/html/tftpy-doc/tftpy.TftpServer'-module.html
new file mode 100644
index 0000000..e95babb
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpServer'-module.html
@@ -0,0 +1,211 @@
+
+
+
+
+ tftpy.TftpServer'
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Module TftpServer'
+
+
+
+
+
+
+
+ Classes
+
+
+
+
+
+
+
+
+
+ TftpServer
+ This class implements a tftp server object.
+
+
+
+
+
+
+
+
+
+
+ Variables
+
+
+
+
+
+
+
+
+
+ DEF_BLKSIZE = 512
+
+
+
+
+
+
+ DEF_TFTP_PORT = 69
+
+
+
+
+
+
+ LOG_LEVEL = 0
+
+
+
+
+
+
+ MAX_BLKSIZE = 65536
+
+
+
+
+
+
+ MAX_DUPS = 20
+
+
+
+
+
+
+ MIN_BLKSIZE = 8
+
+
+
+
+
+
+ SOCK_TIMEOUT = 5
+
+
+
+
+
+
+ TIMEOUT_RETRIES = 5
+
+
+
+
+
+
+ log = logging.getLogger('tftpy')
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpServer'-pysrc.html b/html/tftpy-doc/tftpy.TftpServer'-pysrc.html
new file mode 100644
index 0000000..6eaf04e
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpServer'-pysrc.html
@@ -0,0 +1,377 @@
+
+
+
+
+ tftpy.TftpServer'
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Module tftpy.TftpServer'
+
+ 1 import socket, os, re, time, random
+ 2 import select
+ 3 from TftpShared import *
+ 4 from TftpPacketTypes import *
+ 5 from TftpPacketFactory import *
+ 6 from TftpStates import *
+ 7
+ 9 """This class implements a tftp server object."""
+ 10
+ 12 """Class constructor. It takes two optional arguments. tftproot is
+ 13 the path to the tftproot directory to serve files from and/or write
+ 14 them to. dyn_file_func is a callable that must return a file-like
+ 15 object to read from during downloads. This permits the serving of
+ 16 dynamic content."""
+ 17 self.listenip = None
+ 18 self.listenport = None
+ 19 self.sock = None
+ 20 # FIXME: What about multiple roots?
+ 21 self.root = os.path.abspath(tftproot)
+ 22 self.dyn_file_func = dyn_file_func
+ 23 # A dict of sessions, where each session is keyed by a string like
+ 24 # ip:tid for the remote end.
+ 25 self.sessions = {}
+ 26
+ 27 if os.path.exists(self.root):
+ 28 log.debug("tftproot %s does exist" % self.root)
+ 29 if not os.path.isdir(self.root):
+ 30 raise TftpException, "The tftproot must be a directory."
+ 31 else:
+ 32 log.debug("tftproot %s is a directory" % self.root)
+ 33 if os.access(self.root, os.R_OK):
+ 34 log.debug("tftproot %s is readable" % self.root)
+ 35 else:
+ 36 raise TftpException, "The tftproot must be readable"
+ 37 if os.access(self.root, os.W_OK):
+ 38 log.debug("tftproot %s is writable" % self.root)
+ 39 else:
+ 40 log.warning("The tftproot %s is not writable" % self.root)
+ 41 else:
+ 42 raise TftpException, "The tftproot does not exist."
+ 43
+ 44 - def listen(self,
+ 45 listenip="",
+ 46 listenport=DEF_TFTP_PORT,
+ 47 timeout=SOCK_TIMEOUT):
+ 48 """Start a server listening on the supplied interface and port. This
+ 49 defaults to INADDR_ANY (all interfaces) and UDP port 69. You can also
+ 50 supply a different socket timeout value, if desired."""
+ 51 tftp_factory = TftpPacketFactory()
+ 52
+ 53 # Don't use new 2.5 ternary operator yet
+ 54 # listenip = listenip if listenip else '0.0.0.0'
+ 55 if not listenip: listenip = '0.0.0.0'
+ 56 log.info("Server requested on ip %s, port %s"
+ 57 % (listenip, listenport))
+ 58 try:
+ 59 # FIXME - sockets should be non-blocking?
+ 60 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ 61 self.sock.bind((listenip, listenport))
+ 62 except socket.error, err:
+ 63 # Reraise it for now.
+ 64 raise
+ 65
+ 66 log.info("Starting receive loop...")
+ 67 while True:
+ 68 # Build the inputlist array of sockets to select() on.
+ 69 inputlist = []
+ 70 inputlist.append(self.sock)
+ 71 for key in self.sessions:
+ 72 inputlist.append(self.sessions[key].sock)
+ 73
+ 74 # Block until some socket has input on it.
+ 75 log.debug("Performing select on this inputlist: %s" % inputlist)
+ 76 readyinput, readyoutput, readyspecial = select.select(inputlist,
+ 77 [],
+ 78 [],
+ 79 SOCK_TIMEOUT)
+ 80
+ 81 deletion_list = []
+ 82
+ 83 # Handle the available data, if any. Maybe we timed-out.
+ 84 for readysock in readyinput:
+ 85 # Is the traffic on the main server socket? ie. new session?
+ 86 if readysock == self.sock:
+ 87 log.debug("Data ready on our main socket")
+ 88 buffer, (raddress, rport) = self.sock.recvfrom(MAX_BLKSIZE)
+ 89
+ 90 log.debug("Read %d bytes" % len(buffer))
+ 91
+ 92 recvpkt = tftp_factory.parse(buffer)
+ 93 # Forge a session key based on the client's IP and port,
+ 94 # which should safely work through NAT.
+ 95 key = "%s:%s" % (raddress, rport)
+ 96
+ 97 if not self.sessions.has_key(key):
+ 98 log.debug("Creating new server context for "
+ 99 "session key = %s" % key)
+100 self.sessions[key] = TftpContextServer(raddress,
+101 rport,
+102 timeout,
+103 self.root,
+104 self.dyn_file_func)
+105 self.sessions[key].start(buffer)
+106 else:
+107 log.warn("received traffic on main socket for "
+108 "existing session??")
+109
+110 else:
+111 # Must find the owner of this traffic.
+112 for key in self.sessions:
+113 if readysock == self.sessions[key].sock:
+114 log.info("Matched input to session key %s"
+115 % key)
+116 try:
+117 self.sessions[key].cycle()
+118 if self.sessions[key].state == None:
+119 log.info("Successful transfer.")
+120 deletion_list.append(key)
+121 except TftpException, err:
+122 deletion_list.append(key)
+123 log.error("Fatal exception thrown from "
+124 "session %s: %s"
+125 % (key, str(err)))
+126 break
+127
+128 else:
+129 log.error("Can't find the owner for this packet. "
+130 "Discarding.")
+131
+132 log.debug("Looping on all sessions to check for timeouts")
+133 now = time.time()
+134 for key in self.sessions:
+135 try:
+136 self.sessions[key].checkTimeout(now)
+137 except TftpException, err:
+138 log.error(str(err))
+139 deletion_list.append(key)
+140
+141 log.debug("Iterating deletion list.")
+142 for key in deletion_list:
+143 log.info('')
+144 log.info("Session %s complete" % key)
+145 if self.sessions.has_key(key):
+146 log.debug("Gathering up metrics from session before deleting")
+147 self.sessions[key].end()
+148 metrics = self.sessions[key].metrics
+149 if metrics.duration == 0:
+150 log.info("Duration too short, rate undetermined")
+151 else:
+152 log.info("Transferred %.2f bytes in %.2f seconds"
+153 % (metrics.bytes, metrics.duration))
+154 log.info("Average rate: %.2f kbps" % metrics.kbps)
+155 log.info("%.2f bytes in resent data" % metrics.resent_bytes)
+156 log.info("%d duplicate packets" % metrics.dupcount)
+157 log.debug("Deleting session %s" % key)
+158 del self.sessions[key]
+159 else:
+160 log.warn("Strange, session %s is not on the deletion list"
+161 % key)
+162
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpServer'.TftpServer-class.html b/html/tftpy-doc/tftpy.TftpServer'.TftpServer-class.html
new file mode 100644
index 0000000..5557084
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpServer'.TftpServer-class.html
@@ -0,0 +1,284 @@
+
+
+
+
+ tftpy.TftpServer'.TftpServer
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpServer
+
+ object --+
+ |
+TftpPacketTypes.TftpSession --+
+ |
+ TftpServer
+
+
+
+This class implements a tftp server object.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ tftproot='
/tftpboot
'
,
+ dyn_file_func=None)
+ Class constructor.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ listen(self,
+ listenip='
'
,
+ listenport=69,
+ timeout=5)
+ Start a server listening on the supplied interface and port.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ tftproot='
/tftpboot
'
,
+ dyn_file_func=None)
+
(Constructor)
+
+ source code
+
+
+
+ Class constructor. It takes two optional arguments. tftproot is the
+ path to the tftproot directory to serve files from and/or write them to.
+ dyn_file_func is a callable that must return a file-like object to read
+ from during downloads. This permits the serving of dynamic content.
+
+ - Overrides:
+ object.__init__
+
+
+
+
+
+
+
+
+
+
+ listen(self,
+ listenip='
'
,
+ listenport=69,
+ timeout=5)
+
+ source code
+
+
+
+ Start a server listening on the supplied interface and port. This
+ defaults to INADDR_ANY (all interfaces) and UDP port 69. You can also
+ supply a different socket timeout value, if desired.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpShared-module.html b/html/tftpy-doc/tftpy.TftpShared-module.html
new file mode 100644
index 0000000..42ff4ac
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpShared-module.html
@@ -0,0 +1,339 @@
+
+
+
+
+ tftpy.TftpShared
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Module TftpShared
+
+
+
+
+
+
+
+ Classes
+
+
+
+
+
+
+
+
+
+ TftpErrors
+ This class is a convenience for defining the common tftp error
+ codes, and making them more readable in the code.
+
+
+
+
+
+
+ TftpException
+ This class is the parent class of all exceptions regarding the
+ handling of the TFTP protocol.
+
+
+
+
+
+
+
+
+
+
+ Functions
+
+
+
+
+
+
+
+
+
+
+
+ tftpassert(condition,
+ msg)
+ This function is a simple utility that will check the condition
+ passed for a false state.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setLogLevel(level)
+ This function is a utility function for setting the internal log
+ level.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Variables
+
+
+
+
+
+
+
+
+
+ LOG_LEVEL = 0
+
+
+
+
+
+
+ MIN_BLKSIZE = 8
+
+
+
+
+
+
+ DEF_BLKSIZE = 512
+
+
+
+
+
+
+ MAX_BLKSIZE = 65536
+
+
+
+
+
+
+ SOCK_TIMEOUT = 5
+
+
+
+
+
+
+ MAX_DUPS = 20
+
+
+
+
+
+
+ TIMEOUT_RETRIES = 5
+
+
+
+
+
+
+ DEF_TFTP_PORT = 69
+
+
+
+
+
+
+ log = logging.getLogger('tftpy')
+
+
+
+
+
+
+
+
+
+
+ Function Details
+
+
+
+
+
+
+
+
+
+
+
+
+ tftpassert(condition,
+ msg)
+
+ source code
+
+
+
+ This function is a simple utility that will check the condition passed
+ for a false state. If it finds one, it throws a TftpException with the
+ message passed. This just makes the code throughout cleaner by
+ refactoring.
+
+
+
+
+
+
+
+
+
+
+ setLogLevel(level)
+
+ source code
+
+
+
+ This function is a utility function for setting the internal log
+ level. The log level defaults to logging.NOTSET, so unwanted output to
+ stdout is not created.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpShared-pysrc.html b/html/tftpy-doc/tftpy.TftpShared-pysrc.html
new file mode 100644
index 0000000..57fe26e
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpShared-pysrc.html
@@ -0,0 +1,197 @@
+
+
+
+
+ tftpy.TftpShared
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Module tftpy.TftpShared
+
+ 1 import logging
+ 2
+ 3 LOG_LEVEL = logging.NOTSET
+ 4 MIN_BLKSIZE = 8
+ 5 DEF_BLKSIZE = 512
+ 6 MAX_BLKSIZE = 65536
+ 7 SOCK_TIMEOUT = 5
+ 8 MAX_DUPS = 20
+ 9 TIMEOUT_RETRIES = 5
+10 DEF_TFTP_PORT = 69
+11
+12 # Initialize the logger.
+13 #logging.basicConfig(
+14 # level=LOG_LEVEL,
+15 # format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
+16 # datefmt='%m-%d %H:%M:%S')
+17 logging.basicConfig()
+18 # The logger used by this library. Feel free to clobber it with your own, if you like, as
+19 # long as it conforms to Python's logging.
+20 log = logging.getLogger('tftpy')
+21
+23 """This function is a simple utility that will check the condition
+24 passed for a false state. If it finds one, it throws a TftpException
+25 with the message passed. This just makes the code throughout cleaner
+26 by refactoring."""
+27 if not condition:
+28 raise TftpException, msg
+29
+31 """This function is a utility function for setting the internal log level.
+32 The log level defaults to logging.NOTSET, so unwanted output to stdout is
+33 not created."""
+34 global log
+35 log.setLevel(level)
+36
+38 """This class is a convenience for defining the common tftp error codes,
+39 and making them more readable in the code."""
+40 NotDefined = 0
+41 FileNotFound = 1
+42 AccessViolation = 2
+43 DiskFull = 3
+44 IllegalTftpOp = 4
+45 UnknownTID = 5
+46 FileAlreadyExists = 6
+47 NoSuchUser = 7
+48 FailedNegotiation = 8
+49
+51 """This class is the parent class of all exceptions regarding the handling
+52 of the TFTP protocol."""
+53 pass
+54
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpShared.TftpErrors-class.html b/html/tftpy-doc/tftpy.TftpShared.TftpErrors-class.html
new file mode 100644
index 0000000..65bd076
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpShared.TftpErrors-class.html
@@ -0,0 +1,255 @@
+
+
+
+
+ tftpy.TftpShared.TftpErrors
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpErrors
+
+object --+
+ |
+ TftpErrors
+
+
+
+This class is a convenience for defining the common tftp error codes,
+ and making them more readable in the code.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __init__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Class Variables
+
+
+
+
+
+
+
+
+
+ NotDefined = 0
+
+
+
+
+
+
+ FileNotFound = 1
+
+
+
+
+
+
+ AccessViolation = 2
+
+
+
+
+
+
+ DiskFull = 3
+
+
+
+
+
+
+ IllegalTftpOp = 4
+
+
+
+
+
+
+ UnknownTID = 5
+
+
+
+
+
+
+ FileAlreadyExists = 6
+
+
+
+
+
+
+ NoSuchUser = 7
+
+
+
+
+
+
+ FailedNegotiation = 8
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpShared.TftpException-class.html b/html/tftpy-doc/tftpy.TftpShared.TftpException-class.html
new file mode 100644
index 0000000..a9cef7d
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpShared.TftpException-class.html
@@ -0,0 +1,189 @@
+
+
+
+
+ tftpy.TftpShared.TftpException
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpException
+
+ object --+
+ |
+exceptions.BaseException --+
+ |
+ exceptions.Exception --+
+ |
+ TftpException
+
+
+
+This class is the parent class of all exceptions regarding the
+ handling of the TFTP protocol.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+ Inherited from exceptions.Exception
:
+ __init__
,
+ __new__
+
+ Inherited from exceptions.BaseException
:
+ __delattr__
,
+ __getattribute__
,
+ __getitem__
,
+ __getslice__
,
+ __reduce__
,
+ __repr__
,
+ __setattr__
,
+ __setstate__
,
+ __str__
+
+ Inherited from object
:
+ __hash__
,
+ __reduce_ex__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from exceptions.BaseException
:
+ args
,
+ message
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates-module.html b/html/tftpy-doc/tftpy.TftpStates-module.html
new file mode 100644
index 0000000..2534bda
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates-module.html
@@ -0,0 +1,229 @@
+
+
+
+
+ tftpy.TftpStates
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Module TftpStates
+
+
+
+
+
+
+
+ Classes
+
+
+
+
+
+
+
+
+
+ TftpMetrics
+ A class representing metrics of the transfer.
+
+
+
+
+
+
+ TftpContext
+ The base class of the contexts.
+
+
+
+
+
+
+ TftpContextServer
+ The context for the server.
+
+
+
+
+
+
+ TftpContextClientUpload
+ The upload context for the client during an upload.
+
+
+
+
+
+
+ TftpContextClientDownload
+ The download context for the client during a download.
+
+
+
+
+
+
+ TftpState
+ The base class for the states.
+
+
+
+
+
+
+ TftpStateServerRecvRRQ
+ This class represents the state of the TFTP server when it has just
+ received an RRQ packet.
+
+
+
+
+
+
+ TftpStateServerRecvWRQ
+ This class represents the state of the TFTP server when it has just
+ received a WRQ packet.
+
+
+
+
+
+
+ TftpStateServerStart
+ The start state for the server.
+
+
+
+
+
+
+ TftpStateExpectACK
+ This class represents the state of the transfer when a DAT was just
+ sent, and we are waiting for an ACK from the server.
+
+
+
+
+
+
+ TftpStateExpectDAT
+ Just sent an ACK packet.
+
+
+
+
+
+
+ TftpStateSentWRQ
+ Just sent an WRQ packet for an upload.
+
+
+
+
+
+
+ TftpStateSentRRQ
+ Just sent an RRQ packet.
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates-pysrc.html b/html/tftpy-doc/tftpy.TftpStates-pysrc.html
new file mode 100644
index 0000000..93b492d
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates-pysrc.html
@@ -0,0 +1,1345 @@
+
+
+
+
+ tftpy.TftpStates
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source Code for Module tftpy.TftpStates
+
+ 1 from TftpShared import *
+ 2 from TftpPacketTypes import *
+ 3 from TftpPacketFactory import *
+ 4 import socket, time, os
+ 5
+ 6 ###############################################################################
+ 7 # Utility classes
+ 8 ###############################################################################
+ 9
+ 11 """A class representing metrics of the transfer."""
+ 13 # Bytes transferred
+ 14 self.bytes = 0
+ 15 # Bytes re-sent
+ 16 self.resent_bytes = 0
+ 17 # Duplicate packets received
+ 18 self.dups = {}
+ 19 self.dupcount = 0
+ 20 # Times
+ 21 self.start_time = 0
+ 22 self.end_time = 0
+ 23 self.duration = 0
+ 24 # Rates
+ 25 self.bps = 0
+ 26 self.kbps = 0
+ 27 # Generic errors
+ 28 self.errors = 0
+ 29
+ 31 # Compute transfer time
+ 32 self.duration = self.end_time - self.start_time
+ 33 log.debug("TftpMetrics.compute: duration is %s" % self.duration)
+ 34 self.bps = (self.bytes * 8.0) / self.duration
+ 35 self.kbps = self.bps / 1024.0
+ 36 log.debug("TftpMetrics.compute: kbps is %s" % self.kbps)
+ 37 for key in self.dups:
+ 38 self.dupcount += self.dups[key]
+ 39
+ 41 """This method adds a dup for a block number to the metrics."""
+ 42 log.debug("Recording a dup for block %d" % blocknumber)
+ 43 if self.dups.has_key(blocknumber):
+ 44 self.dups[blocknumber] += 1
+ 45 else:
+ 46 self.dups[blocknumber] = 1
+ 47 tftpassert(self.dups[blocknumber] < MAX_DUPS,
+ 48 "Max duplicates for block %d reached" % blocknumber)
+ 49
+ 50 ###############################################################################
+ 51 # Context classes
+ 52 ###############################################################################
+ 53
+ 55 """The base class of the contexts."""
+ 56
+ 58 """Constructor for the base context, setting shared instance
+ 59 variables."""
+ 60 self.file_to_transfer = None
+ 61 self.fileobj = None
+ 62 self.options = None
+ 63 self.packethook = None
+ 64 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ 65 self.sock.settimeout(timeout)
+ 66 self.state = None
+ 67 self.next_block = 0
+ 68 self.factory = TftpPacketFactory()
+ 69 # Note, setting the host will also set self.address, as it's a property.
+ 70 self.host = host
+ 71 self.port = port
+ 72 # The port associated with the TID
+ 73 self.tidport = None
+ 74 # Metrics
+ 75 self.metrics = TftpMetrics()
+ 76 # Flag when the transfer is pending completion.
+ 77 self.pending_complete = False
+ 78 # Time when this context last received any traffic.
+ 79 # FIXME: does this belong in metrics?
+ 80 self.last_update = 0
+ 81 # The last DAT packet we sent, if applicable, to make resending easy.
+ 82 self.last_dat_pkt = None
+ 83
+ 85 """Compare current time with last_update time, and raise an exception
+ 86 if we're over SOCK_TIMEOUT time."""
+ 87 if now - self.last_update > SOCK_TIMEOUT:
+ 88 raise TftpException, "Timeout waiting for traffic"
+ 89
+ 92
+ 95
+ 99
+101 """Setter method that also sets the address property as a result
+102 of the host that is set."""
+103 self.__host = host
+104 self.address = socket.gethostbyname(host)
+105
+106 host = property(gethost, sethost)
+107
+109 if block > 2 ** 16:
+110 log.debug("Block number rollover to 0 again")
+111 block = 0
+112 self.__eblock = block
+113
+116
+117 next_block = property(getNextBlock, setNextBlock)
+118
+120 """Here we wait for a response from the server after sending it
+121 something, and dispatch appropriate action to that response."""
+122 # FIXME: This won't work very well in a server context with multiple
+123 # sessions running.
+124 for i in range(TIMEOUT_RETRIES):
+125 log.debug("In cycle, receive attempt %d" % i)
+126 try:
+127 (buffer, (raddress, rport)) = self.sock.recvfrom(MAX_BLKSIZE)
+128 except socket.timeout, err:
+129 log.warn("Timeout waiting for traffic, retrying...")
+130 continue
+131 break
+132 else:
+133 raise TftpException, "Hit max timeouts, giving up."
+134
+135 # Ok, we've received a packet. Log it.
+136 log.debug("Received %d bytes from %s:%s"
+137 % (len(buffer), raddress, rport))
+138 # And update our last updated time.
+139 self.last_update = time.time()
+140
+141 # Decode it.
+142 recvpkt = self.factory.parse(buffer)
+143
+144 # Check for known "connection".
+145 if raddress != self.address:
+146 log.warn("Received traffic from %s, expected host %s. Discarding"
+147 % (raddress, self.host))
+148
+149 if self.tidport and self.tidport != rport:
+150 log.warn("Received traffic from %s:%s but we're "
+151 "connected to %s:%s. Discarding."
+152 % (raddress, rport,
+153 self.host, self.tidport))
+154
+155 # If there is a packethook defined, call it. We unconditionally
+156 # pass all packets, it's up to the client to screen out different
+157 # kinds of packets. This way, the client is privy to things like
+158 # negotiated options.
+159 if self.packethook:
+160 self.packethook(recvpkt)
+161
+162 # And handle it, possibly changing state.
+163 self.state = self.state.handle(recvpkt, raddress, rport)
+164
+166 """The context for the server."""
+168 TftpContext.__init__(self,
+169 host,
+170 port,
+171 timeout)
+172 # At this point we have no idea if this is a download or an upload. We
+173 # need to let the start state determine that.
+174 self.state = TftpStateServerStart(self)
+175 self.root = root
+176 self.dyn_file_func = dyn_file_func
+177 # In a server, the tidport is the same as the port. This is also true
+178 # with symmetric UDP, which we haven't implemented yet.
+179 self.tidport = port
+180
+182 """Start the state cycle. Note that the server context receives an
+183 initial packet in its start method. Also note that the server does not
+184 loop on cycle(), as it expects the TftpServer object to manage
+185 that."""
+186 log.debug("In TftpContextServer.start")
+187 self.metrics.start_time = time.time()
+188 log.debug("Set metrics.start_time to %s" % self.metrics.start_time)
+189 # And update our last updated time.
+190 self.last_update = time.time()
+191
+192 pkt = self.factory.parse(buffer)
+193 log.debug("TftpContextServer.start() - factory returned a %s" % pkt)
+194
+195 # Call handle once with the initial packet. This should put us into
+196 # the download or the upload state.
+197 self.state = self.state.handle(pkt,
+198 self.host,
+199 self.port)
+200
+201 # FIXME
+202 # How do we ensure that the server closes files, even on error?
+203
+209
+211 """The upload context for the client during an upload."""
+212 - def __init__(self,
+213 host,
+214 port,
+215 filename,
+216 input,
+217 options,
+218 packethook,
+219 timeout):
+220 TftpContext.__init__(self,
+221 host,
+222 port,
+223 timeout)
+224 self.file_to_transfer = filename
+225 self.options = options
+226 self.packethook = packethook
+227 self.fileobj = open(input, "wb")
+228
+229 log.debug("TftpContextClientUpload.__init__()")
+230 log.debug("file_to_transfer = %s, options = %s" %
+231 (self.file_to_transfer, self.options))
+232
+234 log.info("Sending tftp upload request to %s" % self.host)
+235 log.info(" filename -> %s" % self.file_to_transfer)
+236 log.info(" options -> %s" % self.options)
+237
+238 self.metrics.start_time = time.time()
+239 log.debug("Set metrics.start_time to %s" % self.metrics.start_time)
+240
+241 # FIXME: put this in a sendWRQ method?
+242 pkt = TftpPacketWRQ()
+243 pkt.filename = self.file_to_transfer
+244 pkt.mode = "octet" # FIXME - shouldn't hardcode this
+245 pkt.options = self.options
+246 self.sock.sendto(pkt.encode().buffer, (self.host, self.port))
+247 self.next_block = 1
+248
+249 self.state = TftpStateSentWRQ(self)
+250
+251 try:
+252 while self.state:
+253 log.debug("State is %s" % self.state)
+254 self.cycle()
+255 finally:
+256 self.fileobj.close()
+257
+263
+265 """The download context for the client during a download."""
+266 - def __init__(self,
+267 host,
+268 port,
+269 filename,
+270 output,
+271 options,
+272 packethook,
+273 timeout):
+274 TftpContext.__init__(self,
+275 host,
+276 port,
+277 timeout)
+278 # FIXME: should we refactor setting of these params?
+279 self.file_to_transfer = filename
+280 self.options = options
+281 self.packethook = packethook
+282 # FIXME - need to support alternate return formats than files?
+283 # File-like objects would be ideal, ala duck-typing.
+284 self.fileobj = open(output, "wb")
+285
+286 log.debug("TftpContextClientDownload.__init__()")
+287 log.debug("file_to_transfer = %s, options = %s" %
+288 (self.file_to_transfer, self.options))
+289
+291 """Initiate the download."""
+292 log.info("Sending tftp download request to %s" % self.host)
+293 log.info(" filename -> %s" % self.file_to_transfer)
+294 log.info(" options -> %s" % self.options)
+295
+296 self.metrics.start_time = time.time()
+297 log.debug("Set metrics.start_time to %s" % self.metrics.start_time)
+298
+299 # FIXME: put this in a sendRRQ method?
+300 pkt = TftpPacketRRQ()
+301 pkt.filename = self.file_to_transfer
+302 pkt.mode = "octet" # FIXME - shouldn't hardcode this
+303 pkt.options = self.options
+304 self.sock.sendto(pkt.encode().buffer, (self.host, self.port))
+305 self.next_block = 1
+306
+307 self.state = TftpStateSentRRQ(self)
+308
+309 try:
+310 while self.state:
+311 log.debug("State is %s" % self.state)
+312 self.cycle()
+313 finally:
+314 self.fileobj.close()
+315
+321
+322
+323 ###############################################################################
+324 # State classes
+325 ###############################################################################
+326
+328 """The base class for the states."""
+329
+331 """Constructor for setting up common instance variables. The involved
+332 file object is required, since in tftp there's always a file
+333 involved."""
+334 self.context = context
+335
+337 """An abstract method for handling a packet. It is expected to return
+338 a TftpState object, either itself or a new state."""
+339 raise NotImplementedError, "Abstract method"
+340
+342 """This method handles an OACK from the server, syncing any accepted
+343 options."""
+344 if pkt.options.keys() > 0:
+345 if pkt.match_options(self.context.options):
+346 log.info("Successful negotiation of options")
+347 # Set options to OACK options
+348 self.context.options = pkt.options
+349 for key in self.context.options:
+350 log.info(" %s = %s" % (key, self.context.options[key]))
+351 else:
+352 log.error("Failed to negotiate options")
+353 raise TftpException, "Failed to negotiate options"
+354 else:
+355 raise TftpException, "No options found in OACK"
+356
+358 """This method takes a requested options list from a client, and
+359 returns the ones that are supported."""
+360 # We support the options blksize and tsize right now.
+361 # FIXME - put this somewhere else?
+362 accepted_options = {}
+363 for option in options:
+364 if option == 'blksize':
+365 # Make sure it's valid.
+366 if int(options[option]) > MAX_BLKSIZE:
+367 log.info("Client requested blksize greater than %d "
+368 "setting to maximum" % MAX_BLKSIZE)
+369 accepted_options[option] = MAX_BLKSIZE
+370 elif int(options[option]) < MIN_BLKSIZE:
+371 log.info("Client requested blksize less than %d "
+372 "setting to minimum" % MIN_BLKSIZE)
+373 accepted_options[option] = MIN_BLKSIZE
+374 else:
+375 accepted_options[option] = options[option]
+376 elif option == 'tsize':
+377 log.debug("tsize option is set")
+378 accepted_options['tsize'] = 1
+379 else:
+380 log.info("Dropping unsupported option '%s'" % option)
+381 log.debug("Returning these accepted options: %s" % accepted_options)
+382 return accepted_options
+383
+385 """This method performs initial setup for a server context transfer,
+386 put here to refactor code out of the TftpStateServerRecvRRQ and
+387 TftpStateServerRecvWRQ classes, since their initial setup is
+388 identical. The method returns a boolean, sendoack, to indicate whether
+389 it is required to send an OACK to the client."""
+390 options = pkt.options
+391 sendoack = False
+392 if not options:
+393 log.debug("Setting default options, blksize")
+394 # FIXME: put default options elsewhere
+395 self.context.options = { 'blksize': DEF_BLKSIZE }
+396 else:
+397 log.debug("Options requested: %s" % options)
+398 self.context.options = self.returnSupportedOptions(options)
+399 sendoack = True
+400
+401 # FIXME - only octet mode is supported at this time.
+402 if pkt.mode != 'octet':
+403 self.sendError(TftpErrors.IllegalTftpOp)
+404 raise TftpException, \
+405 "Only octet transfers are supported at this time."
+406
+407 # test host/port of client end
+408 if self.context.host != raddress or self.context.port != rport:
+409 self.sendError(TftpErrors.UnknownTID)
+410 log.error("Expected traffic from %s:%s but received it "
+411 "from %s:%s instead."
+412 % (self.context.host,
+413 self.context.port,
+414 raddress,
+415 rport))
+416 # FIXME: increment an error count?
+417 # Return same state, we're still waiting for valid traffic.
+418 return self
+419
+420 log.debug("Requested filename is %s" % pkt.filename)
+421 # There are no os.sep's allowed in the filename.
+422 # FIXME: Should we allow subdirectories?
+423 if pkt.filename.find(os.sep) >= 0:
+424 self.sendError(TftpErrors.IllegalTftpOp)
+425 raise TftpException, "%s found in filename, not permitted" % os.sep
+426
+427 self.context.file_to_transfer = pkt.filename
+428
+429 return sendoack
+430
+432 """This method sends the next DAT packet based on the data in the
+433 context. It returns a boolean indicating whether the transfer is
+434 finished."""
+435 finished = False
+436 blocknumber = self.context.next_block
+437 tftpassert( blocknumber > 0, "There is no block zero!" )
+438 dat = None
+439 if resend:
+440 log.warn("Resending block number %d" % blocknumber)
+441 dat = self.context.last_dat_pkt
+442 self.context.metrics.resent_bytes += len(dat.data)
+443 self.context.metrics.add_dup(dat)
+444 else:
+445 blksize = int(self.context.options['blksize'])
+446 buffer = self.context.fileobj.read(blksize)
+447 log.debug("Read %d bytes into buffer" % len(buffer))
+448 if len(buffer) < blksize:
+449 log.info("Reached EOF on file %s"
+450 % self.context.file_to_transfer)
+451 finished = True
+452 dat = TftpPacketDAT()
+453 dat.data = buffer
+454 dat.blocknumber = blocknumber
+455 self.context.metrics.bytes += len(dat.data)
+456 log.debug("Sending DAT packet %d" % dat.blocknumber)
+457 self.context.sock.sendto(dat.encode().buffer,
+458 (self.context.host, self.context.port))
+459 if self.context.packethook:
+460 self.context.packethook(dat)
+461 self.context.last_dat_pkt = dat
+462 return finished
+463
+465 """This method sends an ack packet to the block number specified. If
+466 none is specified, it defaults to the next_block property in the
+467 parent context."""
+468 log.debug("In sendACK, blocknumber is %s" % blocknumber)
+469 if blocknumber is None:
+470 blocknumber = self.context.next_block
+471 log.info("Sending ack to block %d" % blocknumber)
+472 ackpkt = TftpPacketACK()
+473 ackpkt.blocknumber = blocknumber
+474 self.context.sock.sendto(ackpkt.encode().buffer,
+475 (self.context.host,
+476 self.context.tidport))
+477
+479 """This method uses the socket passed, and uses the errorcode to
+480 compose and send an error packet."""
+481 log.debug("In sendError, being asked to send error %d" % errorcode)
+482 errpkt = TftpPacketERR()
+483 errpkt.errorcode = errorcode
+484 self.context.sock.sendto(errpkt.encode().buffer,
+485 (self.context.host,
+486 self.context.tidport))
+487
+489 """This method sends an OACK packet with the options from the current
+490 context."""
+491 log.debug("In sendOACK with options %s" % self.context.options)
+492 pkt = TftpPacketOACK()
+493 pkt.options = self.context.options
+494 self.context.sock.sendto(pkt.encode().buffer,
+495 (self.context.host,
+496 self.context.tidport))
+497
+499 """This method handles a DAT packet during a client download, or a
+500 server upload."""
+501 log.info("Handling DAT packet - block %d" % pkt.blocknumber)
+502 log.debug("Expecting block %s" % self.context.next_block)
+503 if pkt.blocknumber == self.context.next_block:
+504 log.debug("Good, received block %d in sequence"
+505 % pkt.blocknumber)
+506
+507 self.sendACK()
+508 self.context.next_block += 1
+509
+510 log.debug("Writing %d bytes to output file"
+511 % len(pkt.data))
+512 self.context.fileobj.write(pkt.data)
+513 self.context.metrics.bytes += len(pkt.data)
+514 # Check for end-of-file, any less than full data packet.
+515 if len(pkt.data) < int(self.context.options['blksize']):
+516 log.info("End of file detected")
+517 return None
+518
+519 elif pkt.blocknumber < self.context.next_block:
+520 if pkt.blocknumber == 0:
+521 log.warn("There is no block zero!")
+522 self.sendError(TftpErrors.IllegalTftpOp)
+523 raise TftpException, "There is no block zero!"
+524 log.warn("Dropping duplicate block %d" % pkt.blocknumber)
+525 self.context.metrics.add_dup(pkt.blocknumber)
+526 log.debug("ACKing block %d again, just in case" % pkt.blocknumber)
+527 self.sendACK(pkt.blocknumber)
+528
+529 else:
+530 # FIXME: should we be more tolerant and just discard instead?
+531 msg = "Whoa! Received future block %d but expected %d" \
+532 % (pkt.blocknumber, self.context.next_block)
+533 log.error(msg)
+534 raise TftpException, msg
+535
+536 # Default is to ack
+537 return TftpStateExpectDAT(self.context)
+538
+540 """This class represents the state of the TFTP server when it has just
+541 received an RRQ packet."""
+543 "Handle an initial RRQ packet as a server."
+544 log.debug("In TftpStateServerRecvRRQ.handle")
+545 sendoack = self.serverInitial(pkt, raddress, rport)
+546 path = self.context.root + os.sep + self.context.file_to_transfer
+547 log.info("Opening file %s for reading" % path)
+548 if os.path.exists(path):
+549 # Note: Open in binary mode for win32 portability, since win32
+550 # blows.
+551 self.context.fileobj = open(path, "rb")
+552 elif self.dyn_file_func:
+553 log.debug("No such file %s but using dyn_file_func" % path)
+554 self.context.fileobj = \
+555 self.dyn_file_func(self.context.file_to_transfer)
+556 else:
+557 send.sendError(TftpErrors.FileNotFound)
+558 raise TftpException, "File not found: %s" % path
+559
+560 # Options negotiation.
+561 if sendoack:
+562 # Note, next_block is 0 here since that's the proper
+563 # acknowledgement to an OACK.
+564 # FIXME: perhaps we do need a TftpStateExpectOACK class...
+565 self.sendOACK()
+566 else:
+567 self.context.next_block = 1
+568 log.debug("No requested options, starting send...")
+569 self.context.pending_complete = self.sendDAT()
+570 # Note, we expect an ack regardless of whether we sent a DAT or an
+571 # OACK.
+572 return TftpStateExpectACK(self.context)
+573
+574 # Note, we don't have to check any other states in this method, that's
+575 # up to the caller.
+576
+578 """This class represents the state of the TFTP server when it has just
+579 received a WRQ packet."""
+581 "Handle an initial WRQ packet as a server."
+582 log.debug("In TftpStateServerRecvWRQ.handle")
+583 sendoack = self.serverInitial(pkt, raddress, rport)
+584 path = self.context.root + os.sep + self.context.file_to_transfer
+585 log.info("Opening file %s for writing" % path)
+586 if os.path.exists(path):
+587 # FIXME: correct behavior?
+588 log.warn("File %s exists already, overwriting...")
+589 # FIXME: I think we should upload to a temp file and not overwrite the
+590 # existing file until the file is successfully uploaded.
+591 self.context.fileobj = open(path, "wb")
+592
+593 # Options negotiation.
+594 if sendoack:
+595 log.debug("Sending OACK to client")
+596 self.sendOACK()
+597 else:
+598 log.debug("No requested options, starting send...")
+599 self.sendACK()
+600 # We may have sent an OACK, but we're expecting a DAT as the response
+601 # to either the OACK or an ACK, so lets unconditionally use the
+602 # TftpStateExpectDAT state.
+603 return TftpStateExpectDAT(self.context)
+604
+605 # Note, we don't have to check any other states in this method, that's
+606 # up to the caller.
+607
+609 """The start state for the server."""
+611 """Handle a packet we just received."""
+612 log.debug("In TftpStateServerStart.handle")
+613 if isinstance(pkt, TftpPacketRRQ):
+614 log.debug("Handling an RRQ packet")
+615 return TftpStateServerRecvRRQ(self.context).handle(pkt,
+616 raddress,
+617 rport)
+618 elif isinstance(pkt, TftpPacketWRQ):
+619 log.debug("Handling a WRQ packet")
+620 return TftpStateServerRecvWRQ(self.context).handle(pkt,
+621 raddress,
+622 rport)
+623 else:
+624 self.sendError(TftpErrors.IllegalTftpOp)
+625 raise TftpException, \
+626 "Invalid packet to begin up/download: %s" % pkt
+627
+629 """This class represents the state of the transfer when a DAT was just
+630 sent, and we are waiting for an ACK from the server. This class is the
+631 same one used by the client during the upload, and the server during the
+632 download."""
+634 "Handle a packet, hopefully an ACK since we just sent a DAT."
+635 if isinstance(pkt, TftpPacketACK):
+636 log.info("Received ACK for packet %d" % pkt.blocknumber)
+637 # Is this an ack to the one we just sent?
+638 if self.context.next_block == pkt.blocknumber:
+639 if self.context.pending_complete:
+640 log.info("Received ACK to final DAT, we're done.")
+641 return None
+642 else:
+643 log.debug("Good ACK, sending next DAT")
+644 self.context.next_block += 1
+645 log.debug("Incremented next_block to %d"
+646 % (self.context.next_block))
+647 self.context.pending_complete = self.sendDAT()
+648
+649 elif pkt.blocknumber < self.context.next_block:
+650 self.context.metrics.add_dup(pkt.blocknumber)
+651
+652 else:
+653 log.warn("Oooh, time warp. Received ACK to packet we "
+654 "didn't send yet. Discarding.")
+655 self.context.metrics.errors += 1
+656 return self
+657 elif isinstance(pkt, TftpPacketERR):
+658 log.error("Received ERR packet from peer: %s" % str(pkt))
+659 raise TftpException, \
+660 "Received ERR packet from peer: %s" % str(pkt)
+661 else:
+662 log.warn("Discarding unsupported packet: %s" % str(pkt))
+663 return self
+664
+666 """Just sent an ACK packet. Waiting for DAT."""
+668 """Handle the packet in response to an ACK, which should be a DAT."""
+669 if isinstance(pkt, TftpPacketDAT):
+670 return self.handleDat(pkt)
+671
+672 # Every other packet type is a problem.
+673 elif isinstance(pkt, TftpPacketACK):
+674 # Umm, we ACK, you don't.
+675 self.sendError(TftpErrors.IllegalTftpOp)
+676 raise TftpException, "Received ACK from peer when expecting DAT"
+677
+678 elif isinstance(pkt, TftpPacketWRQ):
+679 self.sendError(TftpErrors.IllegalTftpOp)
+680 raise TftpException, "Received WRQ from peer when expecting DAT"
+681
+682 elif isinstance(pkt, TftpPacketERR):
+683 self.sendError(TftpErrors.IllegalTftpOp)
+684 raise TftpException, "Received ERR from peer: " + str(pkt)
+685
+686 else:
+687 self.sendError(TftpErrors.IllegalTftpOp)
+688 raise TftpException, "Received unknown packet type from peer: " + str(pkt)
+689
+691 """Just sent an WRQ packet for an upload."""
+693 """Handle a packet we just received."""
+694 if not self.context.tidport:
+695 self.context.tidport = rport
+696 log.debug("Set remote port for session to %s" % rport)
+697
+698 # If we're going to successfully transfer the file, then we should see
+699 # either an OACK for accepted options, or an ACK to ignore options.
+700 if isinstance(pkt, TftpPacketOACK):
+701 log.info("Received OACK from server")
+702 try:
+703 self.handleOACK(pkt)
+704 except TftpException, err:
+705 log.error("Failed to negotiate options")
+706 self.sendError(TftpErrors.FailedNegotiation)
+707 raise
+708 else:
+709 log.debug("Sending first DAT packet")
+710 self.context.pending_complete = self.sendDAT()
+711 log.debug("Changing state to TftpStateExpectACK")
+712 return TftpStateExpectACK(self.context)
+713
+714 elif isinstance(pkt, TftpPacketACK):
+715 log.info("Received ACK from server")
+716 log.debug("Apparently the server ignored our options")
+717 # The block number should be zero.
+718 if pkt.blocknumber == 0:
+719 log.debug("Ack blocknumber is zero as expected")
+720 log.debug("Sending first DAT packet")
+721 self.pending_complete = self.context.sendDAT()
+722 log.debug("Changing state to TftpStateExpectACK")
+723 return TftpStateExpectACK(self.context)
+724 else:
+725 log.warn("Discarding ACK to block %s" % pkt.blocknumber)
+726 log.debug("Still waiting for valid response from server")
+727 return self
+728
+729 elif isinstance(pkt, TftpPacketERR):
+730 self.sendError(TftpErrors.IllegalTftpOp)
+731 raise TftpException, "Received ERR from server: " + str(pkt)
+732
+733 elif isinstance(pkt, TftpPacketRRQ):
+734 self.sendError(TftpErrors.IllegalTftpOp)
+735 raise TftpException, "Received RRQ from server while in upload"
+736
+737 elif isinstance(pkt, TftpPacketDAT):
+738 self.sendError(TftpErrors.IllegalTftpOp)
+739 raise TftpException, "Received DAT from server while in upload"
+740
+741 else:
+742 self.sendError(TftpErrors.IllegalTftpOp)
+743 raise TftpException, "Received unknown packet type from server: " + str(pkt)
+744
+745 # By default, no state change.
+746 return self
+747
+749 """Just sent an RRQ packet."""
+751 """Handle the packet in response to an RRQ to the server."""
+752 if not self.context.tidport:
+753 self.context.tidport = rport
+754 log.debug("Set remote port for session to %s" % rport)
+755
+756 # Now check the packet type and dispatch it properly.
+757 if isinstance(pkt, TftpPacketOACK):
+758 log.info("Received OACK from server")
+759 try:
+760 self.handleOACK(pkt)
+761 except TftpException, err:
+762 log.error("Failed to negotiate options: %s" % str(err))
+763 self.sendError(TftpErrors.FailedNegotiation)
+764 raise
+765 else:
+766 log.debug("Sending ACK to OACK")
+767
+768 self.sendACK(blocknumber=0)
+769
+770 log.debug("Changing state to TftpStateExpectDAT")
+771 return TftpStateExpectDAT(self.context)
+772
+773 elif isinstance(pkt, TftpPacketDAT):
+774 # If there are any options set, then the server didn't honour any
+775 # of them.
+776 log.info("Received DAT from server")
+777 if self.context.options:
+778 log.info("Server ignored options, falling back to defaults")
+779 self.context.options = { 'blksize': DEF_BLKSIZE }
+780 return self.handleDat(pkt)
+781
+782 # Every other packet type is a problem.
+783 elif isinstance(pkt, TftpPacketACK):
+784 # Umm, we ACK, the server doesn't.
+785 self.sendError(TftpErrors.IllegalTftpOp)
+786 raise TftpException, "Received ACK from server while in download"
+787
+788 elif isinstance(pkt, TftpPacketWRQ):
+789 self.sendError(TftpErrors.IllegalTftpOp)
+790 raise TftpException, "Received WRQ from server while in download"
+791
+792 elif isinstance(pkt, TftpPacketERR):
+793 self.sendError(TftpErrors.IllegalTftpOp)
+794 raise TftpException, "Received ERR from server: " + str(pkt)
+795
+796 else:
+797 self.sendError(TftpErrors.IllegalTftpOp)
+798 raise TftpException, "Received unknown packet type from server: " + str(pkt)
+799
+800 # By default, no state change.
+801 return self
+802
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpContext-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpContext-class.html
new file mode 100644
index 0000000..838e280
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpContext-class.html
@@ -0,0 +1,455 @@
+
+
+
+
+ tftpy.TftpStates.TftpContext
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpContext
+
+object --+
+ |
+ TftpContext
+
+
+- Known Subclasses:
+-
+
+
+
+
+The base class of the contexts.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ timeout)
+ Constructor for the base context, setting shared instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ checkTimeout(self,
+ now)
+ Compare current time with last_update time, and raise an exception if
+ we're over SOCK_TIMEOUT time.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ start(self)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ end(self)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ gethost(self)
+ Simple getter method for use in a property.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sethost(self,
+ host)
+ Setter method that also sets the address property as a result of the
+ host that is set.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setNextBlock(self,
+ block)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getNextBlock(self)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cycle(self)
+ Here we wait for a response from the server after sending it
+ something, and dispatch appropriate action to that response.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+
+
+ host
+ Simple getter method for use in a property.
+
+
+
+
+
+
+ next_block
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ timeout)
+
(Constructor)
+
+ source code
+
+
+
+ Constructor for the base context, setting shared instance
+ variables.
+
+ - Overrides:
+ object.__init__
+
+
+
+
+
+
+
+
+
+
+
+
+ Property Details
+
+
+
+
+
+
+
+
+
+
+ host
+ Simple getter method for use in a property.
+
+
+
+
+
+
+
+ next_block
+
+
+ - Get Method:
+ - getNextBlock(self)
+
+ - Set Method:
+ - setNextBlock(self,
+ block)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpContextClientDownload-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpContextClientDownload-class.html
new file mode 100644
index 0000000..ac77766
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpContextClientDownload-class.html
@@ -0,0 +1,339 @@
+
+
+
+
+ tftpy.TftpStates.TftpContextClientDownload
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpContextClientDownload
+
+ object --+
+ |
+TftpContext --+
+ |
+ TftpContextClientDownload
+
+
+
+The download context for the client during a download.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ filename,
+ output,
+ options,
+ packethook,
+ timeout)
+ Constructor for the base context, setting shared instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ start(self)
+ Initiate the download.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ end(self)
+ Finish up the context.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpContext
:
+ checkTimeout
,
+ cycle
,
+ getNextBlock
,
+ gethost
,
+ setNextBlock
,
+ sethost
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpContext
:
+ host
,
+ next_block
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ filename,
+ output,
+ options,
+ packethook,
+ timeout)
+
(Constructor)
+
+ source code
+
+
+
+ Constructor for the base context, setting shared instance
+ variables.
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ start(self)
+
+ source code
+
+
+
+ Initiate the download.
+
+ - Overrides:
+ TftpContext.start
+
+
+
+
+
+
+
+
+
+
+ end(self)
+
+ source code
+
+
+
+ Finish up the context.
+
+ - Overrides:
+ TftpContext.end
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpContextClientUpload-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpContextClientUpload-class.html
new file mode 100644
index 0000000..e4e768f
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpContextClientUpload-class.html
@@ -0,0 +1,338 @@
+
+
+
+
+ tftpy.TftpStates.TftpContextClientUpload
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpContextClientUpload
+
+ object --+
+ |
+TftpContext --+
+ |
+ TftpContextClientUpload
+
+
+
+The upload context for the client during an upload.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ filename,
+ input,
+ options,
+ packethook,
+ timeout)
+ Constructor for the base context, setting shared instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ start(self)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ end(self)
+ Finish up the context.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpContext
:
+ checkTimeout
,
+ cycle
,
+ getNextBlock
,
+ gethost
,
+ setNextBlock
,
+ sethost
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpContext
:
+ host
,
+ next_block
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ filename,
+ input,
+ options,
+ packethook,
+ timeout)
+
(Constructor)
+
+ source code
+
+
+
+ Constructor for the base context, setting shared instance
+ variables.
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ start(self)
+
+ source code
+
+
+
+
+
+ - Overrides:
+ TftpContext.start
+
+
+
+
+
+
+
+
+
+
+ end(self)
+
+ source code
+
+
+
+ Finish up the context.
+
+ - Overrides:
+ TftpContext.end
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpContextServer-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpContextServer-class.html
new file mode 100644
index 0000000..5b6e1d3
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpContextServer-class.html
@@ -0,0 +1,339 @@
+
+
+
+
+ tftpy.TftpStates.TftpContextServer
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpContextServer
+
+ object --+
+ |
+TftpContext --+
+ |
+ TftpContextServer
+
+
+
+The context for the server.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ timeout,
+ root,
+ dyn_file_func)
+ Constructor for the base context, setting shared instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ start(self,
+ buffer)
+ Start the state cycle.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ end(self)
+ Finish up the context.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpContext
:
+ checkTimeout
,
+ cycle
,
+ getNextBlock
,
+ gethost
,
+ setNextBlock
,
+ sethost
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from TftpContext
:
+ host
,
+ next_block
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ host,
+ port,
+ timeout,
+ root,
+ dyn_file_func)
+
(Constructor)
+
+ source code
+
+
+
+ Constructor for the base context, setting shared instance
+ variables.
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+
+ start(self,
+ buffer)
+
+ source code
+
+
+
+ Start the state cycle. Note that the server context receives an
+ initial packet in its start method. Also note that the server does not
+ loop on cycle(), as it expects the TftpServer object to manage that.
+
+ - Overrides:
+ TftpContext.start
+
+
+
+
+
+
+
+
+
+
+ end(self)
+
+ source code
+
+
+
+ Finish up the context.
+
+ - Overrides:
+ TftpContext.end
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpMetrics-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpMetrics-class.html
new file mode 100644
index 0000000..51add67
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpMetrics-class.html
@@ -0,0 +1,267 @@
+
+
+
+
+ tftpy.TftpStates.TftpMetrics
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpMetrics
+
+object --+
+ |
+ TftpMetrics
+
+
+
+A class representing metrics of the transfer.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ compute(self)
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ add_dup(self,
+ blocknumber)
+ This method adds a dup for a block number to the metrics.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self)
+
(Constructor)
+
+ source code
+
+
+
+ x.__init__(...) initializes x; see x.__class__.__doc__ for
+ signature
+
+ - Overrides:
+ object.__init__
+
- (inherited documentation)
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpState-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpState-class.html
new file mode 100644
index 0000000..f261c55
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpState-class.html
@@ -0,0 +1,508 @@
+
+
+
+
+ tftpy.TftpStates.TftpState
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpState
+
+object --+
+ |
+ TftpState
+
+
+- Known Subclasses:
+-
+
+
+
+
+The base class for the states.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ context)
+ Constructor for setting up common instance variables.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ An abstract method for handling a packet.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleOACK(self,
+ pkt)
+ This method handles an OACK from the server, syncing any accepted
+ options.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ returnSupportedOptions(self,
+ options)
+ This method takes a requested options list from a client, and returns
+ the ones that are supported.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ serverInitial(self,
+ pkt,
+ raddress,
+ rport)
+ This method performs initial setup for a server context transfer, put
+ here to refactor code out of the TftpStateServerRecvRRQ and
+ TftpStateServerRecvWRQ classes, since their initial setup is
+ identical.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sendDAT(self,
+ resend=False)
+ This method sends the next DAT packet based on the data in the
+ context.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sendACK(self,
+ blocknumber=None)
+ This method sends an ack packet to the block number specified.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sendError(self,
+ errorcode)
+ This method uses the socket passed, and uses the errorcode to compose
+ and send an error packet.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sendOACK(self)
+ This method sends an OACK packet with the options from the current
+ context.
+
+ source code
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleDat(self,
+ pkt)
+ This method handles a DAT packet during a client download, or a
+ server upload.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ __init__(self,
+ context)
+
(Constructor)
+
+ source code
+
+
+
+ Constructor for setting up common instance variables. The involved
+ file object is required, since in tftp there's always a file
+ involved.
+
+ - Overrides:
+ object.__init__
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ An abstract method for handling a packet. It is expected to return a
+ TftpState object, either itself or a new state.
+
+
+
+
+
+
+
+
+
+
+ serverInitial(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ This method performs initial setup for a server context transfer, put
+ here to refactor code out of the TftpStateServerRecvRRQ and
+ TftpStateServerRecvWRQ classes, since their initial setup is identical.
+ The method returns a boolean, sendoack, to indicate whether it is
+ required to send an OACK to the client.
+
+
+
+
+
+
+
+
+
+
+ sendDAT(self,
+ resend=False)
+
+ source code
+
+
+
+ This method sends the next DAT packet based on the data in the
+ context. It returns a boolean indicating whether the transfer is
+ finished.
+
+
+
+
+
+
+
+
+
+
+ sendACK(self,
+ blocknumber=None)
+
+ source code
+
+
+
+ This method sends an ack packet to the block number specified. If none
+ is specified, it defaults to the next_block property in the parent
+ context.
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateExpectACK-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateExpectACK-class.html
new file mode 100644
index 0000000..f17ae86
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateExpectACK-class.html
@@ -0,0 +1,252 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateExpectACK
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateExpectACK
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateExpectACK
+
+
+
+This class represents the state of the transfer when a DAT was just
+ sent, and we are waiting for an ACK from the server. This class is the
+ same one used by the client during the upload, and the server during the
+ download.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle a packet, hopefully an ACK since we just sent a DAT.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle a packet, hopefully an ACK since we just sent a DAT.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateExpectDAT-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateExpectDAT-class.html
new file mode 100644
index 0000000..1daefd0
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateExpectDAT-class.html
@@ -0,0 +1,249 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateExpectDAT
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateExpectDAT
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateExpectDAT
+
+
+
+Just sent an ACK packet. Waiting for DAT.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle the packet in response to an ACK, which should be a DAT.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle the packet in response to an ACK, which should be a DAT.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateSentRRQ-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateSentRRQ-class.html
new file mode 100644
index 0000000..ea8f49a
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateSentRRQ-class.html
@@ -0,0 +1,249 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateSentRRQ
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateSentRRQ
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateSentRRQ
+
+
+
+Just sent an RRQ packet.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle the packet in response to an RRQ to the server.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle the packet in response to an RRQ to the server.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateSentWRQ-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateSentWRQ-class.html
new file mode 100644
index 0000000..09d9cee
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateSentWRQ-class.html
@@ -0,0 +1,249 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateSentWRQ
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateSentWRQ
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateSentWRQ
+
+
+
+Just sent an WRQ packet for an upload.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle a packet we just received.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle a packet we just received.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateServerRecvRRQ-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateServerRecvRRQ-class.html
new file mode 100644
index 0000000..3574d16
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateServerRecvRRQ-class.html
@@ -0,0 +1,250 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateServerRecvRRQ
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateServerRecvRRQ
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateServerRecvRRQ
+
+
+
+This class represents the state of the TFTP server when it has just
+ received an RRQ packet.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle an initial RRQ packet as a server.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle an initial RRQ packet as a server.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateServerRecvWRQ-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateServerRecvWRQ-class.html
new file mode 100644
index 0000000..a093e93
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateServerRecvWRQ-class.html
@@ -0,0 +1,250 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateServerRecvWRQ
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateServerRecvWRQ
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateServerRecvWRQ
+
+
+
+This class represents the state of the TFTP server when it has just
+ received a WRQ packet.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle an initial WRQ packet as a server.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle an initial WRQ packet as a server.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/tftpy.TftpStates.TftpStateServerStart-class.html b/html/tftpy-doc/tftpy.TftpStates.TftpStateServerStart-class.html
new file mode 100644
index 0000000..6f66f3b
--- /dev/null
+++ b/html/tftpy-doc/tftpy.TftpStates.TftpStateServerStart-class.html
@@ -0,0 +1,249 @@
+
+
+
+
+ tftpy.TftpStates.TftpStateServerStart
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class TftpStateServerStart
+
+object --+
+ |
+ TftpState --+
+ |
+ TftpStateServerStart
+
+
+
+The start state for the server.
+
+
+
+
+
+
+
+
+ Instance Methods
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+ Handle a packet we just received.
+
+ source code
+
+
+
+
+
+
+
+
+
+ Inherited from TftpState
:
+ __init__
,
+ handleDat
,
+ handleOACK
,
+ returnSupportedOptions
,
+ sendACK
,
+ sendDAT
,
+ sendError
,
+ sendOACK
,
+ serverInitial
+
+ Inherited from object
:
+ __delattr__
,
+ __getattribute__
,
+ __hash__
,
+ __new__
,
+ __reduce__
,
+ __reduce_ex__
,
+ __repr__
,
+ __setattr__
,
+ __str__
+
+
+
+
+
+
+
+
+
+
+
+ Properties
+
+
+
+
+
+
+
+ Inherited from object
:
+ __class__
+
+
+
+
+
+
+
+
+
+
+
+ Method Details
+
+
+
+
+
+
+
+
+
+
+
+
+ handle(self,
+ pkt,
+ raddress,
+ rport)
+
+ source code
+
+
+
+ Handle a packet we just received.
+
+ - Overrides:
+ TftpState.handle
+
+
+
+
+
+
+
+
+
+ Home
+
+
+ Trees
+
+
+ Indices
+
+
+ Help
+
+
+
+
+
+
+
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009
+
+
+ http://epydoc.sourceforge.net
+
+
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-everything.html b/html/tftpy-doc/toc-everything.html
new file mode 100644
index 0000000..8f244e0
--- /dev/null
+++ b/html/tftpy-doc/toc-everything.html
@@ -0,0 +1,99 @@
+
+
+
+
+ Everything
+
+
+
+
+
+Everything
+
+ All Classes
+ tftpy.TftpClient'.TftpClient
tftpy.TftpPacketFactory'.TftpPacketFactory
tftpy.TftpPacketTypes.TftpPacket
tftpy.TftpPacketTypes.TftpPacketACK
tftpy.TftpPacketTypes.TftpPacketDAT
tftpy.TftpPacketTypes.TftpPacketERR
tftpy.TftpPacketTypes.TftpPacketInitial
tftpy.TftpPacketTypes.TftpPacketOACK
tftpy.TftpPacketTypes.TftpPacketRRQ
tftpy.TftpPacketTypes.TftpPacketWRQ
tftpy.TftpPacketTypes.TftpPacketWithOptions
tftpy.TftpPacketTypes.TftpSession
tftpy.TftpServer'.TftpServer
tftpy.TftpShared.TftpErrors
tftpy.TftpShared.TftpException
tftpy.TftpStates.TftpContext
tftpy.TftpStates.TftpContextClientDownload
tftpy.TftpStates.TftpContextClientUpload
tftpy.TftpStates.TftpContextServer
tftpy.TftpStates.TftpMetrics
tftpy.TftpStates.TftpState
tftpy.TftpStates.TftpStateExpectACK
tftpy.TftpStates.TftpStateExpectDAT
tftpy.TftpStates.TftpStateSentRRQ
tftpy.TftpStates.TftpStateSentWRQ
tftpy.TftpStates.TftpStateServerRecvRRQ
tftpy.TftpStates.TftpStateServerRecvWRQ
tftpy.TftpStates.TftpStateServerStart
All Functions
+ tftpy.TftpShared.setLogLevel
tftpy.TftpShared.tftpassert
All Variables
+ tftpy.TftpClient'.DEF_BLKSIZE
tftpy.TftpClient'.DEF_TFTP_PORT
tftpy.TftpClient'.LOG_LEVEL
tftpy.TftpClient'.MAX_BLKSIZE
tftpy.TftpClient'.MAX_DUPS
tftpy.TftpClient'.MIN_BLKSIZE
tftpy.TftpClient'.SOCK_TIMEOUT
tftpy.TftpClient'.TIMEOUT_RETRIES
tftpy.TftpClient'.log
tftpy.TftpPacketFactory'.DEF_BLKSIZE
tftpy.TftpPacketFactory'.DEF_TFTP_PORT
tftpy.TftpPacketFactory'.LOG_LEVEL
tftpy.TftpPacketFactory'.MAX_BLKSIZE
tftpy.TftpPacketFactory'.MAX_DUPS
tftpy.TftpPacketFactory'.MIN_BLKSIZE
tftpy.TftpPacketFactory'.SOCK_TIMEOUT
tftpy.TftpPacketFactory'.TIMEOUT_RETRIES
tftpy.TftpPacketFactory'.log
tftpy.TftpServer'.DEF_BLKSIZE
tftpy.TftpServer'.DEF_TFTP_PORT
tftpy.TftpServer'.LOG_LEVEL
tftpy.TftpServer'.MAX_BLKSIZE
tftpy.TftpServer'.MAX_DUPS
tftpy.TftpServer'.MIN_BLKSIZE
tftpy.TftpServer'.SOCK_TIMEOUT
tftpy.TftpServer'.TIMEOUT_RETRIES
tftpy.TftpServer'.log
tftpy.TftpShared.DEF_BLKSIZE
tftpy.TftpShared.DEF_TFTP_PORT
tftpy.TftpShared.LOG_LEVEL
tftpy.TftpShared.MAX_BLKSIZE
tftpy.TftpShared.MAX_DUPS
tftpy.TftpShared.MIN_BLKSIZE
tftpy.TftpShared.SOCK_TIMEOUT
tftpy.TftpShared.TIMEOUT_RETRIES
tftpy.TftpShared.log
tftpy.verlist
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy-module.html b/html/tftpy-doc/toc-tftpy-module.html
new file mode 100644
index 0000000..7dfde74
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy-module.html
@@ -0,0 +1,31 @@
+
+
+
+
+ tftpy
+
+
+
+
+
+Module tftpy
+
+ Variables
+ verlist
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy.TftpClient'-module.html b/html/tftpy-doc/toc-tftpy.TftpClient'-module.html
new file mode 100644
index 0000000..a24abea
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy.TftpClient'-module.html
@@ -0,0 +1,41 @@
+
+
+
+
+ TftpClient'
+
+
+
+
+
+Module TftpClient'
+
+ Classes
+ TftpClient
Variables
+ DEF_BLKSIZE
DEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy.TftpPacketFactory'-module.html b/html/tftpy-doc/toc-tftpy.TftpPacketFactory'-module.html
new file mode 100644
index 0000000..b437bc5
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy.TftpPacketFactory'-module.html
@@ -0,0 +1,41 @@
+
+
+
+
+ TftpPacketFactory'
+
+
+
+
+
+Module TftpPacketFactory'
+
+ Classes
+ TftpPacketFactory
Variables
+ DEF_BLKSIZE
DEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy.TftpPacketTypes-module.html b/html/tftpy-doc/toc-tftpy.TftpPacketTypes-module.html
new file mode 100644
index 0000000..69f9240
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy.TftpPacketTypes-module.html
@@ -0,0 +1,40 @@
+
+
+
+
+ TftpPacketTypes
+
+
+
+
+
+Module TftpPacketTypes
+
+ Classes
+ TftpPacket
TftpPacketACK
TftpPacketDAT
TftpPacketERR
TftpPacketInitial
TftpPacketOACK
TftpPacketRRQ
TftpPacketWRQ
TftpPacketWithOptions
TftpSession
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy.TftpServer'-module.html b/html/tftpy-doc/toc-tftpy.TftpServer'-module.html
new file mode 100644
index 0000000..d40d425
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy.TftpServer'-module.html
@@ -0,0 +1,41 @@
+
+
+
+
+ TftpServer'
+
+
+
+
+
+Module TftpServer'
+
+ Classes
+ TftpServer
Variables
+ DEF_BLKSIZE
DEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy.TftpShared-module.html b/html/tftpy-doc/toc-tftpy.TftpShared-module.html
new file mode 100644
index 0000000..e711d38
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy.TftpShared-module.html
@@ -0,0 +1,45 @@
+
+
+
+
+ TftpShared
+
+
+
+
+
+Module TftpShared
+
+ Classes
+ TftpErrors
TftpException
Functions
+ setLogLevel
tftpassert
Variables
+ DEF_BLKSIZE
DEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+
+
+
+
+
diff --git a/html/tftpy-doc/toc-tftpy.TftpStates-module.html b/html/tftpy-doc/toc-tftpy.TftpStates-module.html
new file mode 100644
index 0000000..9430644
--- /dev/null
+++ b/html/tftpy-doc/toc-tftpy.TftpStates-module.html
@@ -0,0 +1,43 @@
+
+
+
+
+ TftpStates
+
+
+
+
+
+Module TftpStates
+
+ Classes
+ TftpContext
TftpContextClientDownload
TftpContextClientUpload
TftpContextServer
TftpMetrics
TftpState
TftpStateExpectACK
TftpStateExpectDAT
TftpStateSentRRQ
TftpStateSentWRQ
TftpStateServerRecvRRQ
TftpStateServerRecvWRQ
TftpStateServerStart
+
+
+
+
+
diff --git a/html/tftpy-doc/toc.html b/html/tftpy-doc/toc.html
new file mode 100644
index 0000000..77bff32
--- /dev/null
+++ b/html/tftpy-doc/toc.html
@@ -0,0 +1,39 @@
+
+
+
+
+ Table of Contents
+
+
+
+
+
+Table of Contents
+
+ Everything
+
+ Modules
+ tftpy
tftpy.TftpClient'
tftpy.TftpPacketFactory'
tftpy.TftpPacketTypes
tftpy.TftpServer'
tftpy.TftpShared
tftpy.TftpStates
+
+
+
+
+
"; + elt.innerHTML = s; + } +} + +function toggle(id) { + elt = document.getElementById(id+"-toggle"); + if (elt.innerHTML == "-") + collapse(id); + else + expand(id); + return false; +} + +function highlight(id) { + var elt = document.getElementById(id+"-def"); + if (elt) elt.className = "py-highlight-hdr"; + var elt = document.getElementById(id+"-expanded"); + if (elt) elt.className = "py-highlight"; + var elt = document.getElementById(id+"-collapsed"); + if (elt) elt.className = "py-highlight"; +} + +function num_lines(s) { + var n = 1; + var pos = s.indexOf("\n"); + while ( pos > 0) { + n += 1; + pos = s.indexOf("\n", pos+1); + } + return n; +} + +// Collapse all blocks that mave more than `min_lines` lines. +function collapse_all(min_lines) { + var elts = document.getElementsByTagName("div"); + for (var i=0; i
- " +
+ links +
+ "
- "+ + "None of the above
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ |
+ |
+
API Documentation
+ +This document contains the API (Application Programming Interface) +documentation for this project. Documentation for the Python +objects defined by the project is divided into separate pages for each +package, module, and class. The API documentation also includes two +pages containing information about the project as a whole: a trees +page, and an index page.
+ +Object Documentation
+ +Each Package Documentation page contains:
+-
+
- A description of the package. +
- A list of the modules and sub-packages contained by the + package. +
- A summary of the classes defined by the package. +
- A summary of the functions defined by the package. +
- A summary of the variables defined by the package. +
- A detailed description of each function defined by the + package. +
- A detailed description of each variable defined by the + package. +
Each Module Documentation page contains:
+-
+
- A description of the module. +
- A summary of the classes defined by the module. +
- A summary of the functions defined by the module. +
- A summary of the variables defined by the module. +
- A detailed description of each function defined by the + module. +
- A detailed description of each variable defined by the + module. +
Each Class Documentation page contains:
+-
+
- A class inheritance diagram. +
- A list of known subclasses. +
- A description of the class. +
- A summary of the methods defined by the class. +
- A summary of the instance variables defined by the class. +
- A summary of the class (static) variables defined by the + class. +
- A detailed description of each method defined by the + class. +
- A detailed description of each instance variable defined by the + class. +
- A detailed description of each class (static) variable defined + by the class. +
Project Documentation
+ +The Trees page contains the module and class hierarchies:
+-
+
- The module hierarchy lists every package and module, with + modules grouped into packages. At the top level, and within each + package, modules and sub-packages are listed alphabetically. +
- The class hierarchy lists every class, grouped by base + class. If a class has more than one base class, then it will be + listed under each base class. At the top level, and under each base + class, classes are listed alphabetically. +
The Index page contains indices of terms and + identifiers:
+-
+
- The term index lists every term indexed by any object's + documentation. For each term, the index provides links to each + place where the term is indexed. +
- The identifier index lists the (short) name of every package, + module, class, method, function, variable, and parameter. For each + identifier, the index provides a short description, and a link to + its documentation. +
The Table of Contents
+ +The table of contents occupies the two frames on the left side of +the window. The upper-left frame displays the project +contents, and the lower-left frame displays the module +contents:
+ +
+ Project Contents ... |
+
+ API Documentation Frame + |
+
+ Module Contents ... + |
+
+ +
The project contents frame contains a list of all packages +and modules that are defined by the project. Clicking on an entry +will display its contents in the module contents frame. Clicking on a +special entry, labeled "Everything," will display the contents of +the entire project.
+ +The module contents frame contains a list of every +submodule, class, type, exception, function, and variable defined by a +module or package. Clicking on an entry will display its +documentation in the API documentation frame. Clicking on the name of +the module, at the top of the frame, will display the documentation +for the module itself.
+ +The "frames" and "no frames" buttons below the top +navigation bar can be used to control whether the table of contents is +displayed or not.
+ +The Navigation Bar
+ +A navigation bar is located at the top and bottom of every page. +It indicates what type of page you are currently viewing, and allows +you to go to related pages. The following table describes the labels +on the navigation bar. Note that not some labels (such as +[Parent]) are not displayed on all pages.
+ +Label | +Highlighted when... | +Links to... | +
---|---|---|
[Parent] | +(never highlighted) | +the parent of the current package |
[Package] | +viewing a package | +the package containing the current object + |
[Module] | +viewing a module | +the module containing the current object + |
[Class] | +viewing a class | +the class containing the current object |
[Trees] | +viewing the trees page | +the trees page |
[Index] | +viewing the index page | +the index page |
[Help] | +viewing the help page | +the help page |
The "show private" and "hide private" buttons below
+the top navigation bar can be used to control whether documentation
+for private objects is displayed. Private objects are usually defined
+as objects whose (short) names begin with a single underscore, but do
+not end with an underscore. For example, "_x
",
+"__pprint
", and "epydoc.epytext._tokenize
"
+are private objects; but "re.sub
",
+"__init__
", and "type_
" are not. However,
+if a module defines the "__all__
" variable, then its
+contents are used to decide which objects are private.
A timestamp below the bottom navigation bar indicates when each +page was last updated.
+ +Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ |
+ |
+
+Identifier Index+ | +[ + A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z + _ +] + |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ |
+ |
+
+
Module Hierarchy
+-
+
- tftpy: This library implements the tftp protocol, based on rfc 1350.
+
-
+
- tftpy.TftpClient +
- tftpy.TftpClient' +
- tftpy.TftpPacketFactory +
- tftpy.TftpPacketFactory' +
- tftpy.TftpPacketTypes +
- tftpy.TftpServer +
- tftpy.TftpServer' +
- tftpy.TftpShared +
- tftpy.TftpStates +
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Epydoc Auto-redirect page
+ +When javascript is enabled, this page will redirect URLs of +the form redirect.html#dotted.name to the +documentation for the object with the given fully-qualified +dotted name.
+ + + + + + diff --git a/html/tftpy-doc/tftpy-module.html b/html/tftpy-doc/tftpy-module.html new file mode 100644 index 0000000..56850de --- /dev/null +++ b/html/tftpy-doc/tftpy-module.html @@ -0,0 +1,165 @@ + + + + +Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Package tftpy
+This library implements the tftp protocol, based on rfc 1350. + http://www.faqs.org/rfcs/rfc1350.html At the moment it implements only a + client class, but will include a server, with support for variable block + sizes.
+ + + +
+
|
+|||
+
|
+ + +
+
|
+|||
+ + |
+ verlist =
+ |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Package tftpy
++ 1 """This library implements the tftp protocol, based on rfc 1350. + 2 http://www.faqs.org/rfcs/rfc1350.html + 3 At the moment it implements only a client class, but will include a server, + 4 with support for variable block sizes. + 5 """ + 6 + 7 import sys + 8 + 9 # Make sure that this is at least Python 2.3 +10 verlist = sys.version_info +11 if not verlist[0] >= 2 or not verlist[1] >= 3: +12 raise AssertionError, "Requires at least Python 2.3" +13 +14 from TftpShared import * +15 from TftpPacketTypes import * +16 from TftpPacketFactory import * +17 from TftpClient import * +18 from TftpServer import * +19 ++
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Module TftpClient'
+ + +
+
|
+|||
+ + |
+ TftpClient + This class is an implementation of a tftp client. + |
+
+
|
+|||
+ + |
+ DEF_BLKSIZE = 512
+ |
+ ||
+ + |
+ DEF_TFTP_PORT = 69
+ |
+ ||
+ + |
+ LOG_LEVEL = 0
+ |
+ ||
+ + |
+ MAX_BLKSIZE = 65536
+ |
+ ||
+ + |
+ MAX_DUPS = 20
+ |
+ ||
+ + |
+ MIN_BLKSIZE = 8
+ |
+ ||
+ + |
+ SOCK_TIMEOUT = 5
+ |
+ ||
+ + |
+ TIMEOUT_RETRIES = 5
+ |
+ ||
+ + |
+ log = logging.getLogger('tftpy')
+ |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Module tftpy.TftpClient'
++ 1 import time, types + 2 from TftpShared import * + 3 from TftpPacketFactory import * + 4 from TftpStates import TftpContextClientDownload, TftpContextClientUpload + 5 ++7 """This class is an implementation of a tftp client. Once instantiated, a + 8 download can be initiated via the download() method.""" +92 +10 """This constructor returns an instance of TftpClient, taking the +11 remote host, the remote port, and the filename to fetch.""" +12 TftpSession.__init__(self) +13 self.context = None +14 self.host = host +15 self.iport = port +16 self.filename = None +17 self.options = options +18 # FIXME: If the blksize is DEF_BLKSIZE, we should just skip sending +19 # it. +20 if self.options.has_key('blksize'): +21 size = self.options['blksize'] +22 tftpassert(types.IntType == type(size), "blksize must be an int") +23 if size < MIN_BLKSIZE or size > MAX_BLKSIZE: +24 raise TftpException, "Invalid blksize: %d" % size +25 else: +26 self.options['blksize'] = DEF_BLKSIZE +27 +29 """This method initiates a tftp download from the configured remote +30 host, requesting the filename passed. It saves the file to a local +31 file specified in the output parameter. If a packethook is provided, +32 it must be a function that takes a single parameter, which will be a +33 copy of each DAT packet received in the form of a TftpPacketDAT +34 object. The timeout parameter may be used to override the default +35 SOCK_TIMEOUT setting, which is the amount of time that the client will +36 wait for a receive packet to arrive.""" +37 # We're downloading. +38 log.debug("Creating download context with the following params:") +39 log.debug("host = %s, port = %s, filename = %s, output = %s" +40 % (self.host, self.iport, filename, output)) +41 log.debug("options = %s, packethook = %s, timeout = %s" +42 % (self.options, packethook, timeout)) +43 self.context = TftpContextClientDownload(self.host, +44 self.iport, +45 filename, +46 output, +47 self.options, +48 packethook, +49 timeout) +50 self.context.start() +51 # Download happens here +52 self.context.end() +53 +54 metrics = self.context.metrics +55 +56 log.info('') +57 log.info("Download complete.") +58 if metrics.duration == 0: +59 log.info("Duration too short, rate undetermined") +60 else: +61 log.info("Downloaded %.2f bytes in %.2f seconds" % (metrics.bytes, metrics.duration)) +62 log.info("Average rate: %.2f kbps" % metrics.kbps) +63 log.info("%.2f bytes in resent data" % metrics.resent_bytes) +64 log.info("Received %d duplicate packets" % metrics.dupcount) +65 +67 # Open the input file. +68 # FIXME: As of the state machine, this is now broken. Need to +69 # implement with new state machine. +70 self.context = TftpContextClientUpload(self.host, +71 self.iport, +72 filename, +73 input, +74 self.options, +75 packethook, +76 timeout) +77 self.context.start() +78 # Upload happens here +79 self.context.end() +80 +81 metrics = self.context.metrics +82 +83 log.info('') +84 log.info("Upload complete.") +85 if metrics.duration == 0: +86 log.info("Duration too short, rate undetermined") +87 else: +88 log.info("Uploaded %.2f bytes in %.2f seconds" % (metrics.bytes, metrics.duration)) +89 log.info("Average rate: %.2f kbps" % metrics.kbps) +90 log.info("%.2f bytes in resent data" % metrics.resent_bytes) +91 log.info("Resent %d packets" % metrics.dupcount) +
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpClient
++ object --+ + | +TftpPacketTypes.TftpSession --+ + | + TftpClient ++ +
+
This class is an implementation of a tftp client. Once instantiated, a + download can be initiated via the download() method.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
This constructor returns an instance of TftpClient, taking the remote + host, the remote port, and the filename to fetch. +
|
+
This method initiates a tftp download from the configured remote host, + requesting the filename passed. It saves the file to a local file + specified in the output parameter. If a packethook is provided, it must + be a function that takes a single parameter, which will be a copy of each + DAT packet received in the form of a TftpPacketDAT object. The timeout + parameter may be used to override the default SOCK_TIMEOUT setting, which + is the amount of time that the client will wait for a receive packet to + arrive. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Module TftpPacketFactory'
+ + +
+
|
+|||
+ + |
+ TftpPacketFactory + This class generates TftpPacket objects. + |
+
+
|
+|||
+ + |
+ DEF_BLKSIZE = 512
+ |
+ ||
+ + |
+ DEF_TFTP_PORT = 69
+ |
+ ||
+ + |
+ LOG_LEVEL = 0
+ |
+ ||
+ + |
+ MAX_BLKSIZE = 65536
+ |
+ ||
+ + |
+ MAX_DUPS = 20
+ |
+ ||
+ + |
+ MIN_BLKSIZE = 8
+ |
+ ||
+ + |
+ SOCK_TIMEOUT = 5
+ |
+ ||
+ + |
+ TIMEOUT_RETRIES = 5
+ |
+ ||
+ + |
+ log = logging.getLogger('tftpy')
+ |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Module tftpy.TftpPacketFactory'
++ 1 from TftpShared import * + 2 from TftpPacketTypes import * + 3 ++5 """This class generates TftpPacket objects. It is responsible for parsing + 6 raw buffers off of the wire and returning objects representing them, via + 7 the parse() method.""" +38 +9 self.classes = { +10 1: TftpPacketRRQ, +11 2: TftpPacketWRQ, +12 3: TftpPacketDAT, +13 4: TftpPacketACK, +14 5: TftpPacketERR, +15 6: TftpPacketOACK +16 } +17 +19 """This method is used to parse an existing datagram into its +20 corresponding TftpPacket object. The buffer is the raw bytes off of +21 the network.""" +22 log.debug("parsing a %d byte packet" % len(buffer)) +23 (opcode,) = struct.unpack("!H", buffer[:2]) +24 log.debug("opcode is %d" % opcode) +25 packet = self.__create(opcode) +26 packet.buffer = buffer +27 return packet.decode() +28 +30 """This method returns the appropriate class object corresponding to +31 the passed opcode.""" +32 tftpassert(self.classes.has_key(opcode), +33 "Unsupported opcode: %d" % opcode) +34 +35 packet = self.classes[opcode]() +36 +37 return packet +
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketFactory
++object --+ + | + TftpPacketFactory ++ +
+
This class generates TftpPacket objects. It is responsible for parsing + raw buffers off of the wire and returning objects representing them, via + the parse() method.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
This method is used to parse an existing datagram into its + corresponding TftpPacket object. The buffer is the raw bytes off of the + network. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Module TftpPacketTypes
+ + +
+
|
+|||
+ + |
+ TftpSession + This class is the base class for the tftp client and server. + |
+ ||
+ + |
+ TftpPacketWithOptions + This class exists to permit some TftpPacket subclasses to share + code regarding options handling. + |
+ ||
+ + |
+ TftpPacket + This class is the parent class of all tftp packet classes. + |
+ ||
+ + |
+ TftpPacketInitial + This class is a common parent class for the RRQ and WRQ packets, as + they share quite a bit of code. + |
+ ||
+ + |
+ TftpPacketRRQ + 2 bytes string 1 byte string 1 byte... + |
+ ||
+ + |
+ TftpPacketWRQ + 2 bytes string 1 byte string 1 byte... + |
+ ||
+ + |
+ TftpPacketDAT + 2 bytes 2 bytes n bytes... + |
+ ||
+ + |
+ TftpPacketACK + 2 bytes 2 bytes... + |
+ ||
+ + |
+ TftpPacketERR + 2 bytes 2 bytes string 1 byte + ---------------------------------------- +ERROR | 05 | ErrorCode | ErrMsg | 0 | + ---------------------------------------- + Error Codes + |
+ ||
+ + |
+ TftpPacketOACK + # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ # + | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | # + +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Module tftpy.TftpPacketTypes
++ 1 import struct + 2 from TftpShared import * + 3 ++5 """This class is the base class for the tftp client and server. Any shared + 6 code should be in this class.""" + 7 # FIXME: do we need this anymore? + 8 pass +9 +11 """This class exists to permit some TftpPacket subclasses to share code + 12 regarding options handling. It does not inherit from TftpPacket, as the + 13 goal is just to share code here, and not cause diamond inheritance.""" + 14 +79 +16 self.options = {} +17 +19 log.debug("in TftpPacketWithOptions.setoptions") + 20 log.debug("options: " + str(options)) + 21 myoptions = {} + 22 for key in options: + 23 newkey = str(key) + 24 myoptions[newkey] = str(options[key]) + 25 log.debug("populated myoptions with %s = %s" + 26 % (newkey, myoptions[newkey])) + 27 + 28 log.debug("setting options hash to: " + str(myoptions)) + 29 self._options = myoptions +30 + 34 + 35 # Set up getter and setter on options to ensure that they are the proper + 36 # type. They should always be strings, but we don't need to force the + 37 # client to necessarily enter strings if we can avoid it. + 38 options = property(getoptions, setoptions) + 39 +41 """This method decodes the section of the buffer that contains an + 42 unknown number of options. It returns a dictionary of option names and + 43 values.""" + 44 nulls = 0 + 45 format = "!" + 46 options = {} + 47 + 48 log.debug("decode_options: buffer is: " + repr(buffer)) + 49 log.debug("size of buffer is %d bytes" % len(buffer)) + 50 if len(buffer) == 0: + 51 log.debug("size of buffer is zero, returning empty hash") + 52 return {} + 53 + 54 # Count the nulls in the buffer. Each one terminates a string. + 55 log.debug("about to iterate options buffer counting nulls") + 56 length = 0 + 57 for c in buffer: + 58 #log.debug("iterating this byte: " + repr(c)) + 59 if ord(c) == 0: + 60 log.debug("found a null at length %d" % length) + 61 if length > 0: + 62 format += "%dsx" % length + 63 length = -1 + 64 else: + 65 raise TftpException, "Invalid options in buffer" + 66 length += 1 + 67 + 68 log.debug("about to unpack, format is: %s" % format) + 69 mystruct = struct.unpack(format, buffer) + 70 + 71 tftpassert(len(mystruct) % 2 == 0, + 72 "packet with odd number of option/value pairs") + 73 + 74 for i in range(0, len(mystruct), 2): + 75 log.debug("setting option %s to %s" % (mystruct[i], mystruct[i+1])) + 76 options[mystruct[i]] = mystruct[i+1] + 77 + 78 return options +81 """This class is the parent class of all tftp packet classes. It is an + 82 abstract class, providing an interface, and should not be instantiated + 83 directly.""" + 87 +105 +89 """The encode method of a TftpPacket takes keyword arguments specific + 90 to the type of packet, and packs an appropriate buffer in network-byte + 91 order suitable for sending over the wire. + 92 + 93 This is an abstract method.""" + 94 raise NotImplementedError, "Abstract method" +95 +97 """The decode method of a TftpPacket takes a buffer off of the wire in + 98 network-byte order, and decodes it, populating internal properties as + 99 appropriate. This can only be done once the first 2-byte opcode has +100 already been decoded, but the data section does include the entire +101 datagram. +102 +103 This is an abstract method.""" +104 raise NotImplementedError, "Abstract method" +107 """This class is a common parent class for the RRQ and WRQ packets, as +108 they share quite a bit of code.""" +198 +110 TftpPacket.__init__(self) +111 TftpPacketWithOptions.__init__(self) +112 self.filename = None +113 self.mode = None +114 +116 """Encode the packet's buffer from the instance variables.""" +117 tftpassert(self.filename, "filename required in initial packet") +118 tftpassert(self.mode, "mode required in initial packet") +119 +120 ptype = None +121 if self.opcode == 1: ptype = "RRQ" +122 else: ptype = "WRQ" +123 log.debug("Encoding %s packet, filename = %s, mode = %s" +124 % (ptype, self.filename, self.mode)) +125 for key in self.options: +126 log.debug(" Option %s = %s" % (key, self.options[key])) +127 +128 format = "!H" +129 format += "%dsx" % len(self.filename) +130 if self.mode == "octet": +131 format += "5sx" +132 else: +133 raise AssertionError, "Unsupported mode: %s" % mode +134 # Add options. +135 options_list = [] +136 if self.options.keys() > 0: +137 log.debug("there are options to encode") +138 for key in self.options: +139 # Populate the option name +140 format += "%dsx" % len(key) +141 options_list.append(key) +142 # Populate the option value +143 format += "%dsx" % len(str(self.options[key])) +144 options_list.append(str(self.options[key])) +145 +146 log.debug("format is %s" % format) +147 log.debug("options_list is %s" % options_list) +148 log.debug("size of struct is %d" % struct.calcsize(format)) +149 +150 self.buffer = struct.pack(format, +151 self.opcode, +152 self.filename, +153 self.mode, +154 *options_list) +155 +156 log.debug("buffer is " + repr(self.buffer)) +157 return self +158 +160 tftpassert(self.buffer, "Can't decode, buffer is empty") +161 +162 # FIXME - this shares a lot of code with decode_options +163 nulls = 0 +164 format = "" +165 nulls = length = tlength = 0 +166 log.debug("in decode: about to iterate buffer counting nulls") +167 subbuf = self.buffer[2:] +168 for c in subbuf: +169 log.debug("iterating this byte: " + repr(c)) +170 if ord(c) == 0: +171 nulls += 1 +172 log.debug("found a null at length %d, now have %d" +173 % (length, nulls)) +174 format += "%dsx" % length +175 length = -1 +176 # At 2 nulls, we want to mark that position for decoding. +177 if nulls == 2: +178 break +179 length += 1 +180 tlength += 1 +181 +182 log.debug("hopefully found end of mode at length %d" % tlength) +183 # length should now be the end of the mode. +184 tftpassert(nulls == 2, "malformed packet") +185 shortbuf = subbuf[:tlength+1] +186 log.debug("about to unpack buffer with format: %s" % format) +187 log.debug("unpacking buffer: " + repr(shortbuf)) +188 mystruct = struct.unpack(format, shortbuf) +189 +190 tftpassert(len(mystruct) == 2, "malformed packet") +191 log.debug("setting filename to %s" % mystruct[0]) +192 log.debug("setting mode to %s" % mystruct[1]) +193 self.filename = mystruct[0] +194 self.mode = mystruct[1] +195 +196 self.options = self.decode_options(subbuf[tlength+1:]) +197 return self +200 """ +201 2 bytes string 1 byte string 1 byte +202 ----------------------------------------------- +203 RRQ/ | 01/02 | Filename | 0 | Mode | 0 | +204 WRQ ----------------------------------------------- +205 """ +209 +216 +218 """ +219 2 bytes string 1 byte string 1 byte +220 ----------------------------------------------- +221 RRQ/ | 01/02 | Filename | 0 | Mode | 0 | +222 WRQ ----------------------------------------------- +223 """ +227 +234 +236 """ +237 2 bytes 2 bytes n bytes +238 --------------------------------- +239 DATA | 03 | Block # | Data | +240 --------------------------------- +241 """ +280 +243 TftpPacket.__init__(self) +244 self.opcode = 3 +245 self.blocknumber = 0 +246 self.data = None +247 +249 s = 'DAT packet: block %s' % self.blocknumber +250 if self.data: +251 s += '\n data: %d bytes' % len(self.data) +252 return s +253 +255 """Encode the DAT packet. This method populates self.buffer, and +256 returns self for easy method chaining.""" +257 if len(self.data) == 0: +258 log.debug("Encoding an empty DAT packet") +259 format = "!HH%ds" % len(self.data) +260 self.buffer = struct.pack(format, +261 self.opcode, +262 self.blocknumber, +263 self.data) +264 return self +265 +267 """Decode self.buffer into instance variables. It returns self for +268 easy method chaining.""" +269 # We know the first 2 bytes are the opcode. The second two are the +270 # block number. +271 (self.blocknumber,) = struct.unpack("!H", self.buffer[2:4]) +272 log.debug("decoding DAT packet, block number %d" % self.blocknumber) +273 log.debug("should be %d bytes in the packet total" +274 % len(self.buffer)) +275 # Everything else is data. +276 self.data = self.buffer[4:] +277 log.debug("found %d bytes of data" +278 % len(self.data)) +279 return self +282 """ +283 2 bytes 2 bytes +284 ------------------- +285 ACK | 04 | Block # | +286 -------------------- +287 """ +292 +295 +307 +297 log.debug("encoding ACK: opcode = %d, block = %d" +298 % (self.opcode, self.blocknumber)) +299 self.buffer = struct.pack("!HH", self.opcode, self.blocknumber) +300 return self +301 +303 self.opcode, self.blocknumber = struct.unpack("!HH", self.buffer) +304 log.debug("decoded ACK packet: opcode = %d, block = %d" +305 % (self.opcode, self.blocknumber)) +306 return self +309 """ +310 2 bytes 2 bytes string 1 byte +311 ---------------------------------------- +312 ERROR | 05 | ErrorCode | ErrMsg | 0 | +313 ---------------------------------------- +314 Error Codes +315 +316 Value Meaning +317 +318 0 Not defined, see error message (if any). +319 1 File not found. +320 2 Access violation. +321 3 Disk full or allocation exceeded. +322 4 Illegal TFTP operation. +323 5 Unknown transfer ID. +324 6 File already exists. +325 7 No such user. +326 8 Failed to negotiate options +327 """ +382 +329 TftpPacket.__init__(self) +330 self.opcode = 5 +331 self.errorcode = 0 +332 # FIXME: We don't encode the errmsg... +333 self.errmsg = None +334 # FIXME - integrate in TftpErrors references? +335 self.errmsgs = { +336 1: "File not found", +337 2: "Access violation", +338 3: "Disk full or allocation exceeded", +339 4: "Illegal TFTP operation", +340 5: "Unknown transfer ID", +341 6: "File already exists", +342 7: "No such user", +343 8: "Failed to negotiate options" +344 } +345 +347 s = 'ERR packet: errorcode = %d' % self.errorcode +348 s += '\n msg = %s' % self.errmsgs.get(self.errorcode, '') +349 return s +350 +352 """Encode the DAT packet based on instance variables, populating +353 self.buffer, returning self.""" +354 format = "!HH%dsx" % len(self.errmsgs[self.errorcode]) +355 log.debug("encoding ERR packet with format %s" % format) +356 self.buffer = struct.pack(format, +357 self.opcode, +358 self.errorcode, +359 self.errmsgs[self.errorcode]) +360 return self +361 +363 "Decode self.buffer, populating instance variables and return self." +364 buflen = len(self.buffer) +365 tftpassert(buflen >= 4, "malformed ERR packet, too short") +366 log.debug("Decoding ERR packet, length %s bytes" % buflen) +367 if buflen == 4: +368 log.debug("Allowing this affront to the RFC of a 4-byte packet") +369 format = "!HH" +370 log.debug("Decoding ERR packet with format: %s" % format) +371 self.opcode, self.errorcode = struct.unpack(format, +372 self.buffer) +373 else: +374 log.debug("Good ERR packet > 4 bytes") +375 format = "!HH%dsx" % (len(self.buffer) - 5) +376 log.debug("Decoding ERR packet with format: %s" % format) +377 self.opcode, self.errorcode, self.errmsg = struct.unpack(format, +378 self.buffer) +379 log.error("ERR packet - errorcode: %d, message: %s" +380 % (self.errorcode, self.errmsg)) +381 return self +384 """ +385 # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ +386 # | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | +387 # +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ +388 """ +393 +432 +395 return 'OACK packet:\n options = %s' % self.options +396 +398 format = "!H" # opcode +399 options_list = [] +400 log.debug("in TftpPacketOACK.encode") +401 for key in self.options: +402 log.debug("looping on option key %s" % key) +403 log.debug("value is %s" % self.options[key]) +404 format += "%dsx" % len(key) +405 format += "%dsx" % len(self.options[key]) +406 options_list.append(key) +407 options_list.append(self.options[key]) +408 self.buffer = struct.pack(format, self.opcode, *options_list) +409 return self +410 +414 +416 """This method takes a set of options, and tries to match them with +417 its own. It can accept some changes in those options from the server as +418 part of a negotiation. Changed or unchanged, it will return a dict of +419 the options so that the session can update itself to the negotiated +420 options.""" +421 for name in self.options: +422 if options.has_key(name): +423 if name == 'blksize': +424 # We can accept anything between the min and max values. +425 size = self.options[name] +426 if size >= MIN_BLKSIZE and size <= MAX_BLKSIZE: +427 log.debug("negotiated blksize of %d bytes" % size) +428 options[blksize] = size +429 else: +430 raise TftpException, "Unsupported option: %s" % name +431 return True +
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacket
++object --+ + | + TftpPacket ++ +
- Known Subclasses: +
- + +
+
This class is the parent class of all tftp packet classes. It is an + abstract class, providing an interface, and should not be instantiated + directly.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
The encode method of a TftpPacket takes keyword arguments specific to + the type of packet, and packs an appropriate buffer in network-byte order + suitable for sending over the wire. +This is an abstract method. +
|
+
The decode method of a TftpPacket takes a buffer off of the wire in + network-byte order, and decodes it, populating internal properties as + appropriate. This can only be done once the first 2-byte opcode has + already been decoded, but the data section does include the entire + datagram. +This is an abstract method. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketACK
++object --+ + | +TftpPacket --+ + | + TftpPacketACK ++ +
+
+ + 2 bytes 2 bytes + ------------------- +ACK | 04 | Block # | + -------------------- + + ++ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
str(x) +
|
+
The encode method of a TftpPacket takes keyword arguments specific to + the type of packet, and packs an appropriate buffer in network-byte order + suitable for sending over the wire. +This is an abstract method. +
|
+
The decode method of a TftpPacket takes a buffer off of the wire in + network-byte order, and decodes it, populating internal properties as + appropriate. This can only be done once the first 2-byte opcode has + already been decoded, but the data section does include the entire + datagram. +This is an abstract method. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketDAT
++object --+ + | +TftpPacket --+ + | + TftpPacketDAT ++ +
+
+ + 2 bytes 2 bytes n bytes + --------------------------------- +DATA | 03 | Block # | Data | + --------------------------------- + + ++ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
str(x) +
|
+
Encode the DAT packet. This method populates self.buffer, and returns + self for easy method chaining. +
|
+
Decode self.buffer into instance variables. It returns self for easy + method chaining. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketERR
++object --+ + | +TftpPacket --+ + | + TftpPacketERR ++ +
+
+ + 2 bytes 2 bytes string 1 byte + ---------------------------------------- +ERROR | 05 | ErrorCode | ErrMsg | 0 | + ---------------------------------------- + Error Codes + + Value Meaning + + 0 Not defined, see error message (if any). + 1 File not found. + 2 Access violation. + 3 Disk full or allocation exceeded. + 4 Illegal TFTP operation. + 5 Unknown transfer ID. + 6 File already exists. + 7 No such user. + 8 Failed to negotiate options + + ++ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
str(x) +
|
+
Encode the DAT packet based on instance variables, populating + self.buffer, returning self. +
|
+
Decode self.buffer, populating instance variables and return self. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketInitial
++ object --+ + | + TftpPacket --+ + | + object --+ | + | | +TftpPacketWithOptions --+ + | + TftpPacketInitial ++ +
- Known Subclasses: +
- + +
+
This class is a common parent class for the RRQ and WRQ packets, as + they share quite a bit of code.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
Encode the packet's buffer from the instance variables. +
|
+
The decode method of a TftpPacket takes a buffer off of the wire in + network-byte order, and decodes it, populating internal properties as + appropriate. This can only be done once the first 2-byte opcode has + already been decoded, but the data section does include the entire + datagram. +This is an abstract method. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketOACK
++ object --+ + | + TftpPacket --+ + | + object --+ | + | | +TftpPacketWithOptions --+ + | + TftpPacketOACK ++ +
+
# +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ # | + opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | # + +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
str(x) +
|
+
The encode method of a TftpPacket takes keyword arguments specific to + the type of packet, and packs an appropriate buffer in network-byte order + suitable for sending over the wire. +This is an abstract method. +
|
+
The decode method of a TftpPacket takes a buffer off of the wire in + network-byte order, and decodes it, populating internal properties as + appropriate. This can only be done once the first 2-byte opcode has + already been decoded, but the data section does include the entire + datagram. +This is an abstract method. +
|
+
This method takes a set of options, and tries to match them with its + own. It can accept some changes in those options from the server as part + of a negotiation. Changed or unchanged, it will return a dict of the + options so that the session can update itself to the negotiated + options. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketRRQ
++ object --+ + | + TftpPacket --+ + | + object --+ | + | | +TftpPacketWithOptions --+ + | + TftpPacketInitial --+ + | + TftpPacketRRQ ++ +
+
+ + 2 bytes string 1 byte string 1 byte + ----------------------------------------------- +RRQ/ | 01/02 | Filename | 0 | Mode | 0 | +WRQ ----------------------------------------------- + + ++ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
str(x) +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketWRQ
++ object --+ + | + TftpPacket --+ + | + object --+ | + | | +TftpPacketWithOptions --+ + | + TftpPacketInitial --+ + | + TftpPacketWRQ ++ +
+
+ + 2 bytes string 1 byte string 1 byte + ----------------------------------------------- +RRQ/ | 01/02 | Filename | 0 | Mode | 0 | +WRQ ----------------------------------------------- + + ++ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
str(x) +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpPacketWithOptions
++object --+ + | + TftpPacketWithOptions ++ +
- Known Subclasses: +
- + +
+
This class exists to permit some TftpPacket subclasses to share code + regarding options handling. It does not inherit from TftpPacket, as the + goal is just to share code here, and not cause diamond inheritance.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ + | + options + | +||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+
This method decodes the section of the buffer that contains an unknown + number of options. It returns a dictionary of option names and + values. +
|
+ + +
+
|
+
+ options+ +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpSession
++object --+ + | + TftpSession ++ +
- Known Subclasses: +
- + +
+
This class is the base class for the tftp client and server. Any + shared code should be in this class.
+ + + +
+
|
+|||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Module TftpServer'
+ + +
+
|
+|||
+ + |
+ TftpServer + This class implements a tftp server object. + |
+
+
|
+|||
+ + |
+ DEF_BLKSIZE = 512
+ |
+ ||
+ + |
+ DEF_TFTP_PORT = 69
+ |
+ ||
+ + |
+ LOG_LEVEL = 0
+ |
+ ||
+ + |
+ MAX_BLKSIZE = 65536
+ |
+ ||
+ + |
+ MAX_DUPS = 20
+ |
+ ||
+ + |
+ MIN_BLKSIZE = 8
+ |
+ ||
+ + |
+ SOCK_TIMEOUT = 5
+ |
+ ||
+ + |
+ TIMEOUT_RETRIES = 5
+ |
+ ||
+ + |
+ log = logging.getLogger('tftpy')
+ |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Module tftpy.TftpServer'
++ 1 import socket, os, re, time, random + 2 import select + 3 from TftpShared import * + 4 from TftpPacketTypes import * + 5 from TftpPacketFactory import * + 6 from TftpStates import * + 7 ++9 """This class implements a tftp server object.""" + 10 +162 +12 """Class constructor. It takes two optional arguments. tftproot is + 13 the path to the tftproot directory to serve files from and/or write + 14 them to. dyn_file_func is a callable that must return a file-like + 15 object to read from during downloads. This permits the serving of + 16 dynamic content.""" + 17 self.listenip = None + 18 self.listenport = None + 19 self.sock = None + 20 # FIXME: What about multiple roots? + 21 self.root = os.path.abspath(tftproot) + 22 self.dyn_file_func = dyn_file_func + 23 # A dict of sessions, where each session is keyed by a string like + 24 # ip:tid for the remote end. + 25 self.sessions = {} + 26 + 27 if os.path.exists(self.root): + 28 log.debug("tftproot %s does exist" % self.root) + 29 if not os.path.isdir(self.root): + 30 raise TftpException, "The tftproot must be a directory." + 31 else: + 32 log.debug("tftproot %s is a directory" % self.root) + 33 if os.access(self.root, os.R_OK): + 34 log.debug("tftproot %s is readable" % self.root) + 35 else: + 36 raise TftpException, "The tftproot must be readable" + 37 if os.access(self.root, os.W_OK): + 38 log.debug("tftproot %s is writable" % self.root) + 39 else: + 40 log.warning("The tftproot %s is not writable" % self.root) + 41 else: + 42 raise TftpException, "The tftproot does not exist." +43 +44 - def listen(self, + 45 listenip="", + 46 listenport=DEF_TFTP_PORT, + 47 timeout=SOCK_TIMEOUT): +48 """Start a server listening on the supplied interface and port. This + 49 defaults to INADDR_ANY (all interfaces) and UDP port 69. You can also + 50 supply a different socket timeout value, if desired.""" + 51 tftp_factory = TftpPacketFactory() + 52 + 53 # Don't use new 2.5 ternary operator yet + 54 # listenip = listenip if listenip else '0.0.0.0' + 55 if not listenip: listenip = '0.0.0.0' + 56 log.info("Server requested on ip %s, port %s" + 57 % (listenip, listenport)) + 58 try: + 59 # FIXME - sockets should be non-blocking? + 60 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + 61 self.sock.bind((listenip, listenport)) + 62 except socket.error, err: + 63 # Reraise it for now. + 64 raise + 65 + 66 log.info("Starting receive loop...") + 67 while True: + 68 # Build the inputlist array of sockets to select() on. + 69 inputlist = [] + 70 inputlist.append(self.sock) + 71 for key in self.sessions: + 72 inputlist.append(self.sessions[key].sock) + 73 + 74 # Block until some socket has input on it. + 75 log.debug("Performing select on this inputlist: %s" % inputlist) + 76 readyinput, readyoutput, readyspecial = select.select(inputlist, + 77 [], + 78 [], + 79 SOCK_TIMEOUT) + 80 + 81 deletion_list = [] + 82 + 83 # Handle the available data, if any. Maybe we timed-out. + 84 for readysock in readyinput: + 85 # Is the traffic on the main server socket? ie. new session? + 86 if readysock == self.sock: + 87 log.debug("Data ready on our main socket") + 88 buffer, (raddress, rport) = self.sock.recvfrom(MAX_BLKSIZE) + 89 + 90 log.debug("Read %d bytes" % len(buffer)) + 91 + 92 recvpkt = tftp_factory.parse(buffer) + 93 # Forge a session key based on the client's IP and port, + 94 # which should safely work through NAT. + 95 key = "%s:%s" % (raddress, rport) + 96 + 97 if not self.sessions.has_key(key): + 98 log.debug("Creating new server context for " + 99 "session key = %s" % key) +100 self.sessions[key] = TftpContextServer(raddress, +101 rport, +102 timeout, +103 self.root, +104 self.dyn_file_func) +105 self.sessions[key].start(buffer) +106 else: +107 log.warn("received traffic on main socket for " +108 "existing session??") +109 +110 else: +111 # Must find the owner of this traffic. +112 for key in self.sessions: +113 if readysock == self.sessions[key].sock: +114 log.info("Matched input to session key %s" +115 % key) +116 try: +117 self.sessions[key].cycle() +118 if self.sessions[key].state == None: +119 log.info("Successful transfer.") +120 deletion_list.append(key) +121 except TftpException, err: +122 deletion_list.append(key) +123 log.error("Fatal exception thrown from " +124 "session %s: %s" +125 % (key, str(err))) +126 break +127 +128 else: +129 log.error("Can't find the owner for this packet. " +130 "Discarding.") +131 +132 log.debug("Looping on all sessions to check for timeouts") +133 now = time.time() +134 for key in self.sessions: +135 try: +136 self.sessions[key].checkTimeout(now) +137 except TftpException, err: +138 log.error(str(err)) +139 deletion_list.append(key) +140 +141 log.debug("Iterating deletion list.") +142 for key in deletion_list: +143 log.info('') +144 log.info("Session %s complete" % key) +145 if self.sessions.has_key(key): +146 log.debug("Gathering up metrics from session before deleting") +147 self.sessions[key].end() +148 metrics = self.sessions[key].metrics +149 if metrics.duration == 0: +150 log.info("Duration too short, rate undetermined") +151 else: +152 log.info("Transferred %.2f bytes in %.2f seconds" +153 % (metrics.bytes, metrics.duration)) +154 log.info("Average rate: %.2f kbps" % metrics.kbps) +155 log.info("%.2f bytes in resent data" % metrics.resent_bytes) +156 log.info("%d duplicate packets" % metrics.dupcount) +157 log.debug("Deleting session %s" % key) +158 del self.sessions[key] +159 else: +160 log.warn("Strange, session %s is not on the deletion list" +161 % key) +
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpServer
++ object --+ + | +TftpPacketTypes.TftpSession --+ + | + TftpServer ++ +
+
This class implements a tftp server object.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Class constructor. It takes two optional arguments. tftproot is the + path to the tftproot directory to serve files from and/or write them to. + dyn_file_func is a callable that must return a file-like object to read + from during downloads. This permits the serving of dynamic content. +
|
+
Start a server listening on the supplied interface and port. This + defaults to INADDR_ANY (all interfaces) and UDP port 69. You can also + supply a different socket timeout value, if desired. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Module TftpShared
+ + +
+
|
+|||
+ + |
+ TftpErrors + This class is a convenience for defining the common tftp error + codes, and making them more readable in the code. + |
+ ||
+ + |
+ TftpException + This class is the parent class of all exceptions regarding the + handling of the TFTP protocol. + |
+
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+
+
|
+|||
+ + |
+ LOG_LEVEL = 0
+ |
+ ||
+ + |
+ MIN_BLKSIZE = 8
+ |
+ ||
+ + |
+ DEF_BLKSIZE = 512
+ |
+ ||
+ + |
+ MAX_BLKSIZE = 65536
+ |
+ ||
+ + |
+ SOCK_TIMEOUT = 5
+ |
+ ||
+ + |
+ MAX_DUPS = 20
+ |
+ ||
+ + |
+ TIMEOUT_RETRIES = 5
+ |
+ ||
+ + |
+ DEF_TFTP_PORT = 69
+ |
+ ||
+ + |
+ log = logging.getLogger('tftpy')
+ |
+
+
|
+
+
This function is a simple utility that will check the condition passed + for a false state. If it finds one, it throws a TftpException with the + message passed. This just makes the code throughout cleaner by + refactoring. +
|
+
This function is a utility function for setting the internal log + level. The log level defaults to logging.NOTSET, so unwanted output to + stdout is not created. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Module tftpy.TftpShared
++ 1 import logging + 2 + 3 LOG_LEVEL = logging.NOTSET + 4 MIN_BLKSIZE = 8 + 5 DEF_BLKSIZE = 512 + 6 MAX_BLKSIZE = 65536 + 7 SOCK_TIMEOUT = 5 + 8 MAX_DUPS = 20 + 9 TIMEOUT_RETRIES = 5 +10 DEF_TFTP_PORT = 69 +11 +12 # Initialize the logger. +13 #logging.basicConfig( +14 # level=LOG_LEVEL, +15 # format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', +16 # datefmt='%m-%d %H:%M:%S') +17 logging.basicConfig() +18 # The logger used by this library. Feel free to clobber it with your own, if you like, as +19 # long as it conforms to Python's logging. +20 log = logging.getLogger('tftpy') +21 ++23 """This function is a simple utility that will check the condition +24 passed for a false state. If it finds one, it throws a TftpException +25 with the message passed. This just makes the code throughout cleaner +26 by refactoring.""" +27 if not condition: +28 raise TftpException, msg +29 +31 """This function is a utility function for setting the internal log level. +32 The log level defaults to logging.NOTSET, so unwanted output to stdout is +33 not created.""" +34 global log +35 log.setLevel(level) +36 +38 """This class is a convenience for defining the common tftp error codes, +39 and making them more readable in the code.""" +40 NotDefined = 0 +41 FileNotFound = 1 +42 AccessViolation = 2 +43 DiskFull = 3 +44 IllegalTftpOp = 4 +45 UnknownTID = 5 +46 FileAlreadyExists = 6 +47 NoSuchUser = 7 +48 FailedNegotiation = 8 +49 +51 """This class is the parent class of all exceptions regarding the handling +52 of the TFTP protocol.""" +53 pass +54 +
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpErrors
++object --+ + | + TftpErrors ++ +
+
This class is a convenience for defining the common tftp error codes, + and making them more readable in the code.
+ + + +
+
|
+|||
+ Inherited from |
+
+
|
+|||
+ + |
+ NotDefined = 0
+ |
+ ||
+ + |
+ FileNotFound = 1
+ |
+ ||
+ + |
+ AccessViolation = 2
+ |
+ ||
+ + |
+ DiskFull = 3
+ |
+ ||
+ + |
+ IllegalTftpOp = 4
+ |
+ ||
+ + |
+ UnknownTID = 5
+ |
+ ||
+ + |
+ FileAlreadyExists = 6
+ |
+ ||
+ + |
+ NoSuchUser = 7
+ |
+ ||
+ + |
+ FailedNegotiation = 8
+ |
+
+
|
+|||
+ Inherited from |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpException
++ object --+ + | +exceptions.BaseException --+ + | + exceptions.Exception --+ + | + TftpException ++ +
+
This class is the parent class of all exceptions regarding the + handling of the TFTP protocol.
+ + + +
+
|
+|||
+ Inherited from Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Module TftpStates
+ + +
+
|
+|||
+ + |
+ TftpMetrics + A class representing metrics of the transfer. + |
+ ||
+ + |
+ TftpContext + The base class of the contexts. + |
+ ||
+ + |
+ TftpContextServer + The context for the server. + |
+ ||
+ + |
+ TftpContextClientUpload + The upload context for the client during an upload. + |
+ ||
+ + |
+ TftpContextClientDownload + The download context for the client during a download. + |
+ ||
+ + |
+ TftpState + The base class for the states. + |
+ ||
+ + |
+ TftpStateServerRecvRRQ + This class represents the state of the TFTP server when it has just + received an RRQ packet. + |
+ ||
+ + |
+ TftpStateServerRecvWRQ + This class represents the state of the TFTP server when it has just + received a WRQ packet. + |
+ ||
+ + |
+ TftpStateServerStart + The start state for the server. + |
+ ||
+ + |
+ TftpStateExpectACK + This class represents the state of the transfer when a DAT was just + sent, and we are waiting for an ACK from the server. + |
+ ||
+ + |
+ TftpStateExpectDAT + Just sent an ACK packet. + |
+ ||
+ + |
+ TftpStateSentWRQ + Just sent an WRQ packet for an upload. + |
+ ||
+ + |
+ TftpStateSentRRQ + Just sent an RRQ packet. + |
+
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Source Code for Module tftpy.TftpStates
++ 1 from TftpShared import * + 2 from TftpPacketTypes import * + 3 from TftpPacketFactory import * + 4 import socket, time, os + 5 + 6 ############################################################################### + 7 # Utility classes + 8 ############################################################################### + 9 ++11 """A class representing metrics of the transfer.""" +49 + 50 ############################################################################### + 51 # Context classes + 52 ############################################################################### + 53 +13 # Bytes transferred + 14 self.bytes = 0 + 15 # Bytes re-sent + 16 self.resent_bytes = 0 + 17 # Duplicate packets received + 18 self.dups = {} + 19 self.dupcount = 0 + 20 # Times + 21 self.start_time = 0 + 22 self.end_time = 0 + 23 self.duration = 0 + 24 # Rates + 25 self.bps = 0 + 26 self.kbps = 0 + 27 # Generic errors + 28 self.errors = 0 +29 +31 # Compute transfer time + 32 self.duration = self.end_time - self.start_time + 33 log.debug("TftpMetrics.compute: duration is %s" % self.duration) + 34 self.bps = (self.bytes * 8.0) / self.duration + 35 self.kbps = self.bps / 1024.0 + 36 log.debug("TftpMetrics.compute: kbps is %s" % self.kbps) + 37 for key in self.dups: + 38 self.dupcount += self.dups[key] +39 +41 """This method adds a dup for a block number to the metrics.""" + 42 log.debug("Recording a dup for block %d" % blocknumber) + 43 if self.dups.has_key(blocknumber): + 44 self.dups[blocknumber] += 1 + 45 else: + 46 self.dups[blocknumber] = 1 + 47 tftpassert(self.dups[blocknumber] < MAX_DUPS, + 48 "Max duplicates for block %d reached" % blocknumber) +55 """The base class of the contexts.""" + 56 +164 +58 """Constructor for the base context, setting shared instance + 59 variables.""" + 60 self.file_to_transfer = None + 61 self.fileobj = None + 62 self.options = None + 63 self.packethook = None + 64 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + 65 self.sock.settimeout(timeout) + 66 self.state = None + 67 self.next_block = 0 + 68 self.factory = TftpPacketFactory() + 69 # Note, setting the host will also set self.address, as it's a property. + 70 self.host = host + 71 self.port = port + 72 # The port associated with the TID + 73 self.tidport = None + 74 # Metrics + 75 self.metrics = TftpMetrics() + 76 # Flag when the transfer is pending completion. + 77 self.pending_complete = False + 78 # Time when this context last received any traffic. + 79 # FIXME: does this belong in metrics? + 80 self.last_update = 0 + 81 # The last DAT packet we sent, if applicable, to make resending easy. + 82 self.last_dat_pkt = None +83 +85 """Compare current time with last_update time, and raise an exception + 86 if we're over SOCK_TIMEOUT time.""" + 87 if now - self.last_update > SOCK_TIMEOUT: + 88 raise TftpException, "Timeout waiting for traffic" +89 + 92 + 95 + 99 +101 """Setter method that also sets the address property as a result +102 of the host that is set.""" +103 self.__host = host +104 self.address = socket.gethostbyname(host) +105 +106 host = property(gethost, sethost) +107 +109 if block > 2 ** 16: +110 log.debug("Block number rollover to 0 again") +111 block = 0 +112 self.__eblock = block +113 +116 +117 next_block = property(getNextBlock, setNextBlock) +118 +120 """Here we wait for a response from the server after sending it +121 something, and dispatch appropriate action to that response.""" +122 # FIXME: This won't work very well in a server context with multiple +123 # sessions running. +124 for i in range(TIMEOUT_RETRIES): +125 log.debug("In cycle, receive attempt %d" % i) +126 try: +127 (buffer, (raddress, rport)) = self.sock.recvfrom(MAX_BLKSIZE) +128 except socket.timeout, err: +129 log.warn("Timeout waiting for traffic, retrying...") +130 continue +131 break +132 else: +133 raise TftpException, "Hit max timeouts, giving up." +134 +135 # Ok, we've received a packet. Log it. +136 log.debug("Received %d bytes from %s:%s" +137 % (len(buffer), raddress, rport)) +138 # And update our last updated time. +139 self.last_update = time.time() +140 +141 # Decode it. +142 recvpkt = self.factory.parse(buffer) +143 +144 # Check for known "connection". +145 if raddress != self.address: +146 log.warn("Received traffic from %s, expected host %s. Discarding" +147 % (raddress, self.host)) +148 +149 if self.tidport and self.tidport != rport: +150 log.warn("Received traffic from %s:%s but we're " +151 "connected to %s:%s. Discarding." +152 % (raddress, rport, +153 self.host, self.tidport)) +154 +155 # If there is a packethook defined, call it. We unconditionally +156 # pass all packets, it's up to the client to screen out different +157 # kinds of packets. This way, the client is privy to things like +158 # negotiated options. +159 if self.packethook: +160 self.packethook(recvpkt) +161 +162 # And handle it, possibly changing state. +163 self.state = self.state.handle(recvpkt, raddress, rport) +166 """The context for the server.""" +209 +168 TftpContext.__init__(self, +169 host, +170 port, +171 timeout) +172 # At this point we have no idea if this is a download or an upload. We +173 # need to let the start state determine that. +174 self.state = TftpStateServerStart(self) +175 self.root = root +176 self.dyn_file_func = dyn_file_func +177 # In a server, the tidport is the same as the port. This is also true +178 # with symmetric UDP, which we haven't implemented yet. +179 self.tidport = port +180 +182 """Start the state cycle. Note that the server context receives an +183 initial packet in its start method. Also note that the server does not +184 loop on cycle(), as it expects the TftpServer object to manage +185 that.""" +186 log.debug("In TftpContextServer.start") +187 self.metrics.start_time = time.time() +188 log.debug("Set metrics.start_time to %s" % self.metrics.start_time) +189 # And update our last updated time. +190 self.last_update = time.time() +191 +192 pkt = self.factory.parse(buffer) +193 log.debug("TftpContextServer.start() - factory returned a %s" % pkt) +194 +195 # Call handle once with the initial packet. This should put us into +196 # the download or the upload state. +197 self.state = self.state.handle(pkt, +198 self.host, +199 self.port) +200 +201 # FIXME +202 # How do we ensure that the server closes files, even on error? +203 +211 """The upload context for the client during an upload.""" +263 +212 - def __init__(self, +213 host, +214 port, +215 filename, +216 input, +217 options, +218 packethook, +219 timeout): +220 TftpContext.__init__(self, +221 host, +222 port, +223 timeout) +224 self.file_to_transfer = filename +225 self.options = options +226 self.packethook = packethook +227 self.fileobj = open(input, "wb") +228 +229 log.debug("TftpContextClientUpload.__init__()") +230 log.debug("file_to_transfer = %s, options = %s" % +231 (self.file_to_transfer, self.options)) +232 +234 log.info("Sending tftp upload request to %s" % self.host) +235 log.info(" filename -> %s" % self.file_to_transfer) +236 log.info(" options -> %s" % self.options) +237 +238 self.metrics.start_time = time.time() +239 log.debug("Set metrics.start_time to %s" % self.metrics.start_time) +240 +241 # FIXME: put this in a sendWRQ method? +242 pkt = TftpPacketWRQ() +243 pkt.filename = self.file_to_transfer +244 pkt.mode = "octet" # FIXME - shouldn't hardcode this +245 pkt.options = self.options +246 self.sock.sendto(pkt.encode().buffer, (self.host, self.port)) +247 self.next_block = 1 +248 +249 self.state = TftpStateSentWRQ(self) +250 +251 try: +252 while self.state: +253 log.debug("State is %s" % self.state) +254 self.cycle() +255 finally: +256 self.fileobj.close() +257 +265 """The download context for the client during a download.""" +321 +322 +323 ############################################################################### +324 # State classes +325 ############################################################################### +326 +266 - def __init__(self, +267 host, +268 port, +269 filename, +270 output, +271 options, +272 packethook, +273 timeout): +274 TftpContext.__init__(self, +275 host, +276 port, +277 timeout) +278 # FIXME: should we refactor setting of these params? +279 self.file_to_transfer = filename +280 self.options = options +281 self.packethook = packethook +282 # FIXME - need to support alternate return formats than files? +283 # File-like objects would be ideal, ala duck-typing. +284 self.fileobj = open(output, "wb") +285 +286 log.debug("TftpContextClientDownload.__init__()") +287 log.debug("file_to_transfer = %s, options = %s" % +288 (self.file_to_transfer, self.options)) +289 +291 """Initiate the download.""" +292 log.info("Sending tftp download request to %s" % self.host) +293 log.info(" filename -> %s" % self.file_to_transfer) +294 log.info(" options -> %s" % self.options) +295 +296 self.metrics.start_time = time.time() +297 log.debug("Set metrics.start_time to %s" % self.metrics.start_time) +298 +299 # FIXME: put this in a sendRRQ method? +300 pkt = TftpPacketRRQ() +301 pkt.filename = self.file_to_transfer +302 pkt.mode = "octet" # FIXME - shouldn't hardcode this +303 pkt.options = self.options +304 self.sock.sendto(pkt.encode().buffer, (self.host, self.port)) +305 self.next_block = 1 +306 +307 self.state = TftpStateSentRRQ(self) +308 +309 try: +310 while self.state: +311 log.debug("State is %s" % self.state) +312 self.cycle() +313 finally: +314 self.fileobj.close() +315 +328 """The base class for the states.""" +329 +538 +331 """Constructor for setting up common instance variables. The involved +332 file object is required, since in tftp there's always a file +333 involved.""" +334 self.context = context +335 +337 """An abstract method for handling a packet. It is expected to return +338 a TftpState object, either itself or a new state.""" +339 raise NotImplementedError, "Abstract method" +340 +342 """This method handles an OACK from the server, syncing any accepted +343 options.""" +344 if pkt.options.keys() > 0: +345 if pkt.match_options(self.context.options): +346 log.info("Successful negotiation of options") +347 # Set options to OACK options +348 self.context.options = pkt.options +349 for key in self.context.options: +350 log.info(" %s = %s" % (key, self.context.options[key])) +351 else: +352 log.error("Failed to negotiate options") +353 raise TftpException, "Failed to negotiate options" +354 else: +355 raise TftpException, "No options found in OACK" +356 +358 """This method takes a requested options list from a client, and +359 returns the ones that are supported.""" +360 # We support the options blksize and tsize right now. +361 # FIXME - put this somewhere else? +362 accepted_options = {} +363 for option in options: +364 if option == 'blksize': +365 # Make sure it's valid. +366 if int(options[option]) > MAX_BLKSIZE: +367 log.info("Client requested blksize greater than %d " +368 "setting to maximum" % MAX_BLKSIZE) +369 accepted_options[option] = MAX_BLKSIZE +370 elif int(options[option]) < MIN_BLKSIZE: +371 log.info("Client requested blksize less than %d " +372 "setting to minimum" % MIN_BLKSIZE) +373 accepted_options[option] = MIN_BLKSIZE +374 else: +375 accepted_options[option] = options[option] +376 elif option == 'tsize': +377 log.debug("tsize option is set") +378 accepted_options['tsize'] = 1 +379 else: +380 log.info("Dropping unsupported option '%s'" % option) +381 log.debug("Returning these accepted options: %s" % accepted_options) +382 return accepted_options +383 +385 """This method performs initial setup for a server context transfer, +386 put here to refactor code out of the TftpStateServerRecvRRQ and +387 TftpStateServerRecvWRQ classes, since their initial setup is +388 identical. The method returns a boolean, sendoack, to indicate whether +389 it is required to send an OACK to the client.""" +390 options = pkt.options +391 sendoack = False +392 if not options: +393 log.debug("Setting default options, blksize") +394 # FIXME: put default options elsewhere +395 self.context.options = { 'blksize': DEF_BLKSIZE } +396 else: +397 log.debug("Options requested: %s" % options) +398 self.context.options = self.returnSupportedOptions(options) +399 sendoack = True +400 +401 # FIXME - only octet mode is supported at this time. +402 if pkt.mode != 'octet': +403 self.sendError(TftpErrors.IllegalTftpOp) +404 raise TftpException, \ +405 "Only octet transfers are supported at this time." +406 +407 # test host/port of client end +408 if self.context.host != raddress or self.context.port != rport: +409 self.sendError(TftpErrors.UnknownTID) +410 log.error("Expected traffic from %s:%s but received it " +411 "from %s:%s instead." +412 % (self.context.host, +413 self.context.port, +414 raddress, +415 rport)) +416 # FIXME: increment an error count? +417 # Return same state, we're still waiting for valid traffic. +418 return self +419 +420 log.debug("Requested filename is %s" % pkt.filename) +421 # There are no os.sep's allowed in the filename. +422 # FIXME: Should we allow subdirectories? +423 if pkt.filename.find(os.sep) >= 0: +424 self.sendError(TftpErrors.IllegalTftpOp) +425 raise TftpException, "%s found in filename, not permitted" % os.sep +426 +427 self.context.file_to_transfer = pkt.filename +428 +429 return sendoack +430 +432 """This method sends the next DAT packet based on the data in the +433 context. It returns a boolean indicating whether the transfer is +434 finished.""" +435 finished = False +436 blocknumber = self.context.next_block +437 tftpassert( blocknumber > 0, "There is no block zero!" ) +438 dat = None +439 if resend: +440 log.warn("Resending block number %d" % blocknumber) +441 dat = self.context.last_dat_pkt +442 self.context.metrics.resent_bytes += len(dat.data) +443 self.context.metrics.add_dup(dat) +444 else: +445 blksize = int(self.context.options['blksize']) +446 buffer = self.context.fileobj.read(blksize) +447 log.debug("Read %d bytes into buffer" % len(buffer)) +448 if len(buffer) < blksize: +449 log.info("Reached EOF on file %s" +450 % self.context.file_to_transfer) +451 finished = True +452 dat = TftpPacketDAT() +453 dat.data = buffer +454 dat.blocknumber = blocknumber +455 self.context.metrics.bytes += len(dat.data) +456 log.debug("Sending DAT packet %d" % dat.blocknumber) +457 self.context.sock.sendto(dat.encode().buffer, +458 (self.context.host, self.context.port)) +459 if self.context.packethook: +460 self.context.packethook(dat) +461 self.context.last_dat_pkt = dat +462 return finished +463 +465 """This method sends an ack packet to the block number specified. If +466 none is specified, it defaults to the next_block property in the +467 parent context.""" +468 log.debug("In sendACK, blocknumber is %s" % blocknumber) +469 if blocknumber is None: +470 blocknumber = self.context.next_block +471 log.info("Sending ack to block %d" % blocknumber) +472 ackpkt = TftpPacketACK() +473 ackpkt.blocknumber = blocknumber +474 self.context.sock.sendto(ackpkt.encode().buffer, +475 (self.context.host, +476 self.context.tidport)) +477 +479 """This method uses the socket passed, and uses the errorcode to +480 compose and send an error packet.""" +481 log.debug("In sendError, being asked to send error %d" % errorcode) +482 errpkt = TftpPacketERR() +483 errpkt.errorcode = errorcode +484 self.context.sock.sendto(errpkt.encode().buffer, +485 (self.context.host, +486 self.context.tidport)) +487 +489 """This method sends an OACK packet with the options from the current +490 context.""" +491 log.debug("In sendOACK with options %s" % self.context.options) +492 pkt = TftpPacketOACK() +493 pkt.options = self.context.options +494 self.context.sock.sendto(pkt.encode().buffer, +495 (self.context.host, +496 self.context.tidport)) +497 +499 """This method handles a DAT packet during a client download, or a +500 server upload.""" +501 log.info("Handling DAT packet - block %d" % pkt.blocknumber) +502 log.debug("Expecting block %s" % self.context.next_block) +503 if pkt.blocknumber == self.context.next_block: +504 log.debug("Good, received block %d in sequence" +505 % pkt.blocknumber) +506 +507 self.sendACK() +508 self.context.next_block += 1 +509 +510 log.debug("Writing %d bytes to output file" +511 % len(pkt.data)) +512 self.context.fileobj.write(pkt.data) +513 self.context.metrics.bytes += len(pkt.data) +514 # Check for end-of-file, any less than full data packet. +515 if len(pkt.data) < int(self.context.options['blksize']): +516 log.info("End of file detected") +517 return None +518 +519 elif pkt.blocknumber < self.context.next_block: +520 if pkt.blocknumber == 0: +521 log.warn("There is no block zero!") +522 self.sendError(TftpErrors.IllegalTftpOp) +523 raise TftpException, "There is no block zero!" +524 log.warn("Dropping duplicate block %d" % pkt.blocknumber) +525 self.context.metrics.add_dup(pkt.blocknumber) +526 log.debug("ACKing block %d again, just in case" % pkt.blocknumber) +527 self.sendACK(pkt.blocknumber) +528 +529 else: +530 # FIXME: should we be more tolerant and just discard instead? +531 msg = "Whoa! Received future block %d but expected %d" \ +532 % (pkt.blocknumber, self.context.next_block) +533 log.error(msg) +534 raise TftpException, msg +535 +536 # Default is to ack +537 return TftpStateExpectDAT(self.context) +540 """This class represents the state of the TFTP server when it has just +541 received an RRQ packet.""" +573 +574 # Note, we don't have to check any other states in this method, that's +575 # up to the caller. +576 +543 "Handle an initial RRQ packet as a server." +544 log.debug("In TftpStateServerRecvRRQ.handle") +545 sendoack = self.serverInitial(pkt, raddress, rport) +546 path = self.context.root + os.sep + self.context.file_to_transfer +547 log.info("Opening file %s for reading" % path) +548 if os.path.exists(path): +549 # Note: Open in binary mode for win32 portability, since win32 +550 # blows. +551 self.context.fileobj = open(path, "rb") +552 elif self.dyn_file_func: +553 log.debug("No such file %s but using dyn_file_func" % path) +554 self.context.fileobj = \ +555 self.dyn_file_func(self.context.file_to_transfer) +556 else: +557 send.sendError(TftpErrors.FileNotFound) +558 raise TftpException, "File not found: %s" % path +559 +560 # Options negotiation. +561 if sendoack: +562 # Note, next_block is 0 here since that's the proper +563 # acknowledgement to an OACK. +564 # FIXME: perhaps we do need a TftpStateExpectOACK class... +565 self.sendOACK() +566 else: +567 self.context.next_block = 1 +568 log.debug("No requested options, starting send...") +569 self.context.pending_complete = self.sendDAT() +570 # Note, we expect an ack regardless of whether we sent a DAT or an +571 # OACK. +572 return TftpStateExpectACK(self.context) +578 """This class represents the state of the TFTP server when it has just +579 received a WRQ packet.""" +604 +605 # Note, we don't have to check any other states in this method, that's +606 # up to the caller. +607 +581 "Handle an initial WRQ packet as a server." +582 log.debug("In TftpStateServerRecvWRQ.handle") +583 sendoack = self.serverInitial(pkt, raddress, rport) +584 path = self.context.root + os.sep + self.context.file_to_transfer +585 log.info("Opening file %s for writing" % path) +586 if os.path.exists(path): +587 # FIXME: correct behavior? +588 log.warn("File %s exists already, overwriting...") +589 # FIXME: I think we should upload to a temp file and not overwrite the +590 # existing file until the file is successfully uploaded. +591 self.context.fileobj = open(path, "wb") +592 +593 # Options negotiation. +594 if sendoack: +595 log.debug("Sending OACK to client") +596 self.sendOACK() +597 else: +598 log.debug("No requested options, starting send...") +599 self.sendACK() +600 # We may have sent an OACK, but we're expecting a DAT as the response +601 # to either the OACK or an ACK, so lets unconditionally use the +602 # TftpStateExpectDAT state. +603 return TftpStateExpectDAT(self.context) +609 """The start state for the server.""" +627 +611 """Handle a packet we just received.""" +612 log.debug("In TftpStateServerStart.handle") +613 if isinstance(pkt, TftpPacketRRQ): +614 log.debug("Handling an RRQ packet") +615 return TftpStateServerRecvRRQ(self.context).handle(pkt, +616 raddress, +617 rport) +618 elif isinstance(pkt, TftpPacketWRQ): +619 log.debug("Handling a WRQ packet") +620 return TftpStateServerRecvWRQ(self.context).handle(pkt, +621 raddress, +622 rport) +623 else: +624 self.sendError(TftpErrors.IllegalTftpOp) +625 raise TftpException, \ +626 "Invalid packet to begin up/download: %s" % pkt +629 """This class represents the state of the transfer when a DAT was just +630 sent, and we are waiting for an ACK from the server. This class is the +631 same one used by the client during the upload, and the server during the +632 download.""" +664 +634 "Handle a packet, hopefully an ACK since we just sent a DAT." +635 if isinstance(pkt, TftpPacketACK): +636 log.info("Received ACK for packet %d" % pkt.blocknumber) +637 # Is this an ack to the one we just sent? +638 if self.context.next_block == pkt.blocknumber: +639 if self.context.pending_complete: +640 log.info("Received ACK to final DAT, we're done.") +641 return None +642 else: +643 log.debug("Good ACK, sending next DAT") +644 self.context.next_block += 1 +645 log.debug("Incremented next_block to %d" +646 % (self.context.next_block)) +647 self.context.pending_complete = self.sendDAT() +648 +649 elif pkt.blocknumber < self.context.next_block: +650 self.context.metrics.add_dup(pkt.blocknumber) +651 +652 else: +653 log.warn("Oooh, time warp. Received ACK to packet we " +654 "didn't send yet. Discarding.") +655 self.context.metrics.errors += 1 +656 return self +657 elif isinstance(pkt, TftpPacketERR): +658 log.error("Received ERR packet from peer: %s" % str(pkt)) +659 raise TftpException, \ +660 "Received ERR packet from peer: %s" % str(pkt) +661 else: +662 log.warn("Discarding unsupported packet: %s" % str(pkt)) +663 return self +666 """Just sent an ACK packet. Waiting for DAT.""" +689 +668 """Handle the packet in response to an ACK, which should be a DAT.""" +669 if isinstance(pkt, TftpPacketDAT): +670 return self.handleDat(pkt) +671 +672 # Every other packet type is a problem. +673 elif isinstance(pkt, TftpPacketACK): +674 # Umm, we ACK, you don't. +675 self.sendError(TftpErrors.IllegalTftpOp) +676 raise TftpException, "Received ACK from peer when expecting DAT" +677 +678 elif isinstance(pkt, TftpPacketWRQ): +679 self.sendError(TftpErrors.IllegalTftpOp) +680 raise TftpException, "Received WRQ from peer when expecting DAT" +681 +682 elif isinstance(pkt, TftpPacketERR): +683 self.sendError(TftpErrors.IllegalTftpOp) +684 raise TftpException, "Received ERR from peer: " + str(pkt) +685 +686 else: +687 self.sendError(TftpErrors.IllegalTftpOp) +688 raise TftpException, "Received unknown packet type from peer: " + str(pkt) +691 """Just sent an WRQ packet for an upload.""" +747 +693 """Handle a packet we just received.""" +694 if not self.context.tidport: +695 self.context.tidport = rport +696 log.debug("Set remote port for session to %s" % rport) +697 +698 # If we're going to successfully transfer the file, then we should see +699 # either an OACK for accepted options, or an ACK to ignore options. +700 if isinstance(pkt, TftpPacketOACK): +701 log.info("Received OACK from server") +702 try: +703 self.handleOACK(pkt) +704 except TftpException, err: +705 log.error("Failed to negotiate options") +706 self.sendError(TftpErrors.FailedNegotiation) +707 raise +708 else: +709 log.debug("Sending first DAT packet") +710 self.context.pending_complete = self.sendDAT() +711 log.debug("Changing state to TftpStateExpectACK") +712 return TftpStateExpectACK(self.context) +713 +714 elif isinstance(pkt, TftpPacketACK): +715 log.info("Received ACK from server") +716 log.debug("Apparently the server ignored our options") +717 # The block number should be zero. +718 if pkt.blocknumber == 0: +719 log.debug("Ack blocknumber is zero as expected") +720 log.debug("Sending first DAT packet") +721 self.pending_complete = self.context.sendDAT() +722 log.debug("Changing state to TftpStateExpectACK") +723 return TftpStateExpectACK(self.context) +724 else: +725 log.warn("Discarding ACK to block %s" % pkt.blocknumber) +726 log.debug("Still waiting for valid response from server") +727 return self +728 +729 elif isinstance(pkt, TftpPacketERR): +730 self.sendError(TftpErrors.IllegalTftpOp) +731 raise TftpException, "Received ERR from server: " + str(pkt) +732 +733 elif isinstance(pkt, TftpPacketRRQ): +734 self.sendError(TftpErrors.IllegalTftpOp) +735 raise TftpException, "Received RRQ from server while in upload" +736 +737 elif isinstance(pkt, TftpPacketDAT): +738 self.sendError(TftpErrors.IllegalTftpOp) +739 raise TftpException, "Received DAT from server while in upload" +740 +741 else: +742 self.sendError(TftpErrors.IllegalTftpOp) +743 raise TftpException, "Received unknown packet type from server: " + str(pkt) +744 +745 # By default, no state change. +746 return self +749 """Just sent an RRQ packet.""" +802 +751 """Handle the packet in response to an RRQ to the server.""" +752 if not self.context.tidport: +753 self.context.tidport = rport +754 log.debug("Set remote port for session to %s" % rport) +755 +756 # Now check the packet type and dispatch it properly. +757 if isinstance(pkt, TftpPacketOACK): +758 log.info("Received OACK from server") +759 try: +760 self.handleOACK(pkt) +761 except TftpException, err: +762 log.error("Failed to negotiate options: %s" % str(err)) +763 self.sendError(TftpErrors.FailedNegotiation) +764 raise +765 else: +766 log.debug("Sending ACK to OACK") +767 +768 self.sendACK(blocknumber=0) +769 +770 log.debug("Changing state to TftpStateExpectDAT") +771 return TftpStateExpectDAT(self.context) +772 +773 elif isinstance(pkt, TftpPacketDAT): +774 # If there are any options set, then the server didn't honour any +775 # of them. +776 log.info("Received DAT from server") +777 if self.context.options: +778 log.info("Server ignored options, falling back to defaults") +779 self.context.options = { 'blksize': DEF_BLKSIZE } +780 return self.handleDat(pkt) +781 +782 # Every other packet type is a problem. +783 elif isinstance(pkt, TftpPacketACK): +784 # Umm, we ACK, the server doesn't. +785 self.sendError(TftpErrors.IllegalTftpOp) +786 raise TftpException, "Received ACK from server while in download" +787 +788 elif isinstance(pkt, TftpPacketWRQ): +789 self.sendError(TftpErrors.IllegalTftpOp) +790 raise TftpException, "Received WRQ from server while in download" +791 +792 elif isinstance(pkt, TftpPacketERR): +793 self.sendError(TftpErrors.IllegalTftpOp) +794 raise TftpException, "Received ERR from server: " + str(pkt) +795 +796 else: +797 self.sendError(TftpErrors.IllegalTftpOp) +798 raise TftpException, "Received unknown packet type from server: " + str(pkt) +799 +800 # By default, no state change. +801 return self +
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:22 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpContext
++object --+ + | + TftpContext ++ +
- Known Subclasses: +
- + +
+
The base class of the contexts.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ + |
+ host + Simple getter method for use in a property. + |
+ ||
+ + | + next_block + | +||
+ Inherited from |
+
+
|
+
+
Constructor for the base context, setting shared instance + variables. +
|
+ + +
+
|
+
+ host+Simple getter method for use in a property. + + |
+ next_block+ +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpContextClientDownload
++ object --+ + | +TftpContext --+ + | + TftpContextClientDownload ++ +
+
The download context for the client during a download.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
Constructor for the base context, setting shared instance + variables. +
|
+
Initiate the download. +
|
+
Finish up the context. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpContextClientUpload
++ object --+ + | +TftpContext --+ + | + TftpContextClientUpload ++ +
+
The upload context for the client during an upload.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
Constructor for the base context, setting shared instance + variables. +
|
+
|
+
Finish up the context. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpContextServer
++ object --+ + | +TftpContext --+ + | + TftpContextServer ++ +
+
The context for the server.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from Inherited from |
+
+
|
+
+
Constructor for the base context, setting shared instance + variables. +
|
+
Start the state cycle. Note that the server context receives an + initial packet in its start method. Also note that the server does not + loop on cycle(), as it expects the TftpServer object to manage that. +
|
+
Finish up the context. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpMetrics
++object --+ + | + TftpMetrics ++ +
+
A class representing metrics of the transfer.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
x.__init__(...) initializes x; see x.__class__.__doc__ for + signature +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpState
++object --+ + | + TftpState ++ +
- Known Subclasses: +
- + +
+
The base class for the states.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ + |
+
|
+ ||
+ Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Constructor for setting up common instance variables. The involved + file object is required, since in tftp there's always a file + involved. +
|
+
An abstract method for handling a packet. It is expected to return a + TftpState object, either itself or a new state. +
|
+
This method performs initial setup for a server context transfer, put + here to refactor code out of the TftpStateServerRecvRRQ and + TftpStateServerRecvWRQ classes, since their initial setup is identical. + The method returns a boolean, sendoack, to indicate whether it is + required to send an OACK to the client. +
|
+
This method sends the next DAT packet based on the data in the + context. It returns a boolean indicating whether the transfer is + finished. +
|
+
This method sends an ack packet to the block number specified. If none + is specified, it defaults to the next_block property in the parent + context. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateExpectACK
++object --+ + | + TftpState --+ + | + TftpStateExpectACK ++ +
+
This class represents the state of the transfer when a DAT was just + sent, and we are waiting for an ACK from the server. This class is the + same one used by the client during the upload, and the server during the + download.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle a packet, hopefully an ACK since we just sent a DAT. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateExpectDAT
++object --+ + | + TftpState --+ + | + TftpStateExpectDAT ++ +
+
Just sent an ACK packet. Waiting for DAT.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle the packet in response to an ACK, which should be a DAT. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateSentRRQ
++object --+ + | + TftpState --+ + | + TftpStateSentRRQ ++ +
+
Just sent an RRQ packet.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle the packet in response to an RRQ to the server. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateSentWRQ
++object --+ + | + TftpState --+ + | + TftpStateSentWRQ ++ +
+
Just sent an WRQ packet for an upload.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle a packet we just received. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateServerRecvRRQ
++object --+ + | + TftpState --+ + | + TftpStateServerRecvRRQ ++ +
+
This class represents the state of the TFTP server when it has just + received an RRQ packet.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle an initial RRQ packet as a server. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateServerRecvWRQ
++object --+ + | + TftpState --+ + | + TftpStateServerRecvWRQ ++ +
+
This class represents the state of the TFTP server when it has just + received a WRQ packet.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle an initial WRQ packet as a server. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ | + +
+ |
+
Class TftpStateServerStart
++object --+ + | + TftpState --+ + | + TftpStateServerStart ++ +
+
The start state for the server.
+ + + +
+
|
+|||
+ + |
+
|
+ ||
+ Inherited from Inherited from |
+
+
|
+|||
+ Inherited from |
+
+
|
+
+
Handle a packet we just received. +
|
+ +
Home | + + +Trees | + + +Indices | + + +Help | + ++ |
---|
+ Generated by Epydoc 3.0.1 on Sat Oct 24 00:10:21 2009 + | ++ http://epydoc.sourceforge.net + | +
Everything
++
All Classes
+ tftpy.TftpClient'.TftpClienttftpy.TftpPacketFactory'.TftpPacketFactory
tftpy.TftpPacketTypes.TftpPacket
tftpy.TftpPacketTypes.TftpPacketACK
tftpy.TftpPacketTypes.TftpPacketDAT
tftpy.TftpPacketTypes.TftpPacketERR
tftpy.TftpPacketTypes.TftpPacketInitial
tftpy.TftpPacketTypes.TftpPacketOACK
tftpy.TftpPacketTypes.TftpPacketRRQ
tftpy.TftpPacketTypes.TftpPacketWRQ
tftpy.TftpPacketTypes.TftpPacketWithOptions
tftpy.TftpPacketTypes.TftpSession
tftpy.TftpServer'.TftpServer
tftpy.TftpShared.TftpErrors
tftpy.TftpShared.TftpException
tftpy.TftpStates.TftpContext
tftpy.TftpStates.TftpContextClientDownload
tftpy.TftpStates.TftpContextClientUpload
tftpy.TftpStates.TftpContextServer
tftpy.TftpStates.TftpMetrics
tftpy.TftpStates.TftpState
tftpy.TftpStates.TftpStateExpectACK
tftpy.TftpStates.TftpStateExpectDAT
tftpy.TftpStates.TftpStateSentRRQ
tftpy.TftpStates.TftpStateSentWRQ
tftpy.TftpStates.TftpStateServerRecvRRQ
tftpy.TftpStates.TftpStateServerRecvWRQ
tftpy.TftpStates.TftpStateServerStart
All Functions
+ tftpy.TftpShared.setLogLeveltftpy.TftpShared.tftpassert
All Variables
+ tftpy.TftpClient'.DEF_BLKSIZEtftpy.TftpClient'.DEF_TFTP_PORT
tftpy.TftpClient'.LOG_LEVEL
tftpy.TftpClient'.MAX_BLKSIZE
tftpy.TftpClient'.MAX_DUPS
tftpy.TftpClient'.MIN_BLKSIZE
tftpy.TftpClient'.SOCK_TIMEOUT
tftpy.TftpClient'.TIMEOUT_RETRIES
tftpy.TftpClient'.log
tftpy.TftpPacketFactory'.DEF_BLKSIZE
tftpy.TftpPacketFactory'.DEF_TFTP_PORT
tftpy.TftpPacketFactory'.LOG_LEVEL
tftpy.TftpPacketFactory'.MAX_BLKSIZE
tftpy.TftpPacketFactory'.MAX_DUPS
tftpy.TftpPacketFactory'.MIN_BLKSIZE
tftpy.TftpPacketFactory'.SOCK_TIMEOUT
tftpy.TftpPacketFactory'.TIMEOUT_RETRIES
tftpy.TftpPacketFactory'.log
tftpy.TftpServer'.DEF_BLKSIZE
tftpy.TftpServer'.DEF_TFTP_PORT
tftpy.TftpServer'.LOG_LEVEL
tftpy.TftpServer'.MAX_BLKSIZE
tftpy.TftpServer'.MAX_DUPS
tftpy.TftpServer'.MIN_BLKSIZE
tftpy.TftpServer'.SOCK_TIMEOUT
tftpy.TftpServer'.TIMEOUT_RETRIES
tftpy.TftpServer'.log
tftpy.TftpShared.DEF_BLKSIZE
tftpy.TftpShared.DEF_TFTP_PORT
tftpy.TftpShared.LOG_LEVEL
tftpy.TftpShared.MAX_BLKSIZE
tftpy.TftpShared.MAX_DUPS
tftpy.TftpShared.MIN_BLKSIZE
tftpy.TftpShared.SOCK_TIMEOUT
tftpy.TftpShared.TIMEOUT_RETRIES
tftpy.TftpShared.log
tftpy.verlist
+ + + + + diff --git a/html/tftpy-doc/toc-tftpy-module.html b/html/tftpy-doc/toc-tftpy-module.html new file mode 100644 index 0000000..7dfde74 --- /dev/null +++ b/html/tftpy-doc/toc-tftpy-module.html @@ -0,0 +1,31 @@ + + + + +
Module tftpy
++
Variables
+ verlist+ + + + + diff --git a/html/tftpy-doc/toc-tftpy.TftpClient'-module.html b/html/tftpy-doc/toc-tftpy.TftpClient'-module.html new file mode 100644 index 0000000..a24abea --- /dev/null +++ b/html/tftpy-doc/toc-tftpy.TftpClient'-module.html @@ -0,0 +1,41 @@ + + + + +
Module TftpClient'
++
Classes
+ TftpClientVariables
+ DEF_BLKSIZEDEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+ + + + + diff --git a/html/tftpy-doc/toc-tftpy.TftpPacketFactory'-module.html b/html/tftpy-doc/toc-tftpy.TftpPacketFactory'-module.html new file mode 100644 index 0000000..b437bc5 --- /dev/null +++ b/html/tftpy-doc/toc-tftpy.TftpPacketFactory'-module.html @@ -0,0 +1,41 @@ + + + + +
Module TftpPacketFactory'
++
Classes
+ TftpPacketFactoryVariables
+ DEF_BLKSIZEDEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+ + + + + diff --git a/html/tftpy-doc/toc-tftpy.TftpPacketTypes-module.html b/html/tftpy-doc/toc-tftpy.TftpPacketTypes-module.html new file mode 100644 index 0000000..69f9240 --- /dev/null +++ b/html/tftpy-doc/toc-tftpy.TftpPacketTypes-module.html @@ -0,0 +1,40 @@ + + + + +
Module TftpPacketTypes
++
Classes
+ TftpPacketTftpPacketACK
TftpPacketDAT
TftpPacketERR
TftpPacketInitial
TftpPacketOACK
TftpPacketRRQ
TftpPacketWRQ
TftpPacketWithOptions
TftpSession
+ + + + + diff --git a/html/tftpy-doc/toc-tftpy.TftpServer'-module.html b/html/tftpy-doc/toc-tftpy.TftpServer'-module.html new file mode 100644 index 0000000..d40d425 --- /dev/null +++ b/html/tftpy-doc/toc-tftpy.TftpServer'-module.html @@ -0,0 +1,41 @@ + + + + +
Module TftpServer'
++
Classes
+ TftpServerVariables
+ DEF_BLKSIZEDEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+ + + + + diff --git a/html/tftpy-doc/toc-tftpy.TftpShared-module.html b/html/tftpy-doc/toc-tftpy.TftpShared-module.html new file mode 100644 index 0000000..e711d38 --- /dev/null +++ b/html/tftpy-doc/toc-tftpy.TftpShared-module.html @@ -0,0 +1,45 @@ + + + + +
Module TftpShared
++
Classes
+ TftpErrorsTftpException
Functions
+ setLogLeveltftpassert
Variables
+ DEF_BLKSIZEDEF_TFTP_PORT
LOG_LEVEL
MAX_BLKSIZE
MAX_DUPS
MIN_BLKSIZE
SOCK_TIMEOUT
TIMEOUT_RETRIES
log
+ + + + + diff --git a/html/tftpy-doc/toc-tftpy.TftpStates-module.html b/html/tftpy-doc/toc-tftpy.TftpStates-module.html new file mode 100644 index 0000000..9430644 --- /dev/null +++ b/html/tftpy-doc/toc-tftpy.TftpStates-module.html @@ -0,0 +1,43 @@ + + + + +
Module TftpStates
++
Classes
+ TftpContextTftpContextClientDownload
TftpContextClientUpload
TftpContextServer
TftpMetrics
TftpState
TftpStateExpectACK
TftpStateExpectDAT
TftpStateSentRRQ
TftpStateSentWRQ
TftpStateServerRecvRRQ
TftpStateServerRecvWRQ
TftpStateServerStart
+ + + + + diff --git a/html/tftpy-doc/toc.html b/html/tftpy-doc/toc.html new file mode 100644 index 0000000..77bff32 --- /dev/null +++ b/html/tftpy-doc/toc.html @@ -0,0 +1,39 @@ + + + + +
Table of Contents
++ Everything +
+
Modules
+ tftpytftpy.TftpClient'
tftpy.TftpPacketFactory'
tftpy.TftpPacketTypes
tftpy.TftpServer'
tftpy.TftpShared
tftpy.TftpStates
+ + + + +