diff src/protocols/gg/common.c @ 2846:4b3f17ca66bf

[gaim-migrate @ 2859] so here it comes - some bugs fixed, new ones introduced: - password changing (was in part 1) - update to latest libgg (fixes password change on alpha) - auto away on idle (remembers GG_STATE_FRIENDS_MASK) - handle_errcode() can now use hide_login_progress() - remove encode_postdata() and use gg_urlencode() from libgg + encode only fields (not whole url) - fixed status related ugly bug in GG_EVENT_NOTIFY (!!!) - remove linefeed from messages Thanks, Arkadiusz Miskiewicz committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Wed, 05 Dec 2001 09:48:56 +0000
parents
children 7a3f16a375a5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/gg/common.c	Wed Dec 05 09:48:56 2001 +0000
@@ -0,0 +1,330 @@
+/* $Id: common.c 2859 2001-12-05 09:48:56Z warmenhoven $ */
+
+/*
+ *  (C) Copyright 2001 Wojtek Kaniewski <wojtekka@irc.pl>,
+ *                     Robert J. Woźny <speedy@ziew.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License Version 2 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU 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 <stdarg.h>
+#include <pwd.h>
+#include <time.h>
+#ifdef sun
+  #include <sys/filio.h>
+#endif
+#include "libgg.h"
+#include "config.h"
+
+/*
+ * gg_debug()
+ *
+ * wyrzuca komunikat o danym poziomie, o ile użytkownik sobie tego życzy.
+ *
+ *  - level - poziom wiadomości,
+ *  - format... - treść wiadomości (printf-alike.)
+ *
+ * niczego nie zwraca.
+ */
+void gg_debug(int level, char *format, ...)
+{
+	va_list ap;
+	
+	if ((gg_debug_level & level)) {
+		va_start(ap, format);
+		vprintf(format, ap);
+		va_end(ap);
+	}
+}
+
+/*
+ * gg_alloc_sprintf()
+ *
+ * robi dokładnie to samo, co sprintf(), tyle że alokuje sobie wcześniej
+ * miejsce na dane. powinno działać na tych maszynach, które mają funkcję
+ * vsnprintf() zgodną z C99, jak i na wcześniejszych.
+ *
+ *  - format, ... - parametry takie same jak w innych funkcjach *printf()
+ *
+ * zwraca zaalokowany buforek, który wypadałoby później zwolnić, lub NULL
+ * jeśli nie udało się wykonać zadania.
+ */
+char *gg_alloc_sprintf(char *format, ...)
+{
+        va_list ap;
+        char *buf = NULL, *tmp;
+        int size = 0, res;
+
+        va_start(ap, format);
+
+        if ((size = vsnprintf(buf, 0, format, ap)) < 1) {
+                size = 128;
+                do {
+                        size *= 2;
+                        if (!(tmp = realloc(buf, size))) {
+                                free(buf);
+                                return NULL;
+                        }
+                        buf = tmp;
+                        res = vsnprintf(buf, size, format, ap);
+                } while (res == size - 1);
+        } else {
+                if (!(buf = malloc(size + 1)))
+                        return NULL;
+        }
+
+        vsnprintf(buf, size + 1, format, ap);
+
+        va_end(ap);
+
+        return buf;
+}
+
+/*
+ * gg_get_line()
+ * 
+ * podaje kolejną linię z bufora tekstowego. psuje co bezpowrotnie, dzieląc
+ * na kolejne stringi. zdarza się, nie ma potrzeby pisania funkcji dublującej
+ * bufor żeby tylko mieć nieruszone dane wejściowe, skoro i tak nie będą nam
+ * poźniej potrzebne. obcina `\r\n'.
+ * 
+ *  - ptr - wskaźnik do zmiennej, która przechowuje aktualną pozycję
+ *    w przemiatanym buforze.
+ * 
+ * wskaźnik do kolejnej linii tekstu lub NULL, jeśli to już koniec bufora.
+ */
+char *gg_get_line(char **ptr)
+{
+        char *foo, *res;
+
+        if (!ptr || !*ptr || !strcmp(*ptr, ""))
+                return NULL;
+
+        res = *ptr;
+
+        if (!(foo = strchr(*ptr, '\n')))
+                *ptr += strlen(*ptr);
+        else {
+                *ptr = foo + 1;
+                *foo = 0;
+                if (res[strlen(res) - 1] == '\r')
+                        res[strlen(res) - 1] = 0;
+        }
+
+        return res;
+}
+
+/*
+ * gg_connect()
+ *
+ * łączy się z serwerem. pierwszy argument jest typu (void *), żeby nie
+ * musieć niczego inkludować w libgg.h i nie psuć jakiś głupich zależności
+ * na dziwnych systemach.
+ *
+ *  - addr - adres serwera (struct in_addr *),
+ *  - port - port serwera,
+ *  - async - ma być asynchroniczne połączenie?
+ *
+ * zwraca połączonego socketa lub -1 w przypadku błędu. zobacz errno.
+ */
+int gg_connect(void *addr, int port, int async)
+{
+	int sock, one = 1;
+	struct sockaddr_in sin;
+	struct in_addr *a = addr;
+
+	gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async);
+	
+	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+		gg_debug(GG_DEBUG_MISC, "-- socket() failed. errno = %d (%s)\n", errno, strerror(errno));
+		return -1;
+	}
+
+	if (async) {
+		if (ioctl(sock, FIONBIO, &one) == -1) {
+			gg_debug(GG_DEBUG_MISC, "-- ioctl() failed. errno = %d (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+	}
+
+	sin.sin_port = htons(port);
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = a->s_addr;
+	
+	if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) {
+		if (errno && (!async || errno != EINPROGRESS)) {
+			gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+		gg_debug(GG_DEBUG_MISC, "-- connect() in progress\n");
+	}
+	
+	return sock;
+}
+
+/*
+ * gg_read_line()
+ *
+ * czyta jedną linię tekstu z socketa.
+ *
+ *  - sock - socket,
+ *  - buf - wskaźnik bufora,
+ *  - length - długość bufora.
+ *
+ * olewa błędy. jeśli na jakiś trafi, potraktuje go jako koniec linii.
+ */
+void gg_read_line(int sock, char *buf, int length)
+{
+	int ret;
+
+	gg_debug(GG_DEBUG_FUNCTION, "** gg_read_line(...);\n");
+	
+	for (; length > 1; buf++, length--) {
+		do {
+			if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) {
+				*buf = 0;
+				return;
+			}
+		} while (ret == -1 && errno == EINTR);
+
+		if (*buf == '\n') {
+			buf++;
+			break;
+		}
+	}
+
+	*buf = 0;
+	return;
+}
+
+/*
+ * gg_chomp()
+ *
+ * ucina "\r\n" lub "\n" z końca linii.
+ *
+ *  - line - ofiara operacji plastycznej.
+ *
+ * niczego nie zwraca.
+ */
+void gg_chomp(char *line)
+{
+	if (!line || strlen(line) < 1)
+		return;
+
+	if (line[strlen(line) - 1] == '\n')
+		line[strlen(line) - 1] = 0;
+	if (line[strlen(line) - 1] == '\r')
+		line[strlen(line) - 1] = 0;
+}
+
+
+/*
+ * gg_urlencode() // funkcja wewnętrzna
+ *
+ * zamienia podany tekst na ciąg znaków do formularza http. przydaje się
+ * przy szukaniu userów z dziwnymi znaczkami.
+ *
+ *  - str - ciąg znaków do poprawki.
+ *
+ * zwraca zaalokowany bufor, który wypadałoby kiedyś zwolnić albo NULL
+ * w przypadku błędu.
+ */
+char *gg_urlencode(char *str)
+{
+	char *p, *q, *buf, hex[] = "0123456789abcdef";
+	int size = 0;
+
+	if (!str)
+		str = strdup("");
+
+	for (p = str; *p; p++, size++) {
+		if (!((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9')))
+			size += 2;
+	}
+
+	if (!(buf = malloc(size + 1)))
+		return NULL;
+
+	for (p = str, q = buf; *p; p++, q++) {
+		if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9'))
+			*q = *p;
+		else {
+			*q++ = '%';
+			*q++ = hex[*p >> 4 & 15];
+			*q = hex[*p & 15];
+		}
+	}
+
+	*q = 0;
+
+	return buf;
+}
+
+/*
+ * gg_http_hash()
+ *
+ * funkcja, która liczy hash dla adresu e-mail i hasła.
+ *
+ *  - email - adres email,
+ *  - password - hasło.
+ *
+ * zwraca hash wykorzystywany przy rejestracji i wszelkich
+ * manipulacjach własnego wpisu w katalogu publicznym.
+ */
+
+int gg_http_hash(unsigned char *email, unsigned char *password)
+{
+	unsigned int a, c;
+	int b, i;
+	b = (-1);
+
+	i = 0;
+	while ((c = (int) email[i++]) != 0) {
+		a = (c ^ b) + (c << 8);
+		b = (a >> 24) | (a << 8);
+	}
+
+	i = 0;
+	while ((c = (int) password[i++]) != 0) {
+		a = (c ^ b) + (c << 8);
+		b = (a >> 24) | (a << 8);
+	}
+
+	return (b < 0 ? -b : b);
+}
+
+/*
+ * Local variables:
+ * c-indentation-style: k&r
+ * c-basic-offset: 8
+ * indent-tabs-mode: notnil
+ * End:
+ *
+ * vim: shiftwidth=8:
+ */