40 |
|
#define READBUF_SIZE 16384 |
41 |
|
|
42 |
|
struct Callback *iorecv_cb = NULL; |
43 |
– |
struct Callback *iorecvctrl_cb = NULL; |
43 |
|
|
44 |
|
static char readBuf[READBUF_SIZE]; |
45 |
|
static void client_dopacket(struct Client *, char *, size_t); |
271 |
|
} |
272 |
|
|
273 |
|
/* |
275 |
– |
* read_ctrl_packet - Read a 'packet' of data from a servlink control |
276 |
– |
* link and process it. |
277 |
– |
*/ |
278 |
– |
void |
279 |
– |
read_ctrl_packet(fde_t *fd, void *data) |
280 |
– |
{ |
281 |
– |
struct Client *server = data; |
282 |
– |
struct LocalUser *lserver = server->localClient; |
283 |
– |
struct SlinkRpl *reply; |
284 |
– |
int length = 0; |
285 |
– |
unsigned char tmp[2]; |
286 |
– |
unsigned char *len = tmp; |
287 |
– |
struct SlinkRplDef *replydef; |
288 |
– |
|
289 |
– |
assert(lserver != NULL); |
290 |
– |
|
291 |
– |
reply = &lserver->slinkrpl; |
292 |
– |
|
293 |
– |
if (IsDefunct(server)) |
294 |
– |
return; |
295 |
– |
|
296 |
– |
if (!reply->command) |
297 |
– |
{ |
298 |
– |
reply->gotdatalen = 0; |
299 |
– |
reply->readdata = 0; |
300 |
– |
reply->data = NULL; |
301 |
– |
|
302 |
– |
length = recv(fd->fd, tmp, 1, 0); |
303 |
– |
|
304 |
– |
if (length <= 0) |
305 |
– |
{ |
306 |
– |
if ((length == -1) && ignoreErrno(errno)) |
307 |
– |
goto nodata; |
308 |
– |
dead_link_on_read(server, length); |
309 |
– |
return; |
310 |
– |
} |
311 |
– |
reply->command = tmp[0]; |
312 |
– |
} |
313 |
– |
|
314 |
– |
for (replydef = slinkrpltab; replydef->handler; replydef++) |
315 |
– |
{ |
316 |
– |
if (replydef->replyid == (unsigned int)reply->command) |
317 |
– |
break; |
318 |
– |
} |
319 |
– |
|
320 |
– |
/* we should be able to trust a local slink process... |
321 |
– |
* and if it sends an invalid command, that's a bug.. */ |
322 |
– |
assert(replydef->handler); |
323 |
– |
|
324 |
– |
if ((replydef->flags & SLINKRPL_FLAG_DATA) && (reply->gotdatalen < 2)) |
325 |
– |
{ |
326 |
– |
/* we need a datalen u16 which we don't have yet... */ |
327 |
– |
length = recv(fd->fd, len, (2 - reply->gotdatalen), 0); |
328 |
– |
if (length <= 0) |
329 |
– |
{ |
330 |
– |
if ((length == -1) && ignoreErrno(errno)) |
331 |
– |
goto nodata; |
332 |
– |
dead_link_on_read(server, length); |
333 |
– |
return; |
334 |
– |
} |
335 |
– |
|
336 |
– |
if (reply->gotdatalen == 0) |
337 |
– |
{ |
338 |
– |
reply->datalen = *len << 8; |
339 |
– |
reply->gotdatalen++; |
340 |
– |
length--; |
341 |
– |
len++; |
342 |
– |
} |
343 |
– |
if (length && (reply->gotdatalen == 1)) |
344 |
– |
{ |
345 |
– |
reply->datalen |= *len; |
346 |
– |
reply->gotdatalen++; |
347 |
– |
if (reply->datalen > 0) |
348 |
– |
reply->data = MyMalloc(reply->datalen); |
349 |
– |
} |
350 |
– |
|
351 |
– |
if (reply->gotdatalen < 2) |
352 |
– |
return; /* wait for more data */ |
353 |
– |
} |
354 |
– |
|
355 |
– |
if (reply->readdata < reply->datalen) /* try to get any remaining data */ |
356 |
– |
{ |
357 |
– |
length = recv(fd->fd, (reply->data + reply->readdata), |
358 |
– |
(reply->datalen - reply->readdata), 0); |
359 |
– |
if (length <= 0) |
360 |
– |
{ |
361 |
– |
if ((length == -1) && ignoreErrno(errno)) |
362 |
– |
goto nodata; |
363 |
– |
dead_link_on_read(server, length); |
364 |
– |
return; |
365 |
– |
} |
366 |
– |
|
367 |
– |
reply->readdata += length; |
368 |
– |
if (reply->readdata < reply->datalen) |
369 |
– |
return; /* wait for more data */ |
370 |
– |
} |
371 |
– |
|
372 |
– |
execute_callback(iorecvctrl_cb, server, reply->command); |
373 |
– |
|
374 |
– |
/* we now have the command and any data, pass it off to the handler */ |
375 |
– |
(*replydef->handler)(reply->command, reply->datalen, reply->data, server); |
376 |
– |
|
377 |
– |
/* reset SlinkRpl */ |
378 |
– |
if (reply->datalen > 0) |
379 |
– |
MyFree(reply->data); |
380 |
– |
reply->command = 0; |
381 |
– |
|
382 |
– |
if (IsDead(server)) |
383 |
– |
return; |
384 |
– |
|
385 |
– |
nodata: |
386 |
– |
/* If we get here, we need to register for another COMM_SELECT_READ */ |
387 |
– |
comm_setselect(fd, COMM_SELECT_READ, read_ctrl_packet, server, 0); |
388 |
– |
} |
389 |
– |
|
390 |
– |
/* |
274 |
|
* iorecv_default - append a packet to the recvq dbuf |
275 |
|
*/ |
276 |
|
void * |