Command and Conquer 2

Position

From FullCircle issue 24, to issue 55

C&C 11

This chapter tells you how to automatical your tasks using crontab.
Useful commands

	find /var/logs/ -name "*.log" | while read line; do cat "${line}"; done
	sudo crontab -e root

crontab format:

Example:
*/5 * * * * command Every 5 minutes
00 18 * * sun command Every Sunday at 6

C&C 12

This Chapter tells you how to use different shell, and its history, functions.

C&C 13

This chapter tell you how to listen music using MOC(Music On Console), and use IRC under terminal(irssi), later I will install them and try.

C&C 14

This chapter introduce how to change you prompt,(export PS1), some useful tools, for example:
“watch vmstat” will display the vmstat every 2 seconds.
Tiling window manager, awesome, DWM, Xmodnad, ratpoison, ion, etc.
Live-Office?

C&C 15

This chapter take ping for example and show you how to use man and help.

C&C 16

This chapter shows how to detect and bind keys.
xev for X, showkey for terminal, for detecting keys.
.Xmodmap for key definition, keycode 153 = XF86MonBrightnessDown
/usr/include/X11/keysymdef.h contains all of the list of the symbols, extra function keys in /usr/include/X11/XKeySymDB
Further Reading: http://people.freedesktop.org/~hughsient/quirk/quirk-keymap-index.html

C&C 17

This chapter shows disk usage skills.

C&C 18

This chapter introduce harddisk and S.M.A.R.T

C&C 19

This chapter introduct screen, remember use ctlr+a /d for detaching the session.

C&C 20

This chapter continue introducing screen, for sharing session:
ctrl + a :multiuser on ctrl+a :acladd
Other user connect via screen -x $USER/<screenID/name>
Other different commands.

C&C 21

Introducing Tmux for remote usage.Also byobu is introduced.

C&C 22

Switch to ZSH, need to re-read after back.

C&C 23

Colorscheme, need to re-read after back.

C&C 24

Talks on how to set ssh proxy.

C&C 25

gstm of GUI program which did ssh port forwarding.
diff usage

C&C 26

wget and curl, use it according to your own habit.

C&C 27

Network Configuration.

C&C 28

fdisk, find, etc.

C&C 29

Classic Command List.

C&C 30

Language for System.

C&C 31

conky skills, let conky display how many updates available.

C&C 32

Conky skills, his conky could display the listening music and album picture.But how about the pandora?

C&C 33

Conky skills, to-do and the zenity for creating the diaglog.

C&C 34

zenity configuration, MPD daemon.

C&C 35

Asia Language support, in fact we are much more professionaler than the author :)

C&C 36

Use of graphicmagic, which derived from imagik from 2002, try it later.

C&C 37

Latex Introduction.

C&C 38

Issue 51, damaged.

C&C 40

Latex continued.

C&C 41

/etc/motd(Message Of The Day)

C&C 42

vim/gvim, notice some command, and author’s vimrc file.

C&C 43

Advance usage of vi/vim , TBD

Command and Conquer 1

###Position: From FullCircle 13, Ended at FullCircle 23.
###C&C 1 Try to run following command:

man man
man -k PDF
man apropos
apropos PDF
man --help

Fastly get help from manual, for example, following command will let you dive into regex:

man -k regex
re_comp (3)          - BSD regex functions
re_exec (3)          - BSD regex functions
regcomp (3)          - POSIX regex functions
regerror (3)         - POSIX regex functions
regex (3)            - POSIX regex functions
regex (7)            - POSIX.2 regular expressions
regexec (3)          - POSIX regex functions
regfree (3)          - POSIX regex functions

###C&C 2 This part describe how to come and go into the directory. ###C&C 3 This part describe how to copy and move the file.
###C&C 4 This part introduce the nano and vim. Remember one: :e in vim means edit another file.
###C&C 5 This part introduce aptitude, Notice the comment of the aptitude search result:

  1. p, No trace of the package exists on the system.
  2. c, The package is deleted, but its configuration file is still on the system.
  3. i, The package is installed.
  4. v, The package is virtual.
    And one command: sudo aptitude safe-upgrade.
    ###C&C 6 This part shows how to find something in your system.
  5. grep, “grep -n”(print line number), “grep -ir”(recursively and ignore case).
  6. *, difference of “echo ” and “echo ‘'".
  7. xargs,
find recipes -type f -name '*-cake.txt' | xargs -I % cp % old-recipes/
find recipes -type f -name '*-cake.txt'
recipes/a-cake.txt
recipes/b-cake.txt
recipes/c-cake.txt
cp recipes/a-cake.txt old-recipes/
cp recipes/b-cake.txt old-recipes/
cp recipes/c-cake.txt old-recipes/

  1. updatedb and locate.
    ###C&C 7 The author talks lots on why you should not fear terminal.
    ###C&C 8
  2. cut way:
Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue
Ubuntu 13.04 \n \l

Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue|head -n 1
Ubuntu 13.04 \n \l
Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue|head -n 1|cut --delimiter=" " -f 1,2
Ubuntu 13.04

  1. sed way:
Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue | sed '{s/\\n//}'
Ubuntu 13.04  \l

Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue | sed '{s/\\n//; s/\\l//;}'
Ubuntu 13.04  

Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue | sed '{s/\\n//; s/\\l//;/^$/d}'
Ubuntu 13.04  

  1. awk way:
Trusty@HN:~/code/purec/FC/C8$ cat /etc/issue | awk '/\\n/ {print $1,$2}'
Ubuntu 13.04

First find any line which have ‘\n’ in it, then print this line’s $1 and $2.
4. Further reading
http://fullcirclemagazine.org/issue-21-shell-script/
Sed -http://www.grymoire.com/Unix/Sed.html
awk -http://www.linuxjournal.com/article/8913 or http://www.linuxfocus.org/English/September1999/article103.html
cut -http://learnlinux.tsf.org.za/courses/build/shell-scripting/ch03s04.html
###C&C 9 This part introduced the ffmpeg and imagick.
Since the internet is not OK, I cannot install the package, try them later.
###C&C 10 This part is very useful, it shows some system administration tools.

  1. bootchart, install via “sudo apt-get install bootchart”, then in /var/log/bootchart/ you will see the correct image.
  2. sudo lshw will list all of the hw info, sudo lshw -C Network will list all of the infos on networking.
  3. Further reading: http://www.troubleshooters.com/tpromag/200007/200007.htm

Programming in C of FC tutorial 6

###Full Circle C 8 ####Limitation Fibonacci sequence: normally this program limited by the limitation of unsigned long long

#include <stdio.h>

typedef unsigned long long fibo_type;
#define FIBO_FORMAT "%10llu"

void printFibo(fibo_type num)
{
        printf(FIBO_FORMAT, num);
}

int main()
{
        int num = 0;
        fibo_type a = 0, b=1, c;

        printf("%4d: ", ++num);
        printFibo(a);
        printf("\n");

        printf("%4d: ",++num);
        printFibo(b);
        printf("\n");

        c=a+b;
        while(c>=b)
        {
                printf("%4d: ",++num);
                printFibo(c);
                printf("\n");
                a=b;
                b=c;
                c=a+b;
        }

        printf("Stopped after %d digits\n", num);
        printFibo(c);
        printf("\n");
        return 0;
}

This program will exit when c reach the limitation of definition of unsigned long long ####Using GMP Using gmp to re-write this program:

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

int main()
{
        int num = 0;
        mpz_t f_1;
        mpz_t f_2;

        mpz_init(f_1);
        mpz_init(f_2);
        mpz_set_ui(f_1, 0);
        mpz_set_ui(f_1, 1);
        printf("%10d: 0\n", ++num);

        while(1)
        {
                mpz_add(f_1, f_2, f_1);
                mpz_swap(f_1, f_2);
                char *res = mpz_get_str(NULL, 10, f_2);
                printf("%10d: %s\n", ++num, res);
                free(res);
                sleep(1);
        }

        mpz_clear(f_1);
        mpz_clear(f_2);
        return 0;
}

Compile it via:

gcc -o Fibonacci2 Fibonacci2.c -lgmp

This won’t have limitation currently, but you have to finish the execises, when you get internet connection.

Programming in C of FC tutorial 5

###Full Circle C 7 ####Example Following is the origin ifstat.c, this program will list the net-interface payloads, and it will print out the net interface statistics every 2 seconds, but notice this program have several bugs:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef unsigned long long ull;
int parseDevFile(const char * iface, ull *bRx, ull *pRx, ull *bTx, ull *pTx);
void dumpInterfaceUsage(const char * iface);
int parseDevFile(const char * iface, ull *bRx, ull *pRx, ull *bTx, ull *pTx)
{
        FILE * fp = NULL;
        char * line = NULL;
        unsigned int len = 0;
        fp = fopen("/proc/net/dev", "r");
        if(fp == NULL)
        {
                return -1;
        }
        while(getline(&line, &len, fp) != -1)
        {
                if(strstr(line, iface) != NULL)
                {
                        sscanf(strstr(line, ":")+1, "%llu%llu%*u%*u%*u%*u%*u%*u%llu%llu", bRx, pRx, bTx, pTx);
                }
        }
        fclose(fp);
        free(line);
        return 0;
}
void dumpInterfaceUsage(const char * iface)
{
        ull ifaceBRxOld = 0, ifaceBTxOld = 0, ifacePRxOld = 0, ifacePTxOld = 0;
        ull ifaceBRxNew = 0, ifaceBTxNew = 0, ifacePRxNew = 0, ifacePTxNew = 0;
        const int SLEEP_TIME = 2;

        if(parseDevFile(iface, &ifaceBRxOld, &ifacePRxOld, &ifaceBTxOld, &ifacePTxOld) == -1) return;
        sleep(SLEEP_TIME);
        while(1)
        {
                if(parseDevFile(iface, &ifaceBRxNew, &ifacePRxNew, &ifaceBTxNew, &ifacePTxNew) == -1) return;
                printf("%s In: %8.2f kbytes/s  %5llu P/s Out: %8.2f kbytes/s %5llu P/s\n", iface,
                                (ifaceBRxNew - ifaceBRxOld)/(SLEEP_TIME *1024.0),
                                (ifacePRxNew - ifacePRxOld)/(SLEEP_TIME),
                                (ifaceBTxNew - ifaceBTxOld)/(SLEEP_TIME *1024.0),
                                (ifacePTxNew - ifacePTxOld)/(SLEEP_TIME));
                ifaceBRxOld = ifaceBRxNew;
                ifaceBTxOld = ifaceBTxNew;
                ifacePRxOld = ifacePRxNew;
                ifacePTxOld = ifacePTxNew;
                sleep(SLEEP_TIME);
        }
}

int main(int argc, char **argv)
{
        if(argc != 2)
        {
                printf("Usage: %s interfacename\n", argv[0]);
                return 1;
        }
        dumpInterfaceUsage(argv[1]);
        return 0;
}

Running result:

[root@localhost C7]# ./ifstat eth0
eth0 In:     0.24 kbytes/s      2 P/s Out:     0.25 kbytes/s     1 P/s
eth0 In:     0.32 kbytes/s      4 P/s Out:     0.97 kbytes/s     3 P/s
eth0 In:     1.29 kbytes/s     13 P/s Out:     5.06 kbytes/s    13 P/s
eth0 In:     0.06 kbytes/s      1 P/s Out:     0.08 kbytes/s     0 P/s

####Bugs Ok, now let’s see its bug:

#enable the unlimited:
[root@localhost C7]# ulimit -c unlimited
#Get the core file: 
[root@localhost C7]# ./ifstat b
Segmentation fault (core dumped)

####Debugging

[root@localhost C7]# ls -l -h core*
-rw------- 1 root root 272K Oct 14 06:53 core.3961
#Use gdb for anlysing the corefile:    
[root@localhost C7]# gdb ifstat core.3961
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./ifstat b'.
Program terminated with signal 11, Segmentation fault.
[New process 3961]
#0  0x00b6f957 in rawmemchr () from /lib/libc.so.6

Seems the corefile is useless, this because the error is not derived from our own code, but rather from the library. Run gdb for anlysing the ./ifstat b

[root@localhost C7]# gdb ./ifstat
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) run b
Starting program: /root/code/C7/ifstat b

Program received signal SIGSEGV, Segmentation fault.
0x00b6f957 in rawmemchr () from /lib/libc.so.6
(gdb) break parseDevFile
Breakpoint 1 at 0x804854a: file ifstat.c, line 10.
(gdb) run b
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/code/C7/ifstat b

Breakpoint 1, parseDevFile (iface=0xbfe52b5e "b", bRx=0xbfe50f80, pRx=0xbfe50f70, bTx=0xbfe50f78, pTx=0xbfe50f68) at ifstat.c:10
10              FILE * fp = NULL;
(gdb) step
11              char * line = NULL;
(gdb)
12              unsigned int len = 0;
(gdb)
13              fp = fopen("/proc/net/dev", "r");
(gdb) print fp
$1 = (FILE *) 0x0
(gdb) step
14              if(fp == NULL)
(gdb) step
18              while(getline(&line, &len, fp) != -1)
(gdb) display line
1: line = 0x0
(gdb) step
20                      if(strstr(line, iface) != NULL)
1: line = 0x9730170 "Inter-|   Receive", ' ' <repeats 48 times>, "|  Transmit\n"
(gdb) step
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9730170 "Inter-|   Receive", ' ' <repeats 48 times>, "|  Transmit\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9730170 " face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n"
(gdb)
22                              sscanf(strstr(line, ":")+1, "%llu%llu%*u%*u%*u%*u%*u%*u%llu%llu", bRx, pRx, bTx, pTx);
1: line = 0x9730170 " face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n"
(gdb)

Program received signal SIGSEGV, Segmentation fault.
0x00b6f957 in rawmemchr () from /lib/libc.so.6
(gdb)

We found another bug, also we can see ./ifstat dba

[root@localhost C7]# gdb ./ifstat
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) run dba
Starting program: /root/code/C7/ifstat dba
dba In:     0.00 kbytes/s      0 P/s Out:     0.00 kbytes/s     0 P/s
dba In:     0.00 kbytes/s      0 P/s Out:     0.00 kbytes/s     0 P/s

Program received signal SIGINT, Interrupt.
0x00ef3402 in __kernel_vsyscall ()
(gdb) break parseDevFile
Breakpoint 1 at 0x804854a: file ifstat.c, line 10.
(gdb) run dba
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/code/C7/ifstat dba

Breakpoint 1, parseDevFile (iface=0xbf81bb5c "dba", bRx=0xbf81ad40, pRx=0xbf81ad30, bTx=0xbf81ad38, pTx=0xbf81ad28) at ifstat.c:10
10              FILE * fp = NULL;
(gdb) step
11              char * line = NULL;
(gdb) step
12              unsigned int len = 0;
(gdb) step
13              fp = fopen("/proc/net/dev", "r");
(gdb) step
14              if(fp == NULL)
(gdb) step
18              while(getline(&line, &len, fp) != -1)
(gdb) display line
1: line = 0x0
(gdb) step
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "Inter-|   Receive", ' ' <repeats 48 times>, "|  Transmit\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "Inter-|   Receive", ' ' <repeats 48 times>, "|  Transmit\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 " face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 " face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "    lo: 4684910    2267    0    0    0     0          0         0  4684910    2267    0    0    0     0       0          0\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "    lo: 4684910    2267    0    0    0     0          0         0  4684910    2267    0    0    0     0       0          0\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "  eth0: 5135043   75928    0    0    0     0          0         0 15204045  129941    0    0    0     0       0          0\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "  eth0: 5135043   75928    0    0    0     0          0         0 15204045  129941    0    0    0     0       0          0\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
25              fclose(fp);
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
26              free(line);
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
27              return 0;
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
28      }
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
dumpInterfaceUsage (iface=0xbf81bb5c "dba") at ifstat.c:36
36              sleep(SLEEP_TIME);
(gdb)
39                      if(parseDevFile(iface, &ifaceBRxNew, &ifacePRxNew, &ifaceBTxNew, &ifacePTxNew) == -1) return;
(gdb)

Breakpoint 1, parseDevFile (iface=0xbf81bb5c "dba", bRx=0xbf81ad20, pRx=0xbf81ad10, bTx=0xbf81ad18, pTx=0xbf81ad08) at ifstat.c:10
10              FILE * fp = NULL;
1: line = 0xaf5ca0 ""
(gdb)
11              char * line = NULL;
1: line = 0xaf5ca0 ""
(gdb)
12              unsigned int len = 0;
1: line = 0x0
(gdb)
13              fp = fopen("/proc/net/dev", "r");
1: line = 0x0
(gdb)
14              if(fp == NULL)
1: line = 0x0
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x0
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "Inter-|   Receive", ' ' <repeats 48 times>, "|  Transmit\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "Inter-|   Receive", ' ' <repeats 48 times>, "|  Transmit\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 " face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 " face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "    lo: 4684910    2267    0    0    0     0          0         0  4684910    2267    0    0    0     0       0          0\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "    lo: 4684910    2267    0    0    0     0          0         0  4684910    2267    0    0    0     0       0          0\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "  eth0: 5141021   76010    0    0    0     0          0         0 15217535  130042    0    0    0     0       0          0\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "  eth0: 5141021   76010    0    0    0     0          0         0 15217535  130042    0    0    0     0       0          0\n"
(gdb)
20                      if(strstr(line, iface) != NULL)
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
18              while(getline(&line, &len, fp) != -1)
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
25              fclose(fp);
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
26              free(line);
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
27              return 0;
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
28      }
1: line = 0x9101170 "  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n"
(gdb)
dumpInterfaceUsage (iface=0xbf81bb5c "dba") at ifstat.c:40
40                      printf("%s In: %8.2f kbytes/s  %5llu P/s Out: %8.2f kbytes/s %5llu P/s\n", iface,
(gdb)
dba In:     0.00 kbytes/s      0 P/s Out:     0.00 kbytes/s     0 P/s

####Conclusion: And now we can get the reason, the ./ifstat b is because we reached the line2 of the /proc/net/dev, it has b for “bytes”.
./ifstat dba always print 0 because we don’t have this equipment at all !
####Correcting So the corrected code is listed as following:

int parseDevFile(const char * iface, ull *bRx, ull *pRx, ull *bTx, ull *pTx)
{
        FILE * fp = NULL;
        char * line = NULL;
        unsigned int len = 0;
        short int exists = 0;
        fp = fopen("/proc/net/dev", "r");
        if(fp == NULL)
        {
                return -1;
        }
        while(getline(&line, &len, fp) != -1)
        {
                if(strstr(line, iface) != NULL)
                {
                        if(strstr(line, ":") != NULL)
                        {
                                sscanf(strstr(line, ":")+1, "%llu%llu%*u%*u%*u%*u%*u%*u%llu%llu", bRx, pRx, bTx, pTx);
                                exists = 1;
                        }
                }
        }
        fclose(fp);
        free(line);
        if( exists != 1)
        {
                fprintf(stderr, "Your device %s is not in the file /proc/net/dev!\n", iface);
                exit(2);
        }
        return 0;
}

Now run it and the result is listed as:

[root@localhost C7]# ./ifstat_upgrade b
Your device b is not in the file /proc/net/dev!
[root@localhost C7]# ./ifstat_upgrade bba
Your device bba is not in the file /proc/net/dev!
[root@localhost C7]# ./ifstat_upgrade eth0
eth0 In:     0.03 kbytes/s      0 P/s Out:     0.00 kbytes/s     0 P/s
eth0 In:     0.03 kbytes/s      0 P/s Out:     0.08 kbytes/s     0 P/s

Programming in C of FC tutorial 4

###Full Circle C 6 ####Using valgrid for memory check See www.valgrind.org for more information for using the valgrind available tools.
memcheck is the main topic in this chapter.
this tool override libc calls that deal with handling memory. And it will do some bookkeeping. is all memory given back to the system, and is all the allocated memory still reachable?

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

void leak()
{
        char *ptr = malloc(10);
        printf("malloc(10) points to: %p\n", ptr);
}

int main()
{
        int i = 0;
        for(i = 0; i<10; i++)
        {
                leak();
        }
        char *ptr = malloc(15);
        printf("malloc(15) in main: %p\n", ptr);
        while(1){}
        return 0;
}

The result shows:

valgrind --leak-check=full --show-reachable=yes ./memleak
==2144== Memcheck, a memory error detector.
==2144== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==2144== Using LibVEX rev 1658, a library for dynamic binary translation.
==2144== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==2144== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==2144== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==2144== For more details, rerun with: -v
==2144==
malloc(10) points to: 0x4022028
malloc(10) points to: 0x4022068
malloc(10) points to: 0x40220a8
malloc(10) points to: 0x40220e8
malloc(10) points to: 0x4022128
malloc(10) points to: 0x4022168
malloc(10) points to: 0x40221a8
malloc(10) points to: 0x40221e8
malloc(10) points to: 0x4022228
malloc(10) points to: 0x4022268
malloc(15) in main: 0x40222a8
==2144==
==2144== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
==2144== malloc/free: in use at exit: 115 bytes in 11 blocks.
==2144== malloc/free: 11 allocs, 0 frees, 115 bytes allocated.
==2144== For counts of detected errors, rerun with: -v
==2144== searching for pointers to 11 not-freed blocks.
==2144== checked 46,792 bytes.
==2144==
==2144== 15 bytes in 1 blocks are still reachable in loss record 1 of 2
==2144==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==2144==    by 0x8048419: main (leak.c:17)
==2144==
==2144==
==2144== 100 bytes in 10 blocks are definitely lost in loss record 2 of 2
==2144==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==2144==    by 0x80483C5: leak (leak.c:6)
==2144==    by 0x8048403: main (leak.c:15)
==2144==
==2144== LEAK SUMMARY:
==2144==    definitely lost: 100 bytes in 10 blocks.
==2144==      possibly lost: 0 bytes in 0 blocks.
==2144==    still reachable: 15 bytes in 1 blocks.
==2144==         suppressed: 0 bytes in 0 blocks.

If we change the code into following, this means valgrid won’t interpret the output, so this will let the tracked memory add 10

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

void leak()
{
        char *ptr = malloc(10);
        printf("malloc(10) points to: %p\n", ptr);
}

int main()
{
        int i = 0;
        for(i = 0; i<10; i++)
        {
                leak();
        }
        char *ptr = malloc(15);
        printf("malloc(15) in main: %p\n", ptr);
        //while(1){}
        return 0;
}

Compile and verify:

gcc -Wall -g leak1.c -o memleak1
View the valgrind result:
valgrind --leak-check=full --show-reachable=yes ./memleak1
==2190== Memcheck, a memory error detector.
==2190== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==2190== Using LibVEX rev 1658, a library for dynamic binary translation.
==2190== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==2190== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==2190== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==2190== For more details, rerun with: -v
==2190==
malloc(10) points to: 0x4022028
malloc(10) points to: 0x4022068
malloc(10) points to: 0x40220a8
malloc(10) points to: 0x40220e8
malloc(10) points to: 0x4022128
malloc(10) points to: 0x4022168
malloc(10) points to: 0x40221a8
malloc(10) points to: 0x40221e8
malloc(10) points to: 0x4022228
malloc(10) points to: 0x4022268
malloc(15) in main: 0x40222a8
==2190==
==2190== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
==2190== malloc/free: in use at exit: 115 bytes in 11 blocks.
==2190== malloc/free: 11 allocs, 0 frees, 115 bytes allocated.
==2190== For counts of detected errors, rerun with: -v
==2190== searching for pointers to 11 not-freed blocks.
==2190== checked 46,796 bytes.
==2190==
==2190== 15 bytes in 1 blocks are definitely lost in loss record 1 of 2
==2190==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==2190==    by 0x8048419: main (leak1.c:17)
==2190==
==2190==
==2190== 100 bytes in 10 blocks are definitely lost in loss record 2 of 2
==2190==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==2190==    by 0x80483C5: leak (leak1.c:6)
==2190==    by 0x8048403: main (leak1.c:15)
==2190==
==2190== LEAK SUMMARY:
==2190==    definitely lost: 115 bytes in 11 blocks.
==2190==      possibly lost: 0 bytes in 0 blocks.
==2190==    still reachable: 0 bytes in 0 blocks.
==2190==         suppressed: 0 bytes in 0 blocks.

####exercise 1: vmstat is a tool which report system usage statistics, use strace to figure out which /proc/file(s) it uses to generate its output

execve("/usr/bin/vmstat", ["vmstat"], [/* 29 vars */]) = 0
brk(0)                                  = 0x96b7000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=95416, ...}) = 0
mmap2(NULL, 95416, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f80000
close(3)                                = 0
open("/lib/libproc-3.2.7.so", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320c\304\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=54212, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f7f000
mmap2(0xc44000, 133592, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xc44000
mmap2(0xc51000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xc) = 0xc51000
mmap2(0xc52000, 76248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xc52000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320?\261\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1606808, ...}) = 0
mmap2(0xafe000, 1324452, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xafe000
mmap2(0xc3c000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13e) = 0xc3c000
mmap2(0xc3f000, 9636, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xc3f000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f7e000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7f7e6c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xc3c000, 8192, PROT_READ)     = 0
mprotect(0xaf5000, 4096, PROT_READ)     = 0
munmap(0xb7f80000, 95416)               = 0
uname({sys="Linux", node="localhost.localdomain", ...}) = 0
brk(0)                                  = 0x96b7000
brk(0x96d8000)                          = 0x96d8000
open("/proc/stat", O_RDONLY)            = 3
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f97000
read(3, "cpu  14886 15300 97152 608490 41"..., 4096) = 693
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb7f97000, 4096)                = 0
ioctl(1, TIOCGWINSZ, {ws_row=36, ws_col=115, ws_xpixel=0, ws_ypixel=0}) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f97000
write(1, "procs -----------memory---------"..., 82procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
) = 82
write(1, " r  b   swpd   free   buff  cach"..., 81 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
) = 81
open("/proc/meminfo", O_RDONLY)         = 3
lseek(3, 0, SEEK_SET)                   = 0
read(3, "MemTotal:       897068 kB\nMemFre"..., 1023) = 771
open("/proc/stat", O_RDONLY)            = 4
read(4, "cpu  14886 15300 97153 608490 41"..., 65535) = 693
open("/proc/vmstat", O_RDONLY)          = 5
lseek(5, 0, SEEK_SET)                   = 0
read(5, "nr_anon_pages 29682\nnr_mapped 13"..., 1023) = 803
write(1, " 0  0    120  16980  32852 67407"..., 81 0  0    120  16980  32852 674076    0    0   228   223 1040  432  4 13 78  5  0
) = 81
exit_group(0)                           = ?

From the above output, we can see, it access /proc/stat and /proc/vmstat for output message.
####exercise 2 Repeat the ltrace /strace example on wget with ivalid URL, TBD
####exercise 3 Does valgrind automatically trace child process?

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

/* For using fork() */
#include <sys/types.h>
#include <unistd.h>

/* Using errono */
#include <errno.h>
#include <string.h>


void leak()
{
        char *ptr = malloc(10);
        printf("malloc(10) points to: %p\n", ptr);
}

int main(void)
{
        pid_t child;
        /* Parent do leak() */
        int i = 0;
        for(i = 0; i<10; i++)
        {
                leak();
        }

        /* Now fork a child process */
        if((child = fork()) < 0) {
                fprintf(stderr, "fork of child failed: %s\n", strerror(errno));
                return 1;
        }
        else if(child == 0) {
                printf("Now its in child process\n");
                sleep(2);
        }
        else {
                // parent will exit immediately !
                printf("Parent will exit!\n");
                sleep(1);
                return 0;
        }

        // Only Child comes here
        printf("Only child comes here!\n");
        for(i = 0; i<10; i++)
        {
                leak();
        }

        return 0;
}

We use following command for tracing the output:

[root@localhost code]# valgrind --leak-check=full --show-reachable=yes ./memleak_fork
==2561== Memcheck, a memory error detector.
==2561== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==2561== Using LibVEX rev 1658, a library for dynamic binary translation.
==2561== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==2561== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==2561== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==2561== For more details, rerun with: -v
==2561==
malloc(10) points to: 0x4022028
malloc(10) points to: 0x4022068
malloc(10) points to: 0x40220a8
malloc(10) points to: 0x40220e8
malloc(10) points to: 0x4022128
malloc(10) points to: 0x4022168
malloc(10) points to: 0x40221a8
malloc(10) points to: 0x40221e8
malloc(10) points to: 0x4022228
malloc(10) points to: 0x4022268
Now its in child process
Parent will exit!
==2561==
==2561== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
==2561== malloc/free: in use at exit: 100 bytes in 10 blocks.
==2561== malloc/free: 10 allocs, 0 frees, 100 bytes allocated.
==2561== For counts of detected errors, rerun with: -v
==2561== searching for pointers to 10 not-freed blocks.
==2561== checked 46,796 bytes.
==2561==
==2561== 100 bytes in 10 blocks are definitely lost in loss record 1 of 1
==2561==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==2561==    by 0x8048515: leak (fork.c:15)
==2561==    by 0x8048553: main (fork.c:26)
==2561==
==2561== LEAK SUMMARY:
==2561==    definitely lost: 100 bytes in 10 blocks.
==2561==      possibly lost: 0 bytes in 0 blocks.
==2561==    still reachable: 0 bytes in 0 blocks.
==2561==         suppressed: 0 bytes in 0 blocks.
[root@localhost code]# Only child comes here!
malloc(10) points to: 0x40222a8
malloc(10) points to: 0x40222e8
malloc(10) points to: 0x4022328
malloc(10) points to: 0x4022368
malloc(10) points to: 0x40223a8
malloc(10) points to: 0x40223e8
malloc(10) points to: 0x4022428
malloc(10) points to: 0x4022468
malloc(10) points to: 0x40224a8
malloc(10) points to: 0x40224e8
==2562==
==2562== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
==2562== malloc/free: in use at exit: 200 bytes in 20 blocks.
==2562== malloc/free: 20 allocs, 0 frees, 200 bytes allocated.
==2562== For counts of detected errors, rerun with: -v
==2562== searching for pointers to 20 not-freed blocks.
==2562== checked 46,796 bytes.
==2562==
==2562== 200 bytes in 20 blocks are definitely lost in loss record 1 of 1
==2562==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==2562==    by 0x8048515: leak (fork.c:15)
==2562==    by 0x8048553: main (fork.c:26)
==2562==
==2562== LEAK SUMMARY:
==2562==    definitely lost: 200 bytes in 20 blocks.
==2562==      possibly lost: 0 bytes in 0 blocks.
==2562==    still reachable: 0 bytes in 0 blocks.
==2562==         suppressed: 0 bytes in 0 blocks.

From the above output, we can see valgrid also tracked the child process’s memory usage.