]>
Commit | Line | Data |
---|---|---|
1b4f8140 CMN |
1 | /* |
2 | * This file is free software; you can redistribute it and/or modify | |
3 | * it under the terms of the GNU General Public License, version 2, | |
4 | * as published by the Free Software Foundation. | |
5 | * | |
6 | * In addition to the permissions in the GNU General Public License, | |
7 | * the authors give you unlimited permission to link the compiled | |
8 | * version of this file into combinations with other programs, | |
9 | * and to distribute those combinations without any restriction | |
10 | * coming from the use of this file. (The General Public License | |
11 | * restrictions do apply in other respects; for example, they cover | |
12 | * modification of the file, and distribution when not linked into | |
13 | * a combined executable.) | |
14 | * | |
15 | * This file is distributed in the hope that it will be useful, but | |
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | * General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU General Public License | |
21 | * along with this program; see the file COPYING. If not, write to | |
22 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, | |
23 | * Boston, MA 02110-1301, USA. | |
24 | */ | |
25 | ||
4e95ef02 CMN |
26 | #ifndef _MSC_VER |
27 | # include <sys/types.h> | |
28 | # include <sys/socket.h> | |
29 | # include <netdb.h> | |
30 | #else | |
31 | # include <winsock2.h> | |
32 | # include <Ws2tcpip.h> | |
33 | # pragma comment(lib, "Ws2_32.lib") | |
34 | #endif | |
1b4f8140 CMN |
35 | |
36 | #include "git2/errors.h" | |
37 | ||
38 | #include "common.h" | |
39 | #include "netops.h" | |
40 | ||
c7c787ce | 41 | void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, int fd) |
ea7a5452 CMN |
42 | { |
43 | memset(buf, 0x0, sizeof(gitno_buffer)); | |
44 | memset(data, 0x0, len); | |
45 | buf->data = data; | |
46 | buf->len = len - 1; | |
47 | buf->offset = 0; | |
48 | buf->fd = fd; | |
49 | } | |
50 | ||
51 | int gitno_recv(gitno_buffer *buf) | |
52 | { | |
53 | int ret; | |
54 | ||
55 | ret = recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0); | |
56 | if (ret < 0) | |
57 | return git__throw(GIT_EOSERR, "Failed to receive data"); | |
58 | if (ret == 0) /* Orderly shutdown, so exit */ | |
59 | return GIT_SUCCESS; | |
60 | ||
61 | buf->offset += ret; | |
62 | ||
63 | return ret; | |
64 | } | |
65 | ||
66 | /* Consume up to ptr and move the rest of the buffer to the beginning */ | |
c7c787ce | 67 | void gitno_consume(gitno_buffer *buf, const char *ptr) |
ea7a5452 | 68 | { |
c7c787ce | 69 | int consumed; |
ea7a5452 CMN |
70 | |
71 | assert(ptr - buf->data <= (int) buf->len); | |
72 | ||
c7c787ce | 73 | consumed = ptr - buf->data; |
ea7a5452 | 74 | |
c7c787ce CMN |
75 | memmove(buf->data, ptr, buf->offset - consumed); |
76 | memset(buf->data + buf->offset, 0x0, buf->len - buf->offset); | |
77 | buf->offset -= consumed; | |
ea7a5452 CMN |
78 | } |
79 | ||
80 | /* Consume const bytes and move the rest of the buffer to the beginning */ | |
81 | void gitno_consume_n(gitno_buffer *buf, unsigned int cons) | |
82 | { | |
83 | memmove(buf->data, buf->data + cons, buf->len - buf->offset); | |
84 | memset(buf->data + cons, 0x0, buf->len - buf->offset); | |
85 | buf->offset -= cons; | |
86 | } | |
87 | ||
1b4f8140 CMN |
88 | int gitno_connect(const char *host, const char *port) |
89 | { | |
90 | struct addrinfo *info, *p; | |
91 | struct addrinfo hints; | |
92 | int ret, error = GIT_SUCCESS; | |
93 | int s; | |
94 | ||
95 | memset(&hints, 0x0, sizeof(struct addrinfo)); | |
96 | hints.ai_family = AF_UNSPEC; | |
97 | hints.ai_socktype = SOCK_STREAM; | |
98 | ||
99 | ret = getaddrinfo(host, port, &hints, &info); | |
100 | if (ret != 0) { | |
101 | error = GIT_EOSERR; | |
102 | goto cleanup; | |
103 | } | |
104 | ||
105 | for (p = info; p != NULL; p = p->ai_next) { | |
106 | s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); | |
107 | if (s < 0) { | |
108 | error = GIT_EOSERR; | |
109 | goto cleanup; | |
110 | } | |
111 | ||
112 | ret = connect(s, p->ai_addr, p->ai_addrlen); | |
113 | /* If we can't connect, try the next one */ | |
114 | if (ret < 0) { | |
115 | continue; | |
116 | } | |
117 | ||
118 | /* Return the socket */ | |
119 | error = s; | |
120 | goto cleanup; | |
121 | } | |
122 | ||
123 | /* Oops, we couldn't connect to any address */ | |
124 | error = GIT_EOSERR; | |
125 | ||
126 | cleanup: | |
127 | freeaddrinfo(info); | |
128 | return error; | |
129 | } | |
4e95ef02 CMN |
130 | |
131 | int gitno_send(int s, const char *msg, int len, int flags) | |
132 | { | |
133 | int ret, off = 0; | |
134 | ||
135 | while (off < len) { | |
136 | ret = send(s, msg + off, len - off, flags); | |
137 | if (ret < 0) | |
138 | return GIT_EOSERR; | |
139 | ||
140 | off += ret; | |
141 | } | |
142 | ||
143 | return off; | |
144 | } |