X-Git-Url: http://git.cascardo.info/?p=cascardo%2Flibreceita.git;a=blobdiff_plain;f=rnetclient.c;h=e1a30387120c2172cc0d63aacdba9823c086dddc;hp=e109e5f1afa961c6d2cd529ee1779ac3a82f947c;hb=52012f62f845abd12b3e9fddb8aefc95e4b015ed;hpb=e665742060dbeb55be73e89c13b812b256a65ffc diff --git a/rnetclient.c b/rnetclient.c index e109e5f..e1a3038 100644 --- a/rnetclient.c +++ b/rnetclient.c @@ -28,6 +28,8 @@ #include #include #include "decfile.h" +#include "rnet_message.h" +#include "rnet_encode.h" static void * get_creds(char *certfile) { @@ -92,7 +94,7 @@ static int inflateRecord(char *buffer, size_t len, char **out, size_t *olen) zstrm.opaque = Z_NULL; if ((r = inflateInit(&zstrm)) != Z_OK) return -1; - *olen = (buffer[3] << 8 & buffer[4]); + *olen = (buffer[3] << 8 | buffer[4]); *out = malloc(*olen); if (!out) { inflateEnd(&zstrm); @@ -172,15 +174,48 @@ static void usage(void) exit(1); } +static int rnet_send(gnutls_session_t session, char *buffer, size_t len) +{ + char *out; + size_t olen; + deflateRecord(buffer, len, &out, &olen); + gnutls_record_send(session, out, olen); + free(out); + return 0; +} + +static int rnet_recv(gnutls_session_t session, struct rnet_message **message) +{ + char *out; + size_t olen; + int r; + char *buffer; + size_t len; + rnet_message_expand(message, 6); + buffer = (*message)->buffer; + r = gnutls_record_recv(session, buffer, 6); + len = (buffer[1] << 8 | buffer[2]); + rnet_message_expand(message, len); + buffer = (*message)->buffer + 6; + r = gnutls_record_recv(session, buffer, len); + inflateRecord(buffer - 6, len + 6, &out, &olen); + rnet_message_del(*message); + *message = NULL; + rnet_message_expand(message, olen); + memcpy((*message)->buffer, out, olen); + (*message)->len = olen; + free(out); + return 0; +} + int main(int argc, char **argv) { int c; int r; - char buffer[2048]; - char *out; - size_t olen; struct rnet_decfile *decfile; + struct rnet_message *message = NULL; gnutls_session_t session; + int finish = 0; if (argc < 2) { usage(); @@ -209,18 +244,61 @@ int main(int argc, char **argv) if ((r = gnutls_handshake(session)) < 0) fprintf(stderr, "error in handshake: %s\n", gnutls_strerror(r)); - else - fprintf(stderr, "handshake ok\n"); - r = read(0, buffer, sizeof(buffer)); - deflateRecord(buffer, r, &out, &olen); - gnutls_record_send(session, out, olen); - free(out); - while ((r = gnutls_record_recv(session, buffer, sizeof(buffer))) > 0) - write(1, buffer, r); - close(c); - rnet_decfile_close(decfile); + rnet_encode(decfile, &message); + rnet_send(session, message->buffer, message->len); + rnet_message_del(message); + + message = NULL; + r = rnet_recv(session, &message); + if (r || !message || message->len == 0) { + fprintf(stderr, "error when receiving response\n"); + goto out; + } + write(1, message->buffer, message->len); + switch (message->buffer[0]) { + case 1: /* go ahead */ + break; + case 3: /* error */ + finish = 1; + break; + case 2: + case 4: + case 5: + finish = 1; + break; + } + rnet_message_del(message); + + if (finish) + goto out; + message = rnet_decfile_get_file(decfile); + rnet_send(session, message->buffer, message->len); + + message = NULL; + r = rnet_recv(session, &message); + if (r || !message || message->len == 0) { + fprintf(stderr, "error when receiving response\n"); + goto out; + } + write(1, message->buffer, message->len); + switch (message->buffer[0]) { + case 3: /* error */ + finish = 1; + break; + case 2: + case 4: + case 5: + case 1: + finish = 1; + break; + } + +out: + gnutls_bye(session, GNUTLS_SHUT_RDWR); + close(c); + rnet_decfile_close(decfile); gnutls_global_deinit(); return 0;