Libgadu #3 – Obsługa katalogu publicznego

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 e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *