/src/haproxy/src/channel.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Channel management functions. |
3 | | * |
4 | | * Copyright 2000-2014 Willy Tarreau <w@1wt.eu> |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU General Public License |
8 | | * as published by the Free Software Foundation; either version |
9 | | * 2 of the License, or (at your option) any later version. |
10 | | * |
11 | | */ |
12 | | |
13 | | #include <ctype.h> |
14 | | #include <stdarg.h> |
15 | | #include <stdio.h> |
16 | | #include <string.h> |
17 | | |
18 | | #include <haproxy/api.h> |
19 | | #include <haproxy/buf.h> |
20 | | #include <haproxy/channel.h> |
21 | | |
22 | | |
23 | | /* Schedule up to <bytes> more bytes to be forwarded via the channel without |
24 | | * notifying the owner task. Any data pending in the buffer are scheduled to be |
25 | | * sent as well, within the limit of the number of bytes to forward. This must |
26 | | * be the only method to use to schedule bytes to be forwarded. If the requested |
27 | | * number is too large, it is automatically adjusted. The number of bytes taken |
28 | | * into account is returned. Directly touching ->to_forward will cause lockups |
29 | | * when buf->o goes down to zero if nobody is ready to push the remaining data. |
30 | | */ |
31 | | unsigned long long __channel_forward(struct channel *chn, unsigned long long bytes) |
32 | 0 | { |
33 | 0 | unsigned int budget; |
34 | 0 | unsigned int forwarded; |
35 | | |
36 | | /* This is more of a safety measure as it's not supposed to happen in |
37 | | * regular code paths. |
38 | | */ |
39 | 0 | if (unlikely(chn->to_forward == CHN_INFINITE_FORWARD)) { |
40 | 0 | c_adv(chn, ci_data(chn)); |
41 | 0 | return bytes; |
42 | 0 | } |
43 | | |
44 | | /* Bound the transferred size to a 32-bit count since all our values |
45 | | * are 32-bit, and we don't want to reach CHN_INFINITE_FORWARD. |
46 | | */ |
47 | 0 | budget = MIN(bytes, CHN_INFINITE_FORWARD - 1); |
48 | | |
49 | | /* transfer as much as we can of buf->i */ |
50 | 0 | forwarded = MIN(ci_data(chn), budget); |
51 | 0 | c_adv(chn, forwarded); |
52 | 0 | budget -= forwarded; |
53 | |
|
54 | 0 | if (!budget) |
55 | 0 | return forwarded; |
56 | | |
57 | | /* Now we must ensure chn->to_forward sats below CHN_INFINITE_FORWARD, |
58 | | * which also implies it won't overflow. It's less operations in 64-bit. |
59 | | */ |
60 | 0 | bytes = (unsigned long long)chn->to_forward + budget; |
61 | 0 | if (bytes >= CHN_INFINITE_FORWARD) |
62 | 0 | bytes = CHN_INFINITE_FORWARD - 1; |
63 | 0 | budget = bytes - chn->to_forward; |
64 | |
|
65 | 0 | chn->to_forward += budget; |
66 | 0 | forwarded += budget; |
67 | 0 | return forwarded; |
68 | 0 | } |
69 | | |
70 | | /* writes <len> bytes from message <msg> to the channel's buffer. Returns -1 in |
71 | | * case of success, -2 if the message is larger than the buffer size, or the |
72 | | * number of bytes available otherwise. The send limit is automatically |
73 | | * adjusted to the amount of data written. FIXME-20060521: handle unaligned |
74 | | * data. Note: this function appends data to the buffer's output and possibly |
75 | | * overwrites any pending input data which are assumed not to exist. |
76 | | */ |
77 | | int co_inject(struct channel *chn, const char *msg, int len) |
78 | 0 | { |
79 | 0 | int max; |
80 | |
|
81 | 0 | if (len == 0) |
82 | 0 | return -1; |
83 | | |
84 | 0 | if (len < 0 || len > c_size(chn)) { |
85 | | /* we can't write this chunk and will never be able to, because |
86 | | * it is larger than the buffer. This must be reported as an |
87 | | * error. Then we return -2 so that writers that don't care can |
88 | | * ignore it and go on, and others can check for this value. |
89 | | */ |
90 | 0 | return -2; |
91 | 0 | } |
92 | | |
93 | 0 | c_realign_if_empty(chn); |
94 | 0 | max = b_contig_space(&chn->buf); |
95 | 0 | if (len > max) |
96 | 0 | return max; |
97 | | |
98 | 0 | memcpy(co_tail(chn), msg, len); |
99 | 0 | b_add(&chn->buf, len); |
100 | 0 | c_adv(chn, len); |
101 | 0 | chn->total += len; |
102 | 0 | return -1; |
103 | 0 | } |
104 | | |
105 | | /* Tries to copy character <c> into the channel's buffer after some length |
106 | | * controls. The chn->o and to_forward pointers are updated. If the channel |
107 | | * input is closed, -2 is returned. If there is not enough room left in the |
108 | | * buffer, -1 is returned. Otherwise the number of bytes copied is returned |
109 | | * (1). Channel flag READ_PARTIAL is updated if some data can be transferred. |
110 | | */ |
111 | | int ci_putchr(struct channel *chn, char c) |
112 | 0 | { |
113 | 0 | if (unlikely(channel_input_closed(chn))) |
114 | 0 | return -2; |
115 | | |
116 | 0 | if (!channel_may_recv(chn)) |
117 | 0 | return -1; |
118 | | |
119 | 0 | *ci_tail(chn) = c; |
120 | |
|
121 | 0 | b_add(&chn->buf, 1); |
122 | 0 | chn->flags |= CF_READ_EVENT; |
123 | |
|
124 | 0 | if (chn->to_forward >= 1) { |
125 | 0 | if (chn->to_forward != CHN_INFINITE_FORWARD) |
126 | 0 | chn->to_forward--; |
127 | 0 | c_adv(chn, 1); |
128 | 0 | } |
129 | |
|
130 | 0 | chn->total++; |
131 | 0 | return 1; |
132 | 0 | } |
133 | | |
134 | | /* Tries to copy block <blk> at once into the channel's buffer after length |
135 | | * controls. The chn->o and to_forward pointers are updated. If the channel |
136 | | * input is closed, -2 is returned. If the block is too large for this buffer, |
137 | | * -3 is returned. If there is not enough room left in the buffer, -1 is |
138 | | * returned. Otherwise the number of bytes copied is returned (0 being a valid |
139 | | * number). Channel flag READ_PARTIAL is updated if some data can be |
140 | | * transferred. |
141 | | */ |
142 | | int ci_putblk(struct channel *chn, const char *blk, int len) |
143 | 0 | { |
144 | 0 | int max; |
145 | |
|
146 | 0 | if (unlikely(channel_input_closed(chn))) |
147 | 0 | return -2; |
148 | | |
149 | 0 | if (len < 0) |
150 | 0 | return -3; |
151 | | |
152 | 0 | max = channel_recv_limit(chn); |
153 | 0 | if (unlikely(len > max - c_data(chn))) { |
154 | | /* we can't write this chunk right now because the buffer is |
155 | | * almost full or because the block is too large. Returns |
156 | | * -3 if block is too large for this buffer. Or -1 if the |
157 | | * room left is not large enough. |
158 | | */ |
159 | 0 | if (len > max) |
160 | 0 | return -3; |
161 | | |
162 | 0 | return -1; |
163 | 0 | } |
164 | | |
165 | 0 | if (unlikely(len == 0)) |
166 | 0 | return 0; |
167 | | |
168 | | /* OK so the data fits in the buffer in one or two blocks */ |
169 | 0 | max = b_contig_space(&chn->buf); |
170 | 0 | memcpy(ci_tail(chn), blk, MIN(len, max)); |
171 | 0 | if (len > max) |
172 | 0 | memcpy(c_orig(chn), blk + max, len - max); |
173 | |
|
174 | 0 | b_add(&chn->buf, len); |
175 | 0 | channel_add_input(chn, len); |
176 | 0 | return len; |
177 | 0 | } |
178 | | |
179 | | /* Locates the longest part of the channel's output buffer that is composed |
180 | | * exclusively of characters not in the <delim> set, and delimited by one of |
181 | | * these characters, and returns the initial part and the first of such |
182 | | * delimiters. A single escape character in <escape> may be specified so that |
183 | | * when not 0 and found, the character that follows it is never taken as a |
184 | | * delimiter. Note that <delim> cannot contain the zero byte, hence this |
185 | | * function is not usable with byte zero as a delimiter. |
186 | | * |
187 | | * Return values : |
188 | | * >0 : number of bytes read. Includes the sep if present before len or end. |
189 | | * =0 : no sep before end found. <str> is left undefined. |
190 | | * <0 : no more bytes readable because output is shut. |
191 | | * The channel status is not changed. The caller must call co_skip() to |
192 | | * update it. One of the delimiters is waited for as long as neither the buffer |
193 | | * nor the output are full. If either of them is full, the string may be |
194 | | * returned as is, without the delimiter. |
195 | | */ |
196 | | int co_getdelim(const struct channel *chn, char *str, int len, const char *delim, char escape) |
197 | 0 | { |
198 | 0 | uchar delim_map[256 / 8]; |
199 | 0 | int found, escaped; |
200 | 0 | uint pos, bit; |
201 | 0 | int ret, max; |
202 | 0 | uchar b; |
203 | 0 | char *p; |
204 | |
|
205 | 0 | ret = 0; |
206 | 0 | max = len; |
207 | | |
208 | | /* closed or empty + imminent close = -1; empty = 0 */ |
209 | 0 | if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) { |
210 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
211 | 0 | ret = -1; |
212 | 0 | goto out; |
213 | 0 | } |
214 | | |
215 | 0 | p = co_head(chn); |
216 | |
|
217 | 0 | if (max > co_data(chn)) { |
218 | 0 | max = co_data(chn); |
219 | 0 | str[max-1] = 0; |
220 | 0 | } |
221 | | |
222 | | /* create the byte map */ |
223 | 0 | memset(delim_map, 0, sizeof(delim_map)); |
224 | 0 | while ((b = *delim)) { |
225 | 0 | pos = b >> 3; |
226 | 0 | bit = b & 7; |
227 | 0 | delim_map[pos] |= 1 << bit; |
228 | 0 | delim++; |
229 | 0 | } |
230 | |
|
231 | 0 | found = escaped = 0; |
232 | 0 | while (max) { |
233 | 0 | *str++ = b = *p; |
234 | 0 | ret++; |
235 | 0 | max--; |
236 | |
|
237 | 0 | if (escape && (escaped || *p == escape)) { |
238 | 0 | escaped = !escaped; |
239 | 0 | goto skip; |
240 | 0 | } |
241 | | |
242 | 0 | pos = b >> 3; |
243 | 0 | bit = b & 7; |
244 | 0 | if (delim_map[pos] & (1 << bit)) { |
245 | 0 | found = 1; |
246 | 0 | break; |
247 | 0 | } |
248 | 0 | skip: |
249 | 0 | p = b_next(&chn->buf, p); |
250 | 0 | } |
251 | | |
252 | 0 | if (ret > 0 && ret < len && |
253 | 0 | (ret < co_data(chn) || channel_may_recv(chn)) && |
254 | 0 | !found && |
255 | 0 | !(chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))) |
256 | 0 | ret = 0; |
257 | 0 | out: |
258 | 0 | if (max) |
259 | 0 | *str = 0; |
260 | 0 | return ret; |
261 | 0 | } |
262 | | |
263 | | /* Gets one text word out of a channel's buffer from a stream connector. |
264 | | * Return values : |
265 | | * >0 : number of bytes read. Includes the sep if present before len or end. |
266 | | * =0 : no sep before end found. <str> is left undefined. |
267 | | * <0 : no more bytes readable because output is shut. |
268 | | * The channel status is not changed. The caller must call co_skip() to |
269 | | * update it. The line separator is waited for as long as neither the buffer |
270 | | * nor the output are full. If either of them is full, the string may be |
271 | | * returned as is, without the line separator. |
272 | | */ |
273 | | int co_getword(const struct channel *chn, char *str, int len, char sep) |
274 | 0 | { |
275 | 0 | int ret, max; |
276 | 0 | char *p; |
277 | |
|
278 | 0 | ret = 0; |
279 | 0 | max = len; |
280 | | |
281 | | /* closed or empty + imminent close = -1; empty = 0 */ |
282 | 0 | if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) { |
283 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
284 | 0 | ret = -1; |
285 | 0 | goto out; |
286 | 0 | } |
287 | | |
288 | 0 | p = co_head(chn); |
289 | |
|
290 | 0 | if (max > co_data(chn)) { |
291 | 0 | max = co_data(chn); |
292 | 0 | str[max-1] = 0; |
293 | 0 | } |
294 | 0 | while (max) { |
295 | 0 | *str++ = *p; |
296 | 0 | ret++; |
297 | 0 | max--; |
298 | |
|
299 | 0 | if (*p == sep) |
300 | 0 | break; |
301 | 0 | p = b_next(&chn->buf, p); |
302 | 0 | } |
303 | 0 | if (ret > 0 && ret < len && |
304 | 0 | (ret < co_data(chn) || channel_may_recv(chn)) && |
305 | 0 | *(str-1) != sep && |
306 | 0 | !(chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))) |
307 | 0 | ret = 0; |
308 | 0 | out: |
309 | 0 | if (max) |
310 | 0 | *str = 0; |
311 | 0 | return ret; |
312 | 0 | } |
313 | | |
314 | | /* Gets one text line out of a channel's buffer from a stream connector. |
315 | | * Return values : |
316 | | * >0 : number of bytes read. Includes the \n if present before len or end. |
317 | | * =0 : no '\n' before end found. <str> is left undefined. |
318 | | * <0 : no more bytes readable because output is shut. |
319 | | * The channel status is not changed. The caller must call co_skip() to |
320 | | * update it. The '\n' is waited for as long as neither the buffer nor the |
321 | | * output are full. If either of them is full, the string may be returned |
322 | | * as is, without the '\n'. |
323 | | */ |
324 | | int co_getline(const struct channel *chn, char *str, int len) |
325 | 0 | { |
326 | 0 | int ret, max; |
327 | 0 | size_t ofs; |
328 | |
|
329 | 0 | ret = 0; |
330 | 0 | max = len; |
331 | | |
332 | | /* closed or empty + imminent close = -1; empty = 0 */ |
333 | 0 | if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) { |
334 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
335 | 0 | ret = -1; |
336 | 0 | goto out; |
337 | 0 | } |
338 | | |
339 | 0 | if (max > co_data(chn)) { |
340 | 0 | max = co_data(chn); |
341 | 0 | str[max-1] = 0; |
342 | 0 | } |
343 | |
|
344 | 0 | ofs = 0; |
345 | |
|
346 | 0 | while (max) { |
347 | 0 | size_t contig = b_contig_data(&chn->buf, ofs); |
348 | 0 | size_t len = MIN(max, contig); |
349 | 0 | const char *beg = b_peek(&chn->buf, ofs); |
350 | 0 | const char *lf = memchr(beg, '\n', len); |
351 | |
|
352 | 0 | if (lf) /* take the LF with it before stopping */ |
353 | 0 | len = lf + 1 - beg; |
354 | |
|
355 | 0 | memcpy(str, beg, len); |
356 | 0 | ret += len; |
357 | 0 | str += len; |
358 | 0 | ofs += len; |
359 | 0 | max -= len; |
360 | |
|
361 | 0 | if (lf) |
362 | 0 | break; |
363 | 0 | } |
364 | 0 | if (ret > 0 && ret < len && |
365 | 0 | (ret < co_data(chn) || channel_may_recv(chn)) && |
366 | 0 | *(str-1) != '\n' && |
367 | 0 | !(chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))) |
368 | 0 | ret = 0; |
369 | 0 | out: |
370 | 0 | if (max) |
371 | 0 | *str = 0; |
372 | 0 | return ret; |
373 | 0 | } |
374 | | |
375 | | /* Gets one char of data from a channel's buffer, |
376 | | * Return values : |
377 | | * 1 : number of bytes read, equal to requested size. |
378 | | * =0 : not enough data available. <c> is left undefined. |
379 | | * <0 : no more bytes readable because output is shut. |
380 | | * The channel status is not changed. The caller must call co_skip() to |
381 | | * update it. |
382 | | */ |
383 | | int co_getchar(const struct channel *chn, char *c) |
384 | 0 | { |
385 | 0 | if (chn_cons(chn)->flags & SC_FL_SHUT_DONE) |
386 | 0 | return -1; |
387 | | |
388 | 0 | if (unlikely(co_data(chn) == 0)) { |
389 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
390 | 0 | return -1; |
391 | 0 | return 0; |
392 | 0 | } |
393 | | |
394 | 0 | *c = *(co_head(chn)); |
395 | 0 | return 1; |
396 | 0 | } |
397 | | |
398 | | /* Gets one full block of data at once from a channel's buffer, optionally from |
399 | | * a specific offset. Return values : |
400 | | * >0 : number of bytes read, equal to requested size. |
401 | | * =0 : not enough data available. <blk> is left undefined. |
402 | | * <0 : no more bytes readable because output is shut. |
403 | | * The channel status is not changed. The caller must call co_skip() to |
404 | | * update it. |
405 | | */ |
406 | | int co_getblk(const struct channel *chn, char *blk, int len, int offset) |
407 | 0 | { |
408 | 0 | if (chn_cons(chn)->flags & SC_FL_SHUT_DONE) |
409 | 0 | return -1; |
410 | | |
411 | 0 | if (len + offset > co_data(chn) || co_data(chn) == 0) { |
412 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
413 | 0 | return -1; |
414 | 0 | return 0; |
415 | 0 | } |
416 | | |
417 | 0 | return b_getblk(&chn->buf, blk, len, offset); |
418 | 0 | } |
419 | | |
420 | | /* Gets one or two blocks of data at once from a channel's output buffer. |
421 | | * Return values : |
422 | | * >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2. |
423 | | * =0 : not enough data available. <blk*> are left undefined. |
424 | | * <0 : no more bytes readable because output is shut. |
425 | | * The channel status is not changed. The caller must call co_skip() to |
426 | | * update it. Unused buffers are left in an undefined state. |
427 | | */ |
428 | | int co_getblk_nc(const struct channel *chn, const char **blk1, size_t *len1, const char **blk2, size_t *len2) |
429 | 0 | { |
430 | 0 | if (unlikely(co_data(chn) == 0)) { |
431 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
432 | 0 | return -1; |
433 | 0 | return 0; |
434 | 0 | } |
435 | | |
436 | 0 | return b_getblk_nc(&chn->buf, blk1, len1, blk2, len2, 0, co_data(chn)); |
437 | 0 | } |
438 | | |
439 | | /* Gets one text line out of a channel's output buffer from a stream connector. |
440 | | * Return values : |
441 | | * >0 : number of blocks returned (1 or 2). blk1 is always filled before blk2. |
442 | | * =0 : not enough data available. |
443 | | * <0 : no more bytes readable because output is shut. |
444 | | * The '\n' is waited for as long as neither the buffer nor the output are |
445 | | * full. If either of them is full, the string may be returned as is, without |
446 | | * the '\n'. Unused buffers are left in an undefined state. |
447 | | */ |
448 | | int co_getline_nc(const struct channel *chn, |
449 | | const char **blk1, size_t *len1, |
450 | | const char **blk2, size_t *len2) |
451 | 0 | { |
452 | 0 | int retcode; |
453 | 0 | int l; |
454 | |
|
455 | 0 | retcode = co_getblk_nc(chn, blk1, len1, blk2, len2); |
456 | 0 | if (unlikely(retcode <= 0)) |
457 | 0 | return retcode; |
458 | | |
459 | 0 | for (l = 0; l < *len1 && (*blk1)[l] != '\n'; l++); |
460 | 0 | if (l < *len1 && (*blk1)[l] == '\n') { |
461 | 0 | *len1 = l + 1; |
462 | 0 | return 1; |
463 | 0 | } |
464 | | |
465 | 0 | if (retcode >= 2) { |
466 | 0 | for (l = 0; l < *len2 && (*blk2)[l] != '\n'; l++); |
467 | 0 | if (l < *len2 && (*blk2)[l] == '\n') { |
468 | 0 | *len2 = l + 1; |
469 | 0 | return 2; |
470 | 0 | } |
471 | 0 | } |
472 | | |
473 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) { |
474 | | /* If we have found no LF and the buffer is shut, then |
475 | | * the resulting string is made of the concatenation of |
476 | | * the pending blocks (1 or 2). |
477 | | */ |
478 | 0 | return retcode; |
479 | 0 | } |
480 | | |
481 | | /* No LF yet and not shut yet */ |
482 | 0 | return 0; |
483 | 0 | } |
484 | | |
485 | | /* Gets one full block of data at once from a channel's input buffer. |
486 | | * This function can return the data slitted in one or two blocks. |
487 | | * Return values : |
488 | | * >0 : number of blocks returned (1 or 2). blk1 is always filled before blk2. |
489 | | * =0 : not enough data available. |
490 | | * <0 : no more bytes readable because input is shut. |
491 | | */ |
492 | | int ci_getblk_nc(const struct channel *chn, |
493 | | char **blk1, size_t *len1, |
494 | | char **blk2, size_t *len2) |
495 | 0 | { |
496 | 0 | if (unlikely(ci_data(chn) == 0)) { |
497 | 0 | if (chn_prod(chn)->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) |
498 | 0 | return -1; |
499 | 0 | return 0; |
500 | 0 | } |
501 | | |
502 | 0 | if (unlikely(ci_head(chn) + ci_data(chn) > c_wrap(chn))) { |
503 | 0 | *blk1 = ci_head(chn); |
504 | 0 | *len1 = c_wrap(chn) - ci_head(chn); |
505 | 0 | *blk2 = c_orig(chn); |
506 | 0 | *len2 = ci_data(chn) - *len1; |
507 | 0 | return 2; |
508 | 0 | } |
509 | | |
510 | 0 | *blk1 = ci_head(chn); |
511 | 0 | *len1 = ci_data(chn); |
512 | 0 | return 1; |
513 | 0 | } |
514 | | |
515 | | /* Gets one text line out of a channel's input buffer from a stream connector. |
516 | | * Return values : |
517 | | * >0 : number of blocks returned (1 or 2). blk1 is always filled before blk2. |
518 | | * =0 : not enough data available. |
519 | | * <0 : no more bytes readable because output is shut. |
520 | | * The '\n' is waited for as long as neither the buffer nor the input are |
521 | | * full. If either of them is full, the string may be returned as is, without |
522 | | * the '\n'. Unused buffers are left in an undefined state. |
523 | | */ |
524 | | int ci_getline_nc(const struct channel *chn, |
525 | | char **blk1, size_t *len1, |
526 | | char **blk2, size_t *len2) |
527 | 0 | { |
528 | 0 | int retcode; |
529 | 0 | int l; |
530 | |
|
531 | 0 | retcode = ci_getblk_nc(chn, blk1, len1, blk2, len2); |
532 | 0 | if (unlikely(retcode <= 0)) |
533 | 0 | return retcode; |
534 | | |
535 | 0 | for (l = 0; l < *len1 && (*blk1)[l] != '\n'; l++); |
536 | 0 | if (l < *len1 && (*blk1)[l] == '\n') { |
537 | 0 | *len1 = l + 1; |
538 | 0 | return 1; |
539 | 0 | } |
540 | | |
541 | 0 | if (retcode >= 2) { |
542 | 0 | for (l = 0; l < *len2 && (*blk2)[l] != '\n'; l++); |
543 | 0 | if (l < *len2 && (*blk2)[l] == '\n') { |
544 | 0 | *len2 = l + 1; |
545 | 0 | return 2; |
546 | 0 | } |
547 | 0 | } |
548 | | |
549 | 0 | if (chn_cons(chn)->flags & SC_FL_SHUT_DONE) { |
550 | | /* If we have found no LF and the buffer is shut, then |
551 | | * the resulting string is made of the concatenation of |
552 | | * the pending blocks (1 or 2). |
553 | | */ |
554 | 0 | return retcode; |
555 | 0 | } |
556 | | |
557 | | /* No LF yet and not shut yet */ |
558 | 0 | return 0; |
559 | 0 | } |
560 | | |
561 | | /* Inserts <str> at position <pos> relative to channel <c>'s * input head. The |
562 | | * <len> argument informs about the length of string <str> so that we don't have |
563 | | * to measure it. <str> must be a valid pointer. |
564 | | * |
565 | | * The number of bytes added is returned on success. 0 is returned on failure. |
566 | | */ |
567 | | int ci_insert(struct channel *c, int pos, const char *str, int len) |
568 | 0 | { |
569 | 0 | struct buffer *b = &c->buf; |
570 | 0 | char *dst = c_ptr(c, pos); |
571 | |
|
572 | 0 | if (__b_tail(b) + len >= b_wrap(b)) |
573 | 0 | return 0; /* no space left */ |
574 | | |
575 | 0 | if (b_data(b) && |
576 | 0 | b_tail(b) + len > b_head(b) && |
577 | 0 | b_head(b) >= b_tail(b)) |
578 | 0 | return 0; /* no space left before wrapping data */ |
579 | | |
580 | | /* first, protect the end of the buffer */ |
581 | 0 | memmove(dst + len, dst, b_tail(b) - dst); |
582 | | |
583 | | /* now, copy str over dst */ |
584 | 0 | memcpy(dst, str, len); |
585 | |
|
586 | 0 | b_add(b, len); |
587 | 0 | return len; |
588 | 0 | } |
589 | | |
590 | | |
591 | | /* Inserts <str> followed by "\r\n" at position <pos> relative to channel <c>'s |
592 | | * input head. The <len> argument informs about the length of string <str> so |
593 | | * that we don't have to measure it. <str> must be a valid pointer and must not |
594 | | * include the trailing "\r\n". |
595 | | * |
596 | | * The number of bytes added is returned on success. 0 is returned on failure. |
597 | | */ |
598 | | int ci_insert_line2(struct channel *c, int pos, const char *str, int len) |
599 | 0 | { |
600 | 0 | struct buffer *b = &c->buf; |
601 | 0 | char *dst = c_ptr(c, pos); |
602 | 0 | int delta; |
603 | |
|
604 | 0 | delta = len + 2; |
605 | |
|
606 | 0 | if (__b_tail(b) + delta >= b_wrap(b)) |
607 | 0 | return 0; /* no space left */ |
608 | | |
609 | 0 | if (b_data(b) && |
610 | 0 | b_tail(b) + delta > b_head(b) && |
611 | 0 | b_head(b) >= b_tail(b)) |
612 | 0 | return 0; /* no space left before wrapping data */ |
613 | | |
614 | | /* first, protect the end of the buffer */ |
615 | 0 | memmove(dst + delta, dst, b_tail(b) - dst); |
616 | | |
617 | | /* now, copy str over dst */ |
618 | 0 | memcpy(dst, str, len); |
619 | 0 | dst[len] = '\r'; |
620 | 0 | dst[len + 1] = '\n'; |
621 | |
|
622 | 0 | b_add(b, delta); |
623 | 0 | return delta; |
624 | 0 | } |
625 | | |
626 | | /* |
627 | | * Local variables: |
628 | | * c-indent-level: 8 |
629 | | * c-basic-offset: 8 |
630 | | * End: |
631 | | */ |