int XmodemRRcv(char c) { errorCount = 0 ; switch( state ) { case Start: /* shouldn't happen, ignore */ if( c == CAN ) return XmErrCancel ; break ; case Init: /* waiting */ case Wait: switch( c ) { case SOH: case STX: pktLen = c == STX ? 1024 : 128 ; inCount = 0 ; optr = packet ; state = Packet ; xmTimeout = PKTTO ; break ; case EOT: if( ++eotCount > 1 ) { sendFlush(ACK) ; if( ymodem ) return XmodemRInit() ; /* restart protocol */ else return XmDone ; } else return rejectPacket() ; /* make xmitter try again */ case CAN: return XmErrCancel ; default: /* ignore all others */ if( ++ignoreCount > 1030 ) { ignoreCount = 0 ; return sendFlush(NAK) ; } break ; } break ; case Packet: /* mid packet */ *optr++ = c ; if( ++inCount >= pktLen + pktHdrLen ) ProcessPacket() ; break ; } return 0 ; }
static void flushNodes (void) { pwr_tStatus sts; pwr_tNodeId nid; qcom_sNode node; gdb_sNode* np; gdb_AssumeUnlocked; for (nid = qcom_cNNid; qcom_NextNode(&sts, &node, nid); nid = node.nid) { gdb_ScopeLock { np = hash_Search(&sts, gdbroot->nid_ht, &node.nid); } gdb_ScopeUnlock; if (np == NULL) continue; if (np == gdbroot->my_node || np == gdbroot->no_node) continue; if (node.flags.b.connected) { sendFlush(np); #if 0 sendVolumes(np, pool_cNRef); #endif } } }
static int XmodemRStart() { static char pchars[5] = {NAK,'C','W','C','C'} ; static int timeouts[5] = {INITTO, INITTO2, INITTO2, INITTO, INITTO} ; char c = pchars[(int)protocol] ; int err ; if( err=sendFlush(c) ) return err ; xmTimeout = timeouts[(int)protocol] ; return 0 ; }
int sendCancel() { return sendFlush(CAN) || sendFlush(CAN) ; }
static int acceptPacket() { state = Wait ; xmTimeout = INITTO ; return sendFlush(ACK) ; }
static int rejectPacket() { state = Wait ; xmTimeout = INITTO ; return sendFlush(NAK) ; }
static int ProcessPacket() { int id = (u_char)packet[0] ; int idc = (u_char)packet[1] ; int i ; if( idc != 255-id ) return rejectPacket() ; if( id == packetId ) /* duplicate */ return acceptPacket() ; if( id != (packetId+1)%256 ) { /* out of sequence */ (void) sendCancel() ; return XmErrSequence ; } if( protocol == Xmodem ) { /* compute checksum */ int csum = calcChecksum(packet+2, pktLen) ; if( csum != (u_char) packet[2+pktLen] ) return rejectPacket() ; } else { int crc0 = (u_char)packet[pktLen+2] << 8 | (u_char)packet[pktLen+3] ; int crc1 = calcrc(packet+2, pktLen) ; if( crc0 != crc1 ) return rejectPacket() ; } /* it's a good packet */ packetId = (packetId+1)%256 ; /* is this the first packet? */ if( packetCount == 0 ) { if( ymodem ) { if( packet[2] == '\0' ) { /* last file */ (void) acceptPacket() ; return XmDone ; } if( packet[2] == '/' ) strcpy(xmFilename, packet+2) ; else { strcpy(xmFilename, xmDefPath) ; strcat(xmFilename, packet+2) ; } fileLen = fileDate = fileMode = -1 ; sscanf(packet+2+strlen(packet)+1, "%d %o %o", &fileLen, &fileDate, &fileMode) ; } if( (ofile = fopen(xmFilename, "w")) == NULL ) { sendCancel() ; return XmErrCantOpen ; } if( ymodem ) { packetCount = 1 ; (void) acceptPacket() ; return sendFlush('C') ; } else state = Packet ; } ++packetCount ; /* TODO: ymodem: if this is last packet, truncate it */ if( (i=fwrite(packet+2, 1, pktLen, ofile)) != pktLen ) { sendCancel() ; return XmErrSys ; } else return acceptPacket() ; }