X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=rnetclient.c;h=a58b62b43f61cb78083d124c1886e9e71792d6b2;hb=c09b5340844f0e8ea2613e5ad19adc811195dfce;hp=df46b799264cd35c71c43edf8aee6756135c0f6a;hpb=39d6c9b0b131ccce6844fc898ec4fc2ad09a867b;p=cascardo%2Flibreceita.git diff --git a/rnetclient.c b/rnetclient.c index df46b79..a58b62b 100644 --- a/rnetclient.c +++ b/rnetclient.c @@ -31,6 +31,10 @@ #include "rnet_message.h" #include "rnet_encode.h" +static size_t chars2len (unsigned char buf[2]) { + return (buf[0] << 8 | buf[1]); +} + static void * get_creds(char *certfile) { static gnutls_certificate_credentials_t cred; @@ -49,7 +53,7 @@ static void session_new(gnutls_session_t *session) gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE, cred); } -static int deflateRecord(char *buffer, size_t len, char **out, size_t *olen) +static int deflateRecord(char *buffer, size_t len, char **out, size_t *olen, int header) { z_stream zstrm; int r; @@ -74,13 +78,13 @@ static int deflateRecord(char *buffer, size_t len, char **out, size_t *olen) free(*out); return -1; } - *olen = zstrm.avail_out + 6; + *olen = zstrm.total_out + 6; (*out)[0] = 0x1; - (*out)[1] = (zstrm.avail_out >> 8); - (*out)[2] = (zstrm.avail_out & 0xff); + (*out)[1] = (zstrm.total_out >> 8); + (*out)[2] = (zstrm.total_out & 0xff); (*out)[3] = (len >> 8); (*out)[4] = (len & 0xff); - (*out)[5] = 0x1; + (*out)[5] = header ? 0x01 : 0x0; deflateEnd(&zstrm); return 0; } @@ -94,7 +98,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 = chars2len(buffer+3); *out = malloc(*olen); if (!out) { inflateEnd(&zstrm); @@ -174,11 +178,11 @@ static void usage(void) exit(1); } -static int rnet_send(gnutls_session_t session, char *buffer, size_t len) +static int rnet_send(gnutls_session_t session, char *buffer, size_t len, int header) { char *out; size_t olen; - deflateRecord(buffer, len, &out, &olen); + deflateRecord(buffer, len, &out, &olen, header); gnutls_record_send(session, out, olen); free(out); return 0; @@ -194,17 +198,26 @@ static int rnet_recv(gnutls_session_t session, struct rnet_message **message) 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); + if (buffer[0] == 0x01) { + len = chars2len(buffer+1); + 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); + } else { + len = chars2len(buffer+1); + rnet_message_expand(message, len - 1); + buffer = (*message)->buffer + 6; + r = gnutls_record_recv(session, buffer, len - 1); + (*message)->len = len + 4; + rnet_message_strip(*message, 4); + } return 0; } @@ -247,7 +260,7 @@ out: umask(mask); } -static void handle_response_already_found(char *cpf, struct rnet_message *message) +static void handle_response_text_and_file(char *cpf, struct rnet_message *message) { char *value; int vlen; @@ -257,6 +270,11 @@ static void handle_response_already_found(char *cpf, struct rnet_message *messag save_rec_file(cpf, value, vlen); } +static void handle_response_already_found(char *cpf, struct rnet_message *message) +{ + handle_response_text_and_file(cpf, message); +} + static void handle_response_error(struct rnet_message *message) { char *value; @@ -297,7 +315,7 @@ int main(int argc, char **argv) r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); exit(1); } - gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) c); + gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(intptr_t) c); r = handshake(c); if (r < 0) { exit(1); @@ -307,7 +325,7 @@ int main(int argc, char **argv) gnutls_strerror(r)); rnet_encode(decfile, &message); - rnet_send(session, message->buffer, message->len); + rnet_send(session, message->buffer, message->len, 1); rnet_message_del(message); message = NULL; @@ -318,6 +336,7 @@ int main(int argc, char **argv) } switch (message->buffer[0]) { case 1: /* go ahead */ + handle_response_text_and_file(cpf, message); break; case 3: /* error */ handle_response_error(message); @@ -329,6 +348,7 @@ int main(int argc, char **argv) break; case 2: case 5: + handle_response_text_and_file(cpf, message); finish = 1; break; } @@ -338,7 +358,7 @@ int main(int argc, char **argv) goto out; message = rnet_decfile_get_file(decfile); - rnet_send(session, message->buffer, message->len); + rnet_send(session, message->buffer, message->len, 0); message = NULL; r = rnet_recv(session, &message); @@ -354,6 +374,7 @@ int main(int argc, char **argv) case 4: case 5: case 1: + handle_response_text_and_file(cpf, message); break; }