ksh broken ?

  • Follow


Should this work?

  #! /bin/ksh

  printf "%s\n" $(
        for item in CDS EM
        do
                case $item in
                CDS)
                        echo this
                        ;;
                EM)
                        echo that
                        ;;
                esac
        done )

because it gives:

  caser[3]: syntax error at line 3 : `case' unmatched

on both Solaris 8 and Solaris 10 while the "old" format:

  #! /bin/ksh

  printf "%s\n" `
        for item in CDS EM
        do
                case $item in
                CDS)
                        echo this
                        ;;
                EM)
                        echo that
                        ;;
                esac
        done `

works correctly.

Is there something wrong with the Korn shell, or have I missed something
significant?

John Howells
0
Reply John 6/14/2005 7:26:24 AM

> Should this work?

As far as I can tell your script won't work. $() stands for command
substitution which is commonly used for its output. Consult 'man
ksh(1)', header "Command Substitution".

Since your script section will only produce "this" or "that" and since
those are not valid commands (unless you aliases these ;-)) you should
just skip using $() in this case.

-- 
Groetjes, Peter

..\\ PGP/GPG key: http://www.catslair.org/pubkey.asc
0
Reply Lion 6/14/2005 11:14:44 AM


John Howells <John.Howells@marconi.com> writes:
> Should this work?
> 
>   #! /bin/ksh
> 
>   printf "%s\n" $(
                  ^^ <-- this ...
>         for item in CDS EM
>         do
>                 case $item in
>                 CDS)
                     ^ <-- ... matches this.

-- 
James Carlson, KISS Network                    <james.d.carlson@sun.com>
Sun Microsystems / 1 Network Drive         71.234W   Vox +1 781 442 2084
MS UBUR02-212 / Burlington MA 01803-2757   42.497N   Fax +1 781 442 1677
0
Reply James 6/14/2005 1:34:36 PM


Lion-O wrote:
> 
> > Should this work?
> 
> As far as I can tell your script won't work. $() stands for command
> substitution which is commonly used for its output. Consult 'man
> ksh(1)', header "Command Substitution".
> 
> Since your script section will only produce "this" or "that" and since
> those are not valid commands (unless you aliases these ;-)) you should
> just skip using $() in this case.

I suggest you should check "man ksh", where one of the examples is:

  echo $(echo '\$x')

and try and understand the section on Command Substitution.

The output of $() does not need to be valid commands, but merely forms "part or
all of a word", where "word" has the specific meaning used by the shell, defined
earlier in the man page. It provides output that can be used by other commands,
in this case the parameters to the printf. For example, the form:

  #! /bin/ksh

  printf "%s\n" $(
        for item in this that
        do
                echo ${item}
        done )

works fine. It is only when the "case" is introduced that things start to go
wrong, but only for the newer $() form of Command Substitution, not the
"archaic" `` form.

John Howells
0
Reply John 6/14/2005 2:48:38 PM


James Carlson wrote:
> 
> John Howells <John.Howells@marconi.com> writes:
> > Should this work?
> >
> >   #! /bin/ksh
> >
> >   printf "%s\n" $(
>                   ^^ <-- this ...
> >         for item in CDS EM
> >         do
> >                 case $item in
> >                 CDS)
>                      ^ <-- ... matches this.

But should it? Should it not be parsing enough of what is going on to recognize
the elements that make up a case construct? It certainly should to meet the
condition on the man page that:

     With the $(command) form, all characters following the  open
     parenthesis  to  the matching closing parenthesis constitute
     the command. Any valid shell script can be used for command,
     except:

        o  A script consisting solely  of  redirections  produces
           unspecified results.

        o  See the  restriction  on  single  subshells  described
           below.

as the "except" clause makes no mention of the case statement not being allowed
as "Any valid shell script". If the definition of "the matching closing
parenthesis" includes that of a case statement then at the very least it should
be noted as an additional exception!

John Howells
0
Reply John 6/14/2005 3:03:51 PM

John Howells wrote:
> Should this work?
> 
>   #! /bin/ksh
> 
>   printf "%s\n" $(
>         for item in CDS EM
>         do
>                 case $item in
>                 CDS)
>                         echo this
>                         ;;
>                 EM)
>                         echo that
>                         ;;
>                 esac
>         done )
> 
> because it gives:
> 
>   caser[3]: syntax error at line 3 : `case' unmatched
> 
> on both Solaris 8 and Solaris 10 while the "old" format:
> 
>   #! /bin/ksh
> 
>   printf "%s\n" `
>         for item in CDS EM
>         do
>                 case $item in
>                 CDS)
>                         echo this
>                         ;;
>                 EM)
>                         echo that
>                         ;;
>                 esac
>         done `
> 
> works correctly.
> 
> Is there something wrong with the Korn shell, or have I missed something
> significant?
> 
> John Howells

The construct you are trying to use works correctly
in ksh93, but not in ksh88.  The ` .... ` is deprecated,
but perhaps prematurely with respect to ksh88. I've
wondered (out loud, to SUN) in the past why, if they
can ship ksh93 (/usr/dt/bin/dtksh) with a bunch of
GUI support (see below) can't they ship ksh93?

% /bin/ksh /tmp/caser
/tmp/caser: syntax error at line 1 : `case' unmatched
% /usr/dt/bin/dtksh /tmp/caser
this
that

-------------
% /usr/local/bin/ksh          #AST
   Version M 1993-12-28 o+

% /bin/ksh
   Version M-11/16/88i

% /usr/dt/bin/dtksh
   Version M-12/28/93d

% ldd /usr/dt/bin/dtksh
         libDtHelp.so.1 =>        /usr/dt/lib/libDtHelp.so.1
         libDtWidget.so.2 =>      /usr/dt/lib/libDtWidget.so.2
         libDtSvc.so.1 =>         /usr/dt/lib/libDtSvc.so.1
         libtt.so.2 =>    /usr/dt/lib/libtt.so.2
         libXm.so.4 =>    /usr/dt/lib/libXm.so.4
         libXt.so.4 =>    /usr/openwin/lib/libXt.so.4
         libX11.so.4 =>   /usr/openwin/lib/libX11.so.4
         libm.so.2 =>     /lib/libm.so.2
         libgen.so.1 =>   /lib/libgen.so.1
         libdl.so.1 =>    /lib/libdl.so.1
         libsocket.so.1 =>        /lib/libsocket.so.1
         libc.so.1 =>     /lib/libc.so.1
         libCrun.so.1 =>  /usr/lib/libCrun.so.1
         libnsl.so.1 =>   /lib/libnsl.so.1
         libXext.so.0 =>  /usr/openwin/lib/libXext.so.0
         libSM.so.6 =>    /usr/openwin/lib/libSM.so.6
         libICE.so.6 =>   /usr/openwin/lib/libICE.so.6
         libmp.so.2 =>    /lib/libmp.so.2
         libmd5.so.1 =>   /lib/libmd5.so.1
         libscf.so.1 =>   /lib/libscf.so.1
         libdoor.so.1 =>  /lib/libdoor.so.1
         libuutil.so.1 =>         /lib/libuutil.so.1


% ldd /bin/ksh
         libsocket.so.1 =>        /lib/libsocket.so.1
         libsecdb.so.1 =>         /lib/libsecdb.so.1
         libc.so.1 =>     /lib/libc.so.1
         libnsl.so.1 =>   /lib/libnsl.so.1
         libcmd.so.1 =>   /lib/libcmd.so.1
         libmp.so.2 =>    /lib/libmp.so.2
         libmd5.so.1 =>   /lib/libmd5.so.1
         libscf.so.1 =>   /lib/libscf.so.1
         libdoor.so.1 =>  /lib/libdoor.so.1
         libuutil.so.1 =>         /lib/libuutil.so.1
         libm.so.2 =>     /lib/libm.so.2
0
Reply Robert 6/14/2005 3:14:22 PM

In article <leqdnUxoUOLMaTPfRVn-gw@speakeasy.net>,
	Robert Lawhead <news0000.5.unixguru@spamgourmet.com> writes:
[...]
> The construct you are trying to use works correctly
> in ksh93, but not in ksh88.  The ` .... ` is deprecated,
> but perhaps prematurely with respect to ksh88. I've
> wondered (out loud, to SUN) in the past why, if they
> can ship ksh93 (/usr/dt/bin/dtksh) with a bunch of
> GUI support (see below) can't they ship ksh93?
[...]

They can't ship ksh93 as /usr/bin/ksh, because that wouldn't be 100.00%
compatible.  The could ship ksh93 as something else (either as ksh93 or in
some other directory).  I don't recall reading whether there's an RFE for
that or not, but I'd sure like to think so.

FYI, AT&T opened up ksh; start at http://www.kornshell.com/ and follow
the download link..  The build procedure is like nothing else (outside of
the other stuff in the same bundle of tools), and it may be an uphill
battle.  No, I don't have notes...

-- 
mailto:rlhamil@smart.net  http://www.smart.net/~rlhamil

Lasik/PRK theme music:
    "In the Hall of the Mountain King", from "Peer Gynt"
0
Reply Richard 6/14/2005 4:13:25 PM

Richard L. Hamilton wrote:
> In article <leqdnUxoUOLMaTPfRVn-gw@speakeasy.net>,
> 	Robert Lawhead <news0000.5.unixguru@spamgourmet.com> writes:
> [...]
> 
>>The construct you are trying to use works correctly
>>in ksh93, but not in ksh88.  The ` .... ` is deprecated,
>>but perhaps prematurely with respect to ksh88. I've
>>wondered (out loud, to SUN) in the past why, if they
>>can ship ksh93 (/usr/dt/bin/dtksh) with a bunch of
>>GUI support (see below) can't they ship ksh93?
> 
> [...]
> 
> They can't ship ksh93 as /usr/bin/ksh, because that wouldn't be 100.00%
> compatible.  The could ship ksh93 as something else (either as ksh93 or in
> some other directory).  I don't recall reading whether there's an RFE for
> that or not, but I'd sure like to think so.
> 
> FYI, AT&T opened up ksh; start at http://www.kornshell.com/ and follow
> the download link..  The build procedure is like nothing else (outside of
> the other stuff in the same bundle of tools), and it may be an uphill
> battle.  No, I don't have notes...
> 
Can you provide examples of functionality in ksh88 that is absent
in ksh93?  None spring to my mind... compatible != identical
0
Reply Robert 6/14/2005 4:51:44 PM

Richard L. Hamilton wrote:
> In article <leqdnUxoUOLMaTPfRVn-gw@speakeasy.net>,
> 	Robert Lawhead <news0000.5.unixguru@spamgourmet.com> writes:
> [...]
> 
>>The construct you are trying to use works correctly
>>in ksh93, but not in ksh88.  The ` .... ` is deprecated,
>>but perhaps prematurely with respect to ksh88. I've
>>wondered (out loud, to SUN) in the past why, if they
>>can ship ksh93 (/usr/dt/bin/dtksh) with a bunch of
>>GUI support (see below) can't they ship ksh93?
> 
> [...]
> 
> They can't ship ksh93 as /usr/bin/ksh, because that wouldn't be 100.00%
> compatible.  The could ship ksh93 as something else (either as ksh93 or in
> some other directory).  I don't recall reading whether there's an RFE for
> that or not, but I'd sure like to think so.

My RFE was in conversation with developers at LISA; most recently
in a Solaris 10 BOF in Atlanta 2004.

> FYI, AT&T opened up ksh; start at http://www.kornshell.com/ and follow
> the download link..  The build procedure is like nothing else (outside of
> the other stuff in the same bundle of tools), and it may be an uphill
> battle.  No, I don't have notes...
>

Been there, done that... but your note prompted me to check the site
where I noticed "o+" which I build some time ago has been superseded
by "q+".
0
Reply Robert 6/14/2005 5:04:44 PM

John Howells wrote:
> Should this work?
> 
>   #! /bin/ksh
> 
>   printf "%s\n" $(
>         for item in CDS EM
>         do
>                 case $item in
>                 CDS)
>                         echo this
>                         ;;
>                 EM)
>                         echo that
>                         ;;
>                 esac
>         done )
> 
> because it gives:
> 
>   caser[3]: syntax error at line 3 : `case' unmatched
> 
> on both Solaris 8 and Solaris 10 while the "old" format:
> 
>   #! /bin/ksh
> 
>   printf "%s\n" `
>         for item in CDS EM
>         do
>                 case $item in
>                 CDS)
>                         echo this
>                         ;;
>                 EM)
>                         echo that
>                         ;;
>                 esac
>         done `
> 
> works correctly.
> 
> Is there something wrong with the Korn shell, or have I missed something
> significant?
> 
> John Howells

You indeed missed the proper ksh syntax for case patterns.

Here's the correct way:

#! /bin/ksh

printf "%s\n" $(
for item in CDS EM
do
   case $item in
   (CDS)
       echo this
       ;;
   (EM)
     echo that
     ;;
   esac
done )

Jean-Louis
0
Reply Jean 6/14/2005 8:30:26 PM

John Howells wrote:
> 
> James Carlson wrote:
> 
>>John Howells <John.Howells@marconi.com> writes:
>>
>>>Should this work?
>>>
>>>  #! /bin/ksh
>>>
>>>  printf "%s\n" $(
>>
>>                  ^^ <-- this ...
>>
>>>        for item in CDS EM
>>>        do
>>>                case $item in
>>>                CDS)
>>
>>                     ^ <-- ... matches this.
> 
> 
> But should it? Should it not be parsing enough of what is going on to recognize
> the elements that make up a case construct?

It is definitely possible to build a parser that does what you are
saying ksh should be doing.

> It certainly should to meet the
> condition on the man page that:
> 
>      With the $(command) form, all characters following the  open
>      parenthesis  to  the matching closing parenthesis constitute
>      the command. Any valid shell script can be used for command,

I suppose it would depend on what "the matching closing parenthesis"
means.  Personally, I would interpret it like you do, but a case could
be made for interpreting it strictly according to parenthesis that
match the opening one in "$(" and not according to the regular
shell syntax.

Still, if it's true what someone else said that ksh93 handles this
how you'd expect and ksh88 doesn't, then it would seem that this
is in fact a bug in ksh.

For what it's worth, I think you should be able to always get around
the `` construct's inability to nest by placing each level inside a
function.  (And, I think, because of the shell's scoping, you should
have access to the same variable values that you would if you placed
the code inline instead of in a function.)

   - Logan
0
Reply Logan 6/15/2005 6:45:36 AM

Jean-Louis Liagre wrote:
> You indeed missed the proper ksh syntax for case patterns.
> 
> Here's the correct way:
> 
> #! /bin/ksh
> 
> printf "%s\n" $(
> for item in CDS EM
> do
>   case $item in
>   (CDS)
>       echo this
>       ;;
>   (EM)
>     echo that
>     ;;
>   esac
> done )

Interesting.  I didn't know you could have both an opening and
closing parenthesis on a case statement's patterns in ksh.

However, it would appear that if the original poster missed
that syntax, it could be because the manual page for ksh
(at least on Solaris 8) also misses that syntax.  It says:

	case word in [ pattern [ | pattern ] ) list ;; ] ... esac

Note the absence of an opening parenthesis.

   - Logan
0
Reply Logan 6/15/2005 6:50:34 AM


Jean-Louis Liagre wrote:

> You indeed missed the proper ksh syntax for case patterns.
> 
> Here's the correct way:
> 
> #! /bin/ksh
> 
> printf "%s\n" $(
> for item in CDS EM
> do
>    case $item in
>    (CDS)
>        echo this
>        ;;
>    (EM)
>      echo that
>      ;;
>    esac
> done )
> 
> Jean-Louis

I am unfamiliar with this definition of "proper". From "man case" on Solaris 8:

  ksh
     case word  in  [  pattern  [  |  pattern  ]  )  actions   ;;
     ... ]  esac

and

  ksh
     STOPLIGHT=green
     case $STOPLIGHT in
                    red) echo "STOP" ;;
                    orange)   echo "Go with caution; prepare to stop" ;;
                    green)    echo "you may GO" ;;
                    blue|brown)    echo "invalid stoplight colors" ;;
     esac

and from "man ksh" on Solaris 8 and Solaris 10:

     case word in [ pattern [ | pattern ] ) list ;; ] ... esac
           A case command executes the list associated  with  the
           first  pattern that matches word. The form of the pat-
           terns is the same as that used for  file-name  genera-
           tion (see File Name Generation below).

in none of which do I see am opening bracket for the pattern list, though it
does work! OTOH, "man bash" on Solaris 8 gives:

     case word in [ ( pattern [ | pattern ] ... ) list ;; ] ... esac

but does not make the opening bracket optional, which it usually is, or indicate
when it is mandatory, which is the situation seen in my script.

Again, perhaps the various man pages need to be updated. One should not have to
try throwing in additional syntax elements that contradict the supplied
definitions in the hope of finding something that works.

John Howells
0
Reply John 6/15/2005 7:13:53 AM


Robert Lawhead wrote:

> The construct you are trying to use works correctly
> in ksh93, but not in ksh88.  The ` .... ` is deprecated,
> but perhaps prematurely with respect to ksh88. 

Apparently! Now all we need is updates for the various man pages. Thanks.

John Howells
0
Reply John 6/15/2005 7:16:17 AM


John Howells wrote:

> ... OTOH, "man bash" on Solaris 8 gives:
> 
>      case word in [ ( pattern [ | pattern ] ... ) list ;; ] ... esac
> 
> but does not make the opening bracket optional, which it usually is, or indicate
> when it is mandatory, which is the situation seen in my script.

P.S. On Solaris 10 the opening bracket is defined as optional.

John Howells
0
Reply John 6/15/2005 7:40:54 AM

>> Since your script section will only produce "this" or "that" and
>> since those are not valid commands (unless you aliases these ;-)) you
>> should just skip using $() in this case.
>
> I suggest you should check "man ksh", where one of the examples is:
>
>   echo $(echo '\$x')
>
> and try and understand the section on Command Substitution.

And that example tells you that the output of this command is "\$x" (no
""). The command produces "\$x" which is then printed by the use of
'echo'. When reading the example I basicly focussed on its intention;
the display of inconsistant behaviour.

While I do understand that you can use it to nest command sections my
approach in this case would be moving the case ... esac out of the $()
and providing the printf command more than one time. Naturally I do see
the point in using command substitution where redudancy is concerned,
and I'm also quite curious since up untill now I haven't used Command
Substitution in this particular way.

> It is only when the "case" is introduced that things start to go
> wrong, but only for the newer $() form of Command Substitution, not
> the "archaic" `` form.

I have tried this myself and see what you mean. Seems I'm jumping in a
bit late but thats the nature of timezones.


Thanks for your diverse reply, this is a very interesting and somewhat
new approach to me.

-- 
Groetjes, Peter

..\\ PGP/GPG key: http://www.catslair.org/pubkey.asc
0
Reply Lion 6/15/2005 11:56:24 AM

John Howells wrote:
> 
> Jean-Louis Liagre wrote:
> 
> 
>>You indeed missed the proper ksh syntax for case patterns.
>>
>>Here's the correct way:
>>
>>#! /bin/ksh
>>
>>printf "%s\n" $(
>>for item in CDS EM
>>do
>>   case $item in
>>   (CDS)
>>       echo this
>>       ;;
>>   (EM)
>>     echo that
>>     ;;
>>   esac
>>done )
>>
>>Jean-Louis
> 
> 
> I am unfamiliar with this definition of "proper". From "man case" on Solaris 8:
> 
>   ksh
>      case word  in  [  pattern  [  |  pattern  ]  )  actions   ;;
>      ... ]  esac
> 
> and
> 
>   ksh
>      STOPLIGHT=green
>      case $STOPLIGHT in
>                     red) echo "STOP" ;;
>                     orange)   echo "Go with caution; prepare to stop" ;;
>                     green)    echo "you may GO" ;;
>                     blue|brown)    echo "invalid stoplight colors" ;;
>      esac
> 
> and from "man ksh" on Solaris 8 and Solaris 10:
> 
>      case word in [ pattern [ | pattern ] ) list ;; ] ... esac
>            A case command executes the list associated  with  the
>            first  pattern that matches word. The form of the pat-
>            terns is the same as that used for  file-name  genera-
>            tion (see File Name Generation below).
> 
> in none of which do I see am opening bracket for the pattern list, though it
> does work! OTOH, "man bash" on Solaris 8 gives:
> 
>      case word in [ ( pattern [ | pattern ] ... ) list ;; ] ... esac
> 
> but does not make the opening bracket optional, which it usually is, or indicate
> when it is mandatory, which is the situation seen in my script.
> 
> Again, perhaps the various man pages need to be updated. One should not have to
> try throwing in additional syntax elements that contradict the supplied
> definitions in the hope of finding something that works.
> 
> John Howells

Sorry for unproperly using the world "proper" ...

I was sure it was documented, my mistake for not having checked the manual page
before posting.

As your script pointed out, unbalanced brackets are source of errors,
so it would be certainly better to have this "(pattern)" syntax being the
recommended one, and have the old unbalanced one kept only for compatibility
with old bourne shell scripts, which would use the `command` syntax and not
the $(command) one.

The manual page should definitely be fixed.

Jean-Louis
0
Reply Jean 6/15/2005 10:53:51 PM

In article <jcOdnX5_T468ljLfRVn-vw@speakeasy.net>,
	Robert Lawhead <news0000.5.unixguru@spamgourmet.com> writes:
> Richard L. Hamilton wrote:
[...]
> Can you provide examples of functionality in ksh88 that is absent
> in ksh93?  None spring to my mind... compatible != identical

Not so much absent as different enough to have the potential of breaking
existing scripts.  See the file COMPATIBILITY within the ksh93 source
distro for known examples of usages that could cause problems.

Any existing script depending on the ksh88 behavior where the ksh93
behavior was different could well fail or worse, produce unexpected
results.

One could argue that Sun ought to rename ksh to ksh88, add ksh93, and
add a ksh -> ksh88 symlink which would be treated as 
something that might be modified by an installation.  And that Sun
ought to test any existing ksh scripts they have for correct behavior
on both ksh88 and ksh93, update any ksh88-dependent ones to run on ksh93,
and modify those to explicitly point to /usr/bin/ksh93 instead.  That
would clearly make it a customer responsibility to choose whether the
default ksh was the completely unsurprising ksh88 or the superior ksh93.

But that's a lot of work for very modest benefit, compared to just having
two different names or directories for the two versions.

-- 
mailto:rlhamil@smart.net  http://www.smart.net/~rlhamil

Lasik/PRK theme music:
    "In the Hall of the Mountain King", from "Peer Gynt"
0
Reply Richard 6/16/2005 7:02:07 PM

Richard.L.Hamilton@mindwarp.smart.net (Richard L. Hamilton) writes in comp.unix.solaris:
|They can't ship ksh93 as /usr/bin/ksh, because that wouldn't be 100.00%
|compatible.  The could ship ksh93 as something else (either as ksh93 or in
|some other directory).  I don't recall reading whether there's an RFE for
|that or not, but I'd sure like to think so.

http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4113420

-- 
________________________________________________________________________
Alan Coopersmith * alanc@alum.calberkeley.org * Alan.Coopersmith@Sun.COM
 http://www.csua.berkeley.edu/~alanc/   *   http://blogs.sun.com/alanc/
  Working for, but definitely not speaking for, Sun Microsystems, Inc.
0
Reply Alan 6/18/2005 4:44:34 AM

In article <d908ri$ngd$1@agate.berkeley.edu>,
	Alan Coopersmith <alanc@alum.calberkeley.org> writes:
> Richard.L.Hamilton@mindwarp.smart.net (Richard L. Hamilton) writes in comp.unix.solaris:
>|They can't ship ksh93 as /usr/bin/ksh, because that wouldn't be 100.00%
>|compatible.  The could ship ksh93 as something else (either as ksh93 or in
>|some other directory).  I don't recall reading whether there's an RFE for
>|that or not, but I'd sure like to think so.
> 
> http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4113420

And regarding the workaround (/usr/dt/bin/dtksh), according to prior
comments here, it's based on an old and broken version of ksh93.

It would be Very Nice Indeed if the Open Group members could be presuaded
to open up CDE, clearing the way for individual companies to open up their
distros of it; it can't be making much anyway (with new work most places
going into GNOME or KDE) and it would let those who want to continue
using it share more directly in the cost of bringing it more up to date.
However, I'd like to see the x-printing support functions of Motif that
are missing from /usr/dt/lib/libXm.so.4 put back, and perhaps some of the
CDE 2.x x-print support scripts integrated into Sun CDE 1.x before it
totally whithers, regardless.

-- 
mailto:rlhamil@smart.net  http://www.smart.net/~rlhamil

Lasik/PRK theme music:
    "In the Hall of the Mountain King", from "Peer Gynt"
0
Reply Richard 6/19/2005 8:39:47 AM

19 Replies
293 Views

(page loaded in 0.273 seconds)

Similiar Articles:


















7/11/2012 4:42:44 PM


Reply: