X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=rnetclient.c;h=de903cdccd15ce39e2d844058c6c0d9e196bf04f;hb=44392364ec17385cef6a720c640a606c29ca9b40;hp=24d542e829c2512ac682c5fa54c34c787431e0fc;hpb=5fb0636280af43f92233a0466474c42ccbf7c370;p=cascardo%2Flibreceita.git diff --git a/rnetclient.c b/rnetclient.c index 24d542e..de903cd 100644 --- a/rnetclient.c +++ b/rnetclient.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Thadeu Lima de Souza Cascardo + * Copyright (C) 2012-2013 Thadeu Lima de Souza Cascardo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,10 @@ #include #include #include +#include #include #include +#include "decfile.h" static void * get_creds(char *certfile) { @@ -111,42 +113,102 @@ static int inflateRecord(char *buffer, size_t len, char **out, size_t *olen) return 0; } -int main(int argc, char **argv) +#define RNET_ADDRESS "receitanet.receita.fazenda.gov.br" + +static int connect_rnet(int *c) { + struct addrinfo *addresses; + struct addrinfo *addr; + struct addrinfo hint; struct sockaddr_in saddr; + int r; + int fd = *c = -1; + int i; + memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_ADDRCONFIG; + r = getaddrinfo(RNET_ADDRESS, "3456", &hint, &addresses); + if (r) { + return r; + } + for (addr = addresses; addr != NULL; addr = addr->ai_next) { + fd = socket(addr->ai_family, addr->ai_socktype, + addr->ai_protocol); + if (fd >= 0) + if (!(r = connect(fd, addr->ai_addr, + addr->ai_addrlen))) + break; + close(fd); + fd = -1; + } + freeaddrinfo(addresses); + *c = fd; + if (fd == -1) + return EAI_SYSTEM; + return 0; +} + +static int handshake(int c) +{ + char buffer[16]; + int r; + buffer[0] = 1; + write(c, buffer, 1); + write(c, "00000000000000", 14); + r = read(c, buffer, 1); + if (r != 1 && buffer[0] != 'E') + return -1; + r = read(c, buffer, 14); + if (r != 14) + return -1; + return 0; +} + +static void usage(void) +{ + fprintf(stderr, "rnetclient [filename]\n"); + exit(1); +} + +int main(int argc, char **argv) +{ int c; int r; char buffer[2048]; char *out; size_t olen; + struct rnet_decfile *decfile; gnutls_session_t session; + + if (argc < 2) { + usage(); + } + + decfile = rnet_decfile_open(argv[1]); + if (!decfile) { + fprintf(stderr, "could not parse %s: %s\n", argv[1], strerror(errno)); + exit(1); + } + gnutls_global_init(); + session_new(&session); - c = socket(PF_INET, SOCK_STREAM, 0); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(3456); - saddr.sin_addr.s_addr = inet_addr("161.148.185.11"); - r = connect(c, (struct sockaddr *) &saddr, sizeof(saddr)); - if (r < 0) { + r = connect_rnet(&c); + if (r) { fprintf(stderr, "error connecting to server: %s\n", - strerror(errno)); + r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); exit(1); } gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) c); - buffer[0] = 1; - write(c, buffer, 1); - write(c, "00000000000000", 14); - r = read(c, buffer, 1); - if (r != 1 && buffer[0] != 'E') - exit(1); - r = read(c, buffer, 14); - if (r != 14) + r = handshake(c); + if (r < 0) { exit(1); + } 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); @@ -154,6 +216,10 @@ int main(int argc, char **argv) while ((r = gnutls_record_recv(session, buffer, sizeof(buffer))) > 0) write(1, buffer, r); close(c); + + rnet_decfile_close(decfile); + gnutls_global_deinit(); + return 0; }