-#ifdef USE_SASL
- if (sb->sb_sec) {
- int max;
- assert( sb->sb_sec->sbs_release );
- assert( sb->sb_sec_buf_in.buf_base );
- if (sb->sb_read_ahead) {
- max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
- } else {
- max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
- if (max<=0) {
- /* special situation. This means that we need to read the first
- * four bytes for the packet length.
- */
- max += 4;
- }
- }
- for(;;) {
- /* read from stream into sb_sec_buf_in */
- for(;;) {
- ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
- sb->sb_sec_buf_in.buf_ptr, max );
-#ifdef EINTR
- if ((ret<0) && (errno==EINTR))
- continue;
-#endif
- break;
- }
- if (ret<=0) {
- /* read error. return */
- goto do_return;
- }
- sb->sb_sec_buf_in.buf_ptr += ret;
-
- if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
- /* did not finish a packet. give up. */
- goto do_return;
- }
-
- if (sb->sb_sec_buf_in.buf_end == 0) {
- /* Were trying to read the first four bytes... */
- if (sb->sb_sec_buf_in.buf_ptr < 4) {
- /* did not read enough for packet length. give up. */
- goto do_return;
- }
- /* calculate the packet length. */
- sb->sb_sec_buf_in.buf_end =
- packet_length(sb->sb_sec_buf_in.buf_base );
- if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
- (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
- /* buffer has to be to big. exit with error. */
- ret = -1;
- goto do_return;
- }
- if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
- /* finished packet. decode it. */
- goto decode_packet;
- }
- /* did not finish packet yet. try again ? */
- if (sb->sb_read_ahead) {
- /* we were trying to read the max anyway. forget it */
- goto do_return;
- }
- }
-decode_packet:
- /* we read enough for at least 1 packet */
- ret = sockbuf_sec_release( sb, buf, len );
- if (ret<=0) {
- /* something went wrong... */
- goto do_return;
- }
- buf+=ret;
- len-=ret;
- /* we are finished !!! */
- if ((len==0) || (ret!=max))
- goto do_return;
- }
- } else {
-#endif
- if (sb->sb_read_ahead) {
- long max;
- max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
- if (max>len) {
- for(;;) {
- ret = sockbuf_io_read( sb,
- sb->sb_buf.buf_base +
- sb->sb_buf.buf_end,
- max );
-#ifdef EINTR
- if ((ret<0) && (errno==EINTR))
- continue;
-#endif
- break;
- }
- if (ret<=0) {
- /* some error occured */
- goto do_return;
- }
- sb->sb_buf.buf_end += ret;
- /* move out the data... */
- len = sockbuf_copy_out( sb, &buf, len );
- goto do_return;
- }
- }
- /* no read_ahead, just try to put the data in the buf. */
- for(;;) {
- ret = sockbuf_io_read( sb, buf, len );
-#ifdef EINTR
- if ((ret<0) && (errno==EINTR))
- continue;
-#endif
- break;
- }
- if (ret>0) {
- buf+=ret;
- len-=ret;
- }
- /* we might as well return, since there is nothing to do... */
-#ifdef USE_SASL
- }
-#endif
-do_return:
- assert( status_is_ok(sb) );
- if ((ret<=0) && (buf==buf_arg)) {
- /* there was an error. */
- return ret;
- }
- return (buf - ((char *) buf_arg));