Use a GQueue for zephyr plus related cleanup

Wed, 25 Nov 2020 00:43:41 -0600

author
Elliott Sales de Andrade <quantum.analyst@gmail.com>
date
Wed, 25 Nov 2020 00:43:41 -0600
changeset 40628
4266008a7791
parent 40627
3d6797191bf5
child 40629
5ee47cc23b41

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/

libpurple/protocols/zephyr/ZCkIfNot.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/ZIfNotice.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/ZInit.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/ZPeekPkt.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/ZRecvNot.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/ZRecvPkt.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/Zinternal.c file | annotate | diff | comparison | revisions
libpurple/protocols/zephyr/internal.h file | annotate | diff | comparison | revisions
--- 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(&notice.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, &notice, 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, &notice, 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(&notice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr));
+	memcpy(&notice->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 **);

mercurial