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;
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;
}
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;
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 = (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);
+ } else {
+ len = (buffer[1] << 8 | buffer[2]);
+ 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;
}
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;
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;
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;
}
switch (message->buffer[0]) {
case 1: /* go ahead */
+ handle_response_text_and_file(cpf, message);
break;
case 3: /* error */
handle_response_error(message);
break;
case 2:
case 5:
+ handle_response_text_and_file(cpf, message);
finish = 1;
break;
}
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);
case 4:
case 5:
case 1:
+ handle_response_text_and_file(cpf, message);
break;
}