/src/haproxy/src/channel.c
Line | Count | Source |
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 stays 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 | return -1; |
102 | 0 | } |
103 | | |
104 | | /* Tries to copy character <c> into the channel's buffer after some length |
105 | | * controls. The chn->o and to_forward pointers are updated. If the channel |
106 | | * input is closed, -2 is returned. If there is not enough room left in the |
107 | | * buffer, -1 is returned. Otherwise the number of bytes copied is returned |
108 | | * (1). Channel flag CF_READ_EVENT is set if some data can be transferred. |
109 | | */ |
110 | | int ci_putchr(struct channel *chn, char c) |
111 | 0 | { |
112 | 0 | if (unlikely(channel_input_closed(chn))) |
113 | 0 | return -2; |
114 | | |
115 | 0 | if (!channel_may_recv(chn)) |
116 | 0 | return -1; |
117 | | |
118 | 0 | *ci_tail(chn) = c; |
119 | |
|
120 | 0 | b_add(&chn->buf, 1); |
121 | 0 | chn->flags |= CF_READ_EVENT; |
122 | |
|
123 | 0 | if (chn->to_forward >= 1) { |
124 | 0 | if (chn->to_forward != CHN_INFINITE_FORWARD) |
125 | 0 | chn->to_forward--; |
126 | 0 | c_adv(chn, 1); |
127 | 0 | } |
128 | |
|
129 | 0 | return 1; |
130 | 0 | } |
131 | | |
132 | | /* Tries to copy block <blk> at once into the channel's buffer after length |
133 | | * controls. The chn->o and to_forward pointers are updated. If the channel |
134 | | * input is closed, -2 is returned. If the block is too large for this buffer, |
135 | | * -3 is returned. If there is not enough room left in the buffer, -1 is |
136 | | * returned. Otherwise the number of bytes copied is returned (0 being a valid |
137 | | * number). Channel flag CF_READ_EVENT is set if some data can be |
138 | | * transferred. |
139 | | */ |
140 | | int ci_putblk(struct channel *chn, const char *blk, int len) |
141 | 0 | { |
142 | 0 | int max; |
143 | |
|
144 | 0 | if (unlikely(channel_input_closed(chn))) |
145 | 0 | return -2; |
146 | | |
147 | 0 | if (len < 0) |
148 | 0 | return -3; |
149 | | |
150 | 0 | max = channel_recv_limit(chn); |
151 | 0 | if (unlikely(len > max - c_data(chn))) { |
152 | | /* we can't write this chunk right now because the buffer is |
153 | | * almost full or because the block is too large. Returns |
154 | | * -3 if block is too large for this buffer. Or -1 if the |
155 | | * room left is not large enough. |
156 | | */ |
157 | 0 | if (len > max) |
158 | 0 | return -3; |
159 | | |
160 | 0 | return -1; |
161 | 0 | } |
162 | | |
163 | 0 | if (unlikely(len == 0)) |
164 | 0 | return 0; |
165 | | |
166 | | /* OK so the data fits in the buffer in one or two blocks */ |
167 | 0 | max = b_contig_space(&chn->buf); |
168 | 0 | memcpy(ci_tail(chn), blk, MIN(len, max)); |
169 | 0 | if (len > max) |
170 | 0 | memcpy(c_orig(chn), blk + max, len - max); |
171 | |
|
172 | 0 | b_add(&chn->buf, len); |
173 | 0 | channel_add_input(chn, len); |
174 | 0 | return len; |
175 | 0 | } |
176 | | |
177 | | /* Locates the longest part of the channel's output buffer that is composed |
178 | | * exclusively of characters not in the <delim> set, and delimited by one of |
179 | | * these characters, and returns the initial part and the first of such |
180 | | * delimiters. A single escape character in <escape> may be specified so that |
181 | | * when not 0 and found, the character that follows it is never taken as a |
182 | | * delimiter. Note that <delim> cannot contain the zero byte, hence this |
183 | | * function is not usable with byte zero as a delimiter. |
184 | | * |
185 | | * Return values : |
186 | | * >0 : number of bytes read. Includes the sep if present before len or end. |
187 | | * =0 : no sep before end found. <str> is left undefined. |
188 | | * <0 : no more bytes readable because output is shut. |
189 | | * The channel status is not changed. The caller must call co_skip() to |
190 | | * update it. One of the delimiters is waited for as long as neither the buffer |
191 | | * nor the output are full. If either of them is full, the string may be |
192 | | * returned as is, without the delimiter. |
193 | | */ |
194 | | int co_getdelim(const struct channel *chn, char *str, int len, const char *delim, char escape) |
195 | 0 | { |
196 | 0 | uchar delim_map[256 / 8]; |
197 | 0 | int found, escaped; |
198 | 0 | uint pos, bit; |
199 | 0 | int ret, max; |
200 | 0 | uchar b; |
201 | 0 | char *p; |
202 | |
|
203 | 0 | ret = 0; |
204 | 0 | max = len; |
205 | | |
206 | | /* closed or empty + imminent close = -1; empty = 0 */ |
207 | 0 | if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) { |
208 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
209 | 0 | ret = -1; |
210 | 0 | goto out; |
211 | 0 | } |
212 | | |
213 | 0 | p = co_head(chn); |
214 | |
|
215 | 0 | if (max > co_data(chn)) { |
216 | 0 | max = co_data(chn); |
217 | 0 | str[max-1] = 0; |
218 | 0 | } |
219 | | |
220 | | /* create the byte map */ |
221 | 0 | memset(delim_map, 0, sizeof(delim_map)); |
222 | 0 | while ((b = *delim)) { |
223 | 0 | pos = b >> 3; |
224 | 0 | bit = b & 7; |
225 | 0 | delim_map[pos] |= 1 << bit; |
226 | 0 | delim++; |
227 | 0 | } |
228 | |
|
229 | 0 | found = escaped = 0; |
230 | 0 | while (max) { |
231 | 0 | *str++ = b = *p; |
232 | 0 | ret++; |
233 | 0 | max--; |
234 | |
|
235 | 0 | if (escape && (escaped || *p == escape)) { |
236 | 0 | escaped = !escaped; |
237 | 0 | goto skip; |
238 | 0 | } |
239 | | |
240 | 0 | pos = b >> 3; |
241 | 0 | bit = b & 7; |
242 | 0 | if (delim_map[pos] & (1 << bit)) { |
243 | 0 | found = 1; |
244 | 0 | break; |
245 | 0 | } |
246 | 0 | skip: |
247 | 0 | p = b_next(&chn->buf, p); |
248 | 0 | } |
249 | | |
250 | 0 | if (ret > 0 && ret < len && |
251 | 0 | (ret < co_data(chn) || channel_may_recv(chn)) && |
252 | 0 | !found && |
253 | 0 | !(chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))) |
254 | 0 | ret = 0; |
255 | 0 | out: |
256 | 0 | if (max) |
257 | 0 | *str = 0; |
258 | 0 | return ret; |
259 | 0 | } |
260 | | |
261 | | /* Gets one text word out of a channel's buffer from a stream connector. |
262 | | * Return values : |
263 | | * >0 : number of bytes read. Includes the sep if present before len or end. |
264 | | * =0 : no sep before end found. <str> is left undefined. |
265 | | * <0 : no more bytes readable because output is shut. |
266 | | * The channel status is not changed. The caller must call co_skip() to |
267 | | * update it. The line separator is waited for as long as neither the buffer |
268 | | * nor the output are full. If either of them is full, the string may be |
269 | | * returned as is, without the line separator. |
270 | | */ |
271 | | int co_getword(const struct channel *chn, char *str, int len, char sep) |
272 | 0 | { |
273 | 0 | int ret, max; |
274 | 0 | char *p; |
275 | |
|
276 | 0 | ret = 0; |
277 | 0 | max = len; |
278 | | |
279 | | /* closed or empty + imminent close = -1; empty = 0 */ |
280 | 0 | if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) { |
281 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
282 | 0 | ret = -1; |
283 | 0 | goto out; |
284 | 0 | } |
285 | | |
286 | 0 | p = co_head(chn); |
287 | |
|
288 | 0 | if (max > co_data(chn)) { |
289 | 0 | max = co_data(chn); |
290 | 0 | str[max-1] = 0; |
291 | 0 | } |
292 | 0 | while (max) { |
293 | 0 | *str++ = *p; |
294 | 0 | ret++; |
295 | 0 | max--; |
296 | |
|
297 | 0 | if (*p == sep) |
298 | 0 | break; |
299 | 0 | p = b_next(&chn->buf, p); |
300 | 0 | } |
301 | 0 | if (ret > 0 && ret < len && |
302 | 0 | (ret < co_data(chn) || channel_may_recv(chn)) && |
303 | 0 | *(str-1) != sep && |
304 | 0 | !(chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))) |
305 | 0 | ret = 0; |
306 | 0 | out: |
307 | 0 | if (max) |
308 | 0 | *str = 0; |
309 | 0 | return ret; |
310 | 0 | } |
311 | | |
312 | | /* Gets one text line out of a channel's buffer from a stream connector. |
313 | | * Return values : |
314 | | * >0 : number of bytes read. Includes the \n if present before len or end. |
315 | | * =0 : no '\n' before end found. <str> is left undefined. |
316 | | * <0 : no more bytes readable because output is shut. |
317 | | * The channel status is not changed. The caller must call co_skip() to |
318 | | * update it. The '\n' is waited for as long as neither the buffer nor the |
319 | | * output are full. If either of them is full, the string may be returned |
320 | | * as is, without the '\n'. |
321 | | */ |
322 | | int co_getline(const struct channel *chn, char *str, int len) |
323 | 0 | { |
324 | 0 | int ret, max; |
325 | 0 | size_t ofs; |
326 | |
|
327 | 0 | ret = 0; |
328 | 0 | max = len; |
329 | | |
330 | | /* closed or empty + imminent close = -1; empty = 0 */ |
331 | 0 | if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) { |
332 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
333 | 0 | ret = -1; |
334 | 0 | goto out; |
335 | 0 | } |
336 | | |
337 | 0 | if (max > co_data(chn)) { |
338 | 0 | max = co_data(chn); |
339 | 0 | str[max-1] = 0; |
340 | 0 | } |
341 | |
|
342 | 0 | ofs = 0; |
343 | |
|
344 | 0 | while (max) { |
345 | 0 | size_t contig = b_contig_data(&chn->buf, ofs); |
346 | 0 | size_t len = MIN(max, contig); |
347 | 0 | const char *beg = b_peek(&chn->buf, ofs); |
348 | 0 | const char *lf = memchr(beg, '\n', len); |
349 | |
|
350 | 0 | if (lf) /* take the LF with it before stopping */ |
351 | 0 | len = lf + 1 - beg; |
352 | |
|
353 | 0 | memcpy(str, beg, len); |
354 | 0 | ret += len; |
355 | 0 | str += len; |
356 | 0 | ofs += len; |
357 | 0 | max -= len; |
358 | |
|
359 | 0 | if (lf) |
360 | 0 | break; |
361 | 0 | } |
362 | 0 | if (ret > 0 && ret < len && |
363 | 0 | (ret < co_data(chn) || channel_may_recv(chn)) && |
364 | 0 | *(str-1) != '\n' && |
365 | 0 | !(chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))) |
366 | 0 | ret = 0; |
367 | 0 | out: |
368 | 0 | if (max) |
369 | 0 | *str = 0; |
370 | 0 | return ret; |
371 | 0 | } |
372 | | |
373 | | /* Gets one char of data from a channel's buffer, |
374 | | * Return values : |
375 | | * 1 : number of bytes read, equal to requested size. |
376 | | * =0 : not enough data available. <c> is left undefined. |
377 | | * <0 : no more bytes readable because output is shut. |
378 | | * The channel status is not changed. The caller must call co_skip() to |
379 | | * update it. |
380 | | */ |
381 | | int co_getchar(const struct channel *chn, char *c) |
382 | 0 | { |
383 | 0 | if (chn_cons(chn)->flags & SC_FL_SHUT_DONE) |
384 | 0 | return -1; |
385 | | |
386 | 0 | if (unlikely(co_data(chn) == 0)) { |
387 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
388 | 0 | return -1; |
389 | 0 | return 0; |
390 | 0 | } |
391 | | |
392 | 0 | *c = *(co_head(chn)); |
393 | 0 | return 1; |
394 | 0 | } |
395 | | |
396 | | /* Gets one full block of data at once from a channel's buffer, optionally from |
397 | | * a specific offset. Return values : |
398 | | * >0 : number of bytes read, equal to requested size. |
399 | | * =0 : not enough data available. <blk> is left undefined. |
400 | | * <0 : no more bytes readable because output is shut. |
401 | | * The channel status is not changed. The caller must call co_skip() to |
402 | | * update it. |
403 | | */ |
404 | | int co_getblk(const struct channel *chn, char *blk, int len, int offset) |
405 | 0 | { |
406 | 0 | if (chn_cons(chn)->flags & SC_FL_SHUT_DONE) |
407 | 0 | return -1; |
408 | | |
409 | 0 | if (len + offset > co_data(chn) || co_data(chn) == 0) { |
410 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
411 | 0 | return -1; |
412 | 0 | return 0; |
413 | 0 | } |
414 | | |
415 | 0 | return b_getblk(&chn->buf, blk, len, offset); |
416 | 0 | } |
417 | | |
418 | | /* Gets one or two blocks of data at once from a channel's output buffer. |
419 | | * Return values : |
420 | | * >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2. |
421 | | * =0 : not enough data available. <blk*> are left undefined. |
422 | | * <0 : no more bytes readable because output is shut. |
423 | | * The channel status is not changed. The caller must call co_skip() to |
424 | | * update it. Unused buffers are left in an undefined state. |
425 | | */ |
426 | | int co_getblk_nc(const struct channel *chn, const char **blk1, size_t *len1, const char **blk2, size_t *len2) |
427 | 0 | { |
428 | 0 | if (unlikely(co_data(chn) == 0)) { |
429 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) |
430 | 0 | return -1; |
431 | 0 | return 0; |
432 | 0 | } |
433 | | |
434 | 0 | return b_getblk_nc(&chn->buf, blk1, len1, blk2, len2, 0, co_data(chn)); |
435 | 0 | } |
436 | | |
437 | | /* Gets one text line out of a channel's output buffer from a stream connector. |
438 | | * Return values : |
439 | | * >0 : number of blocks returned (1 or 2). blk1 is always filled before blk2. |
440 | | * =0 : not enough data available. |
441 | | * <0 : no more bytes readable because output is shut. |
442 | | * The '\n' is waited for as long as neither the buffer nor the output are |
443 | | * full. If either of them is full, the string may be returned as is, without |
444 | | * the '\n'. Unused buffers are left in an undefined state. |
445 | | */ |
446 | | int co_getline_nc(const struct channel *chn, |
447 | | const char **blk1, size_t *len1, |
448 | | const char **blk2, size_t *len2) |
449 | 0 | { |
450 | 0 | int retcode; |
451 | 0 | int l; |
452 | |
|
453 | 0 | retcode = co_getblk_nc(chn, blk1, len1, blk2, len2); |
454 | 0 | if (unlikely(retcode <= 0)) |
455 | 0 | return retcode; |
456 | | |
457 | 0 | for (l = 0; l < *len1 && (*blk1)[l] != '\n'; l++); |
458 | 0 | if (l < *len1 && (*blk1)[l] == '\n') { |
459 | 0 | *len1 = l + 1; |
460 | 0 | return 1; |
461 | 0 | } |
462 | | |
463 | 0 | if (retcode >= 2) { |
464 | 0 | for (l = 0; l < *len2 && (*blk2)[l] != '\n'; l++); |
465 | 0 | if (l < *len2 && (*blk2)[l] == '\n') { |
466 | 0 | *len2 = l + 1; |
467 | 0 | return 2; |
468 | 0 | } |
469 | 0 | } |
470 | | |
471 | 0 | if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) { |
472 | | /* If we have found no LF and the buffer is shut, then |
473 | | * the resulting string is made of the concatenation of |
474 | | * the pending blocks (1 or 2). |
475 | | */ |
476 | 0 | return retcode; |
477 | 0 | } |
478 | | |
479 | | /* No LF yet and not shut yet */ |
480 | 0 | return 0; |
481 | 0 | } |
482 | | |
483 | | /* Gets one full block of data at once from a channel's input buffer. |
484 | | * This function can return the data slitted in one or two blocks. |
485 | | * Return values : |
486 | | * >0 : number of blocks returned (1 or 2). blk1 is always filled before blk2. |
487 | | * =0 : not enough data available. |
488 | | * <0 : no more bytes readable because input is shut. |
489 | | */ |
490 | | int ci_getblk_nc(const struct channel *chn, |
491 | | char **blk1, size_t *len1, |
492 | | char **blk2, size_t *len2) |
493 | 0 | { |
494 | 0 | if (unlikely(ci_data(chn) == 0)) { |
495 | 0 | if (chn_prod(chn)->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) |
496 | 0 | return -1; |
497 | 0 | return 0; |
498 | 0 | } |
499 | | |
500 | 0 | if (unlikely(ci_head(chn) + ci_data(chn) > c_wrap(chn))) { |
501 | 0 | *blk1 = ci_head(chn); |
502 | 0 | *len1 = c_wrap(chn) - ci_head(chn); |
503 | 0 | *blk2 = c_orig(chn); |
504 | 0 | *len2 = ci_data(chn) - *len1; |
505 | 0 | return 2; |
506 | 0 | } |
507 | | |
508 | 0 | *blk1 = ci_head(chn); |
509 | 0 | *len1 = ci_data(chn); |
510 | 0 | return 1; |
511 | 0 | } |
512 | | |
513 | | /* Gets one text line out of a channel's input buffer from a stream connector. |
514 | | * Return values : |
515 | | * >0 : number of blocks returned (1 or 2). blk1 is always filled before blk2. |
516 | | * =0 : not enough data available. |
517 | | * <0 : no more bytes readable because output is shut. |
518 | | * The '\n' is waited for as long as neither the buffer nor the input are |
519 | | * full. If either of them is full, the string may be returned as is, without |
520 | | * the '\n'. Unused buffers are left in an undefined state. |
521 | | */ |
522 | | int ci_getline_nc(const struct channel *chn, |
523 | | char **blk1, size_t *len1, |
524 | | char **blk2, size_t *len2) |
525 | 0 | { |
526 | 0 | int retcode; |
527 | 0 | int l; |
528 | |
|
529 | 0 | retcode = ci_getblk_nc(chn, blk1, len1, blk2, len2); |
530 | 0 | if (unlikely(retcode <= 0)) |
531 | 0 | return retcode; |
532 | | |
533 | 0 | for (l = 0; l < *len1 && (*blk1)[l] != '\n'; l++); |
534 | 0 | if (l < *len1 && (*blk1)[l] == '\n') { |
535 | 0 | *len1 = l + 1; |
536 | 0 | return 1; |
537 | 0 | } |
538 | | |
539 | 0 | if (retcode >= 2) { |
540 | 0 | for (l = 0; l < *len2 && (*blk2)[l] != '\n'; l++); |
541 | 0 | if (l < *len2 && (*blk2)[l] == '\n') { |
542 | 0 | *len2 = l + 1; |
543 | 0 | return 2; |
544 | 0 | } |
545 | 0 | } |
546 | | |
547 | 0 | if (chn_cons(chn)->flags & SC_FL_SHUT_DONE) { |
548 | | /* If we have found no LF and the buffer is shut, then |
549 | | * the resulting string is made of the concatenation of |
550 | | * the pending blocks (1 or 2). |
551 | | */ |
552 | 0 | return retcode; |
553 | 0 | } |
554 | | |
555 | | /* No LF yet and not shut yet */ |
556 | 0 | return 0; |
557 | 0 | } |
558 | | |
559 | | /* Inserts <str> at position <pos> relative to channel <c>'s * input head. The |
560 | | * <len> argument informs about the length of string <str> so that we don't have |
561 | | * to measure it. <str> must be a valid pointer. |
562 | | * |
563 | | * The number of bytes added is returned on success. 0 is returned on failure. |
564 | | */ |
565 | | int ci_insert(struct channel *c, int pos, const char *str, int len) |
566 | 0 | { |
567 | 0 | struct buffer *b = &c->buf; |
568 | 0 | char *dst = c_ptr(c, pos); |
569 | |
|
570 | 0 | if (__b_tail(b) + len >= b_wrap(b)) |
571 | 0 | return 0; /* no space left */ |
572 | | |
573 | 0 | if (b_data(b) && |
574 | 0 | b_tail(b) + len > b_head(b) && |
575 | 0 | b_head(b) >= b_tail(b)) |
576 | 0 | return 0; /* no space left before wrapping data */ |
577 | | |
578 | | /* first, protect the end of the buffer */ |
579 | 0 | memmove(dst + len, dst, b_tail(b) - dst); |
580 | | |
581 | | /* now, copy str over dst */ |
582 | 0 | memcpy(dst, str, len); |
583 | |
|
584 | 0 | b_add(b, len); |
585 | 0 | return len; |
586 | 0 | } |
587 | | |
588 | | |
589 | | /* Inserts <str> followed by "\r\n" at position <pos> relative to channel <c>'s |
590 | | * input head. The <len> argument informs about the length of string <str> so |
591 | | * that we don't have to measure it. <str> must be a valid pointer and must not |
592 | | * include the trailing "\r\n". |
593 | | * |
594 | | * The number of bytes added is returned on success. 0 is returned on failure. |
595 | | */ |
596 | | int ci_insert_line2(struct channel *c, int pos, const char *str, int len) |
597 | 0 | { |
598 | 0 | struct buffer *b = &c->buf; |
599 | 0 | char *dst = c_ptr(c, pos); |
600 | 0 | int delta; |
601 | |
|
602 | 0 | delta = len + 2; |
603 | |
|
604 | 0 | if (__b_tail(b) + delta >= b_wrap(b)) |
605 | 0 | return 0; /* no space left */ |
606 | | |
607 | 0 | if (b_data(b) && |
608 | 0 | b_tail(b) + delta > b_head(b) && |
609 | 0 | b_head(b) >= b_tail(b)) |
610 | 0 | return 0; /* no space left before wrapping data */ |
611 | | |
612 | | /* first, protect the end of the buffer */ |
613 | 0 | memmove(dst + delta, dst, b_tail(b) - dst); |
614 | | |
615 | | /* now, copy str over dst */ |
616 | 0 | memcpy(dst, str, len); |
617 | 0 | dst[len] = '\r'; |
618 | 0 | dst[len + 1] = '\n'; |
619 | |
|
620 | 0 | b_add(b, delta); |
621 | 0 | return delta; |
622 | 0 | } |
623 | | |
624 | | /* |
625 | | * Local variables: |
626 | | * c-indent-level: 8 |
627 | | * c-basic-offset: 8 |
628 | | * End: |
629 | | */ |