Saturday, May 10, 2008

Ftp Scripting

Here we demonstrate some ways of doing Ftp within shell scripts and the famous problem of passing the password!

First this an example using Here document:


#
# Here document
#
ftp -vn localhost << !
user $USER $PASSWD
pwd
quit
!



Another way using quote Ftp command:
ftp -n $HOST << !
quote USER $USER
quote PASS
$PASSWD
pwd
quit
!




The previous ways are good as long as we don't need to do some logic inside the Ftp connection, like for example looping or conditional statements.

Instead, to able to do so, we have to use another method using "co-process" technique in the Korn shell (ksh) or of course Perl.
#
# Using co-process
# The "|&" turns the process into a co-process that allows subsequent
# "print -p" statements to send lines to the co-process standard-in and
# "read -p" to read from its standard-out.
#
exec 4>&1
ftp -nv >&4 2>&4 |&

print -p open localhost
print
-p user ericsson ericsson
print
-p pwd
for i in 1 2 3 ; do
print -p pwd
done
print -p bye
wait

References:
Inlumine Consulting

Unix forums

In-Place String Filter

This C function would remove from the source string "str" a set of characters that you supply to the it "delims".

It returns a new string with out these characters, just like filtering the string.
The filtering is done in place, meaning that only N memory is used in the processing.

We first mark all occurrence of "delims" in "str" with nulls, then we concatenate the result to itself.



char *removeCharsInPlace(const char *str,const char *delims)
{
char * const result = strdup(str);
const int srcStrLen = strlen(str);
const int delimsStrLen = strlen(delims);
int i1, i2, j, tmp;

// Replace all the characters in 'result' string, which are like
// delims chars with null
for(i1 = 0; i1 < srcStrLen ; i1++) {
// Loop through the 'delims' string
for (i2 = 0; i2 < delimsStrLen ; i2++) {
if (result[i1] == delims[i2])
result[i1] = '\0';
}
}

// Loop through the 'result' string
j = 0;
while(j < srcStrLen) {
// Calculate the position of the next null
for(j; result[j] != '\0'; j++);

// Get the start of next string
j++;
tmp = j;

// Calculate next position to start search for the null
j += strlen(&result[j]);

// Append result to itself
strcat(result, &result[tmp]);
}

return result;
}

Wednesday, October 24, 2007

Bypassing Firewall

We can use a proxy http server to view blocked sites by our firewall like Youtube or facebook, the remote proxy server is opened over the internet and will do the connection on behalf of us, then forward the requested page to us :)

Note that not all the web proxies supports javascript, this may prevent some pages from displaying correctly.

A good one is the http://www.sloxy.com/, if we can access the proxy server then we can view whatever sites the server can access :)

To keep updated, we should frequently visit http://www.freeproxysite.com/.

Another simple way if we only need to view a single link, like a Youtube link <http://www.youtube.com/watch?v=r43yCiKlbCo//n>, just replace the URL with the IP <http://208.65.153.238/watch?v=r43yCiKlbCo//n>.

To get the IP simply ping the host

$ ping www.youtube.com

if the ping is blocked, we can use a webping www.fifi.org/services/ping

The above may not work for the messengers, To get the messengers working, we may use another 3rd parity program like www.hopster.com/ that will connect to the MSN or other servers on behalf. One should read their privacy policy before using it.

Wednesday, October 10, 2007

Shell Clock

A useful clock that is displayed inside your terminal window, it displays the time on the top right edge of your terminal :)

This is done by manipulating the terminal escape sequence, this could be done with any language but I will list here the shell script version (just to save compile effort).

We can learn about terminal escape sequences using the dtterm manual pages ($ man -s5 dtterm), here we will use the "Esc 7" (DECSC), "Esc 8" (DECRC) and "Esc [ p1 ; p2 H" sequences.

The "Esc 7" sequence is used to save cursor position, "Esc 8" is used to restore cursor position and "Esc [ p1 ; p2 H" is used to position the cursor as follows:
A p1 value 0 or 1 moves the cursor to row one. A p1 value of N moves the cursor to row N. A p2 value 0 or 1 moves the cursor to column one. A p2 value of N moves the cursor to column N.

Save the following shell code in a script called for example "clock" and run it in the background as follows

$ clock &


#! /bin/sh

while true
do
# Get time
TIME=$(date +%T)

# Save cursor position
printf "\0337"

# Set color
printf "\033[1;31m"

# Goto row 1, column 70
printf "\033[1;70H$TIME"

# Restore cursor position
printf "\0338"

sleep 1
done

In-place String Reverse

This is an in-place function for reversing null terminated strings (in-place means that no additional space is required for the reverse process)


/***************************************/
/* In-place reverse */
/* Swap array elements (inner to outer)*/
/* ex: "abcde", "Rock" */
/* swap adcbe Rcok */
/* swap edcba kcoR */
/* */
/***************************************/
void reverse (char* str)
{
char temp;
/* right & left to be swapped */
int r, l;
int len = strlen(str);

if (len % 2 == 0)
{
r = len / 2;
l = (len / 2) - 1;
}
else
{
r = (len / 2) + 1;
l = (len / 2) - 1;
}

/***************************************/
/* Swap array elements (inner to outer)*/
/***************************************/
while(l != 0)
{
temp = str[l];
str[l] = str[r];
str[r] = temp;
l--;
r++;
}

return;
}


Monday, October 1, 2007

UNIX Command Piping

It took me some time to master the "Piping" skills so I thought this would be useful to share.
The following is a multi-piping program that connect any number of commands.

Steps:


  1. Calculate the number of needed pipes.

  2. Create the pipes and note that all coming childs will inherit it (remember to close all the pipes in the parent).

  3. Fork a new child and redirect STDIN & STDOUT and note that first command should not redirect STDIN and last command should not redirect STDOUT.

  4. Close all the pipes after redirection in child and repeat 3 until all commands are done.

  5. Close all pipes in the parent.

  6. Parent wait for the last child.



Usage: pipe cmd1 cmd2 cmd3 ...




#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


int main (int argc,char* *argv,char* *envp)
{
int i, j;
int nProcess = argc - 1;
int nPipes = nProcess - 1;
int fd[nPipes][2]; // Pipe file descriptors
pid_t pid;
char cmd[20] = "/bin/";

#ifdef DEBUG
printf("Pipes: [%d] Process [%d]\n", nPipes, nProcess);
#endif

/********************/
/* Create the pipes */
/********************/
for(i=0;i < nPipes;i++)
{
pipe(fd[i]);
}


/************************************/
/* Spawn child(s) for all processes */
/************************************/
for(j = 1;j <= nProcess;j++)
{
#ifdef DEBUG
printf("Child [%d] spawned.\n", j);
#endif
pid = fork();
if (pid == 0)
{
/***********************************************/
/* ----------- ----------- */
/* fd[j-2] --> process --> fd[j-1] */
/* ----------- ----------- */
/***********************************************/
if ( j != 1 ) // First cmd should NOT redirect STDIN
dup2(fd[j-2][1], STDIN_FILENO);
if ( j != nProcess ) // Last cmd should NOT redirect STDOUT
dup2(fd[j-1][0], STDOUT_FILENO);

/*************************************************************/
/* Close unuseful file descriptors: */
/* the pipe's writing and reading ends */
/* (the latter is not needed anymore, after the duplication) */
/*************************************************************/
for(i=0; i < nPipes;i++)
{
close(fd[i][0]);
close(fd[i][1]);
}

/**********************************************************/
/* Append command to /bin/ */
/* Child will have a separate (copy-on-write) copy of cmd */
/**********************************************************/
strcat(cmd, argv[j]);
execlp(cmd, argv[j], (char *)0);
perror("execlp");
exit( EXIT_FAILURE );

} /* end Child section */
}


/*****************************/
/* Parent code will follow */
/* If everything goes right! */
/*****************************/
for(i=0; i < nPipes;i++)
{
close(fd[i][0]);
close(fd[i][1]);
}

/****************************/
/* Wait for the last child! */
/****************************/
waitpid(pid, 0, 0);

return 0;
}


I have tested this code on Solaris and it worked properly!

Wednesday, August 29, 2007

Clear your Oracle database schema

Normally you don't need to clear your working schema, unless you are running test cases that need to update and refresh the data with each run.

I use the following PL/SQL block to do this for me.


DECLARE

/* Variables to hold the result of the query */
t user_tables.TABLE_NAME %TYPE;
CURSOR tablecursor is
select table_namefrom user_tables;
BEGIN

OPEN tablecursor;
LOOP

/* Retrieve each row of the result into PL/SQL variables */
FETCH tablecursor
INTO t;

/* If there are no more rows to fetch, exit the loop */
EXIT WHEN tablecursor % NOTFOUND;
EXECUTE IMMEDIATE 'DROP TABLE "' t '"';
END LOOP;

/* Free cursor used by the query */
CLOSE tablecursor;
END;
/

About Me