libexpect man page on BSDOS

Man page or keyword search:  
man Server   6284 pages
apropos Keyword Search (all sections)
Output format
BSDOS logo
[printable version]



LIBEXPECT(3)					     LIBEXPECT(3)

NAME
       libexpect  - programmed dialogue with interactive programs
       - C functions

DESCRIPTION
       This library contains functions that allow  Expect  to  be
       used  as	 a Tcl extension or to be used directly from C or
       C++ (without Tcl).  Adding Expect as a  Tcl  extension  is
       very short and simple, so that will be covered first.

SYNOPSIS
       #include expect_tcl.h
       Expect_Init(interp);

       cc files... -lexpect5.20 -ltcl7.5 -lm

       Note: library versions may differ in the actual release.

       The Expect_Init function adds expect commands to the named
       interpreter.  It avoids overwriting commands that  already
       exist,  however	aliases	 beginning with "exp_" are always
       created for expect commands.  So for example,  "send"  can
       be used as "exp_send".

       Generally,  you	should	only  call  Expect  commands  via
       Tcl_Eval.   Certain  auxiliary  functions  may  be  called
       directly.   They are summarized below.  They may be useful
       in  constructing	 your  own  main.   Look  at   the   file
       exp_main_exp.c  in  the Expect distribution as a prototype
       main.  Another prototype is tclAppInit.c in the Tcl source
       distribution.   A  prototype  for  working  with	 Tk is in
       exp_main_tk.c in the Expect distribution.

       int exp_cmdlinecmds;
       int exp_interactive;
       FILE *exp_cmdfile;
       char *exp_cmdfilename;
       int exp_tcl_debugger_available;

       void exp_parse_argv(Tcl_Interp *,int argc,char **argv);
       int  exp_interpreter(Tcl_Interp *);
       void exp_interpret_cmdfile(Tcl_Interp *,FILE *);
       void exp_interpret_cmdfilename(Tcl_Interp *,char *);
       void exp_interpret_rcfiles(Tcl_Interp *,int my_rc,int sys_rc);
       char *	 exp_cook(char *s,int *len);
       void (*exp_app_exit)EXP_PROTO((Tcl_Interp *);
       void exp_exit(Tcl_Interp *,int status);
       void exp_exit_handlers(Tcl_Interp *);
       void exp_error(Tcl_Interp,char *,...);

       exp_cmdlinecmds is 1 if Expect has been invoked with  com-
       mands  on  the  program command-line (using "-c" for exam-
       ple).  exp_interactive is 1 if  Expect  has  been  invoked
       with  the  -i  flag  or	if no commands or script is being

			 12 December 1991			1

LIBEXPECT(3)					     LIBEXPECT(3)

       invoked.	 exp_cmdfile is a stream from which  Expect  will
       read  commands.	 exp_cmdfilename  is  the  name of a file
       which  Expect  will   open   and	  read	 commands   from.
       exp_tcl_debugger_available  is  1 if the debugger has been
       armed.

       exp_parse_argv reads the	 representation	 of  the  command
       line.   Based on what is found, any of the other variables
       listed here  are	 initialized  appropriately.   exp_inter-
       preter  interactively  prompts  the  user for commands and
       evaluates them.	 exp_interpret_cmdfile	reads  the  given
       stream  and  evaluates  any  commands  found.   exp_inter-
       pret_cmdfilename opens the named file  and  evaluates  any
       commands	 found.	 exp_interpret_rcfiles reads and evalutes
       the .rc files.  If my_rc	 is  zero,  then  ~/.expectrc  is
       skipped.	 If sys_rc is zero, then the system-wide expectrc
       file is skipped.	 exp_cook returns a  static  buffer  con-
       taining	the argument reproduced with newlines replaced by
       carriage-return linefeed sequences.  The	 primary  purpose
       of this is to allow messages to be produced without worry-
       ing about whether the terminal is in raw	 mode  or  cooked
       mode.   If  length  is  zero,  it  is computed via strlen.
       exp_error is a printf-like function that writes the result
       to interp->result.

SYNOPSIS
       #include <expect.h>

       int
       exp_spawnl(file, arg0 [, arg1, ..., argn] (char *)0);
       char *file;
       char *arg0, *arg1, ... *argn;

       int
       exp_spawnv(file,argv);
       char *file, *argv[ ];

       int
       exp_spawnfd(fd);
       int fd;

       FILE *
       exp_popen(command);
       char *command;

       extern int exp_pid;
       extern int exp_ttyinit;
       extern int exp_ttycopy;
       extern int exp_console;
       extern char *exp_stty_init;
       extern void (*exp_close_in_child)();
       extern void (*exp_child_exec_prelude)();
       extern void exp_close_tcl_files();

			 12 December 1991			2

LIBEXPECT(3)					     LIBEXPECT(3)

       cc files... -lexpect -ltcl -lm


DESCRIPTION
       exp_spawnl  and	exp_spawnv fork a new process so that its
       stdin, stdout, and stderr can be written and read  by  the
       current	process.   file	 is the name of a file to be exe-
       cuted.  The  arg	 pointers  are	null-terminated	 strings.
       Following the style of execve(), arg0 (or argv[0]) is cus-
       tomarily a duplicate of the name of the file.

       Four interfaces are available, exp_spawnl is  useful  when
       the   number  of	 arguments  is	known  at  compile  time.
       exp_spawnv is useful when the number of arguments  is  not
       known at compile time.  exp_spawnfd is useful when an open
       file  descriptor	 is  already  available	 as   a	  source.
       exp_popen is explained later on.

       If  the process is successfully created, a file descriptor
       is returned which corresponds to the process's stdin, std-
       out  and stderr.	 A stream may be associated with the file
       descriptor by using fdopen().  (This  should  almost  cer-
       tainly be followed by setbuf() to unbuffer the I/O.)

       Closing	the file descriptor will typically be detected by
       the process as an EOF.  Once  such  a  process  exits,  it
       should  be  waited upon (via wait) in order to free up the
       kernel process slot.  (Some systems  allow  you	to  avoid
       this if you ignore the SIGCHLD signal).

       exp_popen  is yet another interface, styled after popen().
       It takes a Bourne shell command line, and returns a stream
       that  corresponds  to  the  process's  stdin,  stdout  and
       stderr.	The  actual  implementation  of	 exp_popen  below
       demonstrates exp_spawnl.

       FILE *
       exp_popen(program)
       char *program;
       {
	    FILE *fp;
	    int ec;

	    if (0 > (ec = exp_spawnl("sh","sh","-c",program,(char *)0)))
		 return(0);
	    if (NULL == (fp = fdopen(ec,"r+")) return(0);
	    setbuf(fp,(char *)0);
	    return(fp);
       }

       After a process is started, the variable exp_pid is set to
       the  process-id	of  the	 new   process.	   The	 variable
       exp_pty_slave_name is set to the name of the slave side of
       the pty.

			 12 December 1991			3

LIBEXPECT(3)					     LIBEXPECT(3)

       The spawn functions uses a pty  to  communicate	with  the
       process.	  By default, the pty is initialized the same way
       as the user's tty (if possible, i.e., if	 the  environment
       has  a  controlling terminal.)  This initialization can be
       skipped by setting exp_ttycopy to 0.

       The  pty	 is  further  initialized  to  some  system  wide
       defaults	 if exp_ttyinit is non-zero.  The default is gen-
       erally comparable to "stty sane".

       The tty setting can be further  modified	 by  setting  the
       variable	 exp_stty_init.	  This variable is interpreted in
       the style of stty arguments.  For example, exp_stty_init =
       "sane"; repeats the default initialization.

       On some systems, it is possible to redirect console output
       to ptys.	 If this is supported, you  can	 force	the  next
       spawn to obtain the console output by setting the variable
       exp_console to 1.

       Between the time a process is started and the new  program
       is  given  control,  the	 spawn functions can clean up the
       environment by closing file descriptors.	 By default,  the
       only  file  descriptors closed are ones internal to Expect
       and any marked "close-on-exec".

       If needed, you can close additional  file  descriptors  by
       creating	 an  appropriate  function  and	 assigning  it to
       exp_close_in_child.  The function will be called after the
       fork  and before the exec.  (This also modifies the behav-
       ior of the spawn command in Expect.)

       If you are also using Tcl, it may be convenient to use the
       function	  exp_close_tcl_files	which  closes  all  files
       between the default  standard  file  descriptors	 and  the
       highest descriptor known to Tcl.	 (Expect does this.)

       The  function  exp_child_exec_prelude is the last function
       called prior to the actual exec in  the	child.	 You  can
       redefine	 this for effects such as manipulating the uid or
       the signals.

IF YOU WANT TO ALLOCATE YOUR OWN PTY
       extern int exp_autoallocpty;
       extern int exp_pty[2];

       The spawn functions use a pty to communicate with the pro-
       cess.   By  default, a pty is automatically allocated each
       time a process is spawned.  If you want to  allocate  ptys
       yourself,  before  calling one of the spawn functions, set
       exp_autoallocpty to 0, exp_pty[0] to the master	pty  file
       descriptor  and	exp_pty[1] to the slave pty file descrip-
       tor.   The  expect   library   will   not   do	any   pty

			 12 December 1991			4

LIBEXPECT(3)					     LIBEXPECT(3)

       initializations	(e.g.,	exp_stty_init  will not be used).
       The slave pty file descriptor will be automatically closed
       when  the  process  is  spawned.	  After	 the  process  is
       started, all further communication takes	 place	with  the
       master pty file descriptor.

       exp_spawnl and exp_spawnv duplicate the shell's actions in
       searching for an executable file in a list of directories.
       The directory list is obtained from the environment.

EXPECT PROCESSING
       While  it  is  possible	to use read() to read information
       from a process spawned by exp_spawnl or	exp_spawnv,  more
       convenient functions are provided.  They are as follows:

       int
       exp_expectl(fd,type1,pattern1,[re1,],value1,type2,...,exp_end);
       int fd;
       enum exp_type type;
       char *pattern1, *pattern2, ...;
       regexp *re1, *re2, ...;
       int value1, value2, ...;

       int
       exp_fexpectl(fp,type1,pattern1,[re1,]value1,type2,...,exp_end);
       FILE *fp;
       enum exp_type type;
       char *pattern1, *pattern2, ...;
       regexp *re1, *re2, ...;
       int value1, value2, ...;

       enum exp_type {
       exp_end,
       exp_glob,
       exp_exact,
       exp_regexp,
       exp_compiled,
       exp_null,
       };

       struct exp_case {
       char *pattern;
       regexp *re;
       enum exp_type type;
       int value;
       };

       int
       exp_expectv(fd,cases);
       int fd;
       struct exp_case *cases;

       int
       exp_fexpectv(fp,cases);

			 12 December 1991			5

LIBEXPECT(3)					     LIBEXPECT(3)

       FILE *fp;
       struct exp_case *cases;

       extern int exp_timeout;
       extern char *exp_match;
       extern char *exp_match_end;
       extern char *exp_buffer;
       extern char *exp_buffer_end;
       extern int exp_match_max;
       extern int exp_full_buffer;
       extern int exp_remove_nulls;

       The functions wait until the output from a process matches
       one of the patterns, a specified time period  has  passed,
       or an EOF is seen.

       The  first  argument  to	 each  function	 is either a file
       descriptor or a	stream.	  Successive  sets  of	arguments
       describe	 patterns and associated integer values to return
       when the pattern matches.

       The type argument is one of four	 values.   exp_end  indi-
       cates  that  no	more patterns appear.  exp_glob indicates
       that  the  pattern  is  a   glob-style	string	 pattern.
       exp_exact  indicates  that the pattern is an exact string.
       exp_regexp indicates that the pattern  is  a  regexp-style
       string  pattern.	  exp_compiled indicates that the pattern
       is a regexp-style string pattern, and  that  its	 compiled
       form  is	 also provided.	 exp_null indicates that the pat-
       tern is a null (for debugging purposes, a  string  pattern
       must also follow).

       If  the	compiled  form is not provided with the functions
       exp_expectl and exp_fexpectl, any pattern compilation done
       internally is thrown away after the function returns.  The
       functions exp_expectv and exp_fexpectv will  automatically
       compile	patterns  and will not throw them away.	 Instead,
       they must be discarded by the user,  by	calling	 free  on
       each  pattern.	It is only necessary to discard them, the
       last time the cases are used.

       Regexp subpatterns matched are stored in the compiled reg-
       exp.   Assuming	"re"  contains	a  compiled  regexp,  the
       matched string can be found in re->startp[0].   The  match
       substrings  (according to the parentheses) in the original
       pattern can be found in re->startp[1], re->startp[2],  and
       so  on,	up  to	re->startp[9].	The corresponding strings
       ends are re->endp[x] where x is that same index as for the
       string start.

       The  type exp_null matches if a null appears in the input.
       The variable exp_remove_nulls must be set to 0 to  prevent
       nulls  from  being  automatically  stripped.   By default,
       exp_remove_nulls is set to 1 and nulls  are  automatically

			 12 December 1991			6

LIBEXPECT(3)					     LIBEXPECT(3)

       stripped.

       exp_expectv and exp_fexpectv are useful when the number of
       patterns is not known in advance.  In this case, the  sets
       are provided in an array.  The end of the array is denoted
       by a struct exp_case with type exp_end.	For the	 rest  of
       this  discussion,  these	 functions  will  be  referred to
       generically as expect.

       If a pattern matches, then the corresponding integer value
       is  returned.   Values  need  not  be unique, however they
       should be positive to avoid being  mistaken  for	 EXP_EOF,
       EXP_TIMEOUT,  or EXP_FULLBUFFER.	 Upon EOF or timeout, the
       value EXP_EOF or EXP_TIMEOUT  is	 returned.   The  default
       timeout period is 10 seconds but may be changed by setting
       the variable exp_timeout.  A value of -1 disables a  time-
       out  from occurring.  A value of 0 causes the expect func-
       tion to return immediately (i.e., poll) after one  read().
       However	it must be preceded by a function such as select,
       poll, or an event manager callback to guarantee that there
       is data to be read.

       If  the variable exp_full_buffer is 1, then EXP_FULLBUFFER
       is returned if exp_buffer fills	with  no  pattern  having
       matched.

       When the expect function returns, exp_buffer points to the
       buffer of characters that was being considered for  match-
       ing.  exp_buffer_end points to one past the last character
       in exp_buffer.  If a match occurred, exp_match points into
       exp_buffer where the match began.  exp_match_end points to
       one character past where the match ended.

       Each time new input arrives, it is compared to  each  pat-
       tern in the order they are listed.  Thus, you may test for
       absence of a match by making the	 last  pattern	something
       guaranteed  to  appear,	such  as a prompt.  In situations
       where there is no prompt, you must check	 for  EXP_TIMEOUT
       (just  like  you	 would if you were interacting manually).
       More philosophy and strategies on specifying  expect  pat-
       terns can be found in the documentation on the expect pro-
       gram itself.  See SEE ALSO below.

       Patterns are the usual C-shell-style regular  expressions.
       For example, the following fragment looks for a successful
       login, such as from a telnet dialogue.

	    switch (exp_expectl(
		 exp_glob,"connected",CONN,
		 exp_glob,"busy",BUSY,
		 exp_glob,"failed",ABORT,
		 exp_glob,"invalid password",ABORT,
		 exp_end)) {
	    case CONN:	   /* logged in successfully */

			 12 December 1991			7

LIBEXPECT(3)					     LIBEXPECT(3)

		 break;
	    case BUSY:	   /* couldn't log in at the moment */
		 break;
	    case EXP_TIMEOUT:
	    case ABORT:	   /* can't log in at any moment! */
		 break;
	    default: /* problem with expect */
	    }

       Asterisks (as in the example above) are a useful shorthand
       for omitting line-termination characters and other detail.
       Patterns must match the entire output of the current  pro-
       cess  (since  the  previous  read  on  the  descriptor  or
       stream).	 More than 2000 bytes of output can force earlier
       bytes  to  be "forgotten".  This may be changed by setting
       the variable exp_match_max.  Note that  excessively  large
       values can slow down the pattern matcher.

RUNNING IN THE BACKGROUND
       extern int exp_disconnected;
       int exp_disconnect();

       It is possible to move a process into the background after
       it has begun running.  A typical use for this is	 to  read
       passwords  and then go into the background to sleep before
       using the passwords to do real work.

       To move a process into the background, fork, call exp_dis-
       connect()  in  the  child process and exit() in the parent
       process.	 This disassociates your process  from	the  con-
       trolling terminal.  If you wish to move a process into the
       background in a different way, you must set  the	 variable
       exp_disconnected	 to  1.	  This	allows	processes spawned
       after this point to be started correctly.

MULTIPLEXING
       By default, the expect functions block inside of a read on
       a single file descriptor.  If you want to wait on patterns
       from multiple file descriptors, use select,  poll,  or  an
       event manager.  They will tell you what file descriptor is
       ready to read.

       When a file descriptor is ready to read, you can	 use  the
       expect  functions to do one and only read by setting time-
       out to 0.

SLAVE CONTROL
       void
       exp_slave_control(fd,enable)
       int fd;
       int enable;

       Pty trapping is normally done automatically by the  expect

			 12 December 1991			8

LIBEXPECT(3)					     LIBEXPECT(3)

       functions.   However,  if  you want to issue an ioctl, for
       example, directly on the slave device, you  should  tempo-
       rary disable trapping.

       Pty  trapping  can  be  controlled with exp_slave_control.
       The first argument is the file descriptor corresponding to
       the  spawned process.  The second argument is a 0 if trap-
       ping is to be disabled and 1 if it is to be enabled.

ERRORS
       All functions indicate errors by returning -1 and  setting
       errno.

       Errors  that  occur  after the spawn functions fork (e.g.,
       attempting to spawn a non-existent program) are written to
       the  process's  stderr,	and  will  be  read  by the first
       expect.

SIGNALS
       extern int exp_reading;
       extern jmp_buf exp_readenv;

       expect uses alarm()  to	timeout,  thus	if  you	 generate
       alarms during expect, it will timeout prematurely.

       Internally,  expect  calls read() which can be interrupted
       by signals.  If you define signal handlers, you can choose
       to restart or abort expect's internal read.  The variable,
       exp_reading, is true if (and only if)  expect's	read  has
       been   interrupted.   longjmp(exp_readenv,EXP_ABORT)  will
       abort  the  read.   longjmp(exp_readenv,EXP_RESTART)  will
       restart the read.

LOGGING
       extern int exp_loguser;
       extern int exp_logfile_all
       extern FILE *exp_logfile;

       If  exp_loguser	is  nonzero, expect sends any output from
       the spawned process to stdout.  Since interactive programs
       typically  echo their input, this usually suffices to show
       both sides of the conversation.	If  exp_logfile	 is  also
       nonzero, this same output is written to the stream defined
       by exp_logfile.	If exp_logfile_all is non-zero,	 exp_log-
       file is written regardless of the value of exp_loguser.

DEBUGGING
       While  I	 consider  the library to be easy to use, I think
       that the standalone expect program is much,  much,  easier
       to  use	than  working  with  the C compiler and its usual
       edit, compile, debug cycle.  Unlike  typical  C	programs,
       most  of	 the  debugging	 isn't	getting the C compiler to

			 12 December 1991			9

LIBEXPECT(3)					     LIBEXPECT(3)

       accept your programs - rather, it is getting the	 dialogue
       correct.	  Also,	 translating  scripts from expect to C is
       usually not necessary.  For example, the speed of interac-
       tive dialogues is virtually never an issue.  So please try
       the standalone 'expect' program first.  I suspect it is	a
       more   appropriate  solution  for  most	people	than  the
       library.

       Nonetheless, if you feel compelled to debug in C, here are
       some tools to help you.

       extern int exp_is_debugging;
       extern FILE *exp_debugfile;

       While expect dialogues seem very intuitive, trying to cod-
       ify them in a program can reveal many surprises in a  pro-
       gram's  interface.   Therefore a variety of debugging aids
       are available.  They are controlled  by	the  above  vari-
       ables, all 0 by default.

       Debugging information internal to expect is sent to stderr
       when exp_is_debugging is non-zero.  The debugging informa-
       tion  includes every character received, and every attempt
       made to match the current input against the patterns.   In
       addition,  non-printable	 characters  are  translated to a
       printable form.	For example, a	control-C  appears  as	a
       caret  followed	by a C.	 If exp_logfile is non-zero, this
       information is also written to that stream.

       If exp_debugfile is non-zero,  all  normal  and	debugging
       information  is	written to that stream, regardless of the
       value of exp_is_debugging.

CAVEATS
       The stream versions  of	the  expect  functions	are  much
       slower  than the file descriptor versions because there is
       no way to portably read an unknown number of bytes without
       the  potential  of  timing out.	Thus, characters are read
       one at a time.  You are therefore strongly  encouraged  to
       use  the	 file  descriptor  versions  of expect (although,
       automated versions of interactive programs  don't  usually
       demand high speed anyway).

       You can actually get the best of both worlds, writing with
       the usual stream	 functions  and	 reading  with	the  file
       descriptor versions of expect as long as you don't attempt
       to intermix other stream input  functions  (e.g.,  fgetc).
       To  do  this,  pass  fileno(stream) as the file descriptor
       each time.  Fortunately, there is  little  reason  to  use
       anything but the expect functions when reading from inter-
       active programs.

       There is no matching exp_pclose to exp_popen (unlike popen
       and  pclose).  It only takes two functions to close down a

			 12 December 1991		       10

LIBEXPECT(3)					     LIBEXPECT(3)

       connection (fclose() followed by waiting on the pid),  but
       it  is not uncommon to separate these two actions by large
       time intervals, so the function seems of little value.

       If you are running on a Cray running Unicos  (all  I  know
       for sure from experience), you must run your compiled pro-
       gram as root or setuid.	The problem is that the Cray only
       allows root processes to open ptys.  You should observe as
       much precautions as possible:  If you don't  need  permis-
       sions,  setuid(0)  only	immediately before calling one of
       the spawn functions and immediately  set	 it  back  after-
       wards.

       Normally,  spawn	 takes	little	time  to execute.  If you
       notice spawn taking a significant amount of  time,  it  is
       probably	 encountering  ptys that are wedged.  A number of
       tests are run on ptys to avoid entanglements  with  errant
       processes.   (These take 10 seconds per wedged pty.)  Run-
       ning expect with the -d option  will  show  if  expect  is
       encountering  many ptys in odd states.  If you cannot kill
       the processes to which these ptys are attached, your  only
       recourse may be to reboot.

BUGS
       The  exp_fexpect functions don't work at all under HP-UX -
       it appears to be a bug in getc.	Follow the advice (above)
       about  using  the exp_expect functions (which doesn't need
       to call getc).  If you fix the  problem	(before	 I  do	-
       please check the latest release) let me know.

SEE ALSO
       An  alternative	to  this  library  is the expect program.
       expect interprets scripts written in a high-level language
       which direct the dialogue.  In addition, the user can take
       control and interact directly when desired.  If it is  not
       absolutely  necessary  to  write your own C program, it is
       much easier to use expect to perform the	 entire	 interac-
       tion.   It  is  described  further in the following refer-
       ences:

       "expect: Curing Those Uncontrollable Fits  of  Interactiv-
       ity"  by	 Don Libes, Proceedings of the Summer 1990 USENIX
       Conference, Anaheim, California, June 11-15, 1990.

       "Using expect to Automate System Administration Tasks"  by
       Don  Libes, Proceedings of the 1990 USENIX Large Installa-
       tion Systems Administration Conference, Colorado	 Springs,
       Colorado, October 17-19, 1990.

       expect(1),   alarm(3),	read(2),   write(2),   fdopen(3),
       execve(2), execvp(3), longjmp(3), pty(4).

       There are several examples C programs in the  test  direc-
       tory  of expect's source distribution which use the expect

			 12 December 1991		       11

LIBEXPECT(3)					     LIBEXPECT(3)

       library.

AUTHOR
       Don Libes, libes@nist.gov, National Institute of Standards
       and Technology

ACKNOWLEDGEMENTS
       Thanks  to  John Ousterhout (UCBerkeley) for supplying the
       pattern matcher.

       Design and implementation of the expect library	was  paid
       for  by the U.S. government and is therefore in the public
       domain.	However the author and NIST would like credit  if
       this  program  and  documentation  or portions of them are
       used.

			 12 December 1991		       12

[top]
                             _         _         _ 
                            | |       | |       | |     
                            | |       | |       | |     
                         __ | | __ __ | | __ __ | | __  
                         \ \| |/ / \ \| |/ / \ \| |/ /  
                          \ \ / /   \ \ / /   \ \ / /   
                           \   /     \   /     \   /    
                            \_/       \_/       \_/ 
More information is available in HTML format for server BSDOS

List of man pages available for BSDOS

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net