static int cr_sendfandreceive(NDPI_REDIS rhnd, char recvtype, const char *format, ...) { int rc; va_list ap; cr_buffer *buf = &(rhnd->buf); va_start(ap, format); rc = vsnprintf(buf->data, buf->size, format, ap); va_end(ap); if (rc < 0) return -1; if (rc >= buf->size) { DEBUG_PRINT("truncated, get more memory and try again"); if (cr_moremem(buf, rc - buf->size + 1)) return NDPI_CREDIS_ERR_NOMEM; va_start(ap, format); rc = vsnprintf(buf->data, buf->size, format, ap); va_end(ap); } buf->len = rc; return cr_sendandreceive(rhnd, recvtype); }
/* Appends a zero-terminated string `str' to the end of buffer `buf'. If * available memory in buffer is not enough to hold `str' more memory is * allocated to the buffer. If `space' is not 0 `str' is padded with a space. * Returns: * 0 on success * <0 on error, i.e. more memory not available */ static int cr_appendstr(cr_buffer *buf, const char *str, int space) { int avail, len, reqd; len = strlen(str); avail = buf->size - buf->len; /* required memory: len, terminating zero and possibly a space */ reqd = len + 1; if (space) reqd++; if (reqd > avail) if (cr_moremem(buf, reqd - avail + 1)) return NDPI_CREDIS_ERR_NOMEM; if (space) buf->data[buf->len++] = ' '; memcpy(buf->data + buf->len, str, len); buf->len += len; buf->data[buf->len] = '\0'; return 0; }
/* Appends a printf style formatted to the end of buffer `buf'. If available * memory in buffer is not enough to hold `str' more memory is allocated to * the buffer. * Returns: * 0 on success * <0 on error, i.e. more memory not available */ static int cr_appendstrf(cr_buffer *buf, const char *format, ...) { int rc, avail; va_list ap; avail = buf->size - buf->len; va_start(ap, format); rc = vsnprintf(buf->data + buf->len, avail, format, ap); va_end(ap); if (rc < 0) return -1; if (rc >= avail) { if (cr_moremem(buf, rc - avail + 1)) return NDPI_CREDIS_ERR_NOMEM; va_start(ap, format); rc = vsnprintf(buf->data + buf->len, buf->size - buf->len, format, ap); va_end(ap); } buf->len += rc; return 0; }
/* Buffered read line, returns pointer to zero-terminated string * and length of that string. `start' specifies from which byte * to start looking for "\r\n". * Returns: * >0 length of string to which pointer `line' refers. `idx' is * an optional pointer for returning start index of line with * respect to buffer. * 0 connection to Redis server was closed * -1 on error, i.e. a string is not available */ static int cr_readln(NDPI_REDIS rhnd, int start, char **line, int *idx) { cr_buffer *buf = &(rhnd->buf); char *nl; int rc, len, avail, more; /* do we need more data before we expect to find "\r\n"? */ if ((more = buf->idx + start + 2 - buf->len) < 0) more = 0; while (more > 0 || (nl = cr_findnl(buf->data + buf->idx + start, buf->len - (buf->idx + start))) == NULL) { avail = buf->size - buf->len; if (avail < CR_BUFFER_WATERMARK || avail < more) { DEBUG_PRINT("available buffer memory is low, get more memory"); if (cr_moremem(buf, more>0?more:1)) return NDPI_CREDIS_ERR_NOMEM; avail = buf->size - buf->len; } rc = cr_receivedata(rhnd->fd, rhnd->timeout, buf->data + buf->len, avail); if (rc > 0) { DEBUG_PRINT("received %d bytes: %s", rc, buf->data + buf->len); buf->len += rc; } else if (rc == 0) return 0; /* EOF reached, connection terminated */ else return -1; /* error */ /* do we need more data before we expect to find "\r\n"? */ if ((more = buf->idx + start + 2 - buf->len) < 0) more = 0; } *nl = '\0'; /* zero terminate */ *line = buf->data + buf->idx; if (idx) *idx = buf->idx; len = nl - *line; buf->idx = (nl - buf->data) + 2; /* skip "\r\n" */ DEBUG_PRINT("size=%d, len=%d, idx=%d, start=%d, line=%s", buf->size, buf->len, buf->idx, start, *line); return len; }
/* Appends a string `str' to the end of buffer `buf'. If available memory * in buffer is not enough to hold `str' more memory is allocated to the * buffer. If `space' is not 0 `str' is padded with a space. * Returns: * 0 on success * <0 on error, i.e. more memory not available */ static int cr_appendstr(cr_buffer *buf, const char *str, int space) { int rc, avail; char *format = (space==0?"%s":" %s"); /* TODO instead of using formatted print use memcpy() and don't blindly add a space before `str' */ avail = buf->size - buf->len; rc = snprintf(buf->data + buf->len, avail, format, str); if (rc >= avail) { DEBUG("truncated, get more memory and try again"); if (cr_moremem(buf, rc - avail + 1)) return CREDIS_ERR_NOMEM; avail = buf->size - buf->len; rc = snprintf(buf->data + buf->len, avail, format, str); } buf->len += rc; return 0; }
//__attribute__ ((format(printf,3,4))) static int cr_sendfandreceive(REDIS rhnd, char recvtype, const char *format, ...) { int rc; va_list ap; cr_buffer *buf = &(rhnd->buf); #ifdef WIN32 ap = NULL; #endif va_start(ap, format); #ifdef WIN32 memset(buf->data, 0, buf->size); rc = _vsnprintf(buf->data, buf->size, format, ap); #else rc = vsnprintf(buf->data, buf->size, format, ap); #endif va_end(ap); if (rc < 0) return -1; if (rc >= buf->size) { DEBUG("truncated, get more memory and try again"); if (cr_moremem(buf, rc - buf->size + 1)) return CREDIS_ERR_NOMEM; va_start(ap, format); rc = vsnprintf(buf->data, buf->size, format, ap); va_end(ap); } buf->len = rc; return cr_sendandreceive(rhnd, recvtype); }