예제 #1
0
HANDLE GGPROTO::SearchBasic(const TCHAR *id)
{
	if (!isonline())
		return 0;

	gg_pubdir50_t req = gg_pubdir50_new(GG_PUBDIR50_SEARCH);
	if (!req) {
#ifdef DEBUGMODE
		debugLogA("SearchBasic(): ForkThread 10 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HANDLE)1;
	}

	// Add uin and search it
	gg_pubdir50_add(req, GG_PUBDIR50_UIN, T2Utf(id));
	gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);

	gg_EnterCriticalSection(&sess_mutex, "SearchBasic", 50, "sess_mutex", 1);
	if (!gg_pubdir50(sess, req))
	{
		gg_LeaveCriticalSection(&sess_mutex, "SearchBasic", 50, 1, "sess_mutex", 1);
#ifdef DEBUGMODE
		debugLogA("SearchBasic(): ForkThread 11 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HANDLE)1;
	}
	gg_LeaveCriticalSection(&sess_mutex, "SearchBasic", 50, 2, "sess_mutex", 1);
	debugLogA("SearchBasic(): Seq %d.", req->seq);
	gg_pubdir50_free(req);

	return (HANDLE)1;
}
예제 #2
0
void GaduSearchService::searchNext()
{
	if (!Connection || !Connection->hasSession())
		return;

	Stopped = false;
	gg_pubdir50_t req = gg_pubdir50_new(GG_PUBDIR50_SEARCH);

	if (Query.SearchBuddy.hasContact(account()))
		gg_pubdir50_add(req, GG_PUBDIR50_UIN, Query.SearchBuddy.id(account()).toUtf8().constData());
	if (!Query.SearchBuddy.firstName().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, Query.SearchBuddy.firstName().toUtf8().constData());
	if (!Query.SearchBuddy.lastName().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, Query.SearchBuddy.lastName().toUtf8().constData());
	if (!Query.SearchBuddy.nickName().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, Query.SearchBuddy.nickName().toUtf8().constData());
	if (!Query.SearchBuddy.city().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_CITY, Query.SearchBuddy.city().toUtf8().constData());
	if (!Query.BirthYearFrom.isEmpty())
	{
		QString bufYear = Query.BirthYearFrom + ' ' + Query.BirthYearTo;
		gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, bufYear.toUtf8().constData());
	}

	switch (Query.SearchBuddy.gender())
	{
		case GenderMale:
			gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
			break;
		case GenderFemale:
			gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
			break;
		case GenderUnknown:
			// do nothing
			break;
	}

	if (Query.Active)
		gg_pubdir50_add(req, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);

	gg_pubdir50_add(req, GG_PUBDIR50_START, QString::number(From).toUtf8().constData());

	auto writableSessionToken = Connection->writableSessionToken();
	SearchSeq = gg_pubdir50(writableSessionToken.rawSession(), req);
	gg_pubdir50_free(req);
}
void GaduContactPersonalInfoService::fetchPersonalInfo(Contact contact)
{
	if (!Connection || !Connection.data()->hasSession())
		return;

	Id = contact.id();
	gg_pubdir50_t req = gg_pubdir50_new(GG_PUBDIR50_SEARCH);
	gg_pubdir50_add(req, GG_PUBDIR50_UIN, Id.toUtf8().constData());

	auto writableSessionToken = Connection.data()->writableSessionToken();
	FetchSeq = gg_pubdir50(writableSessionToken.rawSession(), req);
	//gg_pubdir50_free(req);
}
예제 #4
0
bool
GaduSession::publishPersonalInformation( ResLine& d )
{
	gg_pubdir50_t r;
	
	if ( !session_ ) {
		return 0;
        }		
	
	r = gg_pubdir50_new( GG_PUBDIR50_WRITE );

	if ( d.firstname.length() )
		gg_pubdir50_add( r, GG_PUBDIR50_FIRSTNAME, 
			 (const char *)((const char*)textcodec->fromUnicode( d.firstname ) ) );
        if ( d.surname.length() )
		gg_pubdir50_add( r, GG_PUBDIR50_LASTNAME,
			(const char *)((const char*)textcodec->fromUnicode( d.surname ) ) );
	if ( d.nickname.length() )
		gg_pubdir50_add( r, GG_PUBDIR50_NICKNAME,
			(const char *)((const char*)textcodec->fromUnicode( d.nickname ) ) );
	if ( d.age.length() )
		gg_pubdir50_add( r, GG_PUBDIR50_BIRTHYEAR,
			(const char *)((const char*)textcodec->fromUnicode( d.age ) ) );
        if ( d.city.length() )
        	gg_pubdir50_add( r, GG_PUBDIR50_CITY,
			(const char *)((const char*)textcodec->fromUnicode( d.city ) ) );
	if ( d.meiden.length() )
		gg_pubdir50_add( r, GG_PUBDIR50_FAMILYNAME,
			(const char *)((const char*)textcodec->fromUnicode( d.meiden ) ) );
        if ( d.orgin.length() )
		gg_pubdir50_add( r, GG_PUBDIR50_FAMILYCITY,
			(const char *)((const char*)textcodec->fromUnicode( d.orgin ) ) );
	if ( d.gender.length() == 1 )
		gg_pubdir50_add( r, GG_PUBDIR50_GENDER, 
			(const char *)((const char*)textcodec->fromUnicode( d.gender ) ) );
        
	gg_pubdir50( session_, r );
        
	gg_pubdir50_free( r );

	return true;
}
예제 #5
0
void GaduSearchService::searchNext()
{
	Stopped = false;

	gg_pubdir50_t req = gg_pubdir50_new(GG_PUBDIR50_SEARCH);

// 	if (!Query.Uin.isEmpty()) TODO: 0.6.6
// 		gg_pubdir50_add(req, GG_PUBDIR50_UIN, (const char *)unicode2cp(searchRecord.Uin).data());
	if (!Query.firstName().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, (const char *)unicode2cp(Query.firstName()).data());
	if (!Query.lastName().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, (const char *)unicode2cp(Query.lastName()).data());
	if (!Query.nickName().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, (const char *)unicode2cp(Query.nickName()).data());
	if (!Query.city().isEmpty())
		gg_pubdir50_add(req, GG_PUBDIR50_CITY, (const char *)unicode2cp(Query.city()).data());
// 	if (!Query.BirthYearFrom.isEmpty()) TODO: 0.6.6
	if (0 != Query.birthYear())
		gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, (const char *)unicode2cp(QString::number(Query.birthYear())).data());

	switch (Query.gender())
	{
		case ContactData::GenderMale:
			gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
			break;
		case ContactData::GenderFemale:
			gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
			break;
	}

	// TODO: 0.6.6
// 	if (searchRecord.Active)
// 		gg_pubdir50_add(req, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);

	gg_pubdir50_add(req, GG_PUBDIR50_START, qPrintable(QString::number(From)));

	SearchSeq = gg_pubdir50(Protocol->gaduSession(), req);
	gg_pubdir50_free(req);
}
예제 #6
0
unsigned int
GaduSession::pubDirSearch(  ResLine& query, int ageFrom, int ageTo, bool onlyAlive )
{
	QString bufYear;
	unsigned int reqNr;
	gg_pubdir50_t searchRequest;

	if ( !session_ ) {
		return 0;
	}

	searchRequest = gg_pubdir50_new( GG_PUBDIR50_SEARCH_REQUEST );
	if ( !searchRequest ) {
		return 0;
	}

	if ( query.uin == 0 ) {
		if (query.firstname.length()) {
			gg_pubdir50_add( searchRequest, GG_PUBDIR50_FIRSTNAME,
						(const char*)textcodec->fromUnicode( query.firstname ) );
		}
		if ( query.surname.length() ) {
			gg_pubdir50_add( searchRequest, GG_PUBDIR50_LASTNAME,
						(const char*)textcodec->fromUnicode( query.surname ) );
		}
		if ( query.nickname.length() ) {
			gg_pubdir50_add( searchRequest, GG_PUBDIR50_NICKNAME,
						(const char*)textcodec->fromUnicode( query.nickname ) );
		}
		if ( query.city.length() ) {
			gg_pubdir50_add( searchRequest, GG_PUBDIR50_CITY,
						(const char*)textcodec->fromUnicode( query.city ) );
		}
		if ( ageFrom || ageTo ) {
			QString yearFrom = QString::number( QDate::currentDate().year() - ageFrom );
			QString yearTo = QString::number( QDate::currentDate().year() - ageTo );

			if ( ageFrom && ageTo ) {
				gg_pubdir50_add( searchRequest, GG_PUBDIR50_BIRTHYEAR,
							(const char*)textcodec->fromUnicode( yearFrom + " " + yearTo ) );
			}
			if ( ageFrom ) {
				gg_pubdir50_add( searchRequest, GG_PUBDIR50_BIRTHYEAR,
							(const char*)textcodec->fromUnicode( yearFrom ) );
			}
			else {
				gg_pubdir50_add( searchRequest, GG_PUBDIR50_BIRTHYEAR,
							(const char*)textcodec->fromUnicode( yearTo ) );
			}
		}

		if ( query.gender.length() == 1 ) {
                	gg_pubdir50_add( searchRequest, GG_PUBDIR50_GENDER,
				(const char *)((const char*)textcodec->fromUnicode( query.gender ) ) );
		}

		if ( onlyAlive ) {
			gg_pubdir50_add( searchRequest, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE );
		}
	}
	// otherwise we are looking only for one fellow with this nice UIN
	else{
		gg_pubdir50_add( searchRequest, GG_PUBDIR50_UIN, QString::number( query.uin ).ascii() );
	}

	gg_pubdir50_add( searchRequest, GG_PUBDIR50_START, QString::number( searchSeqNr_ ).ascii() );
	reqNr = gg_pubdir50( session_, searchRequest );
	gg_pubdir50_free( searchRequest );

	return reqNr;
}
예제 #7
0
HWND GGPROTO::SearchAdvanced(HWND hwndDlg)
{
	gg_pubdir50_t req;
	TCHAR text[64];
	char data[800] = "\0";
	unsigned long crc;

	// Check if connected
	if (!isonline()) return (HWND)0;

	if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
	{
#ifdef DEBUGMODE
		debugLogA("SearchAdvanced(): ForkThread 14 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HWND)1;
	}

	// Fetch search data
	GetDlgItemText(hwndDlg, IDC_FIRSTNAME, text, sizeof(text));
	if (_tcslen(text))
	{
		char *firstName_utf8 = mir_utf8encodeT(text);
		gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, firstName_utf8);
		strncat(data, firstName_utf8, sizeof(data) - strlen(data));
		mir_free(firstName_utf8);
	}
	/* 1 */ strncat(data, ".", sizeof(data) - strlen(data));

	GetDlgItemText(hwndDlg, IDC_LASTNAME, text, sizeof(text));
	if (_tcslen(text))
	{
		char *lastName_utf8 = mir_utf8encodeT(text);
		gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, lastName_utf8);
		strncat(data, lastName_utf8, sizeof(data) - strlen(data));
		mir_free(lastName_utf8);
	}
	/* 2 */ strncat(data, ".", sizeof(data) - strlen(data));

	GetDlgItemText(hwndDlg, IDC_NICKNAME, text, sizeof(text));
	if (_tcslen(text))
	{
		char *nickName_utf8 = mir_utf8encodeT(text);
		gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, nickName_utf8);
		strncat(data, nickName_utf8, sizeof(data) - strlen(data));
		mir_free(nickName_utf8);
	}
	/* 3 */ strncat(data, ".", sizeof(data) - strlen(data));

	GetDlgItemText(hwndDlg, IDC_CITY, text, sizeof(text));
	if (_tcslen(text))
	{
		char *city_utf8 = mir_utf8encodeT(text);
		gg_pubdir50_add(req, GG_PUBDIR50_CITY, city_utf8);
		strncat(data, city_utf8, sizeof(data) - strlen(data));
		mir_free(city_utf8);
	}
	/* 4 */ strncat(data, ".", sizeof(data) - strlen(data));

	GetDlgItemText(hwndDlg, IDC_AGEFROM, text, sizeof(text));
	if (_tcslen(text))
	{
		int yearTo = _tstoi(text);
		int yearFrom;
		time_t t = time(NULL);
		struct tm *lt = localtime(&t);
		int ay = lt->tm_year + 1900;
		char age[16];

		GetDlgItemTextA(hwndDlg, IDC_AGETO, age, sizeof(age));
		yearFrom = atoi(age);

		// Count & fix ranges
		if (!yearTo)
			yearTo = ay;
		else
			yearTo = ay - yearTo;
		if (!yearFrom)
			yearFrom = 0;
		else
			yearFrom = ay - yearFrom;
		mir_sntprintf(text, sizeof(text), _T("%d %d"), yearFrom, yearTo);

		char *age_utf8 = mir_utf8encodeT(text);
		gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, age_utf8);
		strncat(data, age_utf8, sizeof(data) - strlen(data));
		mir_free(age_utf8);
	}
	/* 5 */ strncat(data, ".", sizeof(data) - strlen(data));

	switch(SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_GETCURSEL, 0, 0))
	{
		case 1:
			gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
			strncat(data, GG_PUBDIR50_GENDER_MALE, sizeof(data) - strlen(data));
			break;
		case 2:
			gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
			strncat(data, GG_PUBDIR50_GENDER_FEMALE, sizeof(data) - strlen(data));
			break;
	}
	/* 6 */ strncat(data, ".", sizeof(data) - strlen(data));

	if (IsDlgButtonChecked(hwndDlg, IDC_ONLYCONNECTED))
	{
		gg_pubdir50_add(req, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
		strncat(data, GG_PUBDIR50_ACTIVE_TRUE, sizeof(data) - strlen(data));
	}
	/* 7 */ strncat(data, ".", sizeof(data) - strlen(data));

	// No data entered
	if (strlen(data) <= 7 || (strlen(data) == 8 && IsDlgButtonChecked(hwndDlg, IDC_ONLYCONNECTED))) return (HWND)0;

	// Count crc & check if the data was equal if yes do same search with shift
	crc = crc_get(data);

	if (crc == last_crc && next_uin)
		gg_pubdir50_add(req, GG_PUBDIR50_START, ditoa(next_uin));
	else
		last_crc = crc;

	gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);

	if (isonline())
	{
		gg_EnterCriticalSection(&sess_mutex, "SearchAdvanced", 52, "sess_mutex", 1);
		if (!gg_pubdir50(sess, req))
		{
			gg_LeaveCriticalSection(&sess_mutex, "SearchAdvanced", 52, 1, "sess_mutex", 1);
#ifdef DEBUGMODE
			debugLogA("SearchAdvanced(): ForkThread 15 GGPROTO::searchthread");
#endif
			ForkThread(&GGPROTO::searchthread, NULL);
			return (HWND)1;
		}
		gg_LeaveCriticalSection(&sess_mutex, "SearchAdvanced", 52, 2, "sess_mutex", 1);
	}
	debugLogA("SearchAdvanced(): Seq %d.", req->seq);
	gg_pubdir50_free(req);

	return (HWND)1;
}
예제 #8
0
HANDLE GGPROTO::SearchByName(const PROTOCHAR *nick, const PROTOCHAR *firstName, const PROTOCHAR *lastName)
{
	gg_pubdir50_t req;
	unsigned long crc;
	char data[512] = "\0";

	// Check if connected and if there's a search data
	if (!isonline())
		return 0;

	if (!nick && !firstName && !lastName)
		return 0;

	if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
	{
#ifdef DEBUGMODE
		debugLogA("SearchByName(): ForkThread 12 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HANDLE)1;
	}

	// Add nick,firstName,lastName and search it
	if (nick)
	{
		char *nick_utf8 = mir_utf8encodeT(nick);
		gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, nick_utf8);
		strncat(data, nick_utf8, sizeof(data) - strlen(data));
		mir_free(nick_utf8);
	}
	strncat(data, ".", sizeof(data) - strlen(data));

	if (firstName)
	{
		char *firstName_utf8 = mir_utf8encodeT(firstName);
		gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, firstName_utf8);
		strncat(data, firstName_utf8, sizeof(data) - strlen(data));
		mir_free(firstName_utf8);
	}
	strncat(data, ".", sizeof(data) - strlen(data));

	if (lastName)
	{
		char *lastName_utf8 = mir_utf8encodeT(lastName);
		gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, lastName_utf8);
		strncat(data, lastName_utf8, sizeof(data) - strlen(data));
		mir_free(lastName_utf8);
	}
	strncat(data, ".", sizeof(data) - strlen(data));

	// Count crc & check if the data was equal if yes do same search with shift
	crc = crc_get(data);

	if (crc == last_crc && next_uin)
		gg_pubdir50_add(req, GG_PUBDIR50_START, ditoa(next_uin));
	else
		last_crc = crc;

	gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);
	gg_EnterCriticalSection(&sess_mutex, "SearchByName", 51, "sess_mutex", 1);
	if (!gg_pubdir50(sess, req))
	{
		gg_LeaveCriticalSection(&sess_mutex, "SearchByName", 51, 1, "sess_mutex", 1);
#ifdef DEBUGMODE
		debugLogA("SearchByName(): ForkThread 13 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HANDLE)1;
	}
	gg_LeaveCriticalSection(&sess_mutex, "SearchByName", 51, 2, "sess_mutex", 1);
	debugLogA("SearchByName(): Seq %d.", req->seq);
	gg_pubdir50_free(req);

	return (HANDLE)1;
}
예제 #9
0
int GGPROTO::GetInfo(HANDLE hContact, int infoType)
{
	gg_pubdir50_t req;

	// Custom contact info
	if (hContact)
	{
		if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
		{
#ifdef DEBUGMODE
			debugLogA("GetInfo(): ForkThread 6 GGPROTO::cmdgetinfothread");
#endif
			ForkThread(&GGPROTO::cmdgetinfothread, hContact);
			return 1;
		}

		// Add uin and search it
		gg_pubdir50_add(req, GG_PUBDIR50_UIN, ditoa((uin_t)getDword(hContact, GG_KEY_UIN, 0)));
		gg_pubdir50_seq_set(req, GG_SEQ_INFO);

		debugLogA("GetInfo(): Requesting user info.", req->seq);
		if (isonline())
		{
			gg_EnterCriticalSection(&sess_mutex, "GetInfo", 48, "sess_mutex", 1);
			if (!gg_pubdir50(sess, req))
			{
				gg_LeaveCriticalSection(&sess_mutex, "GetInfo", 48, 1, "sess_mutex", 1);
#ifdef DEBUGMODE
				debugLogA("GetInfo(): ForkThread 7 GGPROTO::cmdgetinfothread");
#endif
				ForkThread(&GGPROTO::cmdgetinfothread, hContact);
				return 1;
			}
			gg_LeaveCriticalSection(&sess_mutex, "GetInfo", 48, 2, "sess_mutex", 1);
		}
	}
	// Own contact info
	else
	{
		if (!(req = gg_pubdir50_new(GG_PUBDIR50_READ)))
		{
#ifdef DEBUGMODE
			debugLogA("GetInfo(): ForkThread 8 GGPROTO::cmdgetinfothread");
#endif
			ForkThread(&GGPROTO::cmdgetinfothread, hContact);
			return 1;
		}

		// Add seq
		gg_pubdir50_seq_set(req, GG_SEQ_CHINFO);

		debugLogA("GetInfo(): Requesting owner info.", req->seq);
		if (isonline())
		{
			gg_EnterCriticalSection(&sess_mutex, "GetInfo", 49, "sess_mutex", 1);
			if (!gg_pubdir50(sess, req))
			{
				gg_LeaveCriticalSection(&sess_mutex, "GetInfo", 49, 1, "sess_mutex", 1);
#ifdef DEBUGMODE
				debugLogA("GetInfo(): ForkThread 9 GGPROTO::cmdgetinfothread");
#endif
				ForkThread(&GGPROTO::cmdgetinfothread, hContact);
				return 1;
			}
			gg_LeaveCriticalSection(&sess_mutex, "GetInfo", 49, 2, "sess_mutex", 1);
		}
	}
	debugLogA("GetInfo(): Seq %d.", req->seq);
	gg_pubdir50_free(req);

	return 1;
}
예제 #10
0
HANDLE GGPROTO::SearchByName(const TCHAR *nick, const TCHAR *firstName, const TCHAR *lastName)
{
	// Check if connected and if there's a search data
	if (!isonline())
		return 0;

	if (!nick && !firstName && !lastName)
		return 0;

	gg_pubdir50_t req = gg_pubdir50_new(GG_PUBDIR50_SEARCH);
	if (req == NULL) {
#ifdef DEBUGMODE
		debugLogA("SearchByName(): ForkThread 12 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HANDLE)1;
	}

	// Add nick,firstName,lastName and search it
	CMStringA szQuery;
	if (nick)
	{
		T2Utf nick_utf8(nick);
		gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, nick_utf8);
		szQuery.Append(nick_utf8);
	}
	szQuery.AppendChar('.');

	if (firstName)
	{
		T2Utf firstName_utf8(firstName);
		gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, firstName_utf8);
		szQuery.Append(firstName_utf8);
	}
	szQuery.AppendChar('.');

	if (lastName)
	{
		T2Utf lastName_utf8(lastName);
		gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, lastName_utf8);
		szQuery.Append(lastName_utf8);
	}
	szQuery.AppendChar('.');

	// Count crc & check if the data was equal if yes do same search with shift
	unsigned long crc = crc_get(szQuery.GetBuffer());
	if (crc == last_crc && next_uin)
		gg_pubdir50_add(req, GG_PUBDIR50_START, ditoa(next_uin));
	else
		last_crc = crc;

	gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);
	gg_EnterCriticalSection(&sess_mutex, "SearchByName", 51, "sess_mutex", 1);
	if (!gg_pubdir50(sess, req))
	{
		gg_LeaveCriticalSection(&sess_mutex, "SearchByName", 51, 1, "sess_mutex", 1);
#ifdef DEBUGMODE
		debugLogA("SearchByName(): ForkThread 13 GGPROTO::searchthread");
#endif
		ForkThread(&GGPROTO::searchthread, NULL);
		return (HANDLE)1;
	}
	gg_LeaveCriticalSection(&sess_mutex, "SearchByName", 51, 2, "sess_mutex", 1);
	debugLogA("SearchByName(): Seq %d.", req->seq);
	gg_pubdir50_free(req);

	return (HANDLE)1;
}
예제 #11
0
파일: pubdir50.c 프로젝트: 11mariom/ekg2
/*
 * gg_session_handler_search50()
 *
 * zajmuje siê obs³ug± wyniku przeszukiwania katalogu publicznego.
 *
 *  - s - sesja
 *  - e - opis zdarzenia
 */
void gg_session_handler_search50(session_t *s, struct gg_event *e)
{
	gg_private_t *g = session_private_get(s);
	gg_pubdir50_t res = e->event.pubdir50;
	int i, count, all = 0;
	list_t l;
	uin_t last_uin = 0;

	if (!g)
		return;

	if ((count = gg_pubdir50_count(res)) < 1) {
		print("search_not_found");
		return;
	}

	debug_function("gg_session_handler_search50() handle_search50, count = %d\n", gg_pubdir50_count(res));

	for (l = g->searches; l; l = l->next) {
		gg_pubdir50_t req = l->data;

		if (gg_pubdir50_seq(req) == gg_pubdir50_seq(res)) {
			all = 1;
			break;
		}
	}

	for (i = 0; i < count; i++) {
		const char *uin		= gg_pubdir50_get(res, i, "fmnumber");
		const char *__firstname = gg_pubdir50_get(res, i, "firstname");
		const char *__lastname	= gg_pubdir50_get(res, i, "lastname");
		const char *__nickname	= gg_pubdir50_get(res, i, "nickname");
		const char *__fmstatus	= gg_pubdir50_get(res, i, "fmstatus");
		const char *__birthyear = gg_pubdir50_get(res, i, "birthyear");
		const char *__city	= gg_pubdir50_get(res, i, "city");

		char *firstname		= gg_to_core_dup(s, __firstname);
		char *lastname		= gg_to_core_dup(s, __lastname);
		char *nickname		= gg_to_core_dup(s, __nickname);
		char *city		= gg_to_core_dup(s, __city);
		int status		= (__fmstatus)	? atoi(__fmstatus) : GG_STATUS_NOT_AVAIL;
		const char *birthyear	= (__birthyear && xstrcmp(__birthyear, "0")) ? __birthyear : NULL;

		char *name, *active, *gender;
		const char *target = NULL;

		if (count == 1 && !all) {
			xfree(last_search_first_name);
			xfree(last_search_last_name);
			xfree(last_search_nickname);
			xfree(last_search_uid);
			last_search_first_name	= xstrdup(firstname);
			last_search_last_name	= xstrdup(lastname);
			last_search_nickname	= xstrdup(nickname);
			last_search_uid		= saprintf("gg:%s", uin);
		}

		name = saprintf(
			("%s %s"),
					firstname ? firstname : (""), 
					lastname ? lastname : (""));

#define __format(x) ((count == 1 && !all) ? "search_results_single" x : "search_results_multi" x)
		{
			const char *fvalue;
			switch (status) {
				case GG_STATUS_AVAIL:
				case GG_STATUS_AVAIL_DESCR:
					fvalue = format_find(__format("_avail"));
					break;
				case GG_STATUS_BUSY:
				case GG_STATUS_BUSY_DESCR:
					fvalue = format_find(__format("_away"));
					break;
				default:
					fvalue = format_find(__format("_notavail"));
			}
			active = format_string(fvalue, (__firstname) ? __firstname : nickname);
		}
		gender = format_string(format_find(__format("_unknown")), "");

			/* XXX: why do we _exactly_ use it here? can't we just always
			 *	define target and thus display result in right conversation window? */
		for (l = autofinds; l; l = l->next) {
			char *d = (char *) l->data;
		
			if (!xstrcasecmp(d + 3, uin)) {
				target = d;
				break;
			}
		}
		
		print_info(target, s, __format(""), 
			uin		? uin : ("?"), name, 
			nickname	? nickname : (""), 
			city		? city : (""), 
			birthyear	? birthyear : ("-"),
			gender, active);

#undef __format

		xfree(name);
		xfree(active);
		xfree(gender);

		xfree(firstname);
		xfree(lastname);
		xfree(nickname);
		xfree(city);

		last_uin = atoi(uin);
	}

	/* je¶li mieli¶my ,,/find --all'', szukamy dalej */
	for (l = g->searches; l; l = l->next) {
		gg_pubdir50_t req = l->data;
		uin_t next;

		if (gg_pubdir50_seq(req) != gg_pubdir50_seq(res))
			continue;

		/* nie ma dalszych? to dziêkujemy */
		if (!(next = gg_pubdir50_next(res)) || !g->sess || next <= last_uin) {
			list_remove(&g->searches, req, 0);
			gg_pubdir50_free(req);
			break;
		}

		gg_pubdir50_add(req, GG_PUBDIR50_START, ekg_itoa(next));
		gg_pubdir50(g->sess, req);

		break;
	}

}
예제 #12
0
////////////////////////////////////////////////////////////////////////////////
// Info Page : Proc
// lParam: 0 if current user (account owner) details, hContact if on list user details
static INT_PTR CALLBACK gg_detailsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	struct GGDETAILSDLGDATA *dat = (struct GGDETAILSDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);

	switch(msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);

		dat = (struct GGDETAILSDLGDATA *)mir_alloc(sizeof(struct GGDETAILSDLGDATA));
		dat->hContact = lParam;
		dat->disableUpdate = FALSE;
		dat->updating = FALSE;
		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
		// Add genders
		if (!dat->hContact)
		{
			SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)_T(""));				// 0
			SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)TranslateT("Female"));	// 1
			SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)TranslateT("Male"));	// 2
		}
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) {
		case 0:
			switch (((LPNMHDR)lParam)->code) {
			case PSN_PARAMCHANGED:
				dat->gg = (GGPROTO *)((LPPSHNOTIFY)lParam)->lParam;
				break;

			case PSN_INFOCHANGED:
				{
					MCONTACT hContact = (MCONTACT)((LPPSHNOTIFY)lParam)->lParam;
					GGPROTO *gg = dat->gg;
					if (!dat)
						break;

					// Show updated message
					if (dat->updating)
					{
						MessageBox(NULL, TranslateT("Your details has been uploaded to the public directory."),
							gg->m_tszUserName, MB_OK | MB_ICONINFORMATION);
						dat->updating = FALSE;
						break;
					}

					char *szProto = (hContact == NULL) ? gg->m_szModuleName : GetContactProto(hContact);
					if (szProto == NULL)
						break;

					// Disable when updating
					dat->disableUpdate = TRUE;

					SetValue(hwndDlg, IDC_UIN, hContact, szProto, GG_KEY_UIN, 0, hContact != NULL);
					SetValue(hwndDlg, IDC_REALIP, hContact, szProto, GG_KEY_CLIENTIP, SVS_IP, hContact != NULL);
					SetValue(hwndDlg, IDC_PORT, hContact, szProto, GG_KEY_CLIENTPORT, SVS_ZEROISUNSPEC, hContact != NULL);
					SetValue(hwndDlg, IDC_VERSION, hContact, szProto, GG_KEY_CLIENTVERSION, SVS_GGVERSION, hContact != NULL);

					SetValue(hwndDlg, IDC_FIRSTNAME, hContact, szProto, GG_KEY_PD_FIRSTNAME, SVS_NORMAL, hContact != NULL);
					SetValue(hwndDlg, IDC_LASTNAME, hContact, szProto, GG_KEY_PD_LASTNAME, SVS_NORMAL, hContact != NULL);
					SetValue(hwndDlg, IDC_NICKNAME, hContact, szProto, GG_KEY_PD_NICKNAME, SVS_NORMAL, hContact != NULL);
					SetValue(hwndDlg, IDC_BIRTHYEAR, hContact, szProto, GG_KEY_PD_BIRTHYEAR, SVS_ZEROISUNSPEC, hContact != NULL);
					SetValue(hwndDlg, IDC_CITY, hContact, szProto, GG_KEY_PD_CITY, SVS_NORMAL, hContact != NULL);
					SetValue(hwndDlg, IDC_FAMILYNAME, hContact, szProto, GG_KEY_PD_FAMILYNAME, SVS_NORMAL, hContact != NULL);
					SetValue(hwndDlg, IDC_CITYORIGIN, hContact, szProto, GG_KEY_PD_FAMILYCITY	, SVS_NORMAL, hContact != NULL);

					if (hContact)
					{
						SetValue(hwndDlg, IDC_GENDER, hContact, szProto, GG_KEY_PD_GANDER, SVS_GENDER, hContact != NULL);
						SetValue(hwndDlg, IDC_STATUSDESCR, hContact, "CList", GG_KEY_STATUSDESCR, SVS_NORMAL, hContact != NULL);
					}
					else switch((char)db_get_b(hContact, gg->m_szModuleName, GG_KEY_PD_GANDER, (BYTE)'?')) {
					case 'F':
						SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0);
						break;
					case 'M':
						SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0);
						break;
					default:
						SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0);
					}

					// Disable when updating
					dat->disableUpdate = FALSE;
					break;
				}
			}
			break;
		}
		break;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCANCEL:
			SendMessage(GetParent(hwndDlg),msg,wParam,lParam);
			break;
		case IDC_NICKNAME:
		case IDC_FIRSTNAME:
		case IDC_LASTNAME:
		case IDC_FAMILYNAME:
		case IDC_CITY:
		case IDC_CITYORIGIN:
		case IDC_BIRTHYEAR:
			if (HIWORD(wParam) == EN_CHANGE) {
				if (!dat || dat->hContact || dat->disableUpdate)
					break;
				EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), TRUE);
				break;
			}
		case IDC_GENDER:
			if (HIWORD(wParam) == CBN_SELCHANGE) {
				if (!dat || dat->hContact || dat->disableUpdate)
					break;
				EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), TRUE);
				break;
			}
		case IDC_SAVE: // Save current user data
			if (HIWORD(wParam) == BN_CLICKED) {
				if (!dat || dat->hContact || dat->disableUpdate)
					break;
				{
				TCHAR text[256];
				GGPROTO *gg = dat->gg;

				if (!gg->isonline())
				{
					MessageBox(NULL,
						TranslateT("You have to be logged in before you can change your details."),
						gg->m_tszUserName, MB_OK | MB_ICONSTOP);
					break;
				}

				EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), FALSE);

				gg_pubdir50_t req = gg_pubdir50_new(GG_PUBDIR50_WRITE);

				GetDlgItemText(hwndDlg, IDC_FIRSTNAME, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, T2Utf(text));

				GetDlgItemText(hwndDlg, IDC_LASTNAME, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, T2Utf(text));

				GetDlgItemText(hwndDlg, IDC_NICKNAME, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, T2Utf(text));

				GetDlgItemText(hwndDlg, IDC_CITY, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_CITY, T2Utf(text));

				// Gadu-Gadu Female <-> Male
				switch(SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_GETCURSEL, 0, 0)) {
				case 1:
					gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_FEMALE);
					break;
				case 2:
					gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_MALE);
					break;
				default:
					gg_pubdir50_add(req, GG_PUBDIR50_GENDER, "");
				}

				GetDlgItemText(hwndDlg, IDC_BIRTHYEAR, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, T2Utf(text));

				GetDlgItemText(hwndDlg, IDC_FAMILYNAME, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_FAMILYNAME, T2Utf(text));

				GetDlgItemText(hwndDlg, IDC_CITYORIGIN, text, _countof(text));
				if (mir_tstrlen(text))
					gg_pubdir50_add(req, GG_PUBDIR50_FAMILYCITY, T2Utf(text));

				// Run update
				gg_pubdir50_seq_set(req, GG_SEQ_CHINFO);
				gg->gg_EnterCriticalSection(&gg->sess_mutex, "gg_detailsdlgproc", 35, "sess_mutex", 1);
				gg_pubdir50(gg->sess, req);
				gg->gg_LeaveCriticalSection(&gg->sess_mutex, "gg_genoptsdlgproc", 35, 1, "sess_mutex", 1);
				dat->updating = TRUE;

				gg_pubdir50_free(req);
				}
				break;
			}
		}
		break;

	case WM_DESTROY:
		if (dat) mir_free(dat);
		break;
	}
	return FALSE;
}
예제 #13
0
파일: dialogs.c 프로젝트: raoergsls/miranda
////////////////////////////////////////////////////////////////////////////////
// Info Page : Proc
static INT_PTR CALLBACK gg_detailsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	struct GGDETAILSDLGDATA *dat = (struct GGDETAILSDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);

	switch(msg)
	{
		case WM_INITDIALOG:
		{
			TranslateDialogDefault(hwndDlg);
			dat = (struct GGDETAILSDLGDATA *)mir_alloc(sizeof(struct GGDETAILSDLGDATA));
			dat->hContact=(HANDLE)lParam;
			dat->disableUpdate = FALSE;
			dat->updating = FALSE;
			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
			// Add genders
			if(!dat->hContact)
			{
				SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)_T(""));				// 0
				SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)Translate("Female"));	// 1
				SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)Translate("Male"));	// 2
			}
			break;
		}

		case WM_NOTIFY:
			switch (((LPNMHDR)lParam)->idFrom)
			{
				case 0:
					switch (((LPNMHDR)lParam)->code)
					{
						case PSN_PARAMCHANGED:
						{
							dat->gg = (GGPROTO *)((LPPSHNOTIFY)lParam)->lParam;
							break;
						}
						case PSN_INFOCHANGED:
						{
							char *szProto;
							HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
							GGPROTO *gg = dat->gg;

							// Show updated message
							if(dat && dat->updating)
							{
								MessageBox(
									NULL,
									Translate("Your details has been uploaded to the public directory."),
									GG_PROTONAME,
									MB_OK | MB_ICONINFORMATION
								);
								dat->updating = FALSE;
								break;
							}

							if (hContact == NULL)
								szProto = GG_PROTO;
							else
								szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
							if (szProto == NULL)
								break;

							// Disable when updating
							if(dat) dat->disableUpdate = TRUE;

							SetValue(hwndDlg, IDC_UIN, hContact, szProto, GG_KEY_UIN, 0, hContact != NULL);
							SetValue(hwndDlg, IDC_REALIP, hContact, szProto, GG_KEY_CLIENTIP, SVS_IP, hContact != NULL);
							SetValue(hwndDlg, IDC_PORT, hContact, szProto, GG_KEY_CLIENTPORT, SVS_ZEROISUNSPEC, hContact != NULL);
							SetValue(hwndDlg, IDC_VERSION, hContact, szProto, GG_KEY_CLIENTVERSION, SVS_GGVERSION, hContact != NULL);

							SetValue(hwndDlg, IDC_FIRSTNAME, hContact, szProto, "FirstName", SVS_NORMAL, hContact != NULL);
							SetValue(hwndDlg, IDC_LASTNAME, hContact, szProto, "LastName", SVS_NORMAL, hContact != NULL);
							SetValue(hwndDlg, IDC_NICKNAME, hContact, szProto, "NickName", SVS_NORMAL, hContact != NULL);
							SetValue(hwndDlg, IDC_BIRTHYEAR, hContact, szProto, "BirthYear", SVS_ZEROISUNSPEC, hContact != NULL);
							SetValue(hwndDlg, IDC_CITY, hContact, szProto, "City", SVS_NORMAL, hContact != NULL);
							SetValue(hwndDlg, IDC_FAMILYNAME, hContact, szProto, "FamilyName", SVS_NORMAL, hContact != NULL);
							SetValue(hwndDlg, IDC_CITYORIGIN, hContact, szProto, "CityOrigin", SVS_NORMAL, hContact != NULL);

							if (hContact)
							{
								SetValue(hwndDlg, IDC_GENDER, hContact, szProto, "Gender", SVS_GENDER, hContact != NULL);
								SetValue(hwndDlg, IDC_STATUSDESCR, hContact, "CList", GG_KEY_STATUSDESCR, SVS_NORMAL, hContact != NULL);
							}
							else switch((char)DBGetContactSettingByte(hContact, GG_PROTO, "Gender", (BYTE)'?'))
							{
								case 'F':
									SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0);
									break;
								case 'M':
									SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0);
									break;
								default:
									SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0);
							}

							// Disable when updating
							if(dat) dat->disableUpdate = FALSE;
							break;
						}
					}
					break;
				}
				break;
		case WM_COMMAND:
			if (dat && !dat->hContact && LOWORD(wParam) == IDC_SAVE && HIWORD(wParam) == BN_CLICKED)
			{
				// Save user data
				char text[256];
				gg_pubdir50_t req;
				GGPROTO *gg = dat->gg;

				if (!gg_isonline(gg))
				{
					MessageBox(NULL,
						Translate("You have to be logged in before you can change your details."),
						GG_PROTONAME, MB_OK | MB_ICONSTOP
					);
					break;
				}

				EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), FALSE);

				req = gg_pubdir50_new(GG_PUBDIR50_WRITE);

				GetDlgItemText(hwndDlg, IDC_FIRSTNAME, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, text);

				GetDlgItemText(hwndDlg, IDC_LASTNAME, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, text);

				GetDlgItemText(hwndDlg, IDC_NICKNAME, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, text);

				GetDlgItemText(hwndDlg, IDC_CITY, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_CITY, text);

				// Gadu-Gadu Female <-> Male
				switch(SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_GETCURSEL, 0, 0))
				{
					case 1:
						gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_FEMALE);
						break;
					case 2:
						gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_MALE);
						break;
					default:
						gg_pubdir50_add(req, GG_PUBDIR50_GENDER, "");
				}

				GetDlgItemText(hwndDlg, IDC_BIRTHYEAR, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, text);

				GetDlgItemText(hwndDlg, IDC_FAMILYNAME, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FAMILYNAME, text);

				GetDlgItemText(hwndDlg, IDC_CITYORIGIN, text, sizeof(text));
				if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FAMILYCITY, text);

				// Run update
				gg_pubdir50_seq_set(req, GG_SEQ_CHINFO);
				EnterCriticalSection(&gg->sess_mutex);
				gg_pubdir50(gg->sess, req);
				LeaveCriticalSection(&gg->sess_mutex);
				dat->updating = TRUE;

				gg_pubdir50_free(req);
			}

			if(dat && !dat->hContact && !dat->disableUpdate && (HIWORD(wParam) == EN_CHANGE && (
				LOWORD(wParam) == IDC_NICKNAME || LOWORD(wParam) == IDC_FIRSTNAME || LOWORD(wParam) == IDC_LASTNAME || LOWORD(wParam) == IDC_FAMILYNAME ||
				LOWORD(wParam) == IDC_CITY || LOWORD(wParam) == IDC_CITYORIGIN || LOWORD(wParam) == IDC_BIRTHYEAR) ||
				HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_GENDER))
				EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), TRUE);

			switch(LOWORD(wParam))
			{
				case IDCANCEL:
					SendMessage(GetParent(hwndDlg),msg,wParam,lParam);
					break;
			}
			break;
		case WM_DESTROY:
			if(dat) mir_free(dat);
			break;
	}
	return FALSE;
}
예제 #14
0
파일: ggpub.c 프로젝트: leafnode/ggpub
int main(int argc, char **argv)
{

   // Do po³±czenia
   struct gg_session *sess;
   struct gg_event *e;
   struct gg_login_params p;
   list_t searches = NULL;

   char *last_search_first_name = NULL;
   char *last_search_last_name = NULL;
   char *last_search_nickname = NULL;
   uin_t last_search_uin = 0;

   gg_pubdir50_t res;
   // Do wyszukiwania
   char *user;
   gg_pubdir50_t req;
   int i, all = 0;

   if (argc < 4) {
      fprintf(stderr, "Usage: %s <my_uid> <my_password> <params>\n\n", argv[0]);
      fprintf(stderr, "Parameters:\n");
      fprintf(stderr, " -f <val> (--first)     - first name\n");
      fprintf(stderr, " -l <val> (--last)      - last name\n");
      fprintf(stderr, " -n <val> (--nickname)  - nickname\n");
      fprintf(stderr, " -c <val> (--city)      - city\n");
      fprintf(stderr, " -u <val> (--uin)       - user ID\n");
      fprintf(stderr, " -F       (--female)    - search females only\n");
      fprintf(stderr, " -M       (--male)      - search males only\n");
      fprintf(stderr, " -a       (--active)    - search on-line users only\n");
      fprintf(stderr, " -b <val> (--born)      - year of birth\n");
      fprintf(stderr, " -s <val> (--start)     - search offset\n");
      fprintf(stderr, " -A       (--all)       - show all\n");
      return 1;
   }

   // Poziom debugowania
   gg_debug_level = 5;

   memset(&p, 0, sizeof(p));
   p.uin = atoi(argv[1]);
   p.password = argv[2];


   // Po³±czenie

   if (!(sess = gg_login(&p))) {
      printf("Connection failed: %s\n", strerror(errno));
      gg_free_session(sess);
      return 1;
   }

   printf("Po³±czono.\n");

   // Wyszukiwanie

   if (!sess || sess->state != GG_STATE_CONNECTED) {
      printf("not_connected\n");
      return 1;
   }

   argv = argv + 3;

   // próba odpalenia trybu szukania konkretnego usera
   user = strdup(argv[0]);

   // Konwersja do CP
   for (i = 0; argv[i]; i++) {
      iso_to_cp(argv[i]);
   }

   // Zapytanie
   if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH))) {
      printf("\n");
      return 1;
   }

   // wyszukiwanie UIN
   if (argv[0] && argv[0][0] != '-') {
      uin_t uin = get_uin(user);

      if (!uin) {
	 printf("User not found (%s)\n", user);
	 return 1;
      }

      gg_pubdir50_add(req, GG_PUBDIR50_UIN, itoa(uin));
      i = 1;

   } else {
      i = 0;
   }

   free(user);

   // Parsowanie argumentów
   for (; argv[i]; i++) {
      char *arg = argv[i];

      if (match_arg(arg, 'f', "first", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'l', "last", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'n', "nickname", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'c', "city", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_CITY, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'u', "uin", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_UIN, itoa(get_uin(argv[++i])));
	 continue;
      }

      if (match_arg(arg, 's', "start", 3) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_START, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'F', "female", 2)) {
	 gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
	 continue;
      }

      if (match_arg(arg, 'M', "male", 2)) {
	 gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
	 continue;
      }

      if (match_arg(arg, 'a', "active", 2)) {
	 gg_pubdir50_add(req, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
	 continue;
      }

      if (match_arg(arg, 'b', "born", 2) && argv[i + 1]) {
	 char *foo = strchr(argv[++i], ':');

	 if (foo)
	    *foo = ' ';

	 gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, argv[i]);
	 continue;
      }

      if (match_arg(arg, 'A', "all", 3)) {
	 if (!gg_pubdir50_get(req, 0, GG_PUBDIR50_START))
	    gg_pubdir50_add(req, GG_PUBDIR50_START, "0");
	 all = 1;
	 continue;
      }

      printf("invalid_params\n");

      gg_pubdir50_free(req);

      return 1;
   }

   // Wywo³anie wyszukiwania

   if (!gg_pubdir50(sess, req)) {
      printf("Search failed\n");
      return 1;
   }

   // Dodanie wyniku wyszykiwania do listy
   if (all) {
      list_add(&searches, req, 0);
   } else {
      gg_pubdir50_free(req);
   }

   // Pêtla czekaj±ca na wynik wyszukiwania
   while (1) {
      if (!(e = gg_watch_fd(sess))) {
	 printf("Connection interrupted: %s\n", strerror(errno));
	 gg_logoff(sess);
	 gg_free_session(sess);
	 return 1;
      }

      if (e->type == GG_EVENT_PUBDIR50_SEARCH_REPLY) {
         printf("Received results!\n");
         res = e->event.pubdir50;
         all = i = 0;
         int count, all = 0;
         list_t l;
         uin_t last_uin = 0;

         if ((count = gg_pubdir50_count(res)) < 1) {
            printf("search_not_found\n");
            return 1;
         }

         gg_debug(GG_DEBUG_MISC, "handle_search50, count = %d\n", gg_pubdir50_count(res));

         for (l = searches; l; l = l->next) {
            gg_pubdir50_t req = l->data;

            if (gg_pubdir50_seq(req) == gg_pubdir50_seq(res)) {
               all = 1;
               break;
            }
         }

         for (i = 0; i < count; i++) {
            const char *__fmnumber = gg_pubdir50_get(res, i, "fmnumber");
            const char *uin = (__fmnumber) ? __fmnumber : "?";

            const char *__firstname = gg_pubdir50_get(res, i, "firstname");
            char *firstname = strdup((__firstname) ? __firstname : "");

            const char *__lastname = gg_pubdir50_get(res, i, "lastname");
            char *lastname = strdup((__lastname) ? __lastname : "");

            const char *__nickname = gg_pubdir50_get(res, i, "nickname");
            char *nickname = strdup((__nickname) ? __nickname : "");

            const char *__fmstatus = gg_pubdir50_get(res, i, "fmstatus");
            int status = (__fmstatus) ? atoi(__fmstatus) : GG_STATUS_NOT_AVAIL;

            const char *__birthyear = gg_pubdir50_get(res, i, "birthyear");
            const char *birthyear = (__birthyear && strcmp(__birthyear, "0")) ? __birthyear : "-";

            const char *__city = gg_pubdir50_get(res, i, "city");
            char *city = strdup((__city) ? __city : "");

            char *name, *active;

            const char *target = NULL;

            cp_to_iso(firstname);
            cp_to_iso(lastname);
            cp_to_iso(nickname);
            cp_to_iso(city);

            if (count == 1 && !all) {
               free(last_search_first_name);
               free(last_search_last_name);
               free(last_search_nickname);
               last_search_first_name = strdup(firstname);
               last_search_last_name = strdup(lastname);
               last_search_nickname = strdup(nickname);
               last_search_uin = atoi(uin);
            }

            name = saprintf("%s %s", firstname, lastname);

            switch (status & 0x7f) {
               case GG_STATUS_AVAIL:
               case GG_STATUS_AVAIL_DESCR:
                  active = strdup("Avail");
                  break;
               case GG_STATUS_BUSY:
               case GG_STATUS_BUSY_DESCR:
                  active = strdup("Busy");
                  break;
               case GG_STATUS_INVISIBLE:
               case GG_STATUS_INVISIBLE_DESCR:
                  active = strdup("Invis");
                  break;
               default:
                  active = strdup("Inact");
            }

            printf("UIN\t: %s\n", uin);
            printf("Name\t: %s\n", name);
            printf("Nick\t: %s\n", nickname);
            printf("City\t: %s\n", city);
            printf("Birth\t: %s\n", birthyear);
            printf("Active\t: %s\n\n", active);

            free(name);
            free(active);

            free(firstname);
            free(lastname);
            free(nickname);
            free(city);

            last_uin = atoi(uin);
         }

         /* je¶li mieli¶my ,,/find --all'', szukamy dalej */
         for (l = searches; l; l = l->next) {
            gg_pubdir50_t req = l->data;
            uin_t next;

            if (gg_pubdir50_seq(req) != gg_pubdir50_seq(res))
               continue;

            /* nie ma dalszych? to dziêkujemy */
            if (!(next = gg_pubdir50_next(res)) || !sess || next < last_uin) {
               list_remove(&searches, req, 0);
               gg_pubdir50_free(req);
               break;
            }

            gg_pubdir50_add(req, GG_PUBDIR50_START, itoa(next));
            gg_pubdir50(sess, req);

            break;
         }
	 gg_free_event(e);
	 break;
      }

      gg_free_event(e);
   }

   gg_logoff(sess);
   gg_free_session(sess);

   return 0;
}