Libgadu #3 – Obsługa katalogu publicznego

Mar 05
2010

Kadu_logoPotrafiąc już masowo wysyłać jedną wiadomość pod kilka wcześniej zapisanych w pliku tekstowym numerów możemy z dużym powodzeniem poinformować w bardzo szybki i wygodny sposób naszych znajomych o jakimś wydarzeniu.

Co jednak, jeśli tą wiadomość zechcemy wysłać do całego miasta, aby poinformować wszystkich jego mieszkańców o jakiejś uroczystości? W takiej sytuacji z pomocą może nam przyjść katalog publiczny, dzięki któremu wyszukamy interesujące nas osoby na podstawie imienia, pseudonimu, płci, czy też miasta.

W examplach libgadu nie znajdziemy programu łączącego się z katalogiem publicznym, zatem musimy napisać go sami od podstaw. Przed przystąpieniem do pisania kodu wypadałoby zaznajomić się z strukturą katalogu publicznego. Jak widać otrzymujemy prawie, że gotowca z strony projektu. Jedyne co musimy zrobić to wyeliminować zabezpieczenie anty script kiddle oraz dopisać kilka linijek.

Najważniejsze rzeczy, na które należy zwrócić uwagę to:

  • Struktura sesji (gg_login_params)
  • Strultura zdarzenia (gg_event)
  • Zdarzenie GG_EVENT_PUBDIR50_SEARCH_REPLY
  • Wysłanie listy kontaktów przy pomocy funkcji gg_notify(), aby móc komunikować się z serwerem
  • Optymalizacja kodu pod kątem odbierania „paczek” danych, ale tym zajmiemy się na końcu

Najsampierw sklepmy to, co już mamy wyłożone na tacy 🙂

/*
Program łączy się z katalogiem
Publicznym i pobiera dane.
 
Autor:
Komeniusz [Nie odpowiadam za użycie tego programu!]
Licencja: GNU - edukacyjna!
 
Program testowano na:
System: Ubuntu 9.10
Biblioteka: Libgadu 1.9.0-rc2 (wersja testowa)
 
Download Libgadu: http://toxygen.net/libgadu/
Dokumentacja Libgadu: http://toxygen.net/libgadu/doc/
*/
//Niezbędne biblioteki
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "libgadu.h"
 
int main(int argc, char **argv) {
if(argc < 3) {
	printf("Użycie: %s <numer> <hasło>n", argv[0]);
    return 1;
}
 
//Nasze strukturki
struct gg_session *sesja;
struct gg_event *event;
struct gg_login_params p;
 
gg_debug_level = 0;
 
memset(&p, 0, sizeof(p));
p.uin = atoi(argv[1]);
p.password = argv[2];
p.encoding = GG_ENCODING_UTF8;
 
if(!(sesja = gg_login(&p))) {
	printf("Nie udało się połączyć: %sn", strerror(errno));
	gg_free_session(sesja);
	return 1;
}
 
//Tworzymy nowe zapytanie do serwera
gg_pubdir50_t zapytanie;
zapytanie = gg_pubdir50_new(GG_PUBDIR50_SEARCH_REQUEST);
 
if(!zapytanie) {
	printf("Brak pamięci");
}
 
//Wypełniamy pola zapytania do wyszukiwania w katalogu
//Struktura ogólna - gg_pubdir50_add(zapytanie, pole, "wartość");
 
//Zaczynamy od numeru - 0
gg_pubdir50_add(zapytanie, GG_PUBDIR50_START, "0");
 
//Przeszukiwanie według imienia - Anna
gg_pubdir50_add(zapytanie, GG_PUBDIR50_FIRSTNAME, "Anna");
 
//Żądana płeć - kobieta
gg_pubdir50_add(zapytanie, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
 
//Osoby aktualnie dostępne
gg_pubdir50_add(zapytanie, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
 
//Wszystkie rodzaje pól zapytań
/*
GG_PUBDIR50_UIN 	Numer Gadu-Gadu.
GG_PUBDIR50_STATUS 	Status (tylko wynik wyszukiwania).
GG_PUBDIR50_FIRSTNAME 	Imię.
GG_PUBDIR50_LASTNAME 	Nazwisko.
GG_PUBDIR50_NICKNAME 	Pseudonim.
GG_PUBDIR50_BIRTHYEAR 	Rok urodzenia lub przedział lat oddzielony spacją.
GG_PUBDIR50_CITY 	Miejscowość.
GG_PUBDIR50_GENDER 	Płeć.
	GG_PUBDIR50_GENDER_FEMALE 	Kobieta.
	GG_PUBDIR50_GENDER_MALE 	Mężczyzna.
GG_PUBDIR50_ACTIVE 	Osoba dostępna (tylko wyszukiwanie).
	GG_PUBDIR50_ACTIVE_TRUE 	Wyszukaj tylko osoby dostępne.
GG_PUBDIR50_START 	Numer początkowy wyszukiwania (tylko wyszukiwanie).
GG_PUBDIR50_FAMILYNAME 	Nazwisko rodowe (tylko wysyłanie informacji o sobie).
GG_PUBDIR50_FAMILYCITY 	Miejscowość pochodzenia (tylko wysyłanie informacji o sobie).
*/
 
//Wykonujemy zapytanie
gg_pubdir50(sesja, zapytanie);
 
//Aby móc komunikować się z serwerem
//Wysyłamy pustą listę kontaktów
if(gg_notify(sesja, NULL, 0) == -1) {
	printf("Polaczenie przerwane: %sn", strerror(errno));
	gg_free_session(sesja);
	return 1;
}
 
while(1) {
	if(!(event = gg_watch_fd(sesja))) {
		  printf("Polaczenie przerwane: %sn", strerror(errno));
		  gg_logoff(sesja);
		  gg_free_session(sesja);
		  return 1;
	}
 
//Jeśli odebraliśmy odpowiedź od
//Katalogu publicznego
/*
GG_PUBDIR50_WRITE 	Wysłanie do serwera informacji o sobie.
GG_PUBDIR50_READ 	Pobranie z serwera informacji o sobie.
GG_PUBDIR50_SEARCH 	Wyszukiwanie w katalogu publicznym.
GG_PUBDIR50_SEARCH_REPLY 	Wynik wyszukiwania w katalogu publicznym.
*/
	if(event->type == GG_EVENT_PUBDIR50_SEARCH_REPLY)  {
		gg_pubdir50_t wynik;
		int i, ilosc;
 
		wynik = event->event.pubdir50;
		ilosc = gg_pubdir50_count(wynik);
 
		if(ilosc < 1) {
			printf("Nie znaleziono");
			return;
		}
 
//Wyciąganie informacji
		for(i = 0; i < ilosc; i++) {
			const char *numer, *imie, *pseudo, *urodzony, *miasto, *status;
 
			numer = gg_pubdir50_get(wynik, i, GG_PUBDIR50_UIN);
			imie = gg_pubdir50_get(wynik, i, GG_PUBDIR50_FIRSTNAME);
			pseudo = gg_pubdir50_get(wynik, i, GG_PUBDIR50_NICKNAME);
			urodzony = gg_pubdir50_get(wynik, i, GG_PUBDIR50_BIRTHYEAR);
			miasto = gg_pubdir50_get(wynik, i, GG_PUBDIR50_CITY);
			status = gg_pubdir50_get(wynik, i, GG_PUBDIR50_STATUS);
 
//Drukowanie informacji
			printf("Numer: %snImię: %snPseudonim: %sn"
				   "Urodzony: %snMiejscowość: %sn",
				   numer, imie, pseudo, urodzony, miasto);
 
//Wyświetlamy status znalezionej osoby
			switch((status) ? atoi(status) : -1) {
				case GG_STATUS_AVAIL:
				    printf("Dostępnyn");
				    break;
				case GG_STATUS_BUSY:
				    printf("Zajętyn");
				    break;
				default:
				    printf("(?)n");
			}
 
		printf("n");
		}
	}
//Zwolnienie pamięci dla struktury zdarzenia
	gg_event_free(event);
}
 
//Zwolnienie pamięci dla struktury sesji
gg_free_session(sesja);
//Zwolnienie pamięci dla zapytania i odpowiedzi serwera
gg_pubdir50_free(zapytanie);
 
return 0;
}

Program przyjmuje 2 parametry – numer i hasło. Jako wynik zwraca 20 numerów z katalogu publicznego, pasujących do naszego zapytania. Przykładowy wynik może wyglądać następująco

Numer: 1213***
Imię: Anna
Pseudonim: anna
Urodzony: (null)
Miejscowość: Łódź
Zajęty

Numer: 2095***
Imię: Anna
Pseudonim: Anna
Urodzony: 1994
Miejscowość: (null)
Dostępny

Numer: 496***
Imię: Anna
Pseudonim: (null)
Urodzony: 1977
Miejscowość: (null)
Zajęty

[…]

Program zwraca jedynie 20 numerów, ponieważ serwer GG zwraca taką ilość po wykonaniu zapytania. Aby wyciągnąć z niego wszystkie wyniki pasujące do naszego zapytania należy wykonać kilka zapytań z zmieniającym się numerem sekwencyjnym od, którego będziemy kontynuować przeszukiwanie bazy danych.

/* Program łączy się z katalogiem Publicznym i pobiera dane. Autor: Komeniusz [Nie odpowiadam za użycie tego programu!] Licencja: GNU - edukacyjna! Program testowano na: System: Ubuntu 9.10 Biblioteka: Libgadu 1.9.0-rc2 (wersja testowa) Download Libgadu: http://toxygen.net/libgadu/ Dokumentacja Libgadu: http://toxygen.net/libgadu/doc/ */
 
//Niezbędne biblioteki
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "libgadu.h"
 
int main(int argc, char **argv) {
if(argc < 5) {
	printf("Użycie: %s <numer> <hasło> <limit> <tryb>n", argv[0]);
    return 1;
}
 
//Nasze strukturki
struct gg_session *sesja;
struct gg_event *event;
struct gg_login_params p;
 
//Licznik znalezionych osób
int osoby;
 
//Limit odbieranych danych
int limit = atoi(argv[3]);
 
//Rodzaj wyprowadzanych danych
int tryb = atoi(argv[4]);
 
gg_debug_level = 0;
 
memset(&p, 0, sizeof(p));
p.uin = atoi(argv[1]);
p.password = argv[2];
p.encoding = GG_ENCODING_UTF8;
 
if(!(sesja = gg_login(&p))) {
	printf("Nie udało się połączyć: %sn", strerror(errno));
	gg_free_session(sesja);
	return 1;
}
 
//Tworzymy nowe zapytanie do serwera
gg_pubdir50_t zapytanie;
zapytanie = gg_pubdir50_new(GG_PUBDIR50_SEARCH_REQUEST);
 
if(!zapytanie) {
	printf("Brak pamięci");
}
 
//Wypełniamy pola zapytania do wyszukiwania w katalogu
//Struktura ogólna - gg_pubdir50_add(zapytanie, pole, "wartość");
 
//Zaczynamy od numeru - 0
gg_pubdir50_add(zapytanie, GG_PUBDIR50_START, "0");
 
//Przeszukiwanie według imienia - Anna
gg_pubdir50_add(zapytanie, GG_PUBDIR50_FIRSTNAME, "Anna");
 
//Żądana płeć - kobieta
//gg_pubdir50_add(zapytanie, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
 
//Osoby aktualnie dostępne
//gg_pubdir50_add(zapytanie, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
 
//Wszystkie rodzaje pól zapytań
/* GG_PUBDIR50_UIN Numer Gadu-Gadu. GG_PUBDIR50_STATUS Status (tylko wynik wyszukiwania). GG_PUBDIR50_FIRSTNAME Imię. GG_PUBDIR50_LASTNAME Nazwisko. GG_PUBDIR50_NICKNAME Pseudonim. GG_PUBDIR50_BIRTHYEAR Rok urodzenia lub przedział lat oddzielony spacją. GG_PUBDIR50_CITY Miejscowość. GG_PUBDIR50_GENDER Płeć. GG_PUBDIR50_GENDER_FEMALE Kobieta. GG_PUBDIR50_GENDER_MALE Mężczyzna. GG_PUBDIR50_ACTIVE Osoba dostępna (tylko wyszukiwanie). GG_PUBDIR50_ACTIVE_TRUE Wyszukaj tylko osoby dostępne. GG_PUBDIR50_START Numer początkowy wyszukiwania (tylko wyszukiwanie). GG_PUBDIR50_FAMILYNAME Nazwisko rodowe (tylko wysyłanie informacji o sobie). GG_PUBDIR50_FAMILYCITY Miejscowość pochodzenia (tylko wysyłanie informacji o sobie). */
 
//Wykonujemy zapytanie
gg_pubdir50(sesja, zapytanie);
 
//Aby móc komunikować się z serwerem
//Wysyłamy pustą listę kontaktów
if(gg_notify(sesja, NULL, 0) == -1) {
	printf("Polaczenie przerwane: %sn", strerror(errno));
	gg_free_session(sesja);
	return 1;
}
 
while(1) {
	if(!(event = gg_watch_fd(sesja))) {
		  printf("Polaczenie przerwane: %sn", strerror(errno));
		  gg_logoff(sesja);
		  gg_free_session(sesja);
		  return 1;
	}
 
//Jeśli odebraliśmy odpowiedź od
//Katalogu publicznego
/* GG_PUBDIR50_WRITE Wysłanie do serwera informacji o sobie. GG_PUBDIR50_READ Pobranie z serwera informacji o sobie. GG_PUBDIR50_SEARCH Wyszukiwanie w katalogu publicznym. GG_PUBDIR50_SEARCH_REPLY Wynik wyszukiwania w katalogu publicznym. */
	if(event->type == GG_EVENT_PUBDIR50_SEARCH_REPLY)  {
		gg_pubdir50_t wynik;
		int i, ilosc;
 
		wynik = event->event.pubdir50;
		ilosc = gg_pubdir50_count(wynik);
		char tab[32];
 
		if(ilosc < 1) {
			printf("Nie znaleziono");
			return;
		}
 
//Łączna ilość znalezionych osób
		osoby += ilosc;
 
//Wyciąganie informacji
		for(i = 0; i < ilosc; i++) {
			const char *numer, *imie, *pseudo, *urodzony, *miasto, *status;
			//printf("[%d]",i);
 
			numer = gg_pubdir50_get(wynik, i, GG_PUBDIR50_UIN);
			imie = gg_pubdir50_get(wynik, i, GG_PUBDIR50_FIRSTNAME);
			pseudo = gg_pubdir50_get(wynik, i, GG_PUBDIR50_NICKNAME);
			urodzony = gg_pubdir50_get(wynik, i, GG_PUBDIR50_BIRTHYEAR);
			miasto = gg_pubdir50_get(wynik, i, GG_PUBDIR50_CITY);
			status = gg_pubdir50_get(wynik, i, GG_PUBDIR50_STATUS);
 
//Jeśli drukujemy wszystkie informacje
			if(tryb != 1) {
//Drukowanie informacji
				printf("Numer: %snImię: %snPseudonim: %sn"
					   "Urodzony: %snMiejscowość: %sn",
					   numer, imie, pseudo, urodzony, miasto);
 
//Wyświetlamy status znalezionej osoby
				switch((status) ? atoi(status) : -1) {
					case GG_STATUS_AVAIL:
						printf("Dostępnyn");
						break;
					case GG_STATUS_BUSY:
						printf("Zajętyn");
						break;
					default:
						printf("(?)n");
				}
//Jeśli drukujemy wyłącznie numery
			} else {
				printf("%s",numer);
			}
		printf("n");
		}
//Jeśli otrzymamy mniej, niż 20 wyników
//Oznacza to, że nie ma więcej danych do pobrania
		if(ilosc < 20) {
			break;
		}
 
//Jeśli ilość odebranych wyników będzie
//Większa od ustalonego limitu
		if(osoby > limit) {
			break;
		}
 
		snprintf(tab, sizeof(tab), "%d", gg_pubdir50_next(wynik));
		gg_pubdir50_add(zapytanie, GG_PUBDIR50_START, tab);
		gg_pubdir50(sesja, zapytanie);
	}
//Zwolnienie pamięci dla struktury zdarzenia
	gg_event_free(event);
}
 
//Zwolnienie pamięci dla struktury sesji
gg_free_session(sesja);
//Zwolnienie pamięci dla zapytania i odpowiedzi serwera
gg_pubdir50_free(zapytanie);
 
return 0;
}

Powyższy program przyjmuje dodatkowo 2 parametry, maksymalną ilość pobranych wyników, nie przełamując sesji, tzn. jeśli podamy liczbę 31, a serwer będzie miał 237 wyników, dostaniemy ich 40. Drugi parametr natomiast to rodzaj wyświetlania pobranych danych. Jeśli będzie on równy 1 to program wyświetli wyłącznie numery, bez dodatkowych danych. Może nam się to przydać do sporządzenia pliku *.txt z numerami użytkowników naszego miasta, a następnie wykorzystanie ich przy pomocy programu dostępnego w poprzedniej części artykułu o bibliotece Libgadu.

komeniusz@cyber-jadro:~/libgadu/examples$ ./katalog numerek hasełko 2 1 > numery.txt
komeniusz@cyber-jadro:~/libgadu/examples$ cat numery.txt
1672****
11991****
593****
882****
3419****
3323****
1153****
621****
8006****
130****
592****
648****
9690****
131****
174****
283****
879****
649****
642****
8847****
komeniusz@cyber-jadro:~/libgadu/examples$

Jak widać plik *.txt możemy utworzyć wykorzystując standardowy potok Linuksowy >

Co jednak, jeśli zależy nam na mniejszej komplikacji operacji, bez potrzeby korzystania z dwóch programów? Mhh… Można połączyć powyższy katalog.c z plikiem send.c.

/*
Program łączy się z katalogiem
Publicznym, pobiera dane
I wysyła ustaloną wiadomość.
 
Autor:
Komeniusz [Nie odpowiadam za użycie tego programu!]
Licencja: GNU - edukacyjna!
 
Program testowano na:
System: Ubuntu 9.10
Biblioteka: Libgadu 1.9.0-rc2 (wersja testowa)
 
Download Libgadu: http://toxygen.net/libgadu/
Dokumentacja Libgadu: http://toxygen.net/libgadu/doc/
*/
 
//Niezbędne biblioteki
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "libgadu.h"
 
int main(int argc, char **argv) {
if(argc < 4) {
	printf("Użycie: %s <numer> <hasło> <limit>n", argv[0]);
    return 1;
}
 
//Nasze strukturki
struct gg_session *sesja;
struct gg_event *event;
struct gg_login_params p;
 
//Licznik znalezionych osób
int osoby;
 
//Limit odbieranych danych
int limit = atoi(argv[3]);
 
gg_debug_level = 0;
 
memset(&p, 0, sizeof(p));
p.uin = atoi(argv[1]);
p.password = argv[2];
p.encoding = GG_ENCODING_UTF8;
 
if(!(sesja = gg_login(&p))) {
	printf("Nie udało się połączyć: %sn", strerror(errno));
	gg_free_session(sesja);
	return 1;
}
 
//Tworzymy nowe zapytanie do serwera
gg_pubdir50_t zapytanie;
zapytanie = gg_pubdir50_new(GG_PUBDIR50_SEARCH_REQUEST);
 
if(!zapytanie) {
	printf("Brak pamięci");
}
 
//Wypełniamy pola zapytania do wyszukiwania w katalogu
//Struktura ogólna - gg_pubdir50_add(zapytanie, pole, "wartość");
 
//Zaczynamy od numeru - 0
gg_pubdir50_add(zapytanie, GG_PUBDIR50_START, "0");
 
//Miasto
gg_pubdir50_add(zapytanie, GG_PUBDIR50_CITY, "Warszawa");
 
//Przeszukiwanie według imienia - Anna
//gg_pubdir50_add(zapytanie, GG_PUBDIR50_FIRSTNAME, "wojtek");
 
//Żądana płeć - kobieta
//gg_pubdir50_add(zapytanie, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
 
//Osoby aktualnie dostępne
gg_pubdir50_add(zapytanie, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
 
//Wszystkie rodzaje pól zapytań
/*
GG_PUBDIR50_UIN 	Numer Gadu-Gadu.
GG_PUBDIR50_STATUS 	Status (tylko wynik wyszukiwania).
GG_PUBDIR50_FIRSTNAME 	Imię.
GG_PUBDIR50_LASTNAME 	Nazwisko.
GG_PUBDIR50_NICKNAME 	Pseudonim.
GG_PUBDIR50_BIRTHYEAR 	Rok urodzenia lub przedział lat oddzielony spacją.
GG_PUBDIR50_CITY 	Miejscowość.
GG_PUBDIR50_GENDER 	Płeć.
	GG_PUBDIR50_GENDER_FEMALE 	Kobieta.
	GG_PUBDIR50_GENDER_MALE 	Mężczyzna.
GG_PUBDIR50_ACTIVE 	Osoba dostępna (tylko wyszukiwanie).
	GG_PUBDIR50_ACTIVE_TRUE 	Wyszukaj tylko osoby dostępne.
GG_PUBDIR50_START 	Numer początkowy wyszukiwania (tylko wyszukiwanie).
GG_PUBDIR50_FAMILYNAME 	Nazwisko rodowe (tylko wysyłanie informacji o sobie).
GG_PUBDIR50_FAMILYCITY 	Miejscowość pochodzenia (tylko wysyłanie informacji o sobie).
*/
 
//Wykonujemy zapytanie
gg_pubdir50(sesja, zapytanie);
 
//Aby móc komunikować się z serwerem
//Wysyłamy pustą listę kontaktów
if(gg_notify(sesja, NULL, 0) == -1) {
	printf("Polaczenie przerwane: %sn", strerror(errno));
	gg_free_session(sesja);
	return 1;
}
 
while(1) {
	if(!(event = gg_watch_fd(sesja))) {
		  printf("Polaczenie przerwane: %sn", strerror(errno));
		  gg_logoff(sesja);
		  gg_free_session(sesja);
		  return 1;
	}
 
//Jeśli odebraliśmy odpowiedź od
//Katalogu publicznego
/*
GG_PUBDIR50_WRITE 	Wysłanie do serwera informacji o sobie.
GG_PUBDIR50_READ 	Pobranie z serwera informacji o sobie.
GG_PUBDIR50_SEARCH 	Wyszukiwanie w katalogu publicznym.
GG_PUBDIR50_SEARCH_REPLY 	Wynik wyszukiwania w katalogu publicznym.
*/
	if(event->type == GG_EVENT_PUBDIR50_SEARCH_REPLY)  {
		gg_pubdir50_t wynik;
		int i, ilosc;
 
		wynik = event->event.pubdir50;
		ilosc = gg_pubdir50_count(wynik);
		char tab[32];
 
		if(ilosc < 1) {
			printf("Nie znaleziono");
			return;
		}
 
//Łączna ilość znalezionych osób
		osoby += ilosc;
 
//Wyciąganie informacji
		for(i = 0; i > ilosc; i++) {
			const char *numer, *imie, *pseudo, *urodzony, *miasto, *status;
			//printf("[%d]",i);
 
			numer = gg_pubdir50_get(wynik, i, GG_PUBDIR50_UIN);
			imie = gg_pubdir50_get(wynik, i, GG_PUBDIR50_FIRSTNAME);
			pseudo = gg_pubdir50_get(wynik, i, GG_PUBDIR50_NICKNAME);
			urodzony = gg_pubdir50_get(wynik, i, GG_PUBDIR50_BIRTHYEAR);
			miasto = gg_pubdir50_get(wynik, i, GG_PUBDIR50_CITY);
			status = gg_pubdir50_get(wynik, i, GG_PUBDIR50_STATUS);
 
//Jeśli drukujemy wszystkie informacje
 
//Wysyłanie wiadomości
			if(gg_send_message(sesja, GG_CLASS_MSG, atoi(numer), (unsigned char*) ":)") == -1) {
				printf("Połączenie przerwane: %sn", strerror(errno));
				gg_free_session(sesja);
				return 1;
			}
 
//Drukowanie informacji
			printf("Wysłano do %sn",numer);
		}
//Jeśli otrzymamy mniej, niż 20 wyników
//Oznacza to, że nie ma więcej danych do pobrania
		if(ilosc < 20) {
			break;
		}
 
//Jeśli ilość odebranych wyników będzie
//Większa od ustalonego limitu
		if(osoby > limit) {
			break;
		}
 
		snprintf(tab, sizeof(tab), "%d", gg_pubdir50_next(wynik));
		gg_pubdir50_add(zapytanie, GG_PUBDIR50_START, tab);
		gg_pubdir50(sesja, zapytanie);
	}
//Zwolnienie pamięci dla struktury zdarzenia
	gg_event_free(event);
}
 
//Zwolnienie pamięci dla struktury sesji
gg_free_session(sesja);
//Zwolnienie pamięci dla zapytania i odpowiedzi serwera
gg_pubdir50_free(zapytanie);
 
return 0;
}

Od teraz w celu wysłania jakiejś wiadomości do danej grupy sprecyzowanych osób wystarczy wypełnić interesujące nas kryteria, skompilować oraz uruchomić program.

komeniusz@cyber-jadro:~/libgadu/examples$ ./katalog2
Użycie: ./katalog2 <numer> <hasło> <limit>
komeniusz@cyber-jadro:~/libgadu/examples$ ./katalog2 numerek haselko 5
Wysłano do 175***
Wysłano do 340***
Wysłano do 659***
Wysłano do 122***
Wysłano do 128***
Wysłano do 18***
Wysłano do 61***
Wysłano do 729***
[…]
komeniusz@cyber-jadro:~/libgadu/examples$

Jako zadanie dodatkowe można uzupełnić program o pobieranie danych do zapytania poprzez parametry w sposób

./katalog2 -a numer -b haslo -c imie -d miasto

Przykład


UWAGA!
W programie zawarte jest zabezpieczenie anti script kiddie, aby ktoś, kto nie rozumie programu nie miał możliwości bezmyślnego SPIM’owania innych użytkowników.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *