1#include "network_backends.h" 2 3#include "network.h" 4#include "log.h" 5 6#include "sys-socket.h" 7 8#include <unistd.h> 9 10#include <errno.h> 11#include <string.h> 12 13#ifdef HAVE_LIBSMBCLIENT_H 14#include <libsmbclient.h> 15#endif 16 17#define DBE 1 18 19int network_write_mem_chunk(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) { 20 chunk* const c = cq->first; 21 off_t c_len; 22 ssize_t r; 23 UNUSED(con); 24 25 force_assert(NULL != c); 26 force_assert(MEM_CHUNK == c->type); 27 force_assert(c->offset >= 0 && c->offset <= (off_t)buffer_string_length(c->mem)); 28 29 c_len = buffer_string_length(c->mem) - c->offset; 30 if (c_len > *p_max_bytes) c_len = *p_max_bytes; 31 32 if (0 == c_len) { 33 chunkqueue_remove_finished_chunks(cq); 34 return 0; 35 } 36 37#if defined(__WIN32) 38 if ((r = send(fd, c->mem->ptr + c->offset, c_len, 0)) < 0) { 39 int lastError = WSAGetLastError(); 40 switch (lastError) { 41 case WSAEINTR: 42 case WSAEWOULDBLOCK: 43 break; 44 case WSAECONNRESET: 45 case WSAETIMEDOUT: 46 case WSAECONNABORTED: 47 return -2; 48 default: 49 log_error_write(srv, __FILE__, __LINE__, "sdd", 50 "send failed: ", lastError, fd); 51 return -1; 52 } 53 } 54#else /* __WIN32 */ 55 if ((r = write(fd, c->mem->ptr + c->offset, c_len)) < 0) { 56 switch (errno) { 57 case EAGAIN: 58 case EINTR: 59 break; 60 case EPIPE: 61 case ECONNRESET: 62 return -2; 63 default: 64 log_error_write(srv, __FILE__, __LINE__, "ssd", 65 "write failed:", strerror(errno), fd); 66 return -1; 67 } 68 } 69#endif /* __WIN32 */ 70 71 if (r >= 0) { 72 *p_max_bytes -= r; 73 chunkqueue_mark_written(cq, r); 74 } 75 76 return (r > 0 && r == c_len) ? 0 : -3; 77} 78 79int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { 80 while (max_bytes > 0 && NULL != cq->first) { 81 int r = -1; 82 83 switch (cq->first->type) { 84 case MEM_CHUNK: 85 r = network_write_mem_chunk(srv, con, fd, cq, &max_bytes); 86 break; 87 case FILE_CHUNK: 88 r = network_write_file_chunk_mmap(srv, con, fd, cq, &max_bytes); 89 break; 90 } 91 92 if (-3 == r) return 0; 93 if (0 != r) return r; 94 } 95 96 return 0; 97} 98 99int network_write_chunkqueue_sendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { 100 while (max_bytes > 0 && NULL != cq->first) { 101 int r = -1; 102 103 switch (cq->first->type) { 104 case MEM_CHUNK: 105 r = network_writev_mem_chunks(srv, con, fd, cq, &max_bytes); 106 break; 107 case FILE_CHUNK: 108 r = network_write_file_chunk_sendfile(srv, con, fd, cq, &max_bytes); 109 break; 110 case SMB_CHUNK: 111#ifndef EMBEDDED_EANBLE 112 r = network_write_smbfile_chunk_sendfile(srv, con, fd, cq, &max_bytes); 113#endif 114 break; 115 } 116 117 if (-3 == r) return 0; 118 if (0 != r) return r; 119 } 120 121 return 0; 122} 123