From: /usr/ceo on
l v wrote:
> Chris wrote:
> > DJ Stunks wrote:
> >
> >>Chris wrote:
> >>
> > Yeah, I'm grabbing the filename string from an XML file and the ' is in
> > the filename, essentially. If you check out my debug session (the one
> > trying to use Net::FTP) in the OP, you'll see that the 'FILENAME' is
> > being passed literally, as it should be. So no worries there.
> >
>
> The OP may want to verify the version of their Net::FTP is the highest
> avaiable. I once had some issues with Net::FTP, upgrading it corrected
> my problem.
>
> Mainframe file names are quite simple IMO.
>
> Here are the file name translations to unix (using
> usenet(a)DavidFilmer.com's example program):
>
> 1) a . (dot) is a /
> so DEPT.TFOO.BAR is DEPT/TFOO/BAR
>
> 2) if the file name is surrounded by single quotes, then that is the
> full file name.
> 'DEPT.TFOO.BAR' is equlivant to /DEPT/TFOO/BAR
>
> 3) if the file name is *not* surrounded by single quotes, then the
> login user name is prepended.
> DEPT.TFOO.BAR is equlivant to 'MYUSER.DEPT.TFOO.BAR' which is
> equlivant to /home/MYUSER/DEPT/TFOO/BAR
>
> 4) A mainframe file name can not begin with a digit. I think there are
> some other restrictions.
>
> Where it get confusing is that a file (dataset) on the mainframe can be
> of two types, 1) a sequential dataset, or 2) a partitioned dataset.
> You need to know which type you are dealing with.
>
> A sequential dataset is a normal every day file that you would use OPEN
> and CLOSE on. You use DEPT.TFOO.BAR to retrieve
>
> A partition dataset (PDS) contains many files within it. Consider this
> a directory. You retrieve the file using a file name like
> 'MYUSER.DEPT.TFOO.BAR(filename)' and need to do this for every file
> within the PDS you want to ftp.
>
> The following is an edited version of what I run, I hope I did not snip
> too much.
>
> use Net::FTP;
>
> my $jclLib = 'sysx.p.jcllib';
>
> ### logon and ftp spool file to mainframe.
> my $ftp = Net::FTP->new("$host", Debug => 0);
> $ftp->login("$acf2Id", "$acf2Pw") || fail("Could not login - $@");
> $ftp->site("lrecl=132 recfm=fb") || fail("Could not send site commands
> - $@");
> $ftp->put("$mvsFile.data", "'$mfFile'") || fail("Could not put
> $mvsFile.data, '$mfFile' - $@");
>
> # now get jcl
> $ftp->get("'$jclLib(sp12)'", "$fileName.bjcl.in") || fail("Could not
> get $jclLib(sp12 - $@");
>
> # now put the edited jcl on the mainframe.
> $ftp->site("lrecl=80 recfm=fb") || fail("Could not send site commands 2
> - $@");
> $ftp->put("$fileName.bjcl", "'tmp.foo.$mvsFile.bjcl'") || fail("Could
> not put $fileName.bjcl - $@");
>
> # now send the edited NDM jcl to the mainframe's JES queue to execute
> the JCL.
> $ftp->site("filetype=jes lrecl=80 recfm=fb") || fail("Could not send
> site commands to send JCL to JES - $@");
> $ftp->put("$fileName.jcl") || fail("Could not put $fileName.jcl - $@");
>
> # now end the ftp session.
> $ftp->quit || fail("Could not quit ftp session - $@");
>

Very handy and informative. I didn't expect to get that kind of help
here and this may help me resolve what issues I have.

-ceo

From: usenet on
/usr/ceo wrote:
> l v wrote:
> > [ an informative discussion of mainframe filenaming ]

> Very handy and informative.

I'll second that! I usually just guess around until something works!
It's good to have some actual understanding of what's going on.
Thanks!

--
http://DavidFilmer.com

From: Big and Blue on
Chris wrote:

> It would *appear* from using debug in a real FTP client
> and turning on Net::Cmd debugging that the real FTP client sends an
> 'EPSV' command just before each 'get' on a TSO dataset.

As it says, that says the connexion is going int to passive mode. So
instead of the server sending back the data on the ftp-data port it opens a
port, tells you what it is, waits for you to call it then sends the data
back on that. This setup came about to allow access through firewalls,
which wouldn't allow the external servers to open a connexion coming in, but
you (on the inside) can connect to what they've said is open.

> Trying to
> simulate this behavior using Net::FTP doesn't seem to do the job.

That's because all you ar edoing is sending is sending "PSV", which
isn't sufficient. The application has to handle what the response to this is.


> $ftp->quot( 'EPSV' ); # Doesn't seem to matter if I use this or not...

No - the local client needs to work on the response.


> Net::FTP=GLOB(0x87846d0)>>> EPSV
> Net::FTP=GLOB(0x87846d0)<<< 229 Entering Extended Passive Mode (|||1875|)

IIRC the rmeote side has now opened port 1875 and is waiting for you to
call it...

> Net::FTP=GLOB(0x87846d0)>>> PORT 172,17,4,47,4,80

...but you just tell it that it should contact port 80 (!!???) locally.

> Net::FTP=GLOB(0x87846d0)<<< 200 Port request OK.
> Net::FTP=GLOB(0x87846d0)>>> RETR 'FOO.SOX.COBOL(GEN1)'
> Net::FTP=GLOB(0x87846d0): Timeout at ./download-dbload-foo.pl line 69

Presumably there is a firewall in the way

> If anyone has any ideas, I've love to hear about them. I grow weary of
> IBM and Microsoft and their "implementation" of TCP/IP standards.

This isn't TCP/IP - it's FTP (totally different RFC and sits above TCP).
From what I can see its implemented perfectly - just that you aren't using
it correctly.

And it's not Perl either.



--
Just because I've written it doesn't mean that
either you or I have to believe it.
From: /usr/ceo on
Big and Blue wrote:
> Chris wrote:
>
> > It would *appear* from using debug in a real FTP client
> > and turning on Net::Cmd debugging that the real FTP client sends an
> > 'EPSV' command just before each 'get' on a TSO dataset.
>
> As it says, that says the connexion is going int to passive mode. So
> instead of the server sending back the data on the ftp-data port it opens a
> port, tells you what it is, waits for you to call it then sends the data
> back on that. This setup came about to allow access through firewalls,
> which wouldn't allow the external servers to open a connexion coming in, but
> you (on the inside) can connect to what they've said is open.
>
> > Trying to
> > simulate this behavior using Net::FTP doesn't seem to do the job.
>
> That's because all you ar edoing is sending is sending "PSV", which
> isn't sufficient. The application has to handle what the response to this is.
>
>
> > $ftp->quot( 'EPSV' ); # Doesn't seem to matter if I use this or not...
>
> No - the local client needs to work on the response.
>
>
> > Net::FTP=GLOB(0x87846d0)>>> EPSV
> > Net::FTP=GLOB(0x87846d0)<<< 229 Entering Extended Passive Mode (|||1875|)
>
> IIRC the rmeote side has now opened port 1875 and is waiting for you to
> call it...
>
> > Net::FTP=GLOB(0x87846d0)>>> PORT 172,17,4,47,4,80
>
> ...but you just tell it that it should contact port 80 (!!???) locally.
>
> > Net::FTP=GLOB(0x87846d0)<<< 200 Port request OK.
> > Net::FTP=GLOB(0x87846d0)>>> RETR 'FOO.SOX.COBOL(GEN1)'
> > Net::FTP=GLOB(0x87846d0): Timeout at ./download-dbload-foo.pl line 69
>
> Presumably there is a firewall in the way
>
> > If anyone has any ideas, I've love to hear about them. I grow weary of
> > IBM and Microsoft and their "implementation" of TCP/IP standards.
>
> This isn't TCP/IP - it's FTP (totally different RFC and sits above TCP).
> From what I can see its implemented perfectly - just that you aren't using
> it correctly.
>
> And it's not Perl either.

I beg to differ. I just tried this from a Windows machine, and IT
WORKED using Net::FTP. Same script, same everything. I did not get a
timeout. The details of what you shared above may be true, but I
expect when I use Net::FTP that it works the same way everywhere.
Either it should timeout in both places or it should work in both
places. And there is no firewall inbetween.

I'll have to look into more of what you've discussed above. I'm aware
of FTP's place in the TCP/IP scheme of things. "TCP/IP" is often used
to discuss those things which utilize that stack. Microsoft and IBM's
implementation of TCP/IP standards be it the underlying protocols (TCP,
UDP, etc), or the general suite of the various RFC implementations as
well as HTTP standards has been suspect at best.

-ceo

From: Big and Blue on
/usr/ceo wrote:
>
> I beg to differ.

That's your right, but you are the one complaining about IBM and
Microsoft's implementation of IP, TCP and FTP (not sure which) and that is
not Perl.

> I just tried this from a Windows machine, and IT
> WORKED using Net::FTP. Same script, same everything.

No - a totally different environment, with different environment
variables set.

> I did not get a
> timeout.

Then I suggest you get some network snooping software (ethereal?) to
find out what is (not) going on at the network level.

>
> I'll have to look into more of what you've discussed above.

In which case bear in mind that this comment:

>> Net::FTP=GLOB(0x87846d0)>>> PORT 172,17,4,47,4,80
>>
>> ...but you just tell it that it should contact port 80 (!!???) locally.

is wrong - it's actually port 1104 (4*256 + 80).

> Microsoft and IBM's
> implementation of TCP/IP standards be it the underlying protocols (TCP,
> UDP, etc), or the general suite of the various RFC implementations as
> well as HTTP standards has been suspect at best.

I've never hgad a problem with Microsoft's TCP/IP (apart from speed). I
agree that its HTTP implementation is pretty awful though. e.g., use IE to
connect to Web host my1.server.com:1234, which redirects to a URI on
my1.server.com:4321 and you'll find that the Host header on the redirect
call says my1.server.com:1234 (ie: still the original one before redirect).
If the server hostname changes all is OK, so I hate to think what the code
looks like that gets this wrong. But you come to expect that of Microsoft.


--
Just because I've written it doesn't mean that
either you or I have to believe it.