/* Put a string ionto the OWQ structure and return the length check lengths and offsets as part of the process */ static SIZE_OR_ERROR OWQ_parse_output_offset_and_size(const char *string, size_t length, struct one_wire_query *owq) { size_t copy_length = length; off_t offset = OWQ_offset(owq); Debug_Bytes("OWQ_parse_output_offset_and_size", (const BYTE *) string, length); /* offset is after the length of the string -- return 0 since some conditions a read after the end is done automatically */ if (offset > (off_t) length) { return 0; } /* correct length for offset (cannot be negative because of previous check) */ copy_length -= offset; /* correct length for buffer space */ if (copy_length > OWQ_size(owq)) { copy_length = OWQ_size(owq); } /* and copy */ memcpy(OWQ_buffer(owq), &string[offset], copy_length); // Warning, this will overwrite the I U or DATA value, // but that shouldn't matter since it's only called on ascii values // and all structure values OWQ_length(owq) = copy_length; return copy_length; }
void tcp_read_flush( FILE_DESCRIPTOR_OR_ERROR file_descriptor) { BYTE buffer[16]; ssize_t nread; int flags = fcntl(file_descriptor, F_GETFL, 0); // Apparently you can test for GET_FL success like this // see http://www.informit.com/articles/article.asp?p=99706&seqNum=13&rl=1 if (flags < 0) { return; } if (fcntl(file_descriptor, F_SETFL, flags | O_NONBLOCK) < 0) { return; } while ((nread = read(file_descriptor, buffer, 16)) > 0) { Debug_Bytes("tcp_read_flush", buffer, nread); continue; } if ( fcntl(file_descriptor, F_SETFL, flags) < 0 ) { LEVEL_DEBUG("Can't flush"); } }
/* cm.ret is also set to an error <0 or the read length */ void *ReadHandler(struct handlerdata *hd, struct client_msg *cm, struct one_wire_query *owq) { BYTE * retbuffer = NULL ; SIZE_OR_ERROR read_or_error; LEVEL_DEBUG("ReadHandler start"); if (hd == NULL || owq == NULL || cm == NULL) { LEVEL_DEBUG("ReadHandler: illegal null inputs hd==%p owq==%p cm==%p", hd, owq, cm); return NULL; // only sane response for bad inputs } LEVEL_DEBUG("ReadHandler: From Client sm->payload=%d sm->size=%d sm->offset=%d", hd->sm.payload, hd->sm.size, hd->sm.offset); if (hd->sm.payload >= PATH_MAX) { cm->ret = -EMSGSIZE; } else if ((hd->sm.size <= 0) || (hd->sm.size > MAX_OWSERVER_PROTOCOL_PAYLOAD_SIZE)) { cm->ret = -EMSGSIZE; LEVEL_DEBUG("ReadHandler: error hd->sm.size == %d", hd->sm.size); } else if ( BAD( OWQ_allocate_read_buffer(owq)) ) { // allocate read buffer LEVEL_DEBUG("ReadHandler: can't allocate memory"); cm->ret = -ENOBUFS; } else { struct parsedname *pn = PN(owq); if ( OWQ_size(owq) > (size_t) hd->sm.size ) { OWQ_size(owq) = hd->sm.size ; } OWQ_offset(owq) = hd->sm.offset ; LEVEL_DEBUG("ReadHandler: call FS_read_postparse on %s", pn->path); read_or_error = FS_read_postparse(owq); LEVEL_DEBUG("ReadHandler: FS_read_postparse read on %s return = %d", pn->path, read_or_error); Debug_OWQ(owq); if (read_or_error <= 0) { LEVEL_DEBUG("ReadHandler: FS_read_postparse error %d", read_or_error); cm->ret = read_or_error; } else { LEVEL_DEBUG("ReadHandler: FS_read_postparse ok size=%d", read_or_error); // make return size smaller (just large enough) cm->payload = read_or_error; cm->offset = hd->sm.offset; cm->size = read_or_error; cm->ret = read_or_error; /* Move this pointer, and let owfree remove it instead of OWQ_destroy() */ retbuffer = (BYTE *)OWQ_buffer(owq); OWQ_buffer(owq) = NULL; } } LEVEL_DEBUG("ReadHandler: To Client cm->payload=%d cm->size=%d cm->offset=%d", cm->payload, cm->size, cm->offset); if ((cm->size > 0)) { Debug_Bytes("Data returned to client",(BYTE *) OWQ_buffer(owq),cm->size) ; } return retbuffer; }
// _sendback_bits // Send data and return response block // return 0=good static GOOD_OR_BAD LINK_sendback_bits(const BYTE * databits, BYTE * respbits, const size_t size, const struct parsedname *pn) { struct connection_in * in = pn->selected_connection ; size_t left = size; size_t location = 0 ; BYTE buf[1+LINK_SEND_SIZE+1+1+in->CRLF_size] ; if (size == 0) { return gbGOOD; } Debug_Bytes( "ELINK sendback bits send", databits, size) ; while (left > 0) { // Loop through taking only 32 bytes at a time size_t this_length = (left > LINK_SEND_SIZE) ? LINK_SEND_SIZE : left; size_t i ; buf[0] = 'j'; //put in bit mode for ( i=0 ; i<this_length ; ++i ) { buf[i+1] = databits[i+location] ? '1' : '0' ; } buf[1+this_length] = '\r'; // take out of bit mode // send to LINK RETURN_BAD_IF_BAD(LINK_write(buf, 1+this_length+1, in) ) ; // read back RETURN_BAD_IF_BAD( LINK_readback_data(buf, this_length, in) ) ; // place data (converted back to hex) in resp for ( i=0 ; i<this_length ; ++i ) { respbits[i+location] = (buf[i]=='0') ? 0x00 : 0xFF ; } left -= this_length; location += this_length ; } Debug_Bytes( "ELINK sendback bits get", respbits, size) ; return gbGOOD; }
void _print_owq(struct one_wire_query *owq) { char c[32]; fprintf(stderr,"OWQ OneWireQuery structure of %s\n", PN(owq)->path); fprintf(stderr," OneWireQuery size=%lu offset=%lu, extension=%d\n", (unsigned long) OWQ_size(owq), (unsigned long) OWQ_offset(owq), (int) OWQ_pn(owq).extension); if ( OWQ_buffer(owq) != NULL ) { Debug_Bytes("OneWireQuery buffer", (BYTE *) OWQ_buffer(owq), OWQ_size(owq)); } fprintf(stderr," Cleanup = %.4X",OWQ_cleanup(owq)); fprintf(stderr," OneWireQuery I=%d U=%u F=%G Y=%d D=%s\n", OWQ_I(owq), OWQ_U(owq), OWQ_F(owq), OWQ_Y(owq), SAFESTRING(ctime_r(&OWQ_D(owq), c))); fprintf(stderr,"--- OneWireQuery done\n"); }
void tcp_read_flush(int file_descriptor) { ASCII buffer[16]; ssize_t nread; int flags = fcntl(file_descriptor, F_GETFL, 0); // Apparently you can test for GET_FL success like this // see http://www.informit.com/articles/article.asp?p=99706&seqNum=13&rl=1 if (flags < 0) return; if (fcntl(file_descriptor, F_SETFL, flags | O_NONBLOCK) < 0) return; while ((nread = read(file_descriptor, (BYTE *) buffer, 16)) > 0) { Debug_Bytes("tcp_read_flush", (BYTE *) buffer, nread); continue; } fcntl(file_descriptor, F_SETFL, flags); }