[PATCH 3/3] Update header parser for IRPF2014
Alexandre Oliva
lxoliva en fsfla.org
Jue Mar 6 15:58:17 UTC 2014
Desconsidere este, inclusive porque foi com um pedaço que eu não
pretendia:
On Mar 6, 2014, Alexandre Oliva <lxoliva en fsfla.org> wrote:
> - if (msg->alen - msg->len < len) {
> + if (msg->alen < msg->len + len - 10) {
Este aqui, ao invés do 3/3 anterior, parece que completa o que faltava
pro rnetclient funcionar pra declarações de 2014:
Extend header length and parse new header fields introduced in
IRPF2014. Add macros for header sizes, and checks that they match
what is expected and what we find. Update the client internal version
id, and pretend to be running the GNU Interpreter for Java.
---
decfile.c | 40 +++++++++++++++++++++++++++++++++++++++-
doc/FORMATO | 9 ++++-----
rnet_encode.c | 12 +++++++++---
rnet_message.h | 4 ++++
4 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/decfile.c b/decfile.c
index 2220638..b6f9e93 100644
--- a/decfile.c
+++ b/decfile.c
@@ -79,7 +79,7 @@ static int decfile_parse_file(struct rnet_decfile *decfile);
static int decfile_parse_header(struct rnet_decfile *decfile)
{
char *buffer = get_header(decfile);
- if (!buffer || strlen(buffer) != 765)
+ if (!buffer || strlen(buffer) != IRPF_HEADER_LEN)
return 1;
return parse_header(decfile->header, buffer);
}
@@ -165,6 +165,7 @@ static int parse_header(struct pmhash *hash, char *buffer)
char *p = buffer;
char *key;
char *val;
+ char *skip_last_start;
#define parse(field, sz) \
val = malloc(sz + 1); \
@@ -191,6 +192,12 @@ static int parse_header(struct pmhash *hash, char *buffer)
parse("nome", 60);
parse("uf", 2);
parse("hash", 10);
+
+ if (p - buffer != IRPF_HEADER_SKIP_FIRST) {
+ fprintf(stderr, "IRPF_HEADER_SKIP_FIRST in rnet_message.h needs to be adjusted to %i\n", p - buffer);
+ goto out_val;
+ }
+
parse("in_cert", 1);
parse("dt_nasc", 8);
parse("in_comp", 1);
@@ -224,6 +231,8 @@ static int parse_header(struct pmhash *hash, char *buffer)
parse("cpf_rra2", 11);
parse("trib_3rra", 1);
parse("cpf_rra3", 11);
+ parse("trib_4rra", 1);
+ parse("cpf_rra4", 11);
parse("vr_doacao", 13);
parse("cnpj1", 14);
parse("cnpj2", 14);
@@ -258,9 +267,38 @@ static int parse_header(struct pmhash *hash, char *buffer)
parse("vr_totisentos", 13);
parse("vr_totexclusivo", 13);
parse("vr_totpagamentos", 13);
+ parse("nr_conta", 13);
+ parse("nr_dv_conta", 2);
+ parse("in_dv_conta", 1);
+
+ skip_last_start = p;
+
parse("versaotestpgd", 3);
parse("controle", 10);
+ if (*p++ != '\r') {
+ fprintf(stderr,
+ "missing CR at the %ith header character\n",
+ p - buffer);
+ goto out_val;
+ } else if (*p++ != '\n') {
+ fprintf(stderr,
+ "missing LF at the %ith header character\n",
+ p - buffer);
+ goto out_val;
+ } else if (*p != 0) {
+ fprintf(stderr,
+ "missing NUL at the %ith header character\n",
+ p - buffer);
+ goto out_val;
+ } else if (p - buffer != IRPF_HEADER_LEN) {
+ fprintf(stderr, "IRPF_HEADER_LEN in rnet_message.h needs to be adjusted to %i,\nor parse_header in decfile.c needs updating\n", p - buffer);
+ goto out_val;
+ } else if (p - skip_last_start != IRPF_HEADER_SKIP_LAST) {
+ fprintf(stderr, "IRPF_HEADER_SKIP_LAST in rnet_message.h needs to be adjusted to %i\n", p - skip_last_start);
+ goto out_val;
+ }
+
return 0;
out_add:
free(key);
diff --git a/doc/FORMATO b/doc/FORMATO
index ddede18..eeca701 100644
--- a/doc/FORMATO
+++ b/doc/FORMATO
@@ -32,12 +32,11 @@ C: (6 bytes) + deflate(hash)
versao_pgd = 0x00 0x78 (120, mesmo que nr_versao no DEC, segundo arquivo de leiaute)
critica_validador = 0x06 (??)
ip_loc = "127.0.0.1" (endereço IP local)
- versao_java = "1.7.0_03-icedtea;OpenJDK Runtime Environment" (versão do Java em ASCII)
- será que rola uma versão do GCC?
+ versao_java = "1.5.0-gij;Free Software rnetclient pretending to be GNU Interpreter for Java" (versão do Java em ASCII)
origem = "JA2R" (melhor repetir!)
- so = "Linux"
- cliente = "201104" (será a versão do receitanet?)
- dados_val = parte do cabeçalho do DEC (desce in_cert até vr_totpagamentos) bytes 112 a 750
+ so = "GNU"
+ cliente = "201105" (identificador de versão do receitanet)
+ dados_val = parte do cabeçalho do DEC (desde in_cert até vr_totpagamentos) bytes IRPF_HEADER_SKIP_FIRST a IRPF_HEADER_LEN - IRPF_HEADER_SKIP_LAST
tam_dados_val = 0x00 0x00 0x00 0x00 (4 bytes)
tam_dados_val_chave = 0x00 0x00 0x00 0x00 (4 bytes)
arquivos_restantes = 0x00 0x00 0x00 0x00 (4 bytes)
diff --git a/rnet_encode.c b/rnet_encode.c
index ecb97322..0bd0c33 100644
--- a/rnet_encode.c
+++ b/rnet_encode.c
@@ -53,6 +53,8 @@ int rnet_encode(struct rnet_decfile *decfile, struct rnet_message **msg)
if (!hash)
return -1;
header = rnet_decfile_get_header(decfile);
+ if (strlen (header) != IRPF_HEADER_LEN)
+ abort ();
codigo_recnet = rnet_decfile_get_header_field(decfile, "codigo_recnet");
tp_arq = strtoul(codigo_recnet, NULL, 10);
@@ -86,11 +88,15 @@ int rnet_encode(struct rnet_decfile *decfile, struct rnet_message **msg)
r = rnet_message_add_u16(msg, "versao_pgd", versao_pgd);
r = rnet_message_add_u8(msg, "critica_validador", 0x06);
r = rnet_message_add_ascii(msg, "ip_loc", "127.0.0.1");
- r = rnet_message_add_ascii(msg, "versao_java", "1.7.0_03-icedtea;OpenJDK Runtime Environment");
+ r = rnet_message_add_ascii(msg, "versao_java", "1.5.0-gij;Free Software rnetclient pretending to be GNU Interpreter for Java");
r = rnet_message_add_ascii(msg, "origem", "JA2R");
r = rnet_message_add_ascii(msg, "so", "GNU");
- r = rnet_message_add_ascii(msg, "cliente", "201104");
- r = rnet_message_add_buffer(msg, "dados_val", header + 111, 750 - 111);
+ r = rnet_message_add_ascii(msg, "cliente", "201105");
+ r = rnet_message_add_buffer(msg, "dados_val",
+ header + IRPF_HEADER_SKIP_FIRST,
+ IRPF_HEADER_LEN
+ - IRPF_HEADER_SKIP_FIRST
+ - IRPF_HEADER_SKIP_LAST);
r = rnet_message_add_u32(msg, "tam_dados_val", 0);
r = rnet_message_add_u32(msg, "tam_dados_val_chave", 0);
r = rnet_message_add_u32(msg, "arquivos_restantes", 0);
diff --git a/rnet_message.h b/rnet_message.h
index 35fe9ed..30ccf6a 100644
--- a/rnet_message.h
+++ b/rnet_message.h
@@ -44,4 +44,8 @@ int rnet_message_add_buffer(struct rnet_message **msg, char *key,
int rnet_message_parse(struct rnet_message *msg, char *skey,
char** value, int *vlen);
+#define IRPF_HEADER_LEN 793
+#define IRPF_HEADER_SKIP_FIRST 111
+#define IRPF_HEADER_SKIP_LAST 15
+
#endif
--
Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/ FSF Latin America board member
Free Software Evangelist Red Hat Brazil Toolchain Engineer
Más información sobre la lista de distribución Softwares-impostos