diff --git a/src/client/libdistren_request.c b/src/client/libdistren_request.c new file mode 100644 --- /dev/null +++ b/src/client/libdistren_request.c @@ -0,0 +1,144 @@ +/* + * Copyright 2010 Nathan Phillip Brink + * + * This file is a part of DistRen. + * + * DistRen is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * DistRen is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with DistRen. If not, see . + */ + +#include "common/config.h" + +#include "libdistren.h" + +#include "common/protocol.h" +#include "common/remoteio.h" +#include "common/request.h" + +static void handle_ping(struct remoteio *rem, struct distren_request *req, void *req_data); +static void handle_version(struct remoteio *rem, struct distren_request *req, void *req_data); +static void handle_disconnect(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data); + +size_t libdistren_remoteio_read_handle(struct remoteio *rem, void *garbage, void *buf, size_t len, distren_t distren) +{ + size_t to_return; + size_t last_len; + short err; + + struct distren_request *req; + void *req_data; + + to_return = 0; + while(!distren->done_ad) + { + if(!len) + return to_return; + + putchar(*(char *)buf); + if(*(char *)buf == '\n') + distren->done_ad = 1; + + len --; + to_return ++; + buf ++; + } + + /* hack to get into the loop at all ;-) */ + last_len = 1; + while(last_len) + { + last_len = distren_request_handle(NULL, buf, len, &req, &req_data, &err); + if(err) + { + remoteio_close(rem); + return to_return; + } + if(!last_len) + return to_return; + + switch((enum distren_request_type)req->type) + { + case DISTREN_REQUEST_PING: + handle_ping(rem, req, req_data); + break; + + case DISTREN_REQUEST_VERSION: + handle_version(rem, req, req_data); + break; + + case DISTREN_REQUEST_DISCONNECT: + handle_disconnect(distren, rem, req, req_data); + break; + + default: + /* + * we don't implement everything because we don't need to do + * so. But, we should complain when we get something we + * don't recognize because... server protocols change + * ;-). Oh, and when I'm first writing this, this + * block will be hit a lot ;-). + */ + fprintf(stderr, "Unrecognized request type: %lu\n", (unsigned long)req->type); + break; + } + + distren_request_free(req); + buf += last_len; + len -= last_len; + } + + return to_return; +} + +void libdistren_remoteio_close_handle(void *garbage, distren_t distren) +{ + distren->rem = NULL; +} + + +/* handlers */ + +static void handle_ping(struct remoteio *rem, struct distren_request *req, void *req_data) +{ + struct distren_request *pong_req; + void *pong_req_data; + + distren_request_poing(&pong_req, &pong_req_data, 0, req_data, req->len); + distren_request_send(rem, pong_req, pong_req_data); + distren_request_free_with_data(pong_req, pong_req_data); +} + +static void handle_version(struct remoteio *rem, struct distren_request *req, void *req_data) +{ + static const char *package_string = PACKAGE_STRING; + + size_t counter; + + fprintf(stderr, "info: connected to a server running "); + for(counter = 0; counter < req->len; counter ++) + putc(((char *)req_data)[counter], stderr); + putc('\n', stderr); + + /* am I supposed to respond here? ;-) */ +} + +static void handle_disconnect(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data) +{ + size_t tmp; + + fputs("warning: The server has disconnected us because ``", stderr); + tmp = fwrite(req_data, 1, req->len, stderr); + fputs("''\n", stderr); + + remoteio_close(distren->rem); +}