Mercurial > pidgin
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: + */
