Advertising
Paste Description for Nasza-klasa.pl mutual friend fin
Proof-of-concept app written for my blog (http://iqdev.blogspot.com/) that finds mutual friends for 2 given users of the Polish social networking platform. CURL (http://curl.haxx.se/) is required for building, a nasza-klasa.pl account is required for functioning.
- Nasza-klasa.pl mutual friend fin
- Saturday, September 13th, 2008 at 5:34:04pm MDT
- // nasza-klasa.pl mutual friend finder
- // Written by Leszek Godlewski
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <curl/curl.h>
- // friends list request flags
- #define FLF_UID (1 << 0)
- #define FLF_FIRST_NAME (1 << 1)
- #define FLF_LAST_NAME (1 << 2)
- #define FLF_AVATAR (1 << 3)
- #define FLF_FRIENDS_COUNT (1 << 4)
- #define FLF_LOCATION (1 << 5) // city
- #define FLF_MSGC_STATUS (1 << 6) // messaging centre status
- #define FLF_MSGC_STATUS_DESC (1 << 7) // messaging centre status description string
- #define FLF_UNKNOWN (1 << 8) // unknown flag
- #define FLF_ARTIFICIALITY (1 << 9) // whether or not the person in the account is a fictitious one or a real one
- typedef unsigned char bool_t;
- #define btrue 1
- #define bfalse 0
- CURL *easyhandle = NULL;
- char *response = NULL;
- int responseSize = 0;
- void printHelp(char *argv0) {
- "\n"
- "Usage: %s <username> <password> <UID1> <UID2>\n"
- " username - your nasza-klasa.pl username/e-mail address\n"
- " password - your nasza-klasa.pl password\n"
- " UID1 - the UID of the first person\n"
- " UID2 - the UID of the second person\n", argv0);
- }
- size_t writeDocument(void *buf, size_t size, size_t nmemb, void *p) {
- int bytes = size * nmemb;
- char *target;
- if (!response) {
- responseSize = bytes + 1;
- response = malloc(responseSize);
- target = response;
- } else {
- response = realloc(response, responseSize + bytes);
- target = response + responseSize - 1;
- responseSize += bytes;
- }
- memcpy(target, buf, bytes);
- response[responseSize - 1] = 0; // ensure a trailing 0
- return bytes;
- }
- struct curl_slist *headers = NULL;
- void initCurl(void) {
- curl_global_init(CURL_GLOBAL_WIN32);
- easyhandle = curl_easy_init();
- curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, writeDocument);
- curl_easy_setopt(easyhandle, CURLOPT_COOKIEFILE, "dummyfile");
- curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 1);
- #if 0 // debugging
- curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1);
- #endif
- // the server requires a user agent
- headers = curl_slist_append(headers, "User-Agent: nasza-klasa.pl mutual friend finder");
- curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
- }
- bool_t login(char *l, char *p) {
- char postdata[1024], *el, *ep;
- int retval;
- el = curl_easy_escape(easyhandle, l, strlen(l));
- ep = curl_easy_escape(easyhandle, p, strlen(p));
- snprintf(postdata, sizeof(postdata), "login=%s&password=%s", el, ep);
- curl_free(el);
- curl_free(ep);
- curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, postdata);
- curl_easy_setopt(easyhandle, CURLOPT_URL, "http://nasza-klasa.pl/login");
- retval = curl_easy_perform(easyhandle);
- curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, "");
- if (strstr(response, "Nieprawid\305\202owa nazwa u\305\274ytkownika lub has\305\202o."))
- retval = bfalse;
- else
- retval = (retval == 0);
- free(response);
- response = NULL;
- responseSize = 0;
- return retval;
- }
- #define CLIENT_VERSION 135 // version of the nasza-klasa.pl software we're identifying as
- #define MAX_NAME_LENGTH 100 // limit present in the nasza-klasa.pl website's source code
- typedef struct {
- int uid;
- char fname[MAX_NAME_LENGTH];
- char lname[MAX_NAME_LENGTH];
- bool_t mutual;
- } contact_t;
- contact_t *contacts = NULL;
- int numContacts = 0;
- bool_t getContactLists(char *u1, char *u2) {
- char url[1024];
- char *r1 = NULL, *r2 = NULL;
- char *in, *out;
- int retval, i, j, n;
- snprintf(url, sizeof(url), "http://nasza-klasa.pl/friends_list/%s/%d/%d", u1, FLF_UID | FLF_FIRST_NAME | FLF_LAST_NAME, CLIENT_VERSION);
- curl_easy_setopt(easyhandle, CURLOPT_URL, url);
- retval = curl_easy_perform(easyhandle);
- if (retval != 0) {
- if (response) {
- free(response);
- response = NULL;
- }
- return bfalse;
- }
- r1 = response;
- response = NULL;
- responseSize = 0;
- // we don't need as much info from the other person, fetch the UIDs only
- snprintf(url, sizeof(url), "http://nasza-klasa.pl/friends_list/%s/%d/%d", u2, FLF_UID, CLIENT_VERSION);
- curl_easy_setopt(easyhandle, CURLOPT_URL, url);
- retval = curl_easy_perform(easyhandle);
- if (retval != 0) {
- if (response) {
- free(response);
- response = NULL;
- }
- if (r1)
- free(r1);
- return bfalse;
- }
- r2 = response;
- response = NULL;
- responseSize = 0;
- // parse the first contact list
- // get the friends count and allocate memory
- in = strstr(r1 + 3, "\"FRIENDS_COUNT\":");
- if (!in) {
- if (response) {
- free(response);
- response = NULL;
- } if (r1)
- free(r1);
- if (r2)
- free(r2);
- return bfalse;
- }
- in += 16;
- out = url; // reuse the variable
- while (*in < '0' || *in > '9')
- in++;
- while (*in >= '0' && *in <= '9')
- *out++ = *in++;
- *out = 0;
- numContacts = atoi(url);
- contacts = malloc(numContacts * sizeof(*contacts));
- memset(contacts, 0, numContacts * sizeof(*contacts));
- // get the UIDs
- in = strstr(r1 + 3, "\"UID\":");
- if (!in) {
- if (response) {
- free(response);
- response = NULL;
- }
- if (r1)
- free(r1);
- if (r2)
- free(r2);
- free(contacts);
- return bfalse;
- }
- in += 6;
- while (*in != '[')
- in++;
- for (i = 0; i < numContacts; i++) {
- out = url;
- while (*in < '0' || *in > '9')
- in++;
- while (*in >= '0' && *in <= '9')
- *out++ = *in++;
- *out = 0;
- contacts[i].uid = atoi(url);
- }
- // get the first names
- in = strstr(r1 + 3, "\"FIRST_NAME\":");
- if (!in) {
- if (response) {
- free(response);
- response = NULL;
- } if (r1)
- free(r1);
- if (r2)
- free(r2);
- free(contacts);
- return bfalse;
- }
- in += 13;
- while (*in != '[')
- in++;
- for (i = 0; i < numContacts; i++) {
- out = url;
- while (*in != '\"')
- in++;
- in++;
- while (*in != '\"')
- *out++ = *in++;
- in++;
- *out = 0;
- strncpy(contacts[i].fname, url, sizeof(contacts->fname));
- }
- // get the last names
- in = strstr(r1 + 3, "\"LAST_NAME\":");
- if (!in) {
- if (response) {
- free(response);
- response = NULL;
- } if (r1)
- free(r1);
- if (r2)
- free(r2);
- free(contacts);
- return bfalse;
- }
- in += 12;
- while (*in != '[')
- in++;
- for (i = 0; i < numContacts; i++) {
- out = url;
- while (*in != '\"')
- in++;
- in++;
- while (*in != '\"')
- *out++ = *in++;
- in++;
- *out = 0;
- strncpy(contacts[i].lname, url, sizeof(contacts->lname));
- }
- // parse the second contact list
- // get the friends count
- in = strstr(r2 + 3, "\"FRIENDS_COUNT\":");
- if (!in) {
- if (response) {
- free(response);
- response = NULL;
- }
- if (r1)
- free(r1);
- if (r2)
- free(r2);
- return bfalse;
- }
- in += 16;
- out = url; // reuse the variable
- while (*in < '0' || *in > '9')
- in++;
- while (*in >= '0' && *in <= '9')
- *out++ = *in++;
- *out = 0;
- retval = atoi(url); // reuse the variable
- // get the UIDs
- in = strstr(r2 + 3, "\"UID\":");
- if (!in) {
- if (response) {
- free(response);
- response = NULL;
- }
- if (r1)
- free(r1);
- if (r2)
- free(r2);
- free(contacts);
- return bfalse;
- }
- in += 6;
- while (*in != '[')
- in++;
- for (i = 0; i < retval; i++) {
- out = url;
- while (*in < '0' || *in > '9')
- in++;
- while (*in >= '0' && *in <= '9')
- *out++ = *in++;
- *out = 0;
- n = atoi(url);
- for (j = 0; j < numContacts; j++) {
- if (contacts[j].uid == n) {
- contacts[j].mutual = btrue;
- break;
- }
- }
- }
- free(r1);
- free(r2);
- return btrue;
- }
- void logout(void) {
- curl_easy_setopt(easyhandle, CURLOPT_URL, "http://nasza-klasa.pl/logout?l=1");
- curl_easy_perform(easyhandle);
- }
- void cleanupCurl(void) {
- curl_slist_free_all(headers);
- curl_easy_cleanup(easyhandle);
- curl_global_cleanup();
- }
- void printMutualFriends(void) {
- int i;
- for (i = 0; i < numContacts; i++) {
- if (!contacts[i].mutual)
- continue;
- printf("%s %s (http://nasza-klasa.pl/profile/%d)\n", contacts[i].fname, contacts[i].lname, contacts[i].uid);
- }
- }
- int main(int argc, char *argv[]) {
- "Written by Leszek Godlewski\n"
- "This program is free software under the WTFPL license.\n"
- "\n"
- );
- if (argc != 5) {
- printHelp(argv[0]);
- exit(0);
- }
- initCurl();
- if (!login(argv[1], argv[2])) {
- exit(0);
- }
- if (!getContactLists(argv[3], argv[4])) {
- exit(0);
- }
- logout();
- cleanupCurl();
- printMutualFriends();
- free(contacts);
- return 0;
- }
advertising
Update the Post
Either update this post and resubmit it with changes, or make a new post.
You may also comment on this post.
Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.