The Programmer in Indian Corporate

November 15, 2010 at 11:30 am | Posted in Hacking, Programming | 1 Comment
Tags: , , ,

Quite a long time I have not posted anything (was unable to hack into programming, and even Linux). Corporate life has taken a toll on precious human life of mine and unfortunately I can’t do anything about it right now. Was trying to use C API for cURL to get an experience on how to use 3rd party APIs to build something we need. Remember the Hacker’s Belief #2 . 2nd I am writing this blogpost because I have seen many programmers (developers/software-enginners, or whatever fancy word you will like to use here) just don’t read the manual properly before using 3rd party API, they just don’t care, they feel frustration on reading the reference maual or man pages. I never felt so, may be because I started my learning from places like usenet and was more interested in programming itself rather than what kind of degree I will get from university. I say so because in India, most programmers focus on getting higher marks in computer engineering than learning basics of programming and later take this attitude to wherver they work. They become so much used to easy and fast way of writing crappy programs that they completely forget the patience in learning programming skills. Its good to impress some employer with 90-95% marks in degree, its living entirely another kind of life to learn to program well. Its totally another kind of living when your instincts will tell you how much important the ANSI C standard is, how much useful it is to write simple and small program stimulating your ability to undertstand basic algorithms and data structures. A majority of programmers in India (and thats quite of a majority) focus on short-term programming results, like writing a software in 1 month and tetsing it for 3 months while real programmers will write it in 1 or 2 months and testing will almost take care of itself in the end. Correctly written programs have 6 times lesser duration of testing as compared to badly written ones (without any regard for algorithms and data structures). I even say that corporation must hire 10 very good programmers rather than 100 crappy ones, 10 will produce code in half of the time than those 100 and testing will not be as frustrating to project manager as what those 100 will do. These 10 crazy and mad guys will do corrections and put their attitude and mentality into the code while the crappy ones will only add bugs, where fixing one bug will produce another one. A typical programmer in Indian corporate tries to avoid reference manuals and browsing through mailing list discussions for hours and days and defintely avoids doing his home work before asking. All of these lead to softwares with lots of bugs and wastage of time and energy of both corporate and the the new programmer who reads the code later to modify or add to that code. They think its time consuming, it gives a headache and its not important to learn programming as a way of life as compared to project-deadline. They are wrong. Their focus is short term while the real programming is long term. No pain, no gain and pain becomes a joy in long term. The programmers/managers who say that you can’t write programs in small time using the real Hacker’s way are like the persons who say you can’t make money by giving source for free. In fact you can. When your instincts and feelings for programming are dead, the real programmer inside you is dead.

Wrote this small piece of code to get data form any web-site and save it in the program for later use. This is what I wrote in 1 hour hack, a program that compiles fine with -ansi -pedantic -Wall -Wextra flags to gcc and sill buggy:

/* WARNING: Buggy Program. Not using libcurl in a proper way. Not recommended to be even saved on HDD 
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

size_t save_data(void* buffer, size_t size, size_t nmemb, void* incoming_data);

enum {
  SIZE_ERROR_ARR = CURL_ERROR_SIZE * 4
};


int main(void)
{
  CURL* curl;
  CURLcode res;
  char error_arr[SIZE_ERROR_ARR+1] = {0};

  curl = curl_easy_init();
  if(curl)
    {
      /* Use one VERSION by commenting the other */

      /* VERSION 1 : Outputs to stdout*/ 
      curl_easy_setopt(curl, CURLOPT_URL, "http://google.com");
      res = curl_easy_perform(curl); 

      /* VERSION 2 : Saves to array 
      curl_easy_setopt(curl, CURLOPT_URL, "http://google.com");
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, save_data);
      curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_arr);
      res = curl_easy_perform(curl); 
      */
      if(res)
	{
	  printf("IN: %s @%d: Some error occured while curl_easy_perform(), ERRORBUFFER said: \n", __FILE__, __LINE__);
	  printf("%s\n", error_arr);
	}

      /* always cleanup */
      curl_easy_cleanup(curl);
    }

  return 0;
}



size_t save_data(void* buffer, size_t size, size_t nmemb, void* incoming_data)
{
  size_t idx;
  const size_t END_INDEX = size * nmemb;
  char* src = (char*) buffer;

  char* dest = malloc(END_INDEX * sizeof*dest);
  memset(dest, '\0', END_INDEX);

  if(NULL == dest)
    {
      printf("IN: %s @%d: Out of Memory\n", __FILE__, __LINE__);
      exit(EXIT_FAILURE);
    }

  /*  Using Static Array by taking extremely large size wasting 100 times the memoery required.
      char dest[100001] = {0};
      How to know the size of array in advance. 
      char dest[END_INDEX + 1] = {0}; will not work as variable-size arrays are not allowed in ANSI standard. But using variable-size 
      is good solution to the problem ???
      malloc() will be expensive for 10 million http sends/receive  waitings to happen. 
      So what to do ???
  */

  for(idx = 0; idx < END_INDEX - 1; ++idx)
    {
      dest[idx] = *src++;
    }
  dest[idx] = '\0';
  printf("--------------------------------------\n");
  /* I wonder what 4th argument is used for when it contains garbage 😮 */
  printf("incoming_data = %s\n", (char*)incoming_data); 
  printf("dest = %s\n", dest);

  if(0 == strcmp(dest, ""))
    {
      printf("EMPTY string received\n");
    }

  printf("--------------------------------------\n");
  return END_INDEX;
}

Unfortunately, this is exactly what you can expect from a guy with no gifted ability to program, who learns from hard-work and experience only. I learn by dwelling deep into refernce manuals, man pages, FAQs and mailing-list archives and thats tough and the only one way to learn to use a program in proper way, the way the API was supposed to be used. I discussed this on mailing list and I get this reply from the creator of cURL: “See http://curl.haxx.se/libcurl/c/getinmemory.html“, one line reply which matches exactly with what I needed. Any programmer who does his home work before asking questions deserves such kind of meaningful reply :).

Here is the whole conversation: http://curl.haxx.se/mail/lib-2010-11/0123.html and here is the code I needed to understand before aksing anymore questions:

/*****************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 *
 * Example source code to show how the callback function can be used to
 * download data into a chunk of memory instead of storing it in a file.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <curl/curl.h>

struct MemoryStruct {
  char *memory;
  size_t size;
};


static size_t
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)data;

  mem->memory = realloc(mem->memory, mem->size + realsize + 1);
  if (mem->memory == NULL) {
    /* out of memory! */
    printf("not enough memory (realloc returned NULL)\n");
    exit(EXIT_FAILURE);
  }

  memcpy(&(mem->memory[mem->size]), ptr, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}


int main(int argc, char **argv)
{
  CURL *curl_handle;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */
  chunk.size = 0;    /* no data at this point */

  curl_global_init(CURL_GLOBAL_ALL);

  /* init the curl session */
  curl_handle = curl_easy_init();

  /* specify URL to get */
  curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.example.com/");

  /* send all data to this function  */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

  /* we pass our 'chunk' struct to the callback function */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);

  /* some servers don't like requests that are made without a user-agent
     field, so we provide one */
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  /* get it! */
  curl_easy_perform(curl_handle);

  /* cleanup curl stuff */
  curl_easy_cleanup(curl_handle);

  /*
   * Now, our chunk.memory points to a memory block that is chunk.size
   * bytes big and contains the remote file.
   *
   * Do something nice with it!
   *
   * You should be aware of the fact that at this point we might have an
   * allocated data block, and nothing has yet deallocated that data. So when
   * you're done with it, you should free() it as a nice application.
   */

  printf("%lu bytes retrieved\n", chunk.size);

  if(chunk.memory)
    free(chunk.memory);

  /* we're done with libcurl, so clean it up */
  curl_global_cleanup();

  return 0;
}

So I came to know that CURLOPT_WRITEFUNCTION sets the function that libcurl will call. CURLOPT_WRITEDATA is used to set the pointer that the function gets in its fourth argument. They were both needed to use libcurl properly, the way it was supposed to be used. Daniel was very faaaast in replying and to the point. Thanks to him, he saved a lot of time and energy of mine.

 

 


Copyright © 2010 Arnuld Uttre, #331/type-2/sector-1, Naya Nangal, Distt. – Ropar, Punjab (INDIA) – 140126

Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.

Advertisements

1 Comment »

RSS feed for comments on this post. TrackBack URI

  1. […] – 2 November 18, 2010 at 2:02 pm | Posted in Uncategorized | Leave a Comment In my earlier rant I talked about how Indian programmers are not interested in learning and sharpening their […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: