diff options
author | Elliott Sales de Andrade <qulogic@pidgin.im> | 2019-11-03 20:27:37 -0500 |
---|---|---|
committer | Elliott Sales de Andrade <qulogic@pidgin.im> | 2019-11-03 20:27:37 -0500 |
commit | 254a324770fde5359898003755f7bce4b2a2ac0c (patch) | |
tree | a11790c3472a4f1bb40a0a5efb82b75a5e2b3021 | |
parent | 27e58e02bea4fb8f29c5ae10b9ec0f768943c474 (diff) | |
download | pidgin-254a324770fde5359898003755f7bce4b2a2ac0c.tar.gz |
novell: Replace socket wrappers with GIO functions.
-rw-r--r-- | libpurple/protocols/novell/nmconn.c | 247 | ||||
-rw-r--r-- | libpurple/protocols/novell/nmconn.h | 75 | ||||
-rw-r--r-- | libpurple/protocols/novell/nmevent.c | 280 | ||||
-rw-r--r-- | libpurple/protocols/novell/nmuser.c | 73 | ||||
-rw-r--r-- | libpurple/protocols/novell/novell.c | 8 |
5 files changed, 381 insertions, 302 deletions
diff --git a/libpurple/protocols/novell/nmconn.c b/libpurple/protocols/novell/nmconn.c index b2da68f4a3..ae75b6b0df 100644 --- a/libpurple/protocols/novell/nmconn.c +++ b/libpurple/protocols/novell/nmconn.c @@ -36,27 +36,6 @@ #define NO_ESCAPE(ch) ((ch == 0x20) || (ch >= 0x30 && ch <= 0x39) || \ (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a)) -/* Read data from conn until the end of a line */ -static NMERR_T -read_line(NMConn * conn, char *buff, int len) -{ - NMERR_T rc = NM_OK; - int total_bytes = 0; - - while ((rc == NM_OK) && (total_bytes < (len - 1))) { - rc = nm_read_all(conn, &buff[total_bytes], 1); - if (rc == NM_OK) { - total_bytes += 1; - if (buff[total_bytes - 1] == '\n') { - break; - } - } - } - buff[total_bytes] = '\0'; - - return rc; -} - static char * url_escape_string(char *src) { @@ -188,8 +167,8 @@ void nm_release_conn(NMConn *conn) conn->requests = NULL; if (conn->input) { - purple_gio_graceful_close(conn->stream, conn->input, - conn->output); + purple_gio_graceful_close(conn->stream, G_INPUT_STREAM(conn->input), + conn->output); } g_clear_object(&conn->input); g_clear_object(&conn->output); @@ -199,68 +178,10 @@ void nm_release_conn(NMConn *conn) g_free(conn); } -int -nm_tcp_write(NMConn * conn, const void *buff, int len) -{ - if (conn == NULL || buff == NULL) - return -1; - - return g_output_stream_write(conn->output, buff, len, NULL, NULL); -} - -int -nm_tcp_read(NMConn * conn, void *buff, int len) -{ - if (conn == NULL || buff == NULL) - return -1; - - return g_input_stream_read(conn->input, buff, len, NULL, NULL); -} - -NMERR_T -nm_read_all(NMConn * conn, char *buff, int len) -{ - NMERR_T rc = NM_OK; - - if (conn == NULL || buff == NULL) - return NMERR_BAD_PARM; - - if (!g_input_stream_read_all(conn->input, buff, len, NULL, NULL, NULL)) { - rc = NMERR_TCP_READ; - } - - return rc; -} - -NMERR_T -nm_read_uint32(NMConn *conn, guint32 *val) -{ - NMERR_T rc = NM_OK; - - rc = nm_read_all(conn, (char *)val, sizeof(*val)); - if (rc == NM_OK) { - *val = GUINT32_FROM_LE(*val); - } - - return rc; -} - -NMERR_T -nm_read_uint16(NMConn *conn, guint16 *val) -{ - NMERR_T rc = NM_OK; - - rc = nm_read_all(conn, (char *)val, sizeof(*val)); - if (rc == NM_OK) { - *val = GUINT16_FROM_LE(*val); - } - - return rc; -} - NMERR_T -nm_write_fields(NMConn * conn, NMField * fields) +nm_write_fields(NMUser *user, NMField *fields) { + NMConn *conn; NMERR_T rc = NM_OK; NMField *field; char *value = NULL; @@ -270,9 +191,10 @@ nm_write_fields(NMConn * conn, NMField * fields) int bytes_to_send; int val = 0; - if (conn == NULL || fields == NULL) { - return NMERR_BAD_PARM; - } + g_return_val_if_fail(user != NULL, NMERR_BAD_PARM); + conn = user->conn; + g_return_val_if_fail(conn != NULL, NMERR_BAD_PARM); + g_return_val_if_fail(fields != NULL, NMERR_BAD_PARM); /* Format each field as valid "post" data and write it out */ for (field = fields; (rc == NM_OK) && (field->tag); field++) { @@ -285,7 +207,8 @@ nm_write_fields(NMConn * conn, NMField * fields) /* Write the field tag */ bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&tag=%s", field->tag); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -294,7 +217,8 @@ nm_write_fields(NMConn * conn, NMField * fields) if (rc == NM_OK) { method = encode_method(field->method); bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&cmd=%s", method); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -310,9 +234,13 @@ nm_write_fields(NMConn * conn, NMField * fields) bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&val=%s", value); if (bytes_to_send > (int)sizeof(buffer)) { - ret = nm_tcp_write(conn, buffer, sizeof(buffer)); + ret = g_output_stream_write(conn->output, buffer, + sizeof(buffer), + user->cancellable, NULL); } else { - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, + bytes_to_send, + user->cancellable, NULL); } if (ret < 0) { @@ -329,7 +257,9 @@ nm_write_fields(NMConn * conn, NMField * fields) val = nm_count_fields((NMField *) field->ptr_value); bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&val=%u", val); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, + bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -340,7 +270,9 @@ nm_write_fields(NMConn * conn, NMField * fields) bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&val=%u", field->value); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, + bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -353,7 +285,8 @@ nm_write_fields(NMConn * conn, NMField * fields) if (rc == NM_OK) { bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&type=%u", field->type); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -364,8 +297,7 @@ nm_write_fields(NMConn * conn, NMField * fields) if (field->type == NMFIELD_TYPE_ARRAY || field->type == NMFIELD_TYPE_MV) { - rc = nm_write_fields(conn, (NMField *) field->ptr_value); - + rc = nm_write_fields(user, (NMField *)field->ptr_value); } } } @@ -374,9 +306,10 @@ nm_write_fields(NMConn * conn, NMField * fields) } NMERR_T -nm_send_request(NMConn *conn, char *cmd, NMField *fields, - nm_response_cb cb, gpointer data, NMRequest **request) +nm_send_request(NMUser *user, char *cmd, NMField *fields, nm_response_cb cb, + gpointer data, NMRequest **request) { + NMConn *conn; NMERR_T rc = NM_OK; char buffer[512]; int bytes_to_send; @@ -384,13 +317,16 @@ nm_send_request(NMConn *conn, char *cmd, NMField *fields, NMField *request_fields = NULL; char *str = NULL; - if (conn == NULL || cmd == NULL) - return NMERR_BAD_PARM; + g_return_val_if_fail(user != NULL, NMERR_BAD_PARM); + conn = user->conn; + g_return_val_if_fail(conn != NULL, NMERR_BAD_PARM); + g_return_val_if_fail(cmd != NULL, NMERR_BAD_PARM); /* Write the post */ bytes_to_send = g_snprintf(buffer, sizeof(buffer), "POST /%s HTTP/1.0\r\n", cmd); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -400,13 +336,15 @@ nm_send_request(NMConn *conn, char *cmd, NMField *fields, if (purple_strequal("login", cmd)) { bytes_to_send = g_snprintf(buffer, sizeof(buffer), "Host: %s:%d\r\n\r\n", conn->addr, conn->port); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } } else { bytes_to_send = g_snprintf(buffer, sizeof(buffer), "\r\n"); - ret = nm_tcp_write(conn, buffer, bytes_to_send); + ret = g_output_stream_write(conn->output, buffer, bytes_to_send, + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -426,12 +364,13 @@ nm_send_request(NMConn *conn, char *cmd, NMField *fields, /* Send the request to the server */ if (rc == NM_OK) { - rc = nm_write_fields(conn, request_fields); + rc = nm_write_fields(user, request_fields); } /* Write the CRLF to terminate the data */ if (rc == NM_OK) { - ret = nm_tcp_write(conn, "\r\n", strlen("\r\n")); + ret = g_output_stream_write(conn->output, "\r\n", strlen("\r\n"), + user->cancellable, NULL); if (ret < 0) { rc = NMERR_TCP_WRITE; } @@ -457,22 +396,24 @@ nm_send_request(NMConn *conn, char *cmd, NMField *fields, } NMERR_T -nm_read_header(NMConn * conn) +nm_read_header(NMUser *user) { + NMConn *conn; NMERR_T rc = NM_OK; - char buffer[512]; + gchar *buffer; char *ptr = NULL; int i; char rtn_buf[8]; int rtn_code = 0; + GError *error = NULL; - if (conn == NULL) - return NMERR_BAD_PARM; - - *buffer = '\0'; - rc = read_line(conn, buffer, sizeof(buffer)); - if (rc == NM_OK) { + g_return_val_if_fail(user != NULL, NMERR_BAD_PARM); + conn = user->conn; + g_return_val_if_fail(conn != NULL, NMERR_BAD_PARM); + buffer = g_data_input_stream_read_line(conn->input, NULL, user->cancellable, + &error); + if (error == NULL) { /* Find the return code */ ptr = strchr(buffer, ' '); if (ptr != NULL) { @@ -493,8 +434,19 @@ nm_read_header(NMConn * conn) /* Finish reading header, in the future we might want to do more processing here */ /* TODO: handle more general redirects in the future */ - while ((rc == NM_OK) && (!purple_strequal(buffer, "\r\n"))) { - rc = read_line(conn, buffer, sizeof(buffer)); + while ((error == NULL) && !purple_strequal(buffer, "\r")) { + g_free(buffer); + buffer = g_data_input_stream_read_line(conn->input, NULL, + user->cancellable, &error); + } + g_free(buffer); + + if (error != NULL) { + if (error->code != G_IO_ERROR_WOULD_BLOCK && + error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } if (rc == NM_OK && rtn_code == 301) @@ -504,8 +456,9 @@ nm_read_header(NMConn * conn) } NMERR_T -nm_read_fields(NMConn * conn, int count, NMField ** fields) +nm_read_fields(NMUser *user, int count, NMField **fields) { + NMConn *conn; NMERR_T rc = NM_OK; guint8 type; guint8 method; @@ -513,9 +466,12 @@ nm_read_fields(NMConn * conn, int count, NMField ** fields) char tag[64]; NMField *sub_fields = NULL; char *str = NULL; + GError *error = NULL; - if (conn == NULL || fields == NULL) - return NMERR_BAD_PARM; + g_return_val_if_fail(user != NULL, NMERR_BAD_PARM); + conn = user->conn; + g_return_val_if_fail(conn != NULL, NMERR_BAD_PARM); + g_return_val_if_fail(fields != NULL, NMERR_BAD_PARM); do { if (count > 0) { @@ -523,36 +479,46 @@ nm_read_fields(NMConn * conn, int count, NMField ** fields) } /* Read the field type, method, and tag */ - rc = nm_read_all(conn, (char *)&type, sizeof(type)); - if (rc != NM_OK || type == 0) + type = g_data_input_stream_read_byte(conn->input, user->cancellable, + &error); + if (error != NULL || type == 0) { break; + } - rc = nm_read_all(conn, (char *)&method, sizeof(method)); - if (rc != NM_OK) + method = g_data_input_stream_read_byte(conn->input, user->cancellable, + &error); + if (error != NULL) { break; + } - rc = nm_read_uint32(conn, &val); - if (rc != NM_OK) + val = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (error != NULL) { break; + } if (val > sizeof(tag)) { rc = NMERR_PROTOCOL; break; } - rc = nm_read_all(conn, tag, val); - if (rc != NM_OK) + g_input_stream_read_all(G_INPUT_STREAM(conn->input), tag, val, NULL, + user->cancellable, &error); + if (error != NULL) { break; + } if (type == NMFIELD_TYPE_MV || type == NMFIELD_TYPE_ARRAY) { /* Read the subarray (first read the number of items in the array) */ - rc = nm_read_uint32(conn, &val); - if (rc != NM_OK) + val = g_data_input_stream_read_uint32(conn->input, + user->cancellable, &error); + if (error != NULL) { break; + } if (val > 0) { - rc = nm_read_fields(conn, val, &sub_fields); + rc = nm_read_fields(user, val, &sub_fields); if (rc != NM_OK) break; } @@ -565,9 +531,11 @@ nm_read_fields(NMConn * conn, int count, NMField ** fields) } else if (type == NMFIELD_TYPE_UTF8 || type == NMFIELD_TYPE_DN) { /* Read the string (first read the length) */ - rc = nm_read_uint32(conn, &val); - if (rc != NM_OK) + val = g_data_input_stream_read_uint32(conn->input, + user->cancellable, &error); + if (error != NULL) { break; + } if (val >= NMFIELD_MAX_STR_LENGTH) { rc = NMERR_PROTOCOL; @@ -577,9 +545,11 @@ nm_read_fields(NMConn * conn, int count, NMField ** fields) if (val > 0) { str = g_new0(char, val + 1); - rc = nm_read_all(conn, str, val); - if (rc != NM_OK) + g_input_stream_read_all(G_INPUT_STREAM(conn->input), str, val, + NULL, user->cancellable, &error); + if (error != NULL) { break; + } *fields = nm_field_add_pointer(*fields, tag, 0, method, 0, str, type); @@ -589,9 +559,11 @@ nm_read_fields(NMConn * conn, int count, NMField ** fields) } else { /* Read the numerical value */ - rc = nm_read_uint32(conn, &val); - if (rc != NM_OK) + val = g_data_input_stream_read_uint32(conn->input, + user->cancellable, &error); + if (error != NULL) { break; + } *fields = nm_field_add_number(*fields, tag, 0, method, 0, val, type); @@ -605,6 +577,13 @@ nm_read_fields(NMConn * conn, int count, NMField ** fields) nm_free_fields(&sub_fields); } + if (error != NULL) { + if (error->code != G_IO_ERROR_WOULD_BLOCK && error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); + } + return rc; } diff --git a/libpurple/protocols/novell/nmconn.h b/libpurple/protocols/novell/nmconn.h index 363395ffcf..afa68e6aac 100644 --- a/libpurple/protocols/novell/nmconn.h +++ b/libpurple/protocols/novell/nmconn.h @@ -49,7 +49,7 @@ struct _NMConn /* Connections to server. */ GSocketClient *client; GIOStream *stream; - GInputStream *input; + GDataInputStream *input; GOutputStream *output; }; @@ -73,64 +73,9 @@ NMConn *nm_create_conn(const char *addr, int port); void nm_release_conn(NMConn *conn); /** - * Write len bytes from the given buffer. - * - * @param conn The connection to write to. - * @param buff The buffer to write from. - * @param len The number of bytes to write. - * - * @return The number of bytes written. - */ -int nm_tcp_write(NMConn * conn, const void *buff, int len); - -/** - * Read at most len bytes into the given buffer. - * - * @param conn The connection to read from. - * @param buff The buffer to write to. - * @param len The maximum number of bytes to read. - * - * @return The number of bytes read. - */ -int nm_tcp_read(NMConn * conn, void *buff, int len); - -/** - * Read exactly len bytes into the given buffer. - * - * @param conn The connection to read from. - * @param buff The buffer to write to. - * @param len The number of bytes to read. - * - * @return NM_OK on success, NMERR_TCP_READ if read fails. - */ -NMERR_T nm_read_all(NMConn * conn, char *buf, int len); - -/** - * Read a 32 bit value and convert it to the host byte order. - * - * @param conn The connection to read from. - * @param val A pointer to unsigned 32 bit integer - * - * @return NM_OK on success, NMERR_TCP_READ if read fails. - */ -NMERR_T -nm_read_uint32(NMConn *conn, guint32 *val); - -/** - * Read a 16 bit value and convert it to the host byte order. - * - * @param conn The connection to read from. - * @param val A pointer to unsigned 16 bit integer - * - * @return NM_OK on success, NMERR_TCP_READ if read fails. - */ -NMERR_T -nm_read_uint16(NMConn *conn, guint16 *val); - -/** * Dispatch a request to the server. * - * @param conn The connection. + * @param user The logged-in user. * @param cmd The request to dispatch. * @param fields The field list for the request. * @param cb The response callback for the new request object. @@ -140,32 +85,32 @@ nm_read_uint16(NMConn *conn, guint16 *val); * @return NM_OK on success. */ NMERR_T -nm_send_request(NMConn *conn, char *cmd, NMField *fields, - nm_response_cb cb, gpointer data, NMRequest **request); +nm_send_request(NMUser *user, char *cmd, NMField *fields, nm_response_cb cb, + gpointer data, NMRequest **request); /** * Write out the given field list. * - * @param conn The connection to write to. + * @param user The logged-in user. * @param fields The field list to write. * * @return NM_OK on success. */ -NMERR_T nm_write_fields(NMConn * conn, NMField * fields); +NMERR_T nm_write_fields(NMUser *user, NMField *fields); /** * Read the headers for a response. * - * @param conn The connection to read from. + * @param user The logged-in user. * * @return NM_OK on success. */ -NMERR_T nm_read_header(NMConn * conn); +NMERR_T nm_read_header(NMUser *user); /** * Read a field list from the connection. * - * @param conn The connection to read from. + * @param user The logged-in user. * @param count The maximum number of fields to read (or -1 for no max). * @param fields The field list. This is an out param. It * should be freed by calling nm_free_fields @@ -173,7 +118,7 @@ NMERR_T nm_read_header(NMConn * conn); * * @return NM_OK on success. */ -NMERR_T nm_read_fields(NMConn * conn, int count, NMField ** fields); +NMERR_T nm_read_fields(NMUser *user, int count, NMField **fields); /** * Add a request to the connections request list. diff --git a/libpurple/protocols/novell/nmevent.c b/libpurple/protocols/novell/nmevent.c index f709e66bc2..312c9f7fa5 100644 --- a/libpurple/protocols/novell/nmevent.c +++ b/libpurple/protocols/novell/nmevent.c @@ -144,31 +144,43 @@ handle_receive_message(NMUser * user, NMEvent * event, gboolean autoreply) char *msg = NULL; char *nortf = NULL; char *guid = NULL; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } /* Read the conference flags */ - if (rc == NM_OK) { - rc = nm_read_uint32(conn, &flags); + if (error == NULL) { + flags = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); } /* Read the message text */ - if (rc == NM_OK) { - rc = nm_read_uint32(conn, &size); - if (size > 100000) return NMERR_PROTOCOL; + if (error == NULL) { + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 100000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { msg = g_new0(char, size + 1); - rc = nm_read_all(conn, msg, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), msg, size, + NULL, user->cancellable, &error); purple_debug(PURPLE_DEBUG_INFO, "novell", "Message is %s\n", msg); @@ -194,6 +206,16 @@ handle_receive_message(NMUser * user, NMEvent * event, gboolean autoreply) } } + if (error != NULL) { + if (error->code == G_IO_ERROR_CANCELLED) { + rc = NM_OK; + } else { + rc = NMERR_TCP_READ; + } + g_error_free(error); + return rc; + } + /* Check to see if we already know about the conference */ conference = nm_conference_list_find(user, guid); if (conference) { @@ -260,31 +282,42 @@ handle_conference_invite(NMUser * user, NMEvent * event) char *msg = NULL; NMConn *conn; NMUserRecord *user_record; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } /* Read the the message */ - if (rc == NM_OK) { - rc = nm_read_uint32(conn, &size); - if (size > 100000) return NMERR_PROTOCOL; + if (error == NULL) { + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 100000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { msg = g_new0(char, size + 1); - rc = nm_read_all(conn, msg, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), msg, size, + NULL, user->cancellable, &error); } } /* Store the event data */ - if (rc == NM_OK) { + if (error == NULL) { NMConference *conference; nm_event_set_text(event, msg); @@ -316,6 +349,11 @@ handle_conference_invite(NMUser * user, NMEvent * event) nm_release_conference(conference); } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(msg); @@ -336,16 +374,32 @@ handle_conference_invite_notify(NMUser * user, NMEvent * event) NMConn *conn; NMConference *conference; NMUserRecord *user_record; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); + } + + if (error != NULL) { + if (error->code == G_IO_ERROR_CANCELLED) { + rc = NM_OK; + } else { + rc = NMERR_TCP_READ; + } + g_error_free(error); + return rc; } conference = nm_conference_list_find(user, guid); @@ -387,25 +441,36 @@ handle_conference_reject(NMUser * user, NMEvent * event) char *guid = NULL; NMConn *conn; NMConference *conference; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } - if (rc == NM_OK) { + if (error == NULL) { conference = nm_conference_list_find(user, guid); if (conference) { nm_event_set_conference(event, conference); } else { rc = NMERR_CONFERENCE_NOT_FOUND; } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(guid); @@ -425,24 +490,31 @@ handle_conference_left(NMUser * user, NMEvent * event) char *guid = NULL; NMConference *conference; NMConn *conn; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } /* Read the conference flags */ - if (rc == NM_OK) { - rc = nm_read_uint32(conn, &flags); + if (error == NULL) { + flags = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); } - if (rc == NM_OK) { + if (error == NULL) { conference = nm_conference_list_find(user, guid); if (conference) { nm_event_set_conference(event, conference); @@ -456,6 +528,11 @@ handle_conference_left(NMUser * user, NMEvent * event) } else { rc = NMERR_CONFERENCE_NOT_FOUND; } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(guid); @@ -474,19 +551,25 @@ handle_conference_closed(NMUser * user, NMEvent * event) char *guid = NULL; NMConference *conference; NMConn *conn; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } - if (rc == NM_OK) { + if (error == NULL) { conference = nm_conference_list_find(user, guid); if (conference) { nm_event_set_conference(event, conference); @@ -494,6 +577,11 @@ handle_conference_closed(NMUser * user, NMEvent * event) } else { rc = NMERR_CONFERENCE_NOT_FOUND; } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(guid); @@ -513,24 +601,31 @@ handle_conference_joined(NMUser * user, NMEvent * event) NMConn *conn; NMConference *conference; NMUserRecord *user_record; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } /* Read the conference flags */ - if (rc == NM_OK) { - rc = nm_read_uint32(conn, &flags); + if (error == NULL) { + flags = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); } - if (rc == NM_OK) { + if (error == NULL) { conference = nm_conference_list_find(user, guid); if (conference) { nm_conference_set_flags(conference, flags); @@ -555,6 +650,11 @@ handle_conference_joined(NMUser * user, NMEvent * event) } else { rc = NMERR_CONFERENCE_NOT_FOUND; } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(guid); @@ -571,25 +671,36 @@ handle_typing(NMUser * user, NMEvent * event) char *guid = NULL; NMConference *conference; NMConn *conn; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, NULL, + user->cancellable, &error); } - if (rc == NM_OK) { + if (error == NULL) { conference = nm_conference_list_find(user, guid); if (conference) { nm_event_set_conference(event, conference); } else { rc = NMERR_CONFERENCE_NOT_FOUND; } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(guid); @@ -609,24 +720,31 @@ handle_status_change(NMUser * user, NMEvent * event) char *text = NULL; NMUserRecord *user_record; NMConn *conn; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read new status */ - rc = nm_read_uint16(conn, &status); - if (rc == NM_OK) { + status = g_data_input_stream_read_uint16(conn->input, user->cancellable, + &error); + if (error == NULL) { /* Read the status text */ - rc = nm_read_uint32(conn, &size); - if (size > 10000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 10000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { text = g_new0(char, size + 1); - rc = nm_read_all(conn, text, size); + g_input_stream_read_all(G_INPUT_STREAM(conn->input), text, size, + NULL, user->cancellable, &error); } } - if (rc == NM_OK) { + if (error == NULL) { nm_event_set_text(event, text); /* Get a reference to the user record and store the new status */ @@ -635,6 +753,11 @@ handle_status_change(NMUser * user, NMEvent * event) nm_event_set_user_record(event, user_record); nm_user_record_set_status(user_record, status, text); } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(text); @@ -650,16 +773,27 @@ handle_undeliverable_status(NMUser * user, NMEvent * event) guint32 size = 0; char *guid = NULL; NMConn *conn; + GError *error = NULL; conn = nm_user_get_conn(user); /* Read the conference guid */ - rc = nm_read_uint32(conn, &size); - if (size > 1000) return NMERR_PROTOCOL; + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (size > 1000) { + g_clear_error(&error); + return NMERR_PROTOCOL; + } - if (rc == NM_OK) { + if (error == NULL) { guid = g_new0(char, size + 1); - rc = nm_read_all(conn, guid, size); + rc = g_input_stream_read_all(G_INPUT_STREAM(conn->input), guid, size, + NULL, user->cancellable, &error); + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } g_free(guid); @@ -803,6 +937,7 @@ nm_process_event(NMUser * user, int type) char *source = NULL; nm_event_cb cb; NMConn *conn; + GError *error = NULL; if (user == NULL) return NMERR_BAD_PARM; @@ -813,20 +948,22 @@ nm_process_event(NMUser * user, int type) conn = nm_user_get_conn(user); /* Read the event source */ - rc = nm_read_uint32(conn, &size); - if (rc == NM_OK) { + size = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (error == NULL) { if (size > 1000000) { /* Size is larger than our 1MB sanity check. Ignore it. */ rc = NMERR_PROTOCOL; } else { source = g_new0(char, size); - rc = nm_read_all(conn, source, size); + rc = g_input_stream_read_all(G_INPUT_STREAM(conn->input), source, + size, NULL, user->cancellable, &error); } } /* Read the event data */ - if (rc == NM_OK) { + if (error == NULL) { event = nm_create_event(type, source, time(0)); if (event) { @@ -901,6 +1038,11 @@ nm_process_event(NMUser * user, int type) break; } } + } else { + if (error->code != G_IO_ERROR_CANCELLED) { + rc = NMERR_TCP_READ; + } + g_error_free(error); } if (rc == (NMERR_T)-1) { diff --git a/libpurple/protocols/novell/nmuser.c b/libpurple/protocols/novell/nmuser.c index 7e706d1446..68d63e0a0c 100644 --- a/libpurple/protocols/novell/nmuser.c +++ b/libpurple/protocols/novell/nmuser.c @@ -139,7 +139,7 @@ nm_send_login(NMUser * user, const char *pwd, const char *my_addr, } /* Send the login */ - rc = nm_send_request(user->conn, "login", fields, callback, data, NULL); + rc = nm_send_request(user, "login", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -172,7 +172,7 @@ nm_send_set_status(NMUser * user, int status, const char *text, NMFIELD_TYPE_UTF8); } - rc = nm_send_request(user->conn, "setstatus", fields, callback, data, NULL); + rc = nm_send_request(user, "setstatus", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -195,7 +195,7 @@ nm_send_multiple_get_details(NMUser * user, GSList *names, g_strdup(node->data), NMFIELD_TYPE_UTF8); } - rc = nm_send_request(user->conn, "getdetails", fields, callback, data, NULL); + rc = nm_send_request(user, "getdetails", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -229,7 +229,7 @@ nm_send_get_details(NMUser * user, const char *name, } - rc = nm_send_request(user->conn, "getdetails", fields, callback, data, NULL); + rc = nm_send_request(user, "getdetails", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -281,7 +281,7 @@ nm_send_create_conference(NMUser * user, NMConference * conference, NMFIELD_TYPE_DN); } - rc = nm_send_request(user->conn, "createconf", fields, callback, data, &req); + rc = nm_send_request(user, "createconf", fields, callback, data, &req); if (rc == NM_OK && req) { nm_conference_add_ref(conference); nm_request_set_data(req, conference); @@ -317,7 +317,7 @@ nm_send_leave_conference(NMUser * user, NMConference * conference, tmp = NULL; /* Send the request to the server */ - rc = nm_send_request(user->conn, "leaveconf", fields, callback, data, &req); + rc = nm_send_request(user, "leaveconf", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, conference); @@ -350,7 +350,7 @@ nm_send_join_conference(NMUser * user, NMConference * conference, tmp = NULL; /* Send the request to the server */ - rc = nm_send_request(user->conn, "joinconf", fields, callback, data, &req); + rc = nm_send_request(user, "joinconf", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, conference); @@ -384,7 +384,7 @@ nm_send_reject_conference(NMUser * user, NMConference * conference, tmp = NULL; /* Send the request to the server */ - rc = nm_send_request(user->conn, "rejectconf", fields, callback, data, &req); + rc = nm_send_request(user, "rejectconf", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, conference); @@ -428,7 +428,7 @@ nm_send_conference_invite(NMUser *user, NMConference *conference, NMUserRecord * g_strdup(message), NMFIELD_TYPE_UTF8); /* Send the request to the server */ - rc = nm_send_request(user->conn, "sendinvite", fields, callback, data, &req); + rc = nm_send_request(user, "sendinvite", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, conference); @@ -505,7 +505,7 @@ nm_send_message(NMUser * user, NMMessage * message, nm_response_cb callback) } /* Send the request */ - rc = nm_send_request(user->conn, "sendmessage", fields, callback, NULL, NULL); + rc = nm_send_request(user, "sendmessage", fields, callback, NULL, NULL); } nm_free_fields(&fields); @@ -545,7 +545,7 @@ nm_send_typing(NMUser * user, NMConference * conf, tmp, NMFIELD_TYPE_ARRAY); tmp = NULL; - rc = nm_send_request(user->conn, "sendtyping", fields, callback, NULL, NULL); + rc = nm_send_request(user, "sendtyping", fields, callback, NULL, NULL); } nm_free_fields(&fields); @@ -596,7 +596,7 @@ nm_send_create_contact(NMUser * user, NMFolder * folder, g_strdup(display_name), NMFIELD_TYPE_UTF8); /* Dispatch the request */ - rc = nm_send_request(user->conn, "createcontact", fields, callback, data, &req); + rc = nm_send_request(user, "createcontact", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, contact); @@ -631,7 +631,7 @@ nm_send_remove_contact(NMUser * user, NMFolder * folder, NMFIELD_TYPE_UTF8); /* Dispatch the request */ - rc = nm_send_request(user->conn, "deletecontact", fields, callback, data, &req); + rc = nm_send_request(user, "deletecontact", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, contact); @@ -669,7 +669,7 @@ nm_send_create_folder(NMUser * user, const char *name, g_strdup("-1"), NMFIELD_TYPE_UTF8); /* Dispatch the request */ - rc = nm_send_request(user->conn, "createfolder", fields, callback, data, &req); + rc = nm_send_request(user, "createfolder", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, g_strdup(name)); @@ -698,7 +698,7 @@ nm_send_remove_folder(NMUser * user, NMFolder * folder, NMFIELD_TYPE_UTF8); /* Dispatch the request */ - rc = nm_send_request(user->conn, "deletecontact", fields, callback, data, &req); + rc = nm_send_request(user, "deletecontact", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, folder); @@ -730,7 +730,7 @@ nm_send_get_status(NMUser * user, NMUserRecord * user_record, g_strdup(dn), NMFIELD_TYPE_UTF8); /* Dispatch the request */ - rc = nm_send_request(user->conn, "getstatus", fields, callback, data, &req); + rc = nm_send_request(user, "getstatus", fields, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, user_record); @@ -779,7 +779,8 @@ nm_send_rename_contact(NMUser * user, NMContact * contact, 0, fields, NMFIELD_TYPE_ARRAY); fields = NULL; - rc = nm_send_request(user->conn, "updateitem", list, callback, data, &req); + rc = nm_send_request(user, "updateitem", list, callback, data, + &req); if (rc == NM_OK && req) nm_request_set_data(req, contact); } @@ -832,7 +833,8 @@ nm_send_rename_folder(NMUser * user, NMFolder * folder, const char *new_name, 0, fields, NMFIELD_TYPE_ARRAY); fields = NULL; - rc = nm_send_request(user->conn, "updateitem", list, callback, data, &req); + rc = nm_send_request(user, "updateitem", list, callback, data, + &req); if (rc == NM_OK && req) nm_request_set_data(req, folder); } @@ -881,7 +883,7 @@ nm_send_move_contact(NMUser * user, NMContact * contact, NMFolder * folder, NMFIELD_TYPE_UTF8); /* Dispatch the request */ - rc = nm_send_request(user->conn, "movecontact", list, callback, data, &req); + rc = nm_send_request(user, "movecontact", list, callback, data, &req); if (rc == NM_OK && req) nm_request_set_data(req, contact); @@ -916,7 +918,7 @@ nm_send_create_privacy_item(NMUser *user, const char *who, gboolean allow_list, fields = nm_field_add_pointer(fields, tag, 0, NMFIELD_METHOD_ADD, 0, g_strdup(who), NMFIELD_TYPE_UTF8); - rc = nm_send_request(user->conn, "createblock", fields, callback, data, NULL); + rc = nm_send_request(user, "createblock", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -950,7 +952,7 @@ nm_send_remove_privacy_item(NMUser *user, const char *dn, gboolean allow_list, fields = nm_field_add_pointer(fields, tag, 0, NMFIELD_METHOD_DELETE, 0, g_strdup(dn), NMFIELD_TYPE_DN); - rc = nm_send_request(user->conn, "updateblocks", fields, callback, data, NULL); + rc = nm_send_request(user, "updateblocks", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -971,7 +973,7 @@ nm_send_set_privacy_default(NMUser *user, gboolean default_deny, (default_deny ? g_strdup("1") : g_strdup("0")), NMFIELD_TYPE_UTF8); - rc = nm_send_request(user->conn, "updateblocks", fields, callback, data, NULL); + rc = nm_send_request(user, "updateblocks", fields, callback, data, NULL); nm_free_fields(&fields); return rc; @@ -985,7 +987,7 @@ nm_send_keepalive(NMUser *user, nm_response_cb callback, gpointer data) if (user == NULL) return NMERR_BAD_PARM; - rc = nm_send_request(user->conn, "ping", NULL, callback, data, NULL); + rc = nm_send_request(user, "ping", NULL, callback, data, NULL); return rc; } @@ -996,6 +998,7 @@ nm_process_new_data(NMUser * user) NMConn *conn; NMERR_T rc = NM_OK; guint32 val; + GError *error = NULL; if (user == NULL) return NMERR_BAD_PARM; @@ -1003,18 +1006,22 @@ nm_process_new_data(NMUser * user) conn = user->conn; /* Check to see if this is an event or a response */ - rc = nm_read_all(conn, (char *) &val, sizeof(val)); - if (rc == NM_OK) { - if (strncmp((char *) &val, "HTTP", strlen("HTTP")) == 0) + val = g_data_input_stream_read_uint32(conn->input, user->cancellable, + &error); + if (error == NULL) { + if (val == ('H' + ('T' << 8) + ('T' << 16) + ('P' << 24))) { rc = nm_process_response(user); - else - rc = nm_process_event(user, GUINT32_FROM_LE(val)); - + } else { + rc = nm_process_event(user, val); + } } else { - if (errno == EAGAIN) + if (error->code == G_IO_ERROR_WOULD_BLOCK || error->code == G_IO_ERROR_CANCELLED) { + /* Try again later or ignore. */ rc = NM_OK; - else + } else { rc = NMERR_PROTOCOL; + } + g_error_free(error); } return rc; @@ -1757,9 +1764,9 @@ nm_process_response(NMUser * user) NMConn *conn = user->conn; NMRequest *req = NULL; - rc = nm_read_header(conn); + rc = nm_read_header(user); if (rc == NM_OK) { - rc = nm_read_fields(conn, -1, &fields); + rc = nm_read_fields(user, -1, &fields); } if (rc == NM_OK) { diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c index 4ce92e54ba..35909267f6 100644 --- a/libpurple/protocols/novell/novell.c +++ b/libpurple/protocols/novell/novell.c @@ -1732,9 +1732,15 @@ novell_login_callback(GObject *source_object, GAsyncResult *res, gpointer data) 2, NOVELL_CONNECT_STEPS); conn->stream = G_IO_STREAM(sockconn); - conn->input = g_io_stream_get_input_stream(conn->stream); + conn->input = + g_data_input_stream_new(g_io_stream_get_input_stream(conn->stream)); conn->output = g_io_stream_get_output_stream(conn->stream); + g_data_input_stream_set_byte_order(conn->input, + G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + g_data_input_stream_set_newline_type(conn->input, + G_DATA_STREAM_NEWLINE_TYPE_LF); + my_addr = purple_network_get_my_ip_from_gio(sockconn); pwd = purple_connection_get_password(gc); ua = _user_agent_string(); |