Wed, 25 Nov 2020 00:43:41 -0600
Use a GQueue for zephyr plus related cleanup
* Make `_Z_InputQ->complete` a boolean, as that's all it's used as.
* Use GLib allocation functions for `Z_InputQ` members.
* Use a `GQueue` for zephyr input.
* Use `*_find_custom` functions for input queue search.
Testing Done:
Compile only.
Reviewed at https://reviews.imfreedom.org/r/253/
--- a/libpurple/protocols/zephyr/ZCkIfNot.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/ZCkIfNot.c Wed Nov 25 00:43:41 2020 -0600 @@ -17,7 +17,7 @@ ZNotice_t tmpnotice; Code_t retval; register char *buffer; - register struct _Z_InputQ *qptr; + register Z_InputQ *qptr; if ((retval = Z_ReadEnqueue()) != ZERR_NONE) return (retval);
--- a/libpurple/protocols/zephyr/ZIfNotice.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/ZIfNotice.c Wed Nov 25 00:43:41 2020 -0600 @@ -17,7 +17,7 @@ ZNotice_t tmpnotice; Code_t retval; char *buffer; - struct _Z_InputQ *qptr; + Z_InputQ *qptr; if ((retval = Z_WaitForComplete()) != ZERR_NONE) return (retval);
--- a/libpurple/protocols/zephyr/ZInit.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/ZInit.c Wed Nov 25 00:43:41 2020 -0600 @@ -62,9 +62,8 @@ (void) memcpy((char *)&__HM_addr.sin_addr, addr, 4); - /* Initialize the input queue */ - __Q_Tail = NULL; - __Q_Head = NULL; + /* Initialize the input queue */ + g_queue_init(&Z_input_queue); /* If there is no zhm, the code will fall back to something which might * not be "right", but this is is ok, since none of the servers call
--- a/libpurple/protocols/zephyr/ZPeekPkt.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/ZPeekPkt.c Wed Nov 25 00:43:41 2020 -0600 @@ -14,7 +14,7 @@ ZPeekPacket(char **buffer, int *ret_len, struct sockaddr_in *from) { Code_t retval; - struct _Z_InputQ *nextq; + Z_InputQ *nextq; if ((retval = Z_WaitForComplete()) != ZERR_NONE) return (retval);
--- a/libpurple/protocols/zephyr/ZRecvNot.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/ZRecvNot.c Wed Nov 25 00:43:41 2020 -0600 @@ -14,7 +14,7 @@ ZReceiveNotice(ZNotice_t *notice, struct sockaddr_in *from) { char *buffer; - struct _Z_InputQ *nextq; + Z_InputQ *nextq; int len, auth; Code_t retval;
--- a/libpurple/protocols/zephyr/ZRecvPkt.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/ZRecvPkt.c Wed Nov 25 00:43:41 2020 -0600 @@ -14,7 +14,7 @@ ZReceivePacket(ZPacket_t buffer, int *ret_len, struct sockaddr_in *from) { Code_t retval; - struct _Z_InputQ *nextq; + Z_InputQ *nextq; if ((retval = Z_WaitForComplete()) != ZERR_NONE) return (retval);
--- a/libpurple/protocols/zephyr/Zinternal.c Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/Zinternal.c Wed Nov 25 00:43:41 2020 -0600 @@ -22,7 +22,7 @@ struct in_addr __My_addr; int __Q_CompleteLength; int __Q_Size; -struct _Z_InputQ *__Q_Head, *__Q_Tail; +GQueue Z_input_queue = G_QUEUE_INIT; struct sockaddr_in __HM_addr; struct sockaddr_in __HM_addr_real; ZLocations_t *__locate_list; @@ -167,25 +167,27 @@ * notices that haven't been touched in a while */ -static struct _Z_InputQ *Z_SearchQueue(ZUnique_Id_t *uid, ZNotice_Kind_t kind) +static Z_InputQ * +Z_SearchQueue(ZUnique_Id_t *uid, ZNotice_Kind_t kind) { - register struct _Z_InputQ *qptr; - struct _Z_InputQ *next; + register GList *list; + GList *next; gint64 now; now = g_get_monotonic_time(); - qptr = __Q_Head; + list = Z_input_queue.head; - while (qptr) { + while (list) { + Z_InputQ *qptr = (Z_InputQ *)list->data; if (ZCompareUID(uid, &qptr->uid) && qptr->kind == kind) { return qptr; } - next = qptr->next; + next = list->next; if (qptr->time && qptr->time + Z_NOTICETIMELIMIT < now) { Z_RemQueue(qptr); } - qptr = next; + list = next; } return NULL; } @@ -202,7 +204,7 @@ Code_t Z_ReadWait(void) { - register struct _Z_InputQ *qptr; + register Z_InputQ *qptr; Z_Hole *hole = NULL; ZNotice_t notice; ZPacket_t packet; @@ -326,18 +328,13 @@ connections). The other types can be fragmented and MUST run through this code. */ if ((qptr = Z_SearchQueue(¬ice.z_multiuid, notice.z_kind)) != NULL) { - /* - * If this is the first fragment, and we haven't already - * gotten a first fragment, grab the header from it. - */ - if (part == 0 && !qptr->header) { - qptr->header_len = packet_len-notice.z_message_len; - qptr->header = (char *) malloc((unsigned) qptr->header_len); - if (!qptr->header) - return (ENOMEM); - (void) memcpy(qptr->header, packet, qptr->header_len); - } - return (Z_AddNoticeToEntry(qptr, ¬ice, part)); + /* If this is the first fragment, and we haven't already gotten + * a first fragment, grab the header from it. */ + if (part == 0 && qptr->header == NULL) { + qptr->header_len = packet_len - notice.z_message_len; + qptr->header = g_memdup(packet, qptr->header_len); + } + return Z_AddNoticeToEntry(qptr, ¬ice, part); } } @@ -347,25 +344,12 @@ return ZERR_NONE; } - /* - * This is a notice we haven't heard of, so create a new queue - * entry for it and zero it out. - */ - qptr = (struct _Z_InputQ *)malloc(sizeof(struct _Z_InputQ)); - if (!qptr) - return (ENOMEM); - (void) memset((char *)qptr, 0, sizeof(struct _Z_InputQ)); + /* This is a notice we haven't heard of, so create a new queue entry + * for it and zero it out. */ + qptr = g_new0(Z_InputQ, 1); - /* Insert the entry at the end of the queue */ - qptr->next = NULL; - qptr->prev = __Q_Tail; - if (__Q_Tail) - __Q_Tail->next = qptr; - __Q_Tail = qptr; - - if (!__Q_Head) - __Q_Head = qptr; - + /* Insert the entry at the end of the queue */ + g_queue_push_tail(&Z_input_queue, qptr); /* Copy the from field, multiuid, kind, and checked authentication. */ qptr->from = from; @@ -373,50 +357,42 @@ qptr->kind = notice.z_kind; qptr->auth = notice.z_checked_auth; - /* If this is the first part of the notice, we take the header from it. We - * only take it if this is the first fragment so that the Unique ID's will - * be predictable. */ - if (part == 0) { - qptr->header_len = packet_len-notice.z_message_len; - qptr->header = (char *) malloc((unsigned) qptr->header_len); - if (!qptr->header) - return ENOMEM; - (void) memcpy(qptr->header, packet, qptr->header_len); - } + /* If this is the first part of the notice, we take the header from it. + * We only take it if this is the first fragment so that the Unique + * ID's will be predictable. */ + if (part == 0) { + qptr->header_len = packet_len - notice.z_message_len; + qptr->header = g_memdup(packet, qptr->header_len); + } - /* If this is not a fragmented notice, then don't bother with a hole - * list. */ - if (part == 0 && notice.z_message_len == partof) { - __Q_CompleteLength++; - qptr->holelist = NULL; - qptr->complete = 1; - /* allocate a msg buf for this piece */ - if (notice.z_message_len == 0) - qptr->msg = 0; - else if (!(qptr->msg = (char *) malloc((unsigned) notice.z_message_len))) - return(ENOMEM); - else - (void) memcpy(qptr->msg, notice.z_message, notice.z_message_len); - qptr->msg_len = notice.z_message_len; - __Q_Size += notice.z_message_len; - qptr->packet_len = qptr->header_len+qptr->msg_len; - if (!(qptr->packet = (char *) malloc((unsigned) qptr->packet_len))) - return (ENOMEM); - (void) memcpy(qptr->packet, qptr->header, qptr->header_len); - if(qptr->msg) - (void) memcpy(qptr->packet+qptr->header_len, qptr->msg, - qptr->msg_len); - return (ZERR_NONE); - } + /* If this is not a fragmented notice, then don't bother with a hole + * list. */ + if (part == 0 && notice.z_message_len == partof) { + __Q_CompleteLength++; + qptr->holelist = NULL; + qptr->complete = TRUE; + /* allocate a msg buf for this piece */ + if (notice.z_message_len == 0) { + qptr->msg = NULL; + } else { + qptr->msg = g_memdup(notice.z_message, notice.z_message_len); + } + qptr->msg_len = notice.z_message_len; + __Q_Size += notice.z_message_len; + qptr->packet_len = qptr->header_len + qptr->msg_len; + qptr->packet = g_new(gchar, qptr->packet_len); + memcpy(qptr->packet, qptr->header, qptr->header_len); + if (qptr->msg) { + memcpy(qptr->packet + qptr->header_len, qptr->msg, qptr->msg_len); + } + return ZERR_NONE; + } - /* - * We know how long the message is going to be (this is better - * than IP fragmentation...), so go ahead and allocate it all. - */ - if (!(qptr->msg = (char *) malloc((unsigned) partof)) && partof) - return (ENOMEM); - qptr->msg_len = partof; - __Q_Size += partof; + /* We know how long the message is going to be (this is better than IP + * fragmentation...), so go ahead and allocate it all. */ + qptr->msg = g_new0(gchar, partof); + qptr->msg_len = partof; + __Q_Size += partof; /* * Well, it's a fragmented notice...allocate a hole list and @@ -450,7 +426,7 @@ } Code_t -Z_AddNoticeToEntry(struct _Z_InputQ *qptr, ZNotice_t *notice, int part) +Z_AddNoticeToEntry(Z_InputQ *qptr, ZNotice_t *notice, int part) { GSList *thishole; Z_Hole *hole; @@ -468,7 +444,7 @@ last = part + notice->z_message_len - 1; /* copy in the message body */ - (void)memcpy(qptr->msg + part, notice->z_message, notice->z_message_len); + memcpy(qptr->msg + part, notice->z_message, notice->z_message_len); /* Search for a hole that overlaps with the current fragment */ hole = g_new(Z_Hole, 1); @@ -510,14 +486,12 @@ if (!qptr->complete) { __Q_CompleteLength++; } - qptr->complete = 1; + qptr->complete = TRUE; qptr->time = 0; /* don't time out anymore */ qptr->packet_len = qptr->header_len + qptr->msg_len; - if (!(qptr->packet = (char *)malloc((unsigned)qptr->packet_len))) { - return ENOMEM; - } - (void)memcpy(qptr->packet, qptr->header, qptr->header_len); - (void)memcpy(qptr->packet + qptr->header_len, qptr->msg, qptr->msg_len); + qptr->packet = g_new(gchar, qptr->packet_len); + memcpy(qptr->packet, qptr->header, qptr->header_len); + memcpy(qptr->packet + qptr->header_len, qptr->msg, qptr->msg_len); } return ZERR_NONE; @@ -557,7 +531,7 @@ notice->z_uid.tv.tv_sec = htonl((unsigned long)notice->z_uid.tv.tv_sec); notice->z_uid.tv.tv_usec = htonl((unsigned long)notice->z_uid.tv.tv_usec); - (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); + memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); notice->z_multiuid = notice->z_uid; @@ -712,71 +686,52 @@ return 0; } -struct _Z_InputQ * +static gint +find_complete_input(gconstpointer a, G_GNUC_UNUSED gconstpointer b) +{ + Z_InputQ *qptr = (Z_InputQ *)a; + return qptr->complete ? 0 : 1; +} + +Z_InputQ * Z_GetFirstComplete(void) { - struct _Z_InputQ *qptr; - - qptr = __Q_Head; + GList *list; - while (qptr) { - if (qptr->complete) - return (qptr); - qptr = qptr->next; - } - - return ((struct _Z_InputQ *)0); + list = g_queue_find_custom(&Z_input_queue, NULL, find_complete_input); + return list ? (Z_InputQ *)list->data : NULL; } -struct _Z_InputQ * -Z_GetNextComplete(struct _Z_InputQ *qptr) +Z_InputQ * +Z_GetNextComplete(Z_InputQ *qptr) { - qptr = qptr->next; - while (qptr) { - if (qptr->complete) - return (qptr); - qptr = qptr->next; - } + GList *list = g_queue_find(&Z_input_queue, qptr); - return ((struct _Z_InputQ *)0); + if (list) { + list = list->next; + list = g_list_find_custom(list, NULL, find_complete_input); + } + + return list ? (Z_InputQ *)list->data : NULL; } void -Z_RemQueue(struct _Z_InputQ *qptr) +Z_RemQueue(Z_InputQ *qptr) { - if (qptr->complete) - __Q_CompleteLength--; + if (qptr->complete) { + __Q_CompleteLength--; + } - __Q_Size -= qptr->msg_len; + __Q_Size -= qptr->msg_len; - free(qptr->header); - free(qptr->msg); - free(qptr->packet); + g_free(qptr->header); + g_free(qptr->msg); + g_free(qptr->packet); g_slist_free_full(qptr->holelist, g_free); - if (qptr == __Q_Head && __Q_Head == __Q_Tail) { - free ((char *)qptr); - __Q_Head = (struct _Z_InputQ *)0; - __Q_Tail = (struct _Z_InputQ *)0; - return; - } - - if (qptr == __Q_Head) { - __Q_Head = qptr->next; - __Q_Head->prev = (struct _Z_InputQ *)0; - free ((char *)qptr); - return; - } - if (qptr == __Q_Tail) { - __Q_Tail = qptr->prev; - __Q_Tail->next = (struct _Z_InputQ *)0; - free ((char *)qptr); - return; - } - qptr->prev->next = qptr->next; - qptr->next->prev = qptr->prev; - free ((char *)qptr); + g_queue_remove(&Z_input_queue, qptr); + g_free(qptr); } Code_t
--- a/libpurple/protocols/zephyr/internal.h Tue Nov 24 03:52:09 2020 -0600 +++ b/libpurple/protocols/zephyr/internal.h Wed Nov 25 00:43:41 2020 -0600 @@ -59,25 +59,23 @@ gint last; } Z_Hole; -struct _Z_InputQ { - struct _Z_InputQ *next; - struct _Z_InputQ *prev; +typedef struct { ZNotice_Kind_t kind; gint64 time; - int packet_len; - char *packet; - int complete; + gint packet_len; + gchar *packet; + gboolean complete; struct sockaddr_in from; GSList *holelist; /* element-type: Z_Hole* */ ZUnique_Id_t uid; int auth; - int header_len; - char *header; - int msg_len; - char *msg; -}; + gint header_len; + gchar *header; + gint msg_len; + gchar *msg; +} Z_InputQ; -extern struct _Z_InputQ *__Q_Head, *__Q_Tail; +extern GQueue Z_input_queue; extern ZLocations_t *__locate_list; extern int __locate_num; @@ -92,11 +90,11 @@ typedef Code_t (*Z_SendProc)(ZNotice_t *, char *, int, int); -struct _Z_InputQ *Z_GetFirstComplete(void); -struct _Z_InputQ *Z_GetNextComplete(struct _Z_InputQ *); +Z_InputQ *Z_GetFirstComplete(void); +Z_InputQ *Z_GetNextComplete(Z_InputQ *); Code_t Z_XmitFragment(ZNotice_t *, char *, int, int); -void Z_RemQueue(struct _Z_InputQ *); -Code_t Z_AddNoticeToEntry(struct _Z_InputQ *, ZNotice_t *, int); +void Z_RemQueue(Z_InputQ *); +Code_t Z_AddNoticeToEntry(Z_InputQ *, ZNotice_t *, int); Code_t Z_FormatAuthHeader(ZNotice_t *, char *, int, int *, Z_AuthProc); Code_t Z_FormatHeader(ZNotice_t *, char *, int, int *, Z_AuthProc); Code_t Z_FormatRawHeader(ZNotice_t *, char *, gsize, int *, char **, char **);