Thursday, December 15, 2011

Program to read the contact details from collection of VCF files:

After so many days, my techBlog is getting a post, Great.

Recently i baught a new lower end SAMSUMNG phone. I felt good to have that phone, Samsung Metro C3322. My phone is having an option to take the backup of messages, contacts, calendars etc. May be other phones also have. When i took the backup of contacts, .vcf files are created for each contact. I knew something about vcf files due to my project experience.

After few days, a thought came to my mind to take the print out of all the contacts of my phone. But files are more which is of indivual. Then, i decided to write a C program to extract the names and numbers of all the contacts in a directory and started immediately.

Using file I/O and string functions, i could finish as early as possible.

When i was in KPIT, i used strtok() function a lot which made me not to forget. Once again, this program made me to memorise the same. Really, strtok() function is tood good for us like Application programmers.


My program will take directory of vcf files as input and it will write the names and numbers (mobile and home only) into a file, NameNumber.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include
#include
#include

int writeToFile(char *data)
{
FILE *fp;
fp = fopen("NameNumber", "a");
if(fp == NULL)
{
printf("fopen error in function");
exit(10);
}
fwrite(data, 1, strlen(data), fp);
fclose(fp);
return 0;
}


int readFile(FILE *fp2)
{
char *ptr, Number[50], FName[50], buf[80];
int CN, FN;
char data[100];

while(!feof(fp2))
{
if(fgets(buf, 50, fp2)!= NULL)
{
ptr=strtok(buf, ":;");
printf("string is : %s\n", ptr);
while(ptr != NULL)
{
if(FN == 1)
{
memset(&FName, 0, 50); ////Note:
strncpy(FName, ptr, strlen(ptr)-1);
FName[strlen(FName)-1]='\0';
FN=0;
printf("Name is : %s\n", FName);
}
if(strcmp(ptr, "FN")==0)
{
FN=1;
}
if(CN == 1)
{
if(strcmp(ptr, "VOICE")==0)
{
ptr = strtok(NULL, ":;");
}
strcpy(Number, ptr);
CN=0;
printf("Number is %s\n", Number);
}

if(strcmp(ptr, "CELL")==0)
{
CN=1;
strcpy(Number, ptr);
}
if(strcmp(ptr, "HOME")==0)
{
CN=1;
strcpy(Number, ptr);
}
ptr = strtok(NULL, ":;");
}
}
else
{
break;
}
}
sprintf(data,"%s %s %s", FName, ":", Number);
writeToFile(data);
}

int main()
{
FILE *fp, *fp2;
int FN=0, CN=0;
char fileName[50], *ptr=NULL, buf[30], temp[10], FName[30], Number[30];
char path[100];
system("ls myPhone/contact/ > file");
fp = fopen("file", "r");
if(fp == NULL)
{
printf("Fileopen error");
exit(10);
}
while(!feof(fp))
{
strcpy(path, "myPhone/contact/");
if(fgets(fileName, 100, fp) == NULL)
{
printf("fgets error for %s", fileName);
exit(10);
}
fp2 = fopen(strncat(path, fileName, strlen(fileName)-1), "r");
if(fp2 == NULL)
{
printf("Fileopen2 error: %s\n", path);
exit(10);
}
printf("Opened is : %s\n", path);
readFile(fp2);
}
exit(10);
fclose(fp);
fclose(fp2);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

In the above program, memset() function made this program more robust. Because, I was facing some issues related to names. When i was printing the names, i was getting some junk characters. I took quite amount of time to solve using memset function. You can try the same without memset function.

This was written and executed under Linux platform. But when i run the same program under QNX platform, program crashed and code dump is found. I am planning to dig into that to understand the behavior of QNX. Let me see...

I like to write simple programs frequently by having these kind of problem statements in hand which will make me to remember something good about this tech field.

Keep Programming, Keep Doing Good....

Tuesday, October 25, 2011

Sharing a variable between two C files : An Experience

Even though we work for some years on any language, sometimes, we will not aware of some basic concepts of languages, which is becasue of we never use those in our coding styles. For example, if we are working on C language since 5 years and suddenly if you want to use snprintf() function, definitely you will go for Google...!!!

When i wanted to share a variable between two different C files, what i have declared a variable in a common header file for both the files. While testing the application, in one file where the value being assigned, the value was fine and in another file, the value of the variable is always 0. I was wondering..!! Thinking like, how can it happen...?

After all, discussed with my guide-for-all lecturere and then only i came to know that, when we include a header file in 2 different C files, scope of the variables will become limited to those files and those are separate for both the files. That means, if we declare a variable g_temp in abc.h file if we include ab.c in a.c and b.c, g_temp will be different for both the files and hence values are local to those files.

If we declare the variable in one C file and if we use extern keyword to refer to that, then it will work fine.

Otherwise, we have to have a function in one C file and to get and set the value of a global variable which is defined in the same file.


Another scenario:

In the same way, we will not aware of some basic concepts even though we are working on the same technology, becasue we have not used those concepts particularly. For example, in C language, we use switch case statements extensively. But somebody asks if we put one printf statement before the first case statement, what will happen ? We ll test manually or we ll go for google.

Recently only i came across about the above. If we put any statement before the first case statement, that will not be executed.

#define SUCCESS 1

int state=SUCCESS;
switch(State)
{
printf("Before the case statements starts");
case SUCCESS:
printf("Testing the switch case");
break;
default:
printf("default case");
}

In the above code, the printf statement before the case statement starts, will never executes. This looks very very simple, but i came to know very recently. May be this is obvious.

Keep knowing new things... Gud Luck...

Friday, September 16, 2011

Local variables in function stack: An Experience

When we were preparing for the interviews in College days, nothing was in mind except interviews. Also we were no thinking beyond the interview requirements. But when we face the same type of situations while working in any project that will make us to understand our present and past understanding capabilities and also make us to know more.

When I was in 6th sem of my engineering, I was attended an interview of RoboSoft, UDUPI. While preparing for that, I came across a C question as follows.


#include "stdio.h"
void main()
{
int a=10, b=20;
int *ptr = &a;

ptr--;
printf("%d", *ptr);
}
This will print as 20. Also this may depends on compilers. Assume GCC for this.

When local variables are declared, will be pushed into the stack in order of their declaration. Stack address will increment from TOP(decrement from BOTTOM). Here initially ptr will point to a's location and when we decrement it will point to b's location.

Lets come to point. I have following type of declarations.

struct abc
{
union data xyz;
int i;
};

In my program, I was written as follows.

uinon data a;
int temp = 10;
printf("%d", temp);
memset(a, 0, sizeof(struct abc));
printf("%d", temp);

While testing my code, I was getting the value of temp is 10 and 0 both. Initially I was wondering how temp value is changing without doing anything. After sometime, I understood that memset is making temp 0..!!!?? But how ?

Then, due to my interview question, I closely looked into the memset statement and its declaration and came to know how memset was making the temp variable 0. Because, structure is having sizeof union +1 and hence next immediate 32 bit is setting to 0.

After knowing this, I was very happy and was feeling like anything for that point of time.

This is what will make us our work enjoyable to some extent and thats what i expected from this industry.

Happy moment...!! gUd lUcK...

Monday, September 5, 2011

'find' Command Reference : Very Useful

When we use Linux/UNIX based systems, we need to know the usage of commands which will make our work easier and faster. Because, some of the operations can be done through commands itself..!!

Also, how much you know about Linux will be decided by your command knowledge and its usage. One of those is 'find'.

Please have a look once.

1. Find Files Using Name
This is a basic usage of the find command. This example finds all files with name — MyCProgram.c in the current directory and all it’s sub-directories.
# find -name "MyCProgram.c"
./backup/MyCProgram.c
./MyCProgram.c

2. Find Files Using Name and Ignoring Case
This is a basic usage of the find command. This example finds all files with name — MyCProgram.c (ignoring the case) in the current directory and all it’s sub-directories.
# find -iname "MyCProgram.c"
./mycprogram.c
./backup/mycprogram.c
./backup/MyCProgram.c
./MyCProgram.c

3. Limit Search To Specific Directory Level Using mindepth and maxdepth
Find the passwd file under all sub-directories starting from root directory.
# find / -name passwd
./usr/share/doc/nss_ldap-253/pam.d/passwd
./usr/bin/passwd
./etc/pam.d/passwd
./etc/passwd

Find the passwd file under root and one level down. (i.e root — level 1, and one sub-directory — level 2)
# find -maxdepth 2 -name passwd
./etc/passwd

Find the passwd file under root and two levels down. (i.e root — level 1, and two sub-directories — level 2 and 3 )
# find / -maxdepth 3 -name passwd
./usr/bin/passwd
./etc/pam.d/passwd
./etc/passwd

Find the password file between sub-directory level 2 and 4.
# find -mindepth 3 -maxdepth 5 -name passwd
./usr/bin/passwd
./etc/pam.d/passwd

4. Executing Commands on the Files Found by the Find Command.
In the example below, the find command calculates the md5sum of all the files with the name MyCProgram.c (ignoring case). {} is replaced by the current file name.
# find -iname "MyCProgram.c" -exec md5sum {} \;
d41d8cd98f00b204e9800998ecf8427e ./mycprogram.c
d41d8cd98f00b204e9800998ecf8427e ./backup/mycprogram.c
d41d8cd98f00b204e9800998ecf8427e ./backup/MyCProgram.c
d41d8cd98f00b204e9800998ecf8427e ./MyCProgram.c

5. Inverting the match.
Shows the files or directories whose name are not MyCProgram.c .Since the maxdepth is 1, this will look only under current directory.
# find -maxdepth 1 -not -iname "MyCProgram.c"
.
./MybashProgram.sh
./create_sample_files.sh
./backup
./Program.c

6. Finding Files by its inode Number.
Every file has an unique inode number, using that we can identify that file. Create two files with similar name. i.e one file with a space at the end.
# touch "test-file-name"

# touch "test-file-name "
[Note: There is a space at the end]

# ls -1 test*
test-file-name
test-file-name

From the ls output, you cannot identify which file has the space at the end. Using option -i, you can view the inode number of the file, which will be different for these two files.
# ls -i1 test*
16187429 test-file-name
16187430 test-file-name

You can specify inode number on a find command as shown below. In this example, find command renames a file using the inode number.
# find -inum 16187430 -exec mv {} new-test-file-name \;

# ls -i1 *test*
16187430 new-test-file-name
16187429 test-file-name

You can use this technique when you want to do some operation with the files which are named poorly as shown in the example below. For example, the file with name — file?.txt has a special character in it. If you try to execute “rm file?.txt”, all the following three files will get removed. So, follow the steps below to delete only the “file?.txt” file.
# ls
file1.txt file2.txt file?.txt

Find the inode numbers of each file.
# ls -i1
804178 file1.txt
804179 file2.txt
804180 file?.txt

Use the inode number to remove the file that had special character in it as shown below.
# find -inum 804180 -exec rm {} \;

# ls
file1.txt file2.txt
[Note: The file with name "file?.txt" is now removed]

7. Find file based on the File-Permissions
Following operations are possible.
Find files that match exact permission
Check whether the given permission matches, irrespective of other permission bits
Search by giving octal / symbolic representation

For this example, let us assume that the directory contains the following files. Please note that the file-permissions on these files are different.
# ls -l
total 0
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 all_for_all
-rw-r--r-- 1 root root 0 2009-02-19 20:30 everybody_read
---------- 1 root root 0 2009-02-19 20:31 no_for_all
-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file
-rw-r----- 1 root root 0 2009-02-19 20:27 others_can_also_read
----r----- 1 root root 0 2009-02-19 20:27 others_can_only_read

Find files which has read permission to group. Use the following command to find all files that are readable by the world in your home directory, irrespective of other permissions for that file.
# find . -perm -g=r -type f -exec ls -l {} \;
-rw-r--r-- 1 root root 0 2009-02-19 20:30 ./everybody_read
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 ./all_for_all
----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read
-rw-r----- 1 root root 0 2009-02-19 20:27 ./others_can_also_read

Find files which has read permission only to group.
# find . -perm g=r -type f -exec ls -l {} \;
----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read

Find files which has read permission only to group [ search by octal ]
# find . -perm 040 -type f -exec ls -l {} \;
----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read

8. Find all empty files (zero byte file) in your home directory and it’s subdirectory
Most files of the following command output will be lock-files and place holders created by other applications.
# find ~ -empty

List all the empty files only in your home directory.
# find . -maxdepth 1 -empty

List only the non-hidden empty files only in the current directory.
# find . -maxdepth 1 -empty -not -name ".*"

9. Finding the Top 5 Big Files
The following command will display the top 5 largest file in the current directory and it’s subdirectory. This may take a while to execute depending on the total number of files the command has to process.
# find . -type f -exec ls -s {} \; sort -n -r head -5

10. Finding the Top 5 Small Files
Technique is same as finding the bigger files, but the only difference the sort is ascending order.
# find . -type f -exec ls -s {} \; sort -n head -5

In the above command, most probably you will get to see only the ZERO byte files ( empty files ). So, you can use the following command to list the smaller files other than the ZERO byte files.
# find . -not -empty -type f -exec ls -s {} \; sort -n head -5


11. Find Files Based on file-type using option -type

Find only the socket files.
# find . -type s

Find all directories
# find . -type d

Find only the normal files
# find . -type f

Find all the hidden files
# find . -type f -name ".*"

Find all the hidden directories
# find -type d -name ".*"

12. Find files by comparing with the modification time of other file.
Show files which are modified after the specified file. The following find command displays all the files that are created/modified after ordinary_file.
# ls -lrt
total 0
-rw-r----- 1 root root 0 2009-02-19 20:27 others_can_also_read
----r----- 1 root root 0 2009-02-19 20:27 others_can_only_read
-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file
-rw-r--r-- 1 root root 0 2009-02-19 20:30 everybody_read
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 all_for_all
---------- 1 root root 0 2009-02-19 20:31 no_for_all

# find -newer ordinary_file
.
./everybody_read
./all_for_all
./no_for_all
13. Find Files by Size
Using the -size option you can find files by size.

Find files bigger than the given size
# find ~ -size +100M

Find files smaller than the given size
# find ~ -size -100M

Find files that matches the exact given size
# find ~ -size 100M

Note: – means less than the give size, + means more than the given size, and no symbol means exact given size.

14. Create Alias for Frequent Find Operations
If you find some thing as pretty useful, then you can make it as an alias. And execute it whenever you want.

Remove the files named a.out frequently.
# alias rmao="find . -iname a.out -exec rm {} \;"
# rmao

Remove the core files generated by c program.
# alias rmc="find . -iname core -exec rm {} \;"
# rmc


15. Remove big archive files using find command
The following command removes *.zip files that are over 100M.
# find / -type f -name *.zip -size +100M -exec rm -i {} \;"
Remove all *.tar file that are over 100M using the alias rm100m (Remove 100M). Use the similar concepts and create alias like rm1g, rm2g, rm5g to remove file size greater than 1G, 2G and 5G respectively.
# alias rm100m="find / -type f -name *.tar -size +100M -exec rm -i {} \;"
# alias rm1g="find / -type f -name *.tar -size +1G -exec rm -i {} \;"
# alias rm2g="find / -type f -name *.tar -size +2G -exec rm -i {} \;"
# alias rm5g="find / -type f -name *.tar -size +5G -exec rm -i {} \;"

# rm100m
# rm1g
# rm2g
# rm5g

Monday, June 27, 2011

Thread Scheduling : QNX and Linux

After long time and after my first ONSITE experience, i am able to update my blog. I was thinking to do some experiments with QNX to understand or to see the behavioral difference from Linux. But i couldnt do. Now, i am starting with a small one which is not concluded.

One day, when i was reading about pthreads, simply, i have pasted the sample program in linux and run the program and i could see some expected output. But when i run the same program on QNX, i saw the difference..!!!

When i cross compiled and run the program, which creates 5 threads and each thread prints its thread number when it gets the CPU on QNX target, i was getting the same output always. Then immediately i have thought to put that into my blog. Still i couldt get the specific and particlar reason or answer for the behavior of QNX but one thing we can think about the thread library or thread schduing of QNX.

The program is :.


#include
#include
#define NUM_THREADS 5

void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}


The output of the desktop linux is:

[pramod@testing pramod]$ ./a.out
In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
In main: creating thread 3
In main: creating thread 4
Hello World! It's me, thread #3!
Hello World! It's me, thread #4!
Hello World! It's me, thread #0!
Hello World! It's me, thread #1!
Hello World! It's me, thread #2!


The output of the QNX is:

[/] ./pthread_qnx
In main: creating thread 0
Hello World! It's me, thread #0!
In main: creating thread 1
Hello World! It's me, thread #1!
In main: creating thread 2
Hello World! It's me, thread #2!
In main: creating thread 3
Hello World! It's me, thread #3!
In main: creating thread 4
Hello World! It's me, thread #4!

As its output says, this is related to thread scheduling algorithms and mechanisms.

I have put this juft for our information. To conculde on this, many people inputs are required. Please drop your comments on this or drop me a mail about your thoughts on this.

Wednesday, February 2, 2011

C Program: Memory Layout

When I attended an interview, last year, I had one question which I couldn’t answer. Hence that question made me to think more on this and collect and read more information on that.

Normally, all interviews normally start with Storage classes in C. Also, most of the interviews for 2-3 years of experienced people in so called Embedded Domain will have question on Memory layout of a C program which tells which type of data stored at which location. This information is really required for the people who involved in driver/firmware development. But interviewers expect from us atleast theoretical information on this.

Ideally, Memory Layout consists following segments where data/text is managed:

1) Code Segment: Consists of series of instruction.

2) Data Segment: (code, constant data, alternative data)

i) Stack Segment: Area where the current function data is managed.

ii) Heap Segment: Area where dynamically allocated data stored.

iii) BSS Segment (Block started by symbol): For uninitialized data.

Data segment is actually contains the static data which is decided on the compile time. Rest of Area is used by Stack and Heap which is actually modified run time. Stack grows from higher address to lower Address. Heap grows just opposite to the stack.

In our convention, memory for a program will have higher memories on top and lower memories on bottom.



There are some other ways of conveying the same concept. Following figure conveys the same concept but using different terminologies.


From the above figure, following points has to be remembered.

1. Colored sections are static data and other part is dynamic data. Static data means, values are decided at or before the compile time. Dynamic data means, at run time only, values are decided.

2. Alternative data means static and global data which included both initialized and uninitialized

3. Stack is for local data, heap is for dynamically allocated data, Constant data for ‘const’ data

4. Only Code data, constant data and initialized alternate data are stored as part of program file

Another info is, if you run the command size with any binary executable file, you will some needful info like follows.


I feel this information will definitely help us. I have given link below for reference. Once look into that which also make us clear.


Drop me a mail for anything - pramoda.ma@gmail.com


Reference:
http://book.chinaunix.net/special/ebook/addisonWesley/APUE2/0201433079/ch07lev1sec6.html