/* Ajith - Syntax Higlighter - End ----------------------------------------------- */
Showing posts with label How to. Show all posts
Showing posts with label How to. Show all posts

12.02.2013

Displaying MATH formulas in blogger

Introducing math formulas in blogger was a daunting task in olden days. Now using Mathjax we can include them without any issue. Let us see steps to add support for Mathjax to blogger template.

1. In your blog default home page under "template" section select "Edit HTML" option. Add following line after <head> tag
<script type="text/javascript"
   src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

2. Now we can include math formulas as simple ASCII Math notation.

NOTE: We should use ∖( ...∖) for inline math and ∖[ ... ∖] for displayed math.


For inline math

To display \(\left(x-1\right)\left(x+3\right) \sqrt{a^2+b^2}\) as inline formula

Similarly for displayed math

 \[\sqrt{a^2+b^2}x = a_0 + \frac{1}x = a_0 + \frac{1}{\displaystyle a_1 + \frac{1}{\displaystyle a_2 + \frac{1}{\displaystyle a_3 + a_4}}}{a_1 + \frac{1}{a_2 + \frac{1}{a_3 + a_4}}}\]
References:

1. Mathjax
2. Online Latex Editor 

6.10.2013

How to narrate a story to computer scientist


If it brings back old memories or a smile then I hope you understood the characters in STORY.

3.15.2013

Death of Google Reader - Journey towards alternatives

Flashback

Long Long ago when INTERNET is booming up with so many websites its really hard to follow the interesting one. Its quite clumsy to go around miliions of sites to check for new posts.

Am I Doomed ?

No, you are not. RSS feed mechanism is the answer.


Just follow the RSS feed of your favourite site and the RSS reader will maintain the unread articles, favourite articles and so on. Voilla simple and effective solution to follow various sites.

5.02.2012

Decoding hardware information of a PC

Checking out machine hardware information is no more a geeky thing of olden days where you need to go through the hardware specification documents or to open up a physical machine to find out the hardware details if the specification documents are missing. Now we have some really cool handy software tools to help us out.

I thought to make a page with some important tools which help us in decoding the hardware related information on a Linux Box. Feel free to drop a comment with the tool names I missed out in this post.

NOTE: All of them are ordered in alphabetical order and I am trying these tools on a Ubuntu machine running in virtual box. So some of the tool outputs might be displaying names likes VirtualBox and Oracle Corporation.
Tweak

4.05.2012

Connecting via SSH without password prompt

SSH is the common way to connect remote machines these days. Almost all kinds of applications use SSH in background for communicating with end machines.

But sometimes typing password repeatedly for establishing a SSH connection with the trusted end machine is quite daunting task.

Let us see how to automate the things in 3 simple steps where we can ssh to "user@host" without asking a password every time. Replace user with the username and host with the remote machine ip-address or hostname. For E.g. john@192.168.245.129

NOTE: Only do this with trusted machines.

6.30.2010

strace - diagnostic, debugging and reverse engineering tool

Many times we come across hopeless situations where a program when compiled and installed in GNU/Linux just fails to run. Then we have to trace the output of the misbehaving program. But tracing the output of a program throws up a lot of data and it is a daunting task to go through volumes of data. Still there are cases where we are not fruitful in pin pointing the cause of error.

In this situation strace also known as system-call tracer comes for rescue. It is a debugging tool that monitors the system calls used by a program and all the signals it receives.

A system call is the most common way programs communicate with the kernel. System calls include reading and writing data, opening and closing files and all kinds of network communication. Under Linux, a system call is done by calling a special interrupt with the number of the system call and its parameters stored in the CPU's registers.

Using strace is quite simple. There are two ways to let strace monitor a program.


Method 1:

To start strace along with a program, just run the executable with strace as shown below.
strace program-name
For example let us trace ls command.
$ strace ls
execve("/bin/ls", ["ls"], [/* 39 vars */]) = 0
brk(0)                                  = 0x82d4000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7787000
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=76503, ...}) = 0
mmap2(NULL, 76503, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7774000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libselinux.so.1", O_RDONLY)  = 3
read(3, "177ELF111���������3�3�1���@G��004���"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=104148, ...}) = 0
mmap2(NULL, 109432, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x41d000
mmap2(0x436000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18) = 0x436000
close(3)                                = 0
.
.
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7613000
write(1, "01.c  a.outn", 1201.c  a.out
)           = 12
close(1)                                = 0
munmap(0xb7613000, 4096)                = 0
close(2)                                = 0
exit_group(0)                           = ?
In the above example we are not displaying the complete output of strace command. Even though output from strace looks very complicated, this is only due to many system calls made when loading shared libraries. However, once we have found which system calls are the important ones (mainly open, read, write and the like), the results will look fairly intuitive to us.

Method 2:

If we want to monitor a process which is currently running we can attach to the process using –p option. Thus we can even debug a daemon process.
strace –p <pid-of-the-application>
For e.g
#include <stdio.h>
#include <unistd.h>

int main()
{
   sleep(20);
   return 0;
}
We will compile the above code and run it as a background process. Then we try to monitor the program using its process id as shown below.
$ gcc main.c

$ ./a.out &
[1] 1885

$ strace -p 1885
Process 1885 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
exit_group(0)                           = ?
Process 1885 detached
[1]+  Done                    ./a.out
In contrast to a debugger, strace does not need a program's source code to produce human-readable output.

Some handy options

Below example is used in the discussion of other important options supported by strace.
#include <stdio.h>

int main(void)
{
  FILE *fd = NULL;

  if(fd = fopen("test","rw"))
    {   
      printf("TEST file openedn");
      fclose(fd);
    }   
  else
    {   
      printf("Failed to open the filen");
    }   

  return 0;
}

Providing the time taken by multiple system calls in a program


Using –c option strace provides summary information on executing a program.

It provides information like number of times a system call is used, time spent executing various system calls, number of times errors returned as shown below.
$ strace -c ./a.out 
Failed to open the file
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 91.47    0.004000        4000         1           execve
  8.53    0.000373         124         3         3 access
  0.00    0.000000           0         1           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0         3         1 open
  0.00    0.000000           0         2           close
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           mprotect
  0.00    0.000000           0         7           mmap2
  0.00    0.000000           0         3           fstat64
  0.00    0.000000           0         1           set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00    0.004373                    29         4 total

Redirecting the output to a file 


Using -o option we can redirect the complex output of strace into a file.
$ strace -o <output-file-name> <program-name>

Time spent per system call 


Using –T option we can get time spent per system call. In the below example we can see time spent per system call is printed at the end of the line.
$ strace -T ./a.out 
execve("./a.out", ["./a.out"], [/* 39 vars */]) = 0 <0.003256>
.
brk(0x9db0000)                          = 0x9db0000 <0.000123>
open("test", O_RDONLY)                  = -1 ENOENT (No such file or directory) <0.000154>
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 <0.000125>
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d4000 <0.000121>
write(1, "Failed to open the filen", 24Failed to open the file
) = 24 <0.000258>
exit_group(0)                           = ?

Prefixing time of the day for every line in trace 


It is useful sometimes to track at what time a particular is triggered. By using -t option strace will prefix each line of the trace with the time of day, which will be really helpful to find out at particular time at which call is the process blocked.
$ strace -t ./a.out 
execve("./a.out", ["./a.out"], [/* 39 vars */]) = 0 <0.003256>
.
brk(0x9db0000)                          = 0x9db0000 <0.000123>
open("test", O_RDONLY)                  = -1 ENOENT (No such file or directory) <0.000154>
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 <0.000125>
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d4000 <0.000121>
write(1, "Failed to open the filen", 24Failed to open the file
) = 24 <0.000258>
exit_group(0)                           = ?

Tracing only specific system calls 


Using –e option we can also specify which system calls to be traced. To trace only open() and close() system calls use the following command:
$ strace –e trace=’open,close’ <program-name>
Similarly we can also use negation option to not trace specific system calls. If we don’t want to trace open() system call in previous example we can give the below command
$ strace -e trace='!open,close' ./a.out
Check the man page of strace for other options.

1.01.2010

Creating and using static libraries in Linux

Static libraries are simply a collection of ordinary object files.

For more information on shared libraries checkout - Creating and using shared libraries in Linux

Static libraries conventionally end with the ".a" suffix. They are useful for developers to link to their library, but don't want to give the library source code. Theoretically code in static ELF libraries that is linked into an executable should run slightly faster (by 1-5%) than a shared library or a dynamically loaded library, but in practice this rarely seems to be the case due to other confounding factors.

We use following source code files for this post.

calc_mean.c
double mean(double a, double b)
{
return (a+b) / 2;
}
calc_mean.h
double mean(double, double);
main.c - We are including our static library in this application.
#include <stdio.h>
#include "calc_mean.h"

int main(int argc, char* argv[]) {

double v1, v2, m;
v1 = 5.2;
v2 = 7.9;

m  = mean(v1, v2);

printf("The mean of %3.2f and %3.2f is %3.2f\n", v1, v2, m);

return 0;
}
Creating the static library

First we have to create object file for calc_mean.c
gcc -c calc_mean.c -o calc_mean.o
Then, using archiver (ar) we produce a static library (named libmean.a) out of the object file calc_mean.o.
ar rcs libmean.a calc_mean.o
NOTE: A static library must start with the three letters 'lib' and have the suffix '.a'.

Compiling main program and linking with static library

We have already created a static library libmean.a and now let us use the static library by invoking it as part of the compilation and linking process when creating a program executable. Incase of gcc we use following flags to create static library

  • -llibrary
  • searches for the library named library at the time of linking. Linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded. The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
  • -L(path-to-the-library)
  • Specifies the path in which the library file can be found. We can use -L. inorder to point to the current directory and -L/home/tmp to point to /home/tmp directory.
  • -static
  • On systems that support dynamic linking, this prevents linking with the shared libraries.
gcc -static main.c -L. -lmean -o main
Now run the executable program 'main'
$./main

12.16.2009

ctags - vim with steroids

Basically C/C++ projects have thousands of lines of code divided into hundreds in some cases thousands of files. Inorder to access various function definitions within the sourcecode repository effectively using a VIM editor there is a great need for using addons like ctags which provides easy code go through.

Eventhough there are many effective GUI based code editors like eclipse e.t.c I prefer to use VIM editor as my primary code editor. I am not much into GUI funda so still prefer basic editor like VIM.

1. Installing ctags package
Almost all the linux flavours with 2.6.X kernel might have ctags installed by default. If not download the appropriate .deb or rpm file. Sorry I am not dealing with installing of ctags as I havent came across this stage as I am using FEDORA 9.

2. Generating ctags on your source code.
We have to generate a file named 'tags' for all the source code files, use the following command:
ctags *.c *.h
When we have many files in many directories then we have to create a tags file in each of the directories. But VIM will only be able to jump to tags within the same directory. To find more tags files, we have to set the 'tags' option in VIM to include all the relevant tags files. Just set the following command in ~/.vimrc file.
:set tags=./tags,./../tags,./*/tags
This finds a tags file in the same directory as the current file, one directory level higher and in all subdirectories.

But VIM searching many places for tags files is not really robust enough as it may get a bit slow. It's better to generate one big tags file offcourse it takes more time to create a single tags files for whole project. Just give the following command to recursively add all files in your project.
$ cd /proj 
$ ctags -R *
-R is to recursively go across all the directories, and a ‘tags’ file will be created including all the files in the sub-directories also.

Now we can simply include this single tags files as shown below
:set tags=~/proj/tags
3. Start using ctags with VIM editor
We have 3 different ways to use ctags in VIM editor.

From Shell:
We can invoke directly the file or the files containing the definition for a particular function from shell.
vi -t function_name
This will find the correct file or list of files having function_name definition.

OR

VIM command line:
We can invoke from VIM commandline (in command mode) the definition of a function.
:tag function_name
or
:ta function_name
This will jump automatically from the current file to the file containing the function_name definition.

OR

By cursor position:
This option is more user-friendly as we use a key combination instead of giving commands.
ctrl + ]
Place the cursor on the first character of the function name and press ctrl-]. This will jump to the file containing the definition of function_name.
ctrl + t
This command will jump back to previous location.
ctrl + i
To travel forward through the tag history.
ctrl + o
To travel backward through the tag history.

History
To display the list of tags that we have traversed in past give the following command.
:tags
Shows tag stack (history).

Divide and Conquer
As we saw already 'ctrl + ]' replaces the file in the current window with the one containing the new function. But suppose if we want to see not only the old function but also the new one?

We can split the window using the ":split" command followed by the ":tag" command.
:stag function_name
Cursor command for above feature is
ctrl + w + ]
Auto Complete
VIM supports tag name completion. Start typing the tag name (i.e. function name) and then hit TAB key and name completion will be done automatically if there is a tag name.
:tag start-of-tag-name_TAB
Jump to a tag name found by a search.
:tag /search-string
When multiple entries exist in the tags file, such as a function declaration in a header file and a function definition (the function itself), the operator can choose by issuing this command. The user will be presented with all the references to the function and the user will be prompted to enter the number associated with the appropriate one.
:tselect function-name
Jumps to next matching tag.
:tnext
or
:tn
Jump to previous matching tag.
:tprevious
or
:tp
Jump to first matching tag.
:tfirst
or
:tf
or
:trewindor:tr
Jump to last matching tag.
:tlast
or
:tl
Finding global identifiers
You are editing a C program and wonder if a variable is declared as "int" or "unsigned". A quick way to find this is with the "[I" command. Suppose the cursor is on the word "column" then type
[ + shiftkey + i
Vim will list the matching lines it can find. Not only in the current file,
but also in all included files (and files included in them, etc.). The result
looks like this:

structs.h
1: 29 unsigned column; /* column number */
The advantage over using tags or the preview window is that included files are
searched. In most cases this results in the right declaration to be found.
Also when the tags file is out of date. Also when you don't have tags for the
included files.

However, a few things must be right for "[I" to do its work. First of all,
the 'include' option must specify how a file is included. The default value
works for C and C++. For other languages you will have to change it.

Reference:
ctags documentation

Creating Shared Libraries in Linux - Part 2

Check the PART1 of this article.

4. Making the library available at run-time

Using LD_LIBRARY_PATH
We have to create or set the environment variable "LD_LIBRARY_PATH" to the directory containing the shared libraries.
export LD_LIBRARY_PATH=/home/cf/lib
If in current directory you can give the following command
export LD_LIBRARY_PATH=.
If we have to append a new directory to the existing paths then add the directories separated by colons to environment variable "LD_LIBRARY_PATH".
export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
Now recompile the main program
gcc -o test main.c -lcalc_mean -L/home/cf/slib
Now check the ldd command output
$ ldd test
 linux-gate.so.1 =>  (0x007ad000)
 libcalc_mean.so => ./libcalc_mean.so (0x0081e000)
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x005ff000)
 /lib/ld-linux.so.2 (0x00e19000)
It seems now linker is able to locate our shared library as we can see in above output. Now run the program
$./test
LD_LIBRARY_PATH is good for quick tests and for systems on which you don’t have admin privileges. As a downside, however, exporting the LD_LIBRARY_PATH environment variable  might screw up with other programs you run that also rely on LD_LIBRARY_PATH if you don’t reset it to its previous state when you’re done.

12.09.2009

Creating and using shared libraries in Linux

What is a Shared Library ??
A library that is loaded into physical memory only once and reused by multiple processes via virtual memory. 
Generally Shared libraries are .so (or in windows .dll) files.

Why shared libraries ??
  • They reduce memory consumption if used by more than one process, and they reduce the size of the executable.
  • They make developing applications easier: a small change in the implementation of a function in the library don't need the user to recompile and relink his application code every time. You need to only relink if you make incompatible changes, such as adding arguments to a call or changing the size of a struct.
NOTE: Debugging using a shared library is slightly more difficult when compared with static libraries, because the debugger usually used on Linux, gdb, has some problems with shared libraries.

Let us see how to create a shared library on Linux. We use following source code files for this post.
calc_mean.h
#ifndef calc_mean_h__
#define calc_mean_h__
double mean(double, double);
#endif  // calc_mean_h__
calc_mean.c
double mean(double a, double b)
{
return (a+b) / 2;
}
main.c - We are including our shared library in this application.
#include <stdio.h>
#include "calc_mean.h"

int main(int argc, char* argv[]) {

double v1, v2, m;
v1 = 5.2;
v2 = 7.9;

m  = mean(v1, v2);

printf("The mean of %3.2f and %3.2f is %3.2f\n", v1, v2, m);

return 0;
}

1. Creating Object File with Position Independent Code
All the code that goes into a shared library needs to be position independent. We can make gcc emit position-independent code by passing it one of the command-line switches -fpic or -fPIC (the former is preferred, unless the modules have grown so large that the relocatable code table is simply too small in which case the compiler will emit an error message, and you have to use -fPIC).

First we will create object files for all .c files that goes into a shared library.
gcc -c -fPIC calc_mean.c -o calc_mean.o
Above we are compiling calc_mean.c with -fPIC option and generating calc_mean.o object file.

2. Creating Shared library with the Object File
Every shared library has a prefix "lib", the name of the library, the phrase ".so", followed by a period and a version number that is incremented whenever the interface changes (as a special exception, the lowest-level C libraries don't start with "lib").
gcc -shared -o libcalc_mean.so calc_mean.o
Above command on successful produces a shared library named "libcalc_mean.so".
  • -shared: Produces a shared object which can then be linked with other objects to form an executable.

3. Using the Shared Library
Now let us link the created shared library with our application. Compile main.c as shown below
$ gcc -o test main.c -lcalc_mean
/usr/bin/ld: cannot find -lcalc_mean
collect2: ld returned 1 exit status
The linker doesn’t know where to find libcalc_mean. But why ?
GCC has a list of places to look by default for shared libraries, but our directory is not in that list. Bingo that's the reason compilation failed at linking level.

Now we need to tell GCC where to find libcalc_mean.so. We will do that with the -L option.
gcc -o test main.c -lcalc_mean -L/home/cf/slib
  •  -l option tells the compiler to look for a file named libsomething.so The something is specified by the argument immediately following the “-l”. i.e. -lmean
  • -L option tells the compiler where to find the library. The path to the directory containing the shared libraries is followed by "-L". If no “-L” is specified, the compiler will search the usual locations. "-L." means looking for the shared libraries in the current directory and "-L/home/cf/lib" means looking for the shared libraries at "/opt/lib" path. You can specify as many “-l” and “-L” options as you like.
NOTE: It would be a better idea to move all personal shared libraries in one directory rather in the current directory. For easy understanding I am moving "libcalc_mean.so" to "/home/cf/slib".
mv libcalc_mean.so /home/cf/slib
Now compile main.c. It would be successful and creates an executable named "test".
Let us check if the path to our shared library is included successfully into the executable by linker as shown below.

ldd executablename
$ ldd test 
 linux-gate.so.1 =>  (0x00332000)
 libcalc_mean.so => not found
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x006aa000)
 /lib/ld-linux.so.2 (0x00db9000)
You can see that linker cannot find our shared library libcalc_mean.so.

Basically libraries are present in /usr/lib amongst other places. Static libraries (.a suffix) are incorporated into the binary at link time, whereas dynamic ones (.so suffix) are referenced by location.

Check the PART2 of this article to understand further

11.03.2009

Using 'find' command

'find' is one of the useful commands available in Unix/Linux systems. In this article I am trying to use 'find' in a effective way.

Basic syntax of find command as per man page is - find [path...] [expression]
codingfreak find
NOTE: There are many options available for find command which are available in man page for find. Only some of those options are shown in this tutorial.

Finding a particular file in your system
$ find / -name 'filename' 2>/dev/null
$ find / -name 'filename' 2>errors.txt
/ - Start searching from the root directory (i.e / directory)

-name - Given search text is the filename rather than any other attribute of a file 'filename'. Always enclose the filename in single quotes...

NOTE: 2>/dev/null is not related to find tool as such. 2 indicates the error stream in Linux, and /dev/null is the device where anything you send simply disappears. So 2>/dev/null in this case means that while finding for the files, in case any error messages pop up simply send them to /dev/null i.e. simply discard all error messages.

Alternatively you could use 2>error.txt where after the search is completed you would have a file named error.txt in the current directory with all the error messages in it.
$ find -name 'met*'
The above command would start searching for the files that begin with the letters 'met' within the current directory and the directories that are present within the current directory.

If no paths are given, the current directory is used. If no expression is given, the expression ‘-print’ is used.

Searching with respect to type of the file (-type)
$find . -name 'temp'
./keepout/temp
./temp

$find . -name 'temp' -type d
./temp
Where d - directory, p - named pipe (FIFO), f - regular file and so on

Ignoring case-sensitivity (-iname)
$ find /home/temp -iname 'index*'
This command searchs for a file starting with string 'index' without considering the case of the filename. So all files starting with any combination of letters in upper and lower case such as INDEX or indEX or index would be returned.

Searching for a file based on size and time
$ find /home/songs -name '*.mp3' -size -5000k

$ find / -size +10000k
First command finds within a directory called /home/songs, only those mp3 files that have a size less than 5000 Kilobytes.
$ find /home/temp -amin -10 -name '*.c'
$ find /home/temp -atime -2 -name '*.c'
$ find /home/temp -mmin -10 -name '*.c'
$ find /home/temp -mtime -2 -name '*.c'
The 1st command searches for those files that are present in the directory /home/temp and its subdirectories which end in .c and which have been accessed in the last 10 minutes.

The 2nd command does the same but searches for those files that have been accessed in the last 10 hours.

The 3rd and the 4th commands do the same as the 1st and 2nd commands but they search for modified files rather than accessed files. Only if the contents of the files have been modified, would their names be returned in the search results.
$ find / -mount -name 'win*'
This command searches for files starting with the letters 'win' in their filenames. The only difference is that the mounted filesystems would not be searched for this time. This is useful when you have your Windows partitions mounted by default. And a search for 'win' might return many files on those partitions, which you may not be really interested in. This is only one use of -mount parameter.
$ find /home/songs -name 'Metallica*' -and -size +10000k
$ find /home/songs -size +10000k ! -name "Metallica*"
$ find /home/songs -name 'Metallica*' -or -size +10000k
Boolean operators such as AND, OR and NOT make find an extremely useful tool.

The 1st command searches within the directory /songs for files that have their names beginning with 'Metallica' and whose size is greater than 10000 kilobytes (> 10 MB).

The 2nd command searches in the same directory as above case but only for files that are greater than 10MB, but they should not have 'Metallica' as the starting of their filenames.

The 3rd command searches in the same directory for files that begin with 'Metallica' in their names or all the files that are greater than 10 MB in size.

How to apply a unix command to a set of files (-exec) ?
$ find . -name '*.sh' -exec chmod o+r '{}' \; -print
This command will search in the current directory and all sub directories. All files ending with .sh extension will be processed by the chmod -o+r command. The argument '{}' inserts each found file into the chmod command line. The \; argument indicates the exec command line has ended.

The end results of this command is all .sh files have the other permissions set to read access (if the operator is the owner of the file).

Searching for a string in a selection of files (-exec grep ...).
$ find . -exec grep "hello" '{}' \; -print
Prints all files that contain the string 'hello' will have their path printed to standard output.

If you want to just find each file then pass it on for processing use the -q grep option. This finds the first occurrance of the search string. It then signals success to find and find continues searching for more files.
find . -exec grep -q "hello" '{}' \; -print
Finding Empty files (-empty)
$find . -empty
To delete empty files in the current directory:
$ find . -empty -maxdepth 1 -exec rm '{}' \;
For more examples try out

1. linux.ie
2. Devdaily
3. hccfl.edu

9.08.2009

Reading a string of length 'n' from Standard Input [STDIN]

We know how to read a string from STDIN in C by using library functions like scanf, fgets and so on. By using these functions there is a chance for memory corruption and strange behaviour. For example while using scanf if we try to save a string of length more than the variable size there is a chance of memory corruption.

So here in this post I am just trying to implement a function capable to read a string of length 'n' from STDIN without memory corruption and other bugs.

Do help me by checking the code if there is a chance for further improvements.

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

#define BUF_SIZE 6
#define STRING_SIZE 4

/*
* void getStringStdin(char *, int , int );
*
* 1: BUF :Pointer to the array of characters where input string
is to be stored.
* 2: BUF_LEN :Is the length of the array of characters where the
string is stored.buffer where we save the string.
* 3: STRING_LEN :Is the length of the string.
*
* NOTE: STRING_LEN < BUF_LEN
*
*/

getStringStdin(char *buf, int buf_len, int str_len)
{
int ch, len;
char *s;

if(str_len>=buf_len)
len=buf_len-1;
else
len=str_len;

printf ("\nEnter string of length %d(Remaining is ignored): ",len);

if( (fgets(buf, len+1, stdin)) != NULL )
{
s=my_strchr(buf,'\n');

if(s!=NULL)
{
*s='\0';
}
else
{
while ((ch = getchar()) != '\n' && ch != EOF);
}
}
}

int main(void)
{
int i=0;
char buf[BUF_SIZE];

do
{
getString(buf, BUF_SIZE, STRING_SIZE);
printf ("\nString : %s\n", buf);
i++;
}while(i<2);

return 0;
}

How to: Listing all users in a Linux machine

TO list all the users who can access a Linux machine we have to access the /etc/passwd file, which stores information about all registered users of that machine. But it is not really so easy as told above since the file contains many other fields & machine trust accounts & inbuilt accounts.

We'll start by
cat /etc/passwd 

As we all know that by default all the users created will have their home directories in /home share so we'll modify our command a bit by using grep. Now it'll be
cat /etc/passwd | grep "/home"

Now we'll get all the user accounts which have their home share in /home.But the only output we need is the list of users & nothing else. So we'll modify our command again
cat /etc/passwd | grep "/home" |cut -d: -f1
Now what we have done is that we have piped the output of previous command to another variable "cut"

What we have done here is we have added cut -d: -f1
-d: means delimiter :
-f1 means display first field of line i.e. username.

So final command is
cat /etc/passwd | grep "/home" |cut -d: -f1
This works until all your users have their home share in /home. If you have defined their home share to some other destination. Modify the above command accordingly.

2.17.2009

Blogger: Adding syntax highlighter to Blogger

As we know it is really hard to post any source code to the blogger as there is no Syntax Highlighting option by default to the blogger (A Big Deficiency).

After doing some web search first I came across a Javascript tool named syntaxhighlighter and then I came across Heisencoder's post on how to add the syntaxhighlighter option to the blogger template.

NOTE: We are about to tweak the HTML code of the blogger template. Inorder to know how to edit the HTML code of the blogger template check this post.

NOTE: For safety precautions click "Download Full Template" link to download full html code of your present blog's template.

Select "Expand Widget Templates" option to see the full html code in the editor. Now we have to make our hands dirty as we are about to add some code into our blogger template code.

1. Go to http://syntaxhighlighter.googlecode.com/svn/trunk/Styles/SyntaxHighlighter.css, and perform "select all" and "copy" the whole code and paste it at the end of the css section of your blogger html template (i.e.,  before ]]--></b:skin>).

2. Before the </head> tag, paste the following code:


<!-- Add-in CSS for syntax highlighting -->
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCpp.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCSharp.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCss.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushDelphi.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJava.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJScript.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushPhp.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushPython.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushRuby.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushSql.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushVb.js' type='text/javascript'></script>
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushXml.js' type='text/javascript'></script>

NOTE: Simply remove lines for languages which you will never use (for example, Delphi) -- it will save some loading time of the blogs.

3. Before the </body> tag, insert the following:
<!-- Add-in Script for syntax highlighting -->
<script language='javascript'>
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
</script>

NOTE: Tweaking of the Blogger HTML template code is complete. So before you save the template code just click on "Preview" button to see if the code is not crashing & working fine.

4. While posting a post that has source code then click on "Edit Html" tab and post the source code between pre tags shown below
<pre name="code" class="cpp">
...Your html-escaped code goes here...
</pre>

In the above code substitute "cpp" with whatever language you're using. Choices: cpp, c, c++, c#, c-sharp, csharp, css, delphi, pascal, java, js, jscript, javascript, php, py, python, rb, ruby, rails, ror, sql, vb, vb.net, xml, html, xhtml, xslt. Full list can be accessed at Supported languages.

NOTE: Instead of remembering the code everytime we can add this HTML code simply into the template so that it is displayed whenever we create a new post. Click on "Settings" tab and then "formatting" sub-tab and post the html code in the "Post Template" box. As a result next whenever we create a new post it is displayed when we click "Edit Html".

We have to perform HTML escaping which can be done in the sites like Centricle, Accessify.

Reference

[1] Heisencoder - Link

2.04.2009

Blogger: Adding Applet code into the blogger post

Since we cant directly upload the Applet code into the google and then include it in the blogger post checkout the the way we have to add the Applet code into the blogger.

We cant simply add the Applet code to post in the blogger. For e.g. let us add the following applet code <applet code=ThreeD.class width=100 height=100></applet> into the post then we see a box with a 'x' mark on the left side corner as shown below.



Inorder to solve the problem we have to modify the Applet code so that blogger can track down where the following applet is actually present.


Solution to the problem comes up with a tag "codebase" ...

What is codebase?
Codebase tells the browser where the applet files are located, but if all files (including the HTML file, .class files, and images) are all together in one folder on your own server or local system, you should not specify CODEBASE. Likewise, if you are going to use the applet off-line, do not use a CODEBASE.

If you are using something like BLOGGER, then yes, you will definitely need to use a codebase address (since .class files can't be directly stored on the .blogspot server).

Something like this

<applet code=ThreeD.class width=100 height=100 codebase=http://www.yoursite.com/files/ ></applet>

I have provided the exact link location where the applet code is stored.

7.15.2008

Blogger: Optimize post title for more visitors and search engine results

When we search for the posts of a blog in google or yahoo we will find out that the post title is displayed as

Blog Title + Post Title

Such titles really doesn't attract much traffic to your blog. But it is the default setting in our blog template code. Now we will tweak the HTML code of our blog template to optimize the post title for search engines in a more attractive format

Post Title + Blog Title

This tweak will take a while for the Formatted titles to appear in search results(will appear when it is reindexed) but I am sure that it will increase the traffic to your blog.

Check out my post "Editing the HTML code of a Blogger Beta Template" to know how to edit the html code of the blogger template.

Search for the code <title><data:blog.pageTitle/></title> and replace the code with the following code
<b:if cond='data:blog.pageType == &quot;index&quot;'>
<title><data:blog.pageTitle/></title>
<b:else/>
<title><data:blog.pageName/> ~ <data:blog.title/></title>
</b:if>

So use the tweak for more traffic.

7.13.2008

Converting .djvu file to .pdf file

DjVu (pronounced déjà vu) is a computer file format designed primarily to store scanned images, especially those containing text and line drawings. Basically some of the ebooks and comics are present in this format.

Portable Document Format (PDF) is a file format created by Adobe Systems as a represention for two-dimensional documents in a manner independent of the application software, hardware, and operating system. This is the most popular file format used for data and ebooks.

Since DjVu is not so popular as PDF I decided to share the cheap and best way to convert the DjVu format file into PDF format file.

1. Download & Install FreePDF which is used to print the documents as pdf files.
http://www.shbox.de/fpxpdownload.htm

2. Download DjVu viewer namely windjview. It is a sourceforge project so it can be downloaded freely and it is a few kilo bytes file.
http://sourceforge.net/projects/windjview

3. Now open the djvu file with windjview.

4. Choose "print" option and SELECT FreePDF as the PRINTER to print the file as PDF file.

So we successfully converted the djvu file into pdf freely and easily.

Blogger: Setting labels as horizontal tabs

In this post I will discuss how to set the labels in blogger as a horizontal tabs.

NOTE: Read this post completely before you start tweaking your blog.

Since we are about to modify the HTML code of your blog template backup your complete blogger template. Check out my post on Editing the HTML code of a Blogger Beta Template to know how to perform template backup. Also make sure that your blog has posts with labels assigned to them if not nothing will be working out.

Step 1:

Download the free CSS navigation menus from the Exploding Boy website. Once you download the entire set unzip it and decide which type of menu you are going to include in your site. Then we have to upload these GIF images to any photosharing site or any place in internet so that we can access them directly. There are many options like Photobucket, Picasa, Googlepages.

Step 2:

Now we have to change the Header so that it can include page elements. Search for id="header" in html code of your blog's template and modify this line:

<b:section class="header" id="header" maxwidgets="1" showaddelement="no">

as

<b:section class="header" id="header" maxwidgets="2" showaddelement="yes">

Step 3:

Now we will prepare the CSS portion of the tweak. I have uploaded the images tableftF.gif and tabrightF.gif which are related to Menu style F at the links

http://www.site.com/tableftF.gif
and
http://www.site.com/tabrightF.gif

So you have to replace those links in the code with the appropriate links where you have uploaded those images. Below is the CSS code for menu style F:
#tabsF
{
float:left;
width:100%;
font-size:80%;
line-height:normal;
border-bottom:1px solid #000;
}

#tabsF ul
{
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}

#tabsF li
{
display:inline;
margin:0;
padding:0;
}

#tabsF a
{
float:left;
background:url(" http://www.site.com/tableftF.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}

#tabsF a span
{
float:left;
display:block;
background:url(" http://www.site.com/tabrightF.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#666;
}

/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsF a span {float:none;}
/* End IE5-Mac hack */
#tabsF a:hover span
{
color:#FFF;
}

#tabsF a:hover
{
background-position:0% -42px;
}

#tabsF a:hover span
{
background-position:100% -42px;
}

Step 4

Now we have to add the Label Widget. Insert the following Widget code
<b:widget id='Label10' locked='false' title='' type='Label'>
<b:includable id='main'>
<div id='tabsF'>
<ul>
<li><a expr:href='data:blog.homepageUrl'><span>Home</span></a></li>
<b:loop values='data:labels' var='label'>
<li><a expr:href='data:label.url'><span><data:label.name/></span></a></li>
</b:loop>
</ul>
<!-- <b:include name='quickedit'/> -->
</div>
</b:includable>
</b:widget>

NOTE: By using the above code by default tabs for all your labels is created. If you got more number of labels then the tabs for all labels is created by default i.e. If there are 30 labels in your blog then 30 tabs are created which don't looks good. So I modified the green lines in the above code in this way so that we can include only those labels which we want to add.
<b:widget id='Label10' locked='false' title='' type='Label'>
<b:includable id='main'>
<div id='tabsF'>
<ul>
<li><a expr:href='data:blog.homepageUrl'><span>Home</span></a></li>

<b:loop values='data:labels' var='label'>

<!--I am adding the label - Linux in this code -->
<b:if cond='data:label.name == "Linux"'>
<a expr:href='data:label.url'>
<span>
<data:label.name/>
</span>
</a>
</b:if>

<!--I am adding the label - Opensource in this code -->
<b:if cond='data:label.name == "Open Source"'>
<a expr:href='data:label.url'>
<span>
<data:label.name/>
</span>
</a>
</b:if>

</b:loop>

</ul>
<!-- <b:include name='quickedit'/> -->
</div>
</b:includable>
</b:widget>

Depending upon your requirement you can add as many labels you want.

NOTE: If you use a CSS menu style other than F, than make sure id='tabsF' reflects the correct tab, such as id='tabsE' for style E. Later, if you like a different design, just cut-and-paste the style's CSS code, then change this id again to reflect the change. Check out the Tabs in my blog.


Checkout the CSS code for other Menu styles from A to F

/*- Menu Tabs A --------------------------- */

#tabs {
float:left;
width:100%;
background:#BBD9EE;
font-size:93%;
line-height:normal;
}
#tabs ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabs li {
display:inline;
margin:0;
padding:0;
}
#tabs a {
float:left;
background:url("http://www.site.com/tableft.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabs a span {
float:left;
display:block;
background:url("http://www.site.com/tabright.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#666;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabs a span {float:none;}
/* End IE5-Mac hack */
#tabs a:hover span {
color:#FF9834;
}
#tabs a:hover {
background-position:0% -42px;
}
#tabs a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs B--------------------------- */

#tabsB {
float:left;
width:100%;
background:#F4F4F4;
font-size:93%;
line-height:normal;
}
#tabsB ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsB li {
display:inline;
margin:0;
padding:0;
}
#tabsB a {
float:left;
background:url("http://www.site.com/tableftB.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsB a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightB.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#666;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsB a span {float:none;}
/* End IE5-Mac hack */
#tabsB a:hover span {
color:#000;
}
#tabsB a:hover {
background-position:0% -42px;
}
#tabsB a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs C--------------------------- */

#tabsC {
float:left;
width:100%;
background:#EDF7E7;
font-size:93%;
line-height:normal;
}
#tabsC ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsC li {
display:inline;
margin:0;
padding:0;
}
#tabsC a {
float:left;
background:url("http://www.site.com/tableftC.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsC a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightC.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#464E42;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsC a span {float:none;}
/* End IE5-Mac hack */
#tabsC a:hover span {
color:#FFF;
}
#tabsC a:hover {
background-position:0% -42px;
}
#tabsC a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs D--------------------------- */

#tabsD {
float:left;
width:100%;
background:#FCF3F8;
font-size:93%;
line-height:normal;
border-bottom:1px solid #F4B7D6;
}
#tabsD ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsD li {
display:inline;
margin:0;
padding:0;
}
#tabsD a {
float:left;
background:url("http://www.site.com/tableftD.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsD a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightD.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#C7377D;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsD a span {float:none;}
/* End IE5-Mac hack */
#tabsD a:hover span {
color:#C7377D;
}
#tabsD a:hover {
background-position:0% -42px;
}
#tabsD a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs E--------------------------- */

#tabsE {
float:left;
width:100%;
background:#000;
font-size:93%;
line-height:normal;

}
#tabsE ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsE li {
display:inline;
margin:0;
padding:0;
}
#tabsE a {
float:left;
background:url("http://www.site.com/tableftE.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsE a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightE.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#FFF;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsE a span {float:none;}
/* End IE5-Mac hack */
#tabsE a:hover span {
color:#FFF;
}
#tabsE a:hover {
background-position:0% -42px;
}
#tabsE a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs F--------------------------- */

#tabsF {
float:left;
width:100%;
background:#efefef;
font-size:93%;
line-height:normal;
border-bottom:1px solid #666;
}
#tabsF ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsF li {
display:inline;
margin:0;
padding:0;
}
#tabsF a {
float:left;
background:url("http://www.site.com/tableftF.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsF a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightF.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#666;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsF a span {float:none;}
/* End IE5-Mac hack */
#tabsF a:hover span {
color:#FFF;
}
#tabsF a:hover {
background-position:0% -42px;
}
#tabsF a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs G--------------------------- */

#tabsG {
float:left;
width:100%;
background:#666;
font-size:93%;
line-height:normal;
}
#tabsG ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsG li {
display:inline;
margin:0;
padding:0;
}
#tabsG a {
float:left;
background:url("http://www.site.com/tableftG.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsG a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightG.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#FFF;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsG a span {float:none;}
/* End IE5-Mac hack */
#tabsG a:hover span {
color:#FFF;
}
#tabsG a:hover {
background-position:0% -42px;
}
#tabsG a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs H--------------------------- */

#tabsH {
float:left;
width:100%;
background:#000;
font-size:93%;
line-height:normal;
}
#tabsH ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsH li {
display:inline;
margin:0;
padding:0;
}
#tabsH a {
float:left;
background:url("http://www.site.com/tableftH.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsH a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightH.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#FFF;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsH a span {float:none;}
/* End IE5-Mac hack */
#tabsH a:hover span {
color:#FFF;
}
#tabsH a:hover {
background-position:0% -42px;
}
#tabsH a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs I--------------------------- */

#tabsI {
float:left;
width:100%;
background:#EFF4FA;
font-size:93%;
line-height:normal;
border-bottom:1px solid #DD740B;
}
#tabsI ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsI li {
display:inline;
margin:0;
padding:0;
}
#tabsI a {
float:left;
background:url("http://www.site.com/tableftI.gif") no-repeat left top;
margin:0;
padding:0 0 0 5px;
text-decoration:none;
}
#tabsI a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightI.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#FFF;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsI a span {float:none;}
/* End IE5-Mac hack */
#tabsI a:hover span {
color:#FFF;
}
#tabsI a:hover {
background-position:0% -42px;
}
#tabsI a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs J--------------------------- */

#tabsJ {
float:left;
width:100%;
background:#F4F4F4;
font-size:93%;
line-height:normal;
border-bottom:1px solid #24618E;
}
#tabsJ ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsJ li {
display:inline;
margin:0;
padding:0;
}
#tabsJ a {
float:left;
background:url("http://www.site.com/tableftJ.gif") no-repeat left top;
margin:0;
padding:0 0 0 5px;
text-decoration:none;
}
#tabsJ a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightJ.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#24618E;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsJ a span {float:none;}
/* End IE5-Mac hack */
#tabsJ a:hover span {
color:#FFF;
}
#tabsJ a:hover {
background-position:0% -42px;
}
#tabsJ a:hover span {
background-position:100% -42px;
}

/*- Menu Tabs K--------------------------- */

#tabsK {
float:left;
width:100%;
background:#E7E5E2;
font-size:93%;
line-height:normal;
border-bottom:1px solid #54545C;
}
#tabsK ul {
margin:0;
padding:10px 10px 0 50px;
list-style:none;
}
#tabsK li {
display:inline;
margin:0;
padding:0;
}
#tabsK a {
float:left;
background:url("http://www.site.com/tableftK.gif") no-repeat left top;
margin:0;
padding:0 0 0 4px;
text-decoration:none;
}
#tabsK a span {
float:left;
display:block;
background:url("http://www.site.com/tabrightK.gif") no-repeat right top;
padding:5px 15px 4px 6px;
color:#FFF;
}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#tabsK a span {float:none;}
/* End IE5-Mac hack */
#tabsK a:hover span {
color:#FFF;
background-position:100% -42px;
}
#tabsK a:hover {
background-position:0% -42px;
}
#tabsK a:hover span {
background-position:100% -42px;
}