<commit_before>/* $Id$ */

/*
 *  (C) Copyright 2001-2002 <NAME> <<EMAIL>>,
 *                          <NAME> <<EMAIL>>,
 *                          <NAME> <<EMAIL>>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License Version
 *  2.1 as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netdb.h>
#include <errno.h>
#ifndef _AIX
#  include <string.h>
#endif
#include <time.h>
#include "libgadu.h"
#include "config.h"

/*
 * gg_free_event()
 *
 * zwalnia pami zajmowan przez informacj o zdarzeniu
 *
 *  - event - wskanik do informacji o zdarzeniu
 *
 * nie ma czego zwraca.
 */
void gg_free_event(struct gg_event *e)
{
	if (!e)
		return;
	
	if (e->type == GG_EVENT_MSG) {
		free(e->event.msg.message);
		free(e->event.msg.formats);
		free(e->event.msg.recipients);
	}
	
	if (e->type == GG_EVENT_NOTIFY)
		free(e->event.notify);
	
	if (e->type == GG_EVENT_STATUS)
		free(e->event.status.descr);

	if (e->type == GG_EVENT_NOTIFY_DESCR) {
		free(e->event.notify_descr.notify);
		free(e->event.notify_descr.descr);
	}
	
	free(e);
}

/*
 * gg_handle_message() // funkcja wewntrzna
 */
static int gg_handle_recv_msg(struct gg_header *h, struct gg_event *e)
{
	struct gg_recv_msg *r = (void*) h + sizeof(struct gg_header);
	char *p, *packet_end = (void*) r + h->length;

	gg_debug(GG_DEBUG_MISC, "-- received a message\n");

	//printf("packet=%p\n", h);

	for (p = (void*) r + sizeof(*r); *p; p++) {
		if (p >= packet_end) {
			gg_debug(GG_DEBUG_MISC, "-- malformed packet, message out of bounds.\n");
			errno = EINVAL;
			goto fail;
		}
	}
	p++;
	//printf("p=%p\npacket:end=%p\n", p, packet_end);

	/* przeanalizuj dodatkowe opcje */
	while (p < packet_end) {
		
		if (*p == 1) {			/* konferencje */

			struct gg_msg_recipients *m = (void*) p;
			int i, count;
			
			p += sizeof(*m);
			
			if (p > packet_end) {
				gg_debug(GG_DEBUG_MISC, "-- packet out of bounds\n");
				errno = EINVAL;
				goto fail;
			}

			count = fix32(m->count);
			
			if (!(e->event.msg.recipients = (void*) malloc(count * sizeof(uin_t)))) {
				gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
				errno = EINVAL;
				goto fail;
			}
			
			memcpy(e->event.msg.recipients, p, sizeof(uin_t) * count);

			p += sizeof(uin_t) * count;

			for (i = 0; i < count; i++)
				e->event.msg.recipients[i] = fix32(e->event.msg.recipients[i]);
			
			e->event.msg.recipients_count = count;

		} else if (*p == 2) {		/* richtext */

			unsigned short *len;
			void *tmp;
			
			if (p + 3 > packet_end) {
				gg_debug(GG_DEBUG_MISC, "-- packet out of bounds\n");
				errno = EINVAL;
				goto fail;
			}

			len = (unsigned short*) (p + 1);
			gg_debug(GG_DEBUG_MISC, "-- p = %p, packetend = %p, len = %d\n", p, packet_end, len);

			if (!(tmp = malloc(*len))) {
				gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
				goto fail;
			}

			p += 3;

			if (p + *len > packet_end) {
				gg_debug(GG_DEBUG_MISC, "-- packet out of bounds\n");
				errno = EINVAL;
				goto fail;
			}
				
			memcpy(tmp, p, *len);

			e->event.msg.formats = tmp;
			e->event.msg.formats_length = *len;

		} else				/* nieznana opcja */
			p = packet_end;
	}

	e->type = GG_EVENT_MSG;
	e->event.msg.msgclass = fix32(r->msgclass);
	e->event.msg.sender = fix32(r->sender);
	e->event.msg.time = fix32(r->time);
	e->event.msg.message = strdup((void*) r + sizeof(*r));

	return 0;
	
fail:
	free(e->event.msg.recipients);
	free(e->event.msg.formats);
	return -1;
}

/*<commit_msg>- poprawka listowania (joshua/w) - usunięcie wykrywania niewidocznych (w) - błędy w F1 (w) - można tylko raz zarejestrować numerek w ciągu sesji, by dzieciom trochę   utrudnić zabawę w polowanie na numerki (w) - rozpoznawanie płci. szczegóły w docs/themes.txt (w) - małe poprawki w dokumentacji (w)<commit_after>/* $Id$ */

/*
 *  (C) Copyright 2001-2002 <NAME> <<EMAIL>>,
 *                          <NAME> <<EMAIL>>,
 *                          <NAME> <<EMAIL>>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License Version
 *  2.1 as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netdb.h>
#include <errno.h>
#ifndef _AIX
#  include <string.h>
#endif
#include <time.h>
#include "libgadu.h"
#include "config.h"

/*
 * gg_free_event()
 *
 * zwalnia pami zajmowan przez informacj o zdarzeniu
 *
 *  - event - wskanik do informacji o zdarzeniu
 *
 * nie ma czego zwraca.
 */
void gg_free_event(struct gg_event *e)
{
	if (!e)
		return;
	
	if (e->type == GG_EVENT_MSG) {
		free(e->event.msg.message);
		free(e->event.msg.formats);
		free(e->event.msg.recipients);
	}
	
	if (e->type == GG_EVENT_NOTIFY)
		free(e->event.notify);
	
	if (e->type == GG_EVENT_STATUS)
		free(e->event.status.descr);

	if (e->type == GG_EVENT_NOTIFY_DESCR) {
		free(e->event.notify_descr.notify);
		free(e->event.notify_descr.descr);
	}
	
	free(e);
}

/*
 * gg_handle_message() // funkcja wewntrzna
 */
static int gg_handle_recv_msg(struct gg_header *h, struct gg_event *e)
{
	struct gg_recv_msg *r = (void*) h + sizeof(struct gg_header);
	char *p, *packet_end = (void*) r + h->length;

	gg_debug(GG_DEBUG_MISC, "-- received a message\n");

	//printf("packet=%p\n", h);

	for (p = (void*) r + sizeof(*r); *p; p++) {
		if (p >= packet_end) {
			gg_debug(GG_DEBUG_MISC, "-- malformed packet, message out of bounds.\n");
			errno = EINVAL;
			goto fail;
		}
	}
	p++;
	//printf("p=%p\npacket:end=%p\n", p, packet_end);

	/* przeanalizuj dodatkowe opcje */
	while (p < packet_end) {
		
		if (*p == 1) {			/* konferencje */

			struct gg_msg_recipients *m = (void*) p;
			int i, count;
			
			p += sizeof(*m);
			
			if (p > packet_end) {
				gg_debug(GG_DEBUG_MISC, "-- packet out of bounds\n");
				errno = EINVAL;
				goto fail;
			}

			count = fix32(m->count);
			
			if (!(e->event.msg.recipients = (void*) malloc(count * sizeof(uin_t)))) {
				gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
				errno = EINVAL;
				goto fail;
			}
			
			memcpy(e->event.msg.recipients, p, sizeof(uin_t) * count);

			p += sizeof(uin_t) * count;

			for (i = 0; i < count; i++)
				e->event.msg.recipients[i] = fix32(e->event.msg.recipients[i]);
			
			e->event.msg.recipients_count = count;

		} else if (*p == 2) {		/* richtext */

			unsigned short *len;
			void *tmp;
			
			if (p + 3 > packet_end) {
				gg_debug(GG_DEBUG_MISC, "-- packet out of bounds\n");
				errno = EINVAL;
				goto fail;
			}

			len = (unsigned short*) (p + 1);
			gg_debug(GG_DEBUG_MISC, "-- p = %p, packetend = %p, len = %d\n", p, packet_end, *len);

			if (!(tmp = malloc(*len))) {
				gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
				goto fail;
			}

			p += 3;

			if (p + *len > packet_end) {
				gg_debug(GG_DEBUG_MISC, "-- packet out of bounds\n");
				errno = EINVAL;
				goto fail;
			}
				
			memcpy(tmp, p, *len);

			e->event.msg.formats = tmp;
			e->event.msg.formats_length = *len;

		} else {				/* nieznana opcja */
			gg_debug(GG_DEBUG_MISC, "-- unknown option 0x%.2x\n", *p);
			p = packet_end;
		}
	}

	e->type = GG_EVENT_MSG;
	e->event.msg.msgclass = fix32(r->msgclass);
	e->event.msg.sender = fix32(r->sender);
	e->event.msg.time = fix32(r->time);
	e->event.msg.message = strdup((void*) r + sizeof(*r));

	return 0;
	
fail:
	free(e->event.msg.recipients);
	free(e->event.msg.formats);
	return -1;
}

/*
{'fraction_non_alphanumeric': 0.16274016468435498, 'fraction_numerical': 0.008577310155535225, 'mean_word_length': 2.991328160657234, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 117, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3250150', 'n_tokens_mistral': 3825, 'n_tokens_neox': 3374, 'n_words': 857}