Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

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 11:34:04pm UTC 

  1. // nasza-klasa.pl mutual friend finder
  2. // Written by Leszek Godlewski
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <curl/curl.h>
  8.  
  9. // friends list request flags
  10. #define FLF_UID     (1 << 0)
  11. #define FLF_FIRST_NAME      (1 << 1)
  12. #define FLF_LAST_NAME         (1 << 2)
  13. #define FLF_AVATAR                        (1 << 3)
  14. #define FLF_FRIENDS_COUNT              (1 << 4)
  15. #define FLF_LOCATION            (1 << 5)    // city
  16. #define FLF_MSGC_STATUS   (1 << 6) // messaging centre status
  17. #define FLF_MSGC_STATUS_DESC    (1 << 7)    // messaging centre status description string
  18. #define FLF_UNKNOWN                    (1 << 8)     // unknown flag
  19. #define FLF_ARTIFICIALITY              (1 << 9)       // whether or not the person in the account is a fictitious one or a real one
  20.  
  21. typedef unsigned char   bool_t;
  22. #define btrue         1
  23. #define bfalse      0
  24.  
  25. CURL    *easyhandle = NULL;
  26.  
  27. char    *response = NULL;
  28. int          responseSize = 0;
  29.  
  30. void printHelp(char *argv0) {
  31.         printf("Compares the friend lists of 2 given users and returns mutual friends.\n"
  32.                 "\n"
  33.                 "Usage: %s <username> <password> <UID1> <UID2>\n"
  34.                 "   username    - your nasza-klasa.pl username/e-mail address\n"
  35.                 "   password    - your nasza-klasa.pl password\n"
  36.                 "   UID1        - the UID of the first person\n"
  37.                 "   UID2        - the UID of the second person\n", argv0);
  38. }
  39.  
  40. size_t writeDocument(void *buf, size_t size, size_t nmemb, void *p) {
  41.         int          bytes = size * nmemb;
  42.         char    *target;
  43.         if (!response) {
  44.                 responseSize = bytes + 1;
  45.                 response = malloc(responseSize);
  46.                 target = response;
  47.         } else {
  48.                 response = realloc(response, responseSize + bytes);
  49.                 target = response + responseSize - 1;
  50.                 responseSize += bytes;
  51.         }
  52.         memcpy(target, buf, bytes);
  53.         response[responseSize - 1] = 0// ensure a trailing 0
  54.         return bytes;
  55. }
  56.  
  57. struct curl_slist       *headers = NULL;
  58.  
  59. void initCurl(void) {
  60.         curl_global_init(CURL_GLOBAL_WIN32);
  61.         easyhandle = curl_easy_init();
  62.         curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, writeDocument);
  63.         curl_easy_setopt(easyhandle, CURLOPT_COOKIEFILE, "dummyfile");
  64.         curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 1);
  65. #if 0   // debugging
  66.         curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1);
  67. #endif
  68.  
  69.         // the server requires a user agent
  70.         headers = curl_slist_append(headers, "User-Agent: nasza-klasa.pl mutual friend finder");
  71.         curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
  72. }
  73.  
  74. bool_t login(char *l, char *p) {
  75.         char                postdata[1024], *el, *ep;
  76.         int                         retval;
  77.  
  78.         el = curl_easy_escape(easyhandle, l, strlen(l));
  79.         ep = curl_easy_escape(easyhandle, p, strlen(p));
  80.         snprintf(postdata, sizeof(postdata), "login=%s&password=%s", el, ep);
  81.         curl_free(el);
  82.         curl_free(ep);
  83.         curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, postdata);
  84.  
  85.         curl_easy_setopt(easyhandle, CURLOPT_URL, "http://nasza-klasa.pl/login");
  86.         retval = curl_easy_perform(easyhandle);
  87.  
  88.         curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, "");
  89.  
  90.         if (strstr(response, "Nieprawid\305\202owa nazwa u\305\274ytkownika lub has\305\202o."))
  91.                 retval = bfalse;
  92.         else
  93.                 retval = (retval == 0);
  94.  
  95.         free(response);
  96.         response = NULL;
  97.         responseSize = 0;
  98.  
  99.         return retval;
  100. }
  101.  
  102. #define CLIENT_VERSION    135              // version of the nasza-klasa.pl software we're identifying as
  103.  
  104. #define MAX_NAME_LENGTH  100            // limit present in the nasza-klasa.pl website's source code
  105.  
  106. typedef struct {
  107.         int          uid;
  108.         char    fname[MAX_NAME_LENGTH];
  109.         char    lname[MAX_NAME_LENGTH];
  110.         bool_t  mutual;
  111. } contact_t;
  112.  
  113. contact_t       *contacts = NULL;
  114. int               numContacts = 0;
  115.  
  116. bool_t getContactLists(char *u1, char *u2) {
  117.         char    url[1024];
  118.         char    *r1 = NULL, *r2 = NULL;
  119.         char    *in, *out;
  120.         int          retval, i, j, n;
  121.  
  122.         snprintf(url, sizeof(url), "http://nasza-klasa.pl/friends_list/%s/%d/%d", u1, FLF_UID | FLF_FIRST_NAME | FLF_LAST_NAME, CLIENT_VERSION);
  123.         curl_easy_setopt(easyhandle, CURLOPT_URL, url);
  124.         retval = curl_easy_perform(easyhandle);
  125.         if (retval != 0) {
  126.                 if (response) {
  127.                         free(response);
  128.                         response = NULL;
  129.                 }
  130.                 return bfalse;
  131.         }
  132.         r1 = response;
  133.  
  134.         response = NULL;
  135.         responseSize = 0;
  136.  
  137.         // we don't need as much info from the other person, fetch the UIDs only
  138.         snprintf(url, sizeof(url), "http://nasza-klasa.pl/friends_list/%s/%d/%d", u2, FLF_UID, CLIENT_VERSION);
  139.         curl_easy_setopt(easyhandle, CURLOPT_URL, url);
  140.         retval = curl_easy_perform(easyhandle);
  141.         if (retval != 0) {
  142.                 if (response) {
  143.                         free(response);
  144.                         response = NULL;
  145.                 }
  146.                 if (r1)
  147.                         free(r1);
  148.                 return bfalse;
  149.         }
  150.         r2 = response;
  151.  
  152.         response = NULL;
  153.         responseSize = 0;
  154.  
  155.         // parse the first contact list
  156.         // get the friends count and allocate memory
  157.         in = strstr(r1 + 3, "\"FRIENDS_COUNT\":");
  158.         if (!in) {
  159.                 if (response) {
  160.                         free(response);
  161.                         response = NULL;
  162.                 } if (r1)
  163.                         free(r1);
  164.                 if (r2)
  165.                         free(r2);
  166.                 return bfalse;
  167.         }
  168.         in += 16;
  169.         out = url;      // reuse the variable
  170.         while (*in < '0' || *in > '9')
  171.                 in++;
  172.         while (*in >= '0' && *in <= '9')
  173.                 *out++ = *in++;
  174.         *out = 0;
  175.         numContacts = atoi(url);
  176.         contacts = malloc(numContacts * sizeof(*contacts));
  177.         memset(contacts, 0, numContacts * sizeof(*contacts));
  178.  
  179.         // get the UIDs
  180.         in = strstr(r1 + 3, "\"UID\":");
  181.         if (!in) {
  182.                 if (response) {
  183.                         free(response);
  184.                         response = NULL;
  185.                 }
  186.                 if (r1)
  187.                         free(r1);
  188.                 if (r2)
  189.                         free(r2);
  190.                 free(contacts);
  191.                 return bfalse;
  192.         }
  193.         in += 6;
  194.         while (*in != '[')
  195.                 in++;
  196.         for (i = 0; i < numContacts; i++) {
  197.                 out = url;
  198.                 while (*in < '0' || *in > '9')
  199.                         in++;
  200.                 while (*in >= '0' && *in <= '9')
  201.                         *out++ = *in++;
  202.                 *out = 0;
  203.                 contacts[i].uid = atoi(url);
  204.         }
  205.  
  206.         // get the first names
  207.         in = strstr(r1 + 3, "\"FIRST_NAME\":");
  208.         if (!in) {
  209.                 if (response) {
  210.                         free(response);
  211.                         response = NULL;
  212.                 } if (r1)
  213.                         free(r1);
  214.                 if (r2)
  215.                         free(r2);
  216.                 free(contacts);
  217.                 return bfalse;
  218.         }
  219.         in += 13;
  220.         while (*in != '[')
  221.                 in++;
  222.         for (i = 0; i < numContacts; i++) {
  223.                 out = url;
  224.                 while (*in != '\"')
  225.                         in++;
  226.                 in++;
  227.                 while (*in != '\"')
  228.                         *out++ = *in++;
  229.                 in++;
  230.                 *out = 0;
  231.                 strncpy(contacts[i].fname, url, sizeof(contacts->fname));
  232.         }
  233.  
  234.         // get the last names
  235.         in = strstr(r1 + 3, "\"LAST_NAME\":");
  236.         if (!in) {
  237.                 if (response) {
  238.                         free(response);
  239.                         response = NULL;
  240.                 } if (r1)
  241.                         free(r1);
  242.                 if (r2)
  243.                         free(r2);
  244.                 free(contacts);
  245.                 return bfalse;
  246.         }
  247.         in += 12;
  248.         while (*in != '[')
  249.                 in++;
  250.         for (i = 0; i < numContacts; i++) {
  251.                 out = url;
  252.                 while (*in != '\"')
  253.                         in++;
  254.                 in++;
  255.                 while (*in != '\"')
  256.                         *out++ = *in++;
  257.                 in++;
  258.                 *out = 0;
  259.                 strncpy(contacts[i].lname, url, sizeof(contacts->lname));
  260.         }
  261.  
  262.         // parse the second contact list
  263.         // get the friends count
  264.         in = strstr(r2 + 3, "\"FRIENDS_COUNT\":");
  265.         if (!in) {
  266.                 if (response) {
  267.                         free(response);
  268.                         response = NULL;
  269.                 }
  270.                 if (r1)
  271.                         free(r1);
  272.                 if (r2)
  273.                         free(r2);
  274.                 return bfalse;
  275.         }
  276.         in += 16;
  277.         out = url;      // reuse the variable
  278.         while (*in < '0' || *in > '9')
  279.                 in++;
  280.         while (*in >= '0' && *in <= '9')
  281.                 *out++ = *in++;
  282.         *out = 0;
  283.         retval = atoi(url);     // reuse the variable
  284.  
  285.         // get the UIDs
  286.         in = strstr(r2 + 3, "\"UID\":");
  287.         if (!in) {
  288.                 if (response) {
  289.                         free(response);
  290.                         response = NULL;
  291.                 }
  292.                 if (r1)
  293.                         free(r1);
  294.                 if (r2)
  295.                         free(r2);
  296.                 free(contacts);
  297.                 return bfalse;
  298.         }
  299.         in += 6;
  300.         while (*in != '[')
  301.                 in++;
  302.         for (i = 0; i < retval; i++) {
  303.                 out = url;
  304.                 while (*in < '0' || *in > '9')
  305.                         in++;
  306.                 while (*in >= '0' && *in <= '9')
  307.                         *out++ = *in++;
  308.                 *out = 0;
  309.                 n = atoi(url);
  310.                 for (j = 0; j < numContacts; j++) {
  311.                         if (contacts[j].uid == n) {
  312.                                 contacts[j].mutual = btrue;
  313.                                 break;
  314.                         }
  315.                 }
  316.         }
  317.  
  318.         free(r1);
  319.         free(r2);
  320.         return btrue;
  321. }
  322.  
  323. void logout(void) {
  324.         curl_easy_setopt(easyhandle, CURLOPT_URL, "http://nasza-klasa.pl/logout?l=1");
  325.         curl_easy_perform(easyhandle);
  326. }
  327.  
  328. void cleanupCurl(void) {
  329.         curl_slist_free_all(headers);
  330.         curl_easy_cleanup(easyhandle);
  331.         curl_global_cleanup();
  332. }
  333.  
  334. void printMutualFriends(void) {
  335.         int     i;
  336.  
  337.         for (i = 0; i < numContacts; i++) {
  338.                 if (!contacts[i].mutual)
  339.                         continue;
  340.                 printf("%s %s (http://nasza-klasa.pl/profile/%d)\n", contacts[i].fname, contacts[i].lname, contacts[i].uid);
  341.         }
  342. }
  343.  
  344. int main(int argc, char *argv[]) {
  345.         printf("nasza-klasa.pl mutual friend finder\n"
  346.                 "Written by Leszek Godlewski\n"
  347.                 "This program is free software under the WTFPL license.\n"
  348.                 "\n"
  349.                 );
  350.         if (argc != 5) {
  351.                 printHelp(argv[0]);
  352.                 exit(0);
  353.         }
  354.         initCurl();
  355.         printf("Logging in...\n");
  356.         if (!login(argv[1], argv[2])) {
  357.                 printf("Logging in failed. Check your login details and internet connection.\n");
  358.                 exit(0);
  359.         }
  360.         printf("Downloading and processing contact lists...\n");
  361.         if (!getContactLists(argv[3], argv[4])) {
  362.                 printf("Retrieving contact lists failed. Check your internet connection.\n");
  363.                 exit(0);
  364.         }
  365.         printf("Logging out...\n");
  366.         logout();
  367.         cleanupCurl();
  368.         printf("Mutual friends are:\n");
  369.         printMutualFriends();
  370.         free(contacts);
  371.     return 0;
  372. }

Paste Details

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



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.

comments powered by Disqus
worth-right