Linux notebook / Perl
Description: Documents various Linux or *nix programs and concepts, including qmail, djbdns, emacs, Perl, hardware, bash, TCP/IP, DNS, etc...
Keywords: find djbdns system dns typical bash less gdb daemontools mirrordir math tables mysql qmail isdn make http ezmlm shell pppd cftp regexps intro awk dhcp test hardware ucspi-tcp apache html perl php3 fetchmail versions emacs email peripherals

Apache Awk Bash C cftp daemontools DHCP djbdns DNS Emacs Email ezmlm Fetchmail find GDB Hardware HTML HTTP Intro ISDN less Make Math mc mirrordir MySQL Peripherals Perl PHP3 pppd qmail Regexps Shell System Tables test To do Typical ucspi-tcp Versions Index TCP/IP slides
Perl |
Idioms | Command line | Regexps | Pattern match operators | Syntax | Operator precedence | Special variables | Arrays & lists | Hashes | Quote constructs | (s)printf | References | File tests | SMTP | MySQL | MD5 & LWP | Net::FTP
| top

> Idioms

> example | operation
> --- | ---
> $alfa="123abc456"; print "Alfa starts as '$alfa'\n"; ($beta=$alfa) =~ s/abc/def/; print "Alfa is still '$alfa'\n"; print "Beta is '$beta'\n"; | demonstrates that $beta gets substituted value of $alfa, which is unchanged
> undef $/; $_=<>; | reads the whole file into $_ (slurp mode)
> { local $/; $_=<>; } | same thing, reads the whole file into $_ (slurp mode), but does not disturb the global $/
> @x=split(/pattern/,$s) | splits $s into @x using pattern as separator
> foreach my $v (@a) { print $v; } | assigns to $v each element of @a in turn and prints it. $v is local to the block (and the my is redundant)
> $_="alfa"; print "Global $_\n"; foreach (1..3) { print "Outer $_\n"; foreach ('A'..'C') { print "Inner $_\n"; } print "Again outer $_\n"; } print "Again global $_\n"; | demonstrates that $_ is local to the foreach block
> while(($key,$value) = each %x) { print "$key=$value\n"; } | assigns $value for each $key in %x in turn and prints it
> @x=sort @y; | places in @x a sorted version of list @y
> print "yes" if exists $hash{$key}; | print "yes" if the given $key exists in the %hash
> for($a=0,$b=9;$a<10;$a++,$b--) { print "$a : $b\n"; } | how to iterate over two variables simultaneously
> for(my ($a,$b)=(0,9);$a<10;$a++,$b--) { print "$a : $b\n"; } | how to iterate over two variables local to the for simultaneously
> print "Found\n" if grep $_==123,@a; | prints Found if 123 exists in the array @a
> s/(\d+)/sprintf "%02x",$1/eg; s/\.//g; | to convert decimal quad-dotted IP addresses to hex also see v flag for sprintf below
> s/(\w{2})/hex($1)."."/eg; s/\.$//; | to convert hex IP addresses to quad-dotted decimal

> Command line options

> option | description
> --- | ---
> -e [script] | Executes the script defined on the command line
> -i | The files read by <> are processed in place
> -n | simulates the following loop around the script: while(<>) { ... } Note that the lines read are not printed, see -p
> -p | Like -n, but the lines are printed
> -de 1 | To use perl in a interactive mode (testing constructs, for example)

> Perl regular expressions

> special characters
> \ | Quote the next meta-character
> ^ | Match the beginning of the line
> . | Match any character (except newline)
> $ | Match the end of the line (or before newline at the end)
> | | Alternation
> () | Grouping and capturing
> [] | Character class
> repetition specifiers
> maximal¹ | minimal² | description
> --- | --- | ---
> * | *? | Match 0 or more times
> + | +? | Match 1 or more times
> ? | ?? | Match 1 or 0 times
> {n} | {n}? | Match exactly n times
> {n,} | {n,}? | Match at least n times
> {n,m} | {n,m}? | Match at least n but not more than m times
> ¹ Maximal: longest possible match ² Minimal: shortest possible match
> special sequences
> \t | tab (HT, TAB)
> \n | newline (LF, NL)
> \r | return (CR)
> \f | form feed (FF)
> \a | alarm (bell) (BEL)
> \e | escape (ESC)
> \033 | octal char (example is ESC)
> \x1B | hex char (example is ESC)
> \x{1B} | hex char (example is ESC)
> \c[ | control char (example is C-[ or ESC)
> \l | lowercase next char
> \u | uppercase next char
> \L | lowercase till \E
> \U | uppercase till \E
> \E | end case modification
> \Q | quote (disable) regexp meta-characters till \E
> syntactic unit sequences
> \w | Match a "word" character (alphanumeric plus "_")
> \W | Match a non-word character
> \s | Match a whitespace character
> \S | Match a non-whitespace character
> \d | Match a digit character
> \D | Match a non-digit character
> non-repeatable syntactic unit sequences
> \b | Match a word boundary
> \B | Match a non-(word boundary)
> \A | Match at only beginning of string
> \Z | Match at only end of string (or before newline at the end)
> \G | Match only where previous m//g left off (works only with /g)
> extended sequences
> (?#...) | Comment, ignored
> (?:...) | Cluster-only parentheses, no capturing

> Pattern matching operators (and similar)

> Operator | Modifier | Description
> --- | --- | ---
> m// s/// qr// | /i | Ignore alphabetic case (case insensitive)
> /s | . matches newline, ignoring $* (the matched string is assumed as a single line)
> /m | ^ and $ match next to embedded \n (the matched string is assumed as multiple lines)
> /x | Ignore most whitespace and permit comments
> /o | Compile pattern once only
> m// | /g | Globally find all matches
> /cg | Allow continued search after failed /g match
> s/// | /g | Globally replace all matches
> /e | Evaluate the right side as an expression
> tr/// | /c | Complement the search list
> /d | Delete found but unreplaced characters
> /s | Squash duplicate replaced characters

> Operator | Function | Return in scalar context | Return in list context
> --- | --- | --- | ---
> m// | Matching | 1 (true) if match,"" (false) if not | List of strings corresponding to capturing parentheses, if there is match and capturing parentheses Null list if matchind did not succed List with sole element 1 if match and no capturing parentheses
> s/// | Substitution | Number of replacemente done | Same as scalar
> tr/// | Transliteration | Number of characters replaced or deleted | Same as scalar

> Special variables

> variable | description
> --- | ---
> $digits | Represented by $1, $2 and so on, these read-only variables stand for the text that was matched in the corresponding set of parenthesis in the last pattern match. The first opening parenthesis is $1, the second is $2, etc.
> $a | Used by the sort function to stand for the first of each pair of values to be compared.
> $b | Used by the sort function to stand for the second of each pair of values to be compared.
> $_ | The default input and pattern search space. Used unless other variable is specified in print,m//,s///,foreach, etc.
> @_ | The array holing the parameters inside a subroutine
> ARGV | The special filehandle that iterates over the command line filenames in @ARGV. This is the implicit filehandle in <>
> $ARGV | The current filename associated to the ARGV filehandle. This the file name of the file being read by <>
> @ARGV | Array containing the command line arguments. $#ARGV is the number of arguments minus one; scalar @ARGV is the number of arguments. The command name is not $ARGV[0), that is the first argument. $0 holds the program name.
> $^T | The time at which the script began running, in seconds since the epoch
> $? | The status returned by the last pipe close, backtick command, wait, waitpid or system functions. Note that this is the complete 16 bits status vector returned. The usual status code is obtained by $? >> 8
> DATA | A special filehandle referring to anything after __DATA__ token in the current file
> $) | The effective group id of the current process (a space separated list of group ids if the systems supports more than one group id for a process)
> $> | The effective user id of the process
> %ENV | Hash containing the environment passed to the script. Can be assigned to, to change the environment to any child programs (not for the parent process)
> $@ | Exception or Perl syntax error message from the last eval
> @INC | The list of directories where Perl searches for do, require or use files.
> $. | The current record (line) number from the last file read. Note that it increases across ARGV files
> $/ | The input record separator, newline by default
> $+ | The contents of the last parenthesis pair matched on the last match
> $" | The separator used when a array is interpolated into a scalar, default is space
> $& | The text of last successful match. See also $' and $`
> $| | If set to true, the output buffer is flushed after each print, printf and write. Default is false, which means that the output if line or block buffered
> $, | The output field separator for print, default is empty
> $\ | The output record separator for print, default is empty
> $' | Contains anything that follows the last successful match (that is, anything after what's returned by $&). See also $& and $`.
> $` | Contains anything that precedes the last successful match (that is, anything preceding $&). See also $& and $'. The following example illustrates all three variables: $_="abcdefgh"; /def/; print "$`:$&:$'\n"; # prints abd:def:gh
> $$ | The process id of the Perl interpreter running the script
> $0 | Name of the file containing the script
> $( | The real group id of the process
> $< | The real user id of the process
> %SIG | The hash containing the signal handlers for the various signals (under Linux, the keys to this hash include ABRT, ALRM, BUS, CHLD, CLD, CONT, FPE, HUP, ILL, INT, IO, IOT, KILL, PIPE, POLL, PROF, PWR, QUIT, RTMAX, RTMIN, SEGV, STKFLT, STOP, TERM, TRAP, TSTP, TTIN, TTOU, UNUSED, URG, USR1, USR2, VTALRM, WINCH, XCPU and XFSZ )
> STDERR | The filehandle used for standard error output
> STDIN | The filehandle used for standard input
> STDOUT | The filehandle used for standard output
> $; | The subscript separator used for multidimensional hash emulation, default is \034

> Syntax notes

> form | result
> --- | ---
> STATEMENT if EXPR | Perform STATEMENT if EXPR true
> STATEMENT unless EXPR | Perform STATEMENT if EXPR false
> STATEMENT while EXPR | Perform STATEMENT while EXPR true (EXPR evaluated first)
> STATEMENT until EXPR | Perform STATEMENT until EXPR true (EXPR evaluated first)
> STATEMENT foreach EXPR | Perform STATEMENT for each value in EXPR, which is evaluated in LIST context. Each of the values in the list will be aliased to the $_ variable, so changing $_ will change the corresponding list element.
> do {BLOCK} while EXPR | Perform {BLOCK} while EXPR true (EXPR evaluated last)
> do {BLOCK} until EXPR | Perform {BLOCK} until EXPR true (EXPR evaluated last)
> if (EXPR) {BLOCK} | Perform {BLOCK} if EXPR true
> if (EXPR) {BLOCK1} else {BLOCK2} | Perform {BLOCK1} if EXPR true, {BLOCK2} if false
> if (EXPR1) {BLOCK1} elsif (EXPR2) {BLOCK2} else {BLOCK3} | Perform {BLOCK1} if EXPR1 true, else perform {BLOCK2} if EXPR2 true, else perform {BLOCK3}
> unless (EXPR) {BLOCK} | Perform {BLOCK} if EXPR false
> unless (EXPR) {BLOCK1} else {BLOCK2} | Perform {BLOCK1} if EXPR false, else perform {BLOCK2}
> unless (EXPR1) {BLOCK1} elsif (EXPR2) {BLOCK2} else {BLOCK3} | Perform {BLOCK1} if EXPR1 false, else perform {BLOCK2} if EXPR2 true, else perform {BLOCK3}
> LABEL: while (EXPR) {BLOCK} | Perform {BLOCK} while EXPR true, LABEL is optional (see next, last, redo qv)
> LABEL: while (EXPR) {BLOCK1} continue {BLOCK2} | Perform {BLOCK1} while EXPR true, LABEL is optional (see next, last, redo qv), perform {BLOCK2} before evaluating EXPR on second and following passes
> LABEL: for (EXPR1;EXPR2;EXPR3) {BLOCK} | Evaluate EXPR1, and while EXPR2 is false perform {BLOCK} and evaluate EXPR3
> LABEL: foreach VAR (LIST) {BLOCK} | Alias VAR to each value in LIST, and perform {BLOCK} for each such value. Changing VAR will change the corresponding value in the LIST.

> continue, last, next, redo

> A absent continue is equivalent to a empty one. The continue block is always executed before the EXPR is about to be evaluated, on the second and following passes

> >                         while (EXPR)
> >                         {
> >                         ### redo always comes here
> >                         do_something;
> >                         }
> >                         continue
> >                         {
> >                         ### next always comes here
> >                         do_something_else;
> >                         ### then back to the top to re-check EXPR
> >                         }
> >                         ### last always comes here

> Declaring subroutines

> form | description
> --- | ---
> sub NAME; | A "forward" declaration
> sub NAME(PROTO); | A prototyped forward declaration
> sub NAME {BLOCK} | A declaration and definition
> sub NAME(PROTO) {BLOCK} | A prototyped declaration and definition

> Any arguments passed to a subroutine are passed by reference in the array @_. Therefore, the first argument will be $_[0], the second $_[1], and so on.

> >                         sub example
> >                         {
> >                            my $x=shift;
> >                            # now $x has a copy of the first argument
> >                            my $y=shift;
> >                            # now $y has a copy of the second argument
> >                         }

> The return value of a subroutine can be a list or a scalar, depending on the context in which the routine was called.

> Operator precedence and arity

> Precedence | Associativity | Arity | Precedence class
> --- | --- | --- | ---
> 23 | None | 0 | terms and leftward list operators
> 22 | Left | 2 | ->
> 21 | None | 1 | ++ --/td>
> 20 | Right | 2 | **
> 19 | Right | 1 | ! ~ \ and unary + -
> 18 | Left | 2 | =~ !~
> 17 | Left | 2 | * / % x
> 16 | Left | 2 | + - .
> 15 | Left | 2 | << >>
> 14 | Right | 0,1 | Named unary operators
> 13 | None | 2 | < > <= >= lt gt le ge
> 12 | None | 2 | == != <=> eq ne cmp
> 11 | Left | 2 | &
> 10 | Left | 2 | | ^
> 9 | Left | 2 | &&
> 8 | Left | 2 | ||
> 7 | None | 2 | .. ...
> 6 | Right | 3 | ?:
> 5 | Right | 2 | = **= += -= .= *= /= %= x= &= |= ^= <<= >>= &&= ||=
> 4 | Left | 2 | , =>
> 3 | Right | 0+ | Rightward list operators
> 2 | Right | 1 | not
> 1 | Left | 2 | and
> 0 | Left | 2 | or xor

> The terms and leftward list operators include variables, quote and quote-like operators, expressions in parentheses, and functions with parenthesized arguments.

> The named unary operators include the -X file tests and a number of "functions" that are really operators:

> -X (file tests) alarm caller chdir chroot cos defined delete do eval exists exit | gethostbyname getnetbyname getpgrp getprotobyname glob gmtime goto hex int lc lcfirst length | localtime lock log lstat my oct ord quotemeta rand readlink ref require | return rmdir scalar sin sleep sqrt srand stat uc ucfirst umask undef

> Array usage

> Given an array @a=('a','b','c','d'); then:

> command | result | returns, corresponds to
> --- | --- | ---
> push @a,'e'; | @a=('a','b','c','d','e') | 5 = new # of elements in array
> pop @a; | @a=('a','b','c') | 'd'
> unshift @a,'x'; | @a=('x', 'a','b','c','d') | 5 = new # of elements in array
> shift @a; | @a=('b','c','d') | 'a'
> $#a; | 3 | index of last element in array
> $a[0] | 'a' | first element of array
> @b=reverse @a; | @b=('d','c','b','a') | @a not changed
> $b=@a; | $b=4 | # of elements in array
> $b=scalar(@a); | $b=4 | # of elements in array
> push @a,('e','f','g'); | @a=('a','b','c','d','e','f','g') | 7 = new # of elements in array (this is the way to concatenate arrays)
> @b=@a[1,3]; | @b=('b','d') | @b is filled with the values of the given array slice (in the example, corresponding to elements 1 and 3 of the array @a)
> @b=@a[1..3]; | @b=('b','c','d') | @b is filled with the values of the given array slice (in the example, corresponding to elements 1 to 3 of the array @a)
> splice @a,1,2; | @a=('a','d') | two elements are removed from the array @a, starting from index 1
> splice @a,1,2,('z','y','x'); | @a=('a','z','y','x','d') | two elements are removed from the array @a, starting from index 1, and the given list is inserted in that place
> splice @a,3,0,('z','y','x'); | @a=('a','b','c','z','y','x','d') | no elements are removed from the array @a, and the given list is inserted starting at index 3
> map { $_=uc($_); } @a; | @a=('A','B','C','D') | the $_ variable is set as an alias for each element of @a, and the given block is executed

> Arrays/Lists as stacks

> Array and List operations

> operation | example
> --- | ---
> Pre-declaration | @daysofweek=("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
> Reading from files (one line = one element) | open(CONFIG,"filename.ext"); @configlines=<CONFIG>;
> Adding to end of list | push(@things,"keyboard");
> Adding to start of list | unshift(@things,"keyboard");
> Creating from string | @things=split(/,/,"keyboard,screen,mouse");
> Accessing elements by index | print "$things[0]\n"; # === keyboard print "$things[2]\n"; # === mouse
> Getting and removing first element | print shift(@things);
> Getting and removing last element | print pop(@things);
> Looping over elements | foreach $temp (@things) print "$temp\n";
> Transform to a string | $result=join(",",@things);
> To "pop" $N elements from the end of a @ARRAY | @POPPED=splice(@ARRAY,-$N);
> To "shift" $N elements from the beginning of a @ARRAY | @SHIFTED=splice(@ARRAY,0,$N);

> Hashes

> operation | example
> --- | ---
> Pre-declaration | %colors=( "door"=>"brown", "wall"=>"white", "roof"=>"red" ); %colors=( "door","brown", "wall","white", "roof","red" );
> Adding one item | $color{"ceiling"}="yellow";
> Accessing value by key | print $color{"wall"}; # === white
> Looping over elements | while(($key,$value) = each(%colors)) print "key=$key value=$value\n";
> Getting all keys | @keys=keys(%colors);
> Getting all values | @values=values(%colors);
> Deleting one item | delete($colors{"ceiling"});

> Quote constructs

> custumary | generic | meaning | interpolation | mnemonic
> --- | --- | --- | --- | ---
> ' ' | q// | Literal string | No | quote
> " " | qq// | Literal string | Yes | double quote
> ` ` | qx// | Command execution | Yes | quote execution
> () | qw// | Word list | No | quote words

> (s)printf reference

> format specs
> format | meaning | notes
> --- | --- | ---
> %% | percent sign |
> %c | chracter with the given code |
> %s | string |
> %d | signed decimal integer |
> %u | unsigned decimal integer |
> %o | unsigned octal integer |
> %x | unsigned hexadecimal integer |
> %e | floating point scientific notation number |
> %f | floating point fixed decimal number |
> %g | floating point in fixed decimal or scientific notation number |
> %X | unsigned hexadecimal upper-case integer |
> %E | floating point scientific notation upper-case number |
> %G | floating point in fixed decimal or scientific upper-case notation number |
> %b | binary unsigned integer |
> %p | pointer address in hexadecimal |
> %n | stores the number of characters writen so far into the next variable in the argument list |
> %i | same as %d | deprecated
> %D | same as %ld | deprecated
> %U | same as %lu | deprecated
> %O | same as %lo | deprecated
> %F | same as %f | deprecated
> flags insertable after %
> space | prefix positive number with a space |
> + | prefix positive number with a plus sign |
> - | left-justify in field |
> 0 | right-justify using zeros instead of spaces |
> # | prefix octal format with '0', hexadecimal with '0x' |
> number | maximum field width |
> * | as number, but value obtained from argument preceding the one of interest a negative value implies left justification |
> .number | digits after point in floating point numbers maximum length for strings minimum length for integer numbers |
> .* | as .number, but value obtained from argument preceding the one of interest |
> l | interpret the number as a C style long or unsigned long |
> h | interpret the number as a C style short or unsigned short |
> V | interpret the number as a Perl style integer | Perl special
> v | interpret string as a vector of integers, output as numbers separated by dots | Perl special see examples below
> *v | interpret string as a vector of integers, output as numbers separated by the string preceding the argument | Perl special see examples below

> Examples regarding the v flag:

> assuming $a='ABCD';
> command | result
> --- | ---
> printf "%vi\n",$a; | 65.66.67.68
> printf "%*vi\n",':',$a; | 65:66:67:68
> printf "%vb\n",$a; | 1000001.1000010.1000011.1000100

> References

> variable | referencing it | dereferencing | accessing an element | constructing
> --- | --- | --- | --- | ---
> $scalar | $ref=\$scalar | $$ref ${$ref} |  | $ref = \1234
> @list | $ref=\@list | @{$ref} | $$ref[3] ${$ref}[3] $ref->[3] | $ref = [1, 2, 3, 4]
> %hash | $ref=\%hash | %{$ref} | $$ref{"ceiling"} ${$ref}{"ceiling"} $ref->{"ceiling"} | $ref = { 'alfa' => 'beta', 'gama' => 'delta' }

> File tests

> File tests are in the format -X FILEHANDLE or -X FILENAME, where -X is one of the following tables

> uid/gid tests
> -r | File is readable by effective uid/gid
> -w | File is writable by effective uid/gid
> -x | File is executable by effective uid/gid
> -o | File is owned by effective uid
> -R | File is readable by real uid/gid
> -W | File is writable by real uid/gid
> -X | File is executable by real uid/gid
> -O | File is owned by real uid
> size tests
> -e | File exists
> -z | File has zero size
> -s | File has nonzero size (returns size)
> attribute tests
> -u | File has setuid bit set
> -g | File has setgid bit set
> -k | File has sticky bit set
> type tests
> -f | File is a plain file
> -d | File is a directory
> -l | File is a symbolic link
> -p | File is a named pipe (FIFO)
> -S | File is a socket
> -b | File is a block special file
> -c | File is a character special file
> -t | File handle is opened to a tty
> contents tests
> -T | File is a text file
> -B | File is a binary file (opposite of -T)
> age tests
> -M | Age of file in days when script started
> -A | Same for access time
> -C | Same for inode change time

> Net::SMTP

> This is an example of using the Net::SMTP module to send mail. The sender is sender@domain.com, the recipient is recipient@elsewhere.org and the SMTP server is mail.gateway.net. Note that the datasend() argument is a multiline string.

> > use Net::SMTP;
> > $smtp=Net::SMTP->new('mail.gateway.net');
> > $smtp->mail('sender@domain.com');
> > $smtp->to('recipient@elsewhere.org');
> > $smtp->data();
> > $smtp->datasend('From: "Example sender" <sender@domain.com>
> > To: "Example recipient" <recipient@elsewhere.org>
> > Subject: Example message using Net::SMTP
> > And this is text, must have a blank line before and after.
> > ');
> > $smtp->dataend();
> > $smtp->quit();

> DBD::mysql

> This is an example of using the DBD::mysql module to visit all records of a given table in a given database. The database is exdbf, the table is extable and the MySQL server server localhost.

> > use DBI;
> > $|=1; # forces immediate flush on output
> > $dsn = "DBI:mysql:exdbf;localhost";
> > $dbh = DBI->connect($dsn, 'username', 'password');
> > exit unless defined $dbh;
> > # use the four lines below if the query results in many rows
> > # or if you get 'out of memory' errors
> > # $query="SET SQL_BIG_TABLES=1";
> > # $cursor = $dbh->prepare( "$query" );
> > # $cursor->execute;
> > # $cursor->finish;
> > $query="select column1,column2 from extable";
> > $cursor = $dbh->prepare( "$query" );
> > $cursor->execute;
> > print "Number of fields:",$cursor->{'NUM_OF_FIELDS'},"\n";
> > while ( @row = $cursor->fetchrow )
> > {
> > ($col_1,$col_2)=@row;
> > print "==================\nColumn one: $col_1\nColumn two: $col_2\n";
> > }
> > $cursor->finish;
> > $dbh->disconnect;

> MD5 and LWP

> This is an example of using the MD5 and LWP::Simple modules to find the MD5 digest value for a given URL, which is also fetched.

> > use LWP::Simple;
> > use MD5;
> > $doc= get 'http://www.yahoo.com/index.html';
> > # now $doc contains the fetched page
> > print "Digest:",MD5->hexhash($doc),"\n";

> Net::FTP

> This is an example of using the Net::FTP module to get a file from a FTP server.

> > use Net::FTP;
> > $ftpserver='ftp.telepac.pt';
> > $branch='/pub/cpan/modules/by-module/Net';
> > $leaf='libnet-1.10.tar.gz';
> > $localname=$leaf;
> > print "Connecting to $ftpserver\n";
> > if($ftp=Net::FTP->new($ftpserver,Timeout => 30,Debug =>0,Hash => \*STDERR))
> > {
> > print "Connected to $ftpserver\nLogging in\n";
> > if($ftp->login('anonymous','root@system'))
> > {
> > print "Logged in\n";
> > print "Setting binary transfer mode\n";
> > $ftp->binary();
> > print "Changing remote directory\n";
> > if($ftp->cwd($branch))
> > {
> > print "Changed to $branch\nGetting the file\n";
> > if($ftp->get($leaf,$localname))
> > {
> > print "Success\n";
> > }
> > else
> > {
> > print "Failure\n";
> > }
> > }
> > }
> > $ftp->quit;
> > }
> > else
> > {
> > print "Can't connect to $ftpserver\n";
> > }

Last update: Wed, 2 Nov 2005 10:16:21 GMT | top