Can't get SFTP routine to work

47 views
Skip to first unread message

Rich Brim

unread,
Sep 16, 2013, 4:43:02 PM9/16/13
to InterSy...@googlegroups.com
Hi everyone, I am working on an automated SFTP and there isn't much documentation on it.

Here is what I have. I am not understanding the Dir command and how to process.

    SERVER='ftp.testing.com'
    USER=transferuser'
    PASSWORD='xxxxxxxxx'
    PORT=22
    PATH='/mydir'
    FTP="%Net.SSH.Session"->%New()
    FTP->Connect(SERVER)
    FTP->AuthenticateWithUsername(
USER,PASSWORD)
    FTP->OpenSFTP(SFTP)
*** I believe it's working up to this point. I am trying to get a list of files in the directory but I get a unknown variable error for FL
    SFTP->Dir(PATH,FL)       **** FL is supposed to be a $List.
    CRT $LIST(FL)
    SFTP->CloseSFTP()

Here is some code  that I found in system files.

ClassMethod Test(host As %String, username As %String, password As %String, dir As %String = "/etc") As %Status
{
    Set = ##class(%Net.SSH.Session).%New()
    Set sc = s.Connect(host)
    Quit:$$$ISERR(sc) sc
    Set sc = s.AuthenticateWithUsername(username,password)
    Quit:$$$ISERR(sc) sc
    Set sc = s.OpenSFTP(.t)
    Quit:$$$ISERR(sc) sc
    Set sc = t.Dir(dir,.files)
    Quit:$$$ISERR(sc) sc
    
    // Determine the length of the longest file
    Set i="",l=0
    For {
        Set = $O(files(i))
        Quit:i=""
        Set fn=$LG(files(i),1)
        Set:$L(fn)>l=$L(fn)
    }
    
    Set l=l+2
    Write "Name",?l,"Size",?(l+10),"Ty",?(l+14),"Perm",?(l+24),"UID",?(l+30),"GID",!
    Write $TR($J("",l+36)," ","="),!
    
    // Dump out the directory contents, note that file times are relative to UTC time.
    For {
        Set = $O(files(i))
        Quit:i=""
        Write $LG(files(i),1) // Filename
        Write ?l,$J($LG(files(i),2),8) // Size
        Write ?(l+10),$LG(files(i),3) // Type
        Write ?(l+14),..Permissions2Text($LG(files(i),4)) // Permissions
        Write ?(l+24),$LG(files(i),5) // UID
        Write ?(l+30),$LG(files(i),6) // GID
        //Write !,?20,$ZDT(..UTCFileTime2H($LG(files(i),7)),3)," UTC" // Last Access Time
        //Write !,?20,$ZDT(..UTCFileTime2H($LG(files(i),8)),3)," UTC" // Last Modification Time
        Write !
    }
    
    Quit $$$OK
}

Michael Cohen

unread,
Sep 16, 2013, 5:48:01 PM9/16/13
to InterSy...@googlegroups.com

Perhaps you need to initialize FL, and, on older releases, pass it as a reference.

 

Else you might use TRY/CATCH to catch the error (if it is from Caché).  This example illustrates how to display the error.

 

CRT "THIS WILL WORK"

TRY

   CRT "THE NEXT LINE WILL FAIL"

   X="CLASSDOESNOTEXIST"->%New()

   CRT "WON'T GET HERE"

CATCH ERR

   CRT "CAUGHT THE ERROR"

   CRT ERR->Name

   CRT ERR->Location

   CRT "OR ALTERNATIVELY:"

   STATUS=ERR->AsStatus()

   "%SYSTEM.Status"->DisplayError(STATUS)

   CRT

END TRY

--
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
---
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to InterSystems-...@googlegroups.com.
To post to this group, send email to InterSy...@googlegroups.com.
Visit this group at http://groups.google.com/group/InterSystems-MV.
For more options, visit https://groups.google.com/groups/opt_out.

Rich Brim

unread,
Sep 16, 2013, 6:35:50 PM9/16/13
to InterSy...@googlegroups.com

thanks, Michael, I added try/catch code but there doesn't appear to be any error. There just isn't any results in "contents" on return.

    FTP->Connect(SERVER)
    FTP->AuthenticateWithUsername(USER,PASSWORD)
    FTP->OpenSFTP(SFTP)
    contents=$LISTBUILD("TEST")
    try
    crt 'get dir'
    SFTP->Dir(PATH,contents)
    catch err
    crt 'n':err->Name
    crt 'l':err->Location
    crt 'a':err->AsStatus()
    "%SYSTEM.Status"->DisplayError(STATUS)
    end try
    CRT $LIST(contents)
    SFTP->CloseSFTP()

output

RUN BP FTP.TEST
get dir
TEST

Edward Clark

unread,
Sep 16, 2013, 6:42:40 PM9/16/13
to InterSy...@googlegroups.com
The second argument to dir returns an array of $lists. For example:
 
    SERVER='ftp.somewhere.com'
    FTP="%Net.SSH.Session"->%New()
    st=FTP->Connect(SERVER)
    if st#1 then stopm "connect failed: ":$SYSTEM.Status->GetErrorText(st)
    st=FTP->AuthenticateWithUsername("user","password")
    if st#1 then stopm "authentication failed: ":$SYSTEM.Status->GetErrorText(st)
    st=FTP->OpenSFTP(SFTP)
    if st#1 then stopm "open failed: ":$SYSTEM.Status->GetErrorText(st)
    st=SFTP->Dir("/usr",%zFL)
    if st#1 then stopm "dir request failed failed: ":$SYSTEM.Status->GetErrorText(st)
    $xecute "zwrite %zFL"
    SFTP->CloseSFTP()
 
outputs something like:
 %zFL(0)=$lb("lib",4096,"D",16749,0,0,1378799188,1315336988)
%zFL(1)=$lb("libexec",4096,"D",16877,0,0,1378799188,1315413095)
%zFL(2)=$lb("share",4096,"D",16877,0,0,1368750176,1316192110)
%zFL(3)=$lb("..",4096,"D",16749,0,0,1379368850,1364647396)
%zFL(4)=$lb("lib64",36864,"D",16749,0,0,1378799189,1352536774)
%zFL(5)=$lb("src",4096,"D",16877,0,0,1368750177,1315336640)
%zFL(6)=$lb("sbin",12288,"D",16749,0,0,1378799187,1352536774)
%zFL(7)=$lb(".",4096,"D",16877,0,0,1379369820,1316099167)
%zFL(8)=$lb("local",4096,"D",16877,0,0,1368750177,1315336639)
%zFL(9)=$lb("games",4096,"D",16877,0,0,1378799187,1259933605)
%zFL(10)=$lb("bin",36864,"D",16749,0,0,1378799187,1328626987)
%zFL(11)=$lb("etc",4096,"D",16877,0,0,1368750177,1259933605)
%zFL(12)=$lb("oper",4096,"D",16877,0,0,1379304002,1379304002)
%zFL(13)=$lb("users.tar",255621120,"F",33188,0,0,1315927201,1315927339)
%zFL(14)=$lb("include",4096,"D",16877,0,0,1368750177,1315336960)
%zFL(15)=$lb("tmp",10,"L",41471,0,0,1379318406,1315336640)
%zFL(16)=$lb("users",4096,"D",16877,0,0,1378400950,1279118602)
 
I used a %variable for the argument so that I could pass it to $xecute and use ZWRITE to dump it with. Note also that I saved and tested the return values for all the method calls--there's potentially a lot of information in the status results when things go wrong.
 
You get a complaint that FL is unassigned because the root node of the array isn't set. Often, arrays are returned with the root node set to the count of elements, but in this case the index of the elements isn't a line count--it's the position count from the remote directory, and may not be sequential. To traverse this array you will need to use $order. For example:
 
dim FL()
st=SFTP->Dir("/usr",FL)
if st#1 then stopm "dir request failed failed: ":$SYSTEM.Status->GetErrorText(st)
idx=''
loop
  idx=$order(FL(idx))
until idx='' do
  crt idx,$list(FL(idx))
repeat
SFTP->CloseSFTP()
 
which outputs
 0 lib
1 libexec
2 share
3 ..
4 lib64
5 src
6 sbin
7 .
8 local
9 games
10 bin
11 etc
12 oper
13 users.tar
14 include
15 tmp
16 users
to demonstrate what I meant above about the array indexes, add a filter to the Dir command: change
st=SFTP->Dir("/usr",FL)
to
st=SFTP->Dir("/usr",FL,"u*")
and the output is now:
13 users.tar
16 users
 
There were 2 array elements returned, but their indexes were not 1 and 2.
 



From: InterSy...@googlegroups.com [mailto:InterSy...@googlegroups.com] On Behalf Of Rich Brim
Sent: Monday, September 16, 2013 4:43 PM
To: InterSy...@googlegroups.com
Subject: [InterSystems-MV] Can't get SFTP routine to work

Rich Brim

unread,
Oct 15, 2013, 5:43:43 PM10/15/13
to InterSy...@googlegroups.com
I haven't had time to work on this further, but this is working.
thanks,
rb



    SERVER='ftp.testing.com'
    USER=transferuser'
    PASSWORD='xxxxxxxxx'
    PORT=22
    PATH='/mydir'
    FTP="%Net.SSH.Session"->%New()
    FTP->Connect(SERVER)
    FTP->AuthenticateWithUsername(USER,PASSWORD)
    FTP->OpenSFTP(SFTP)
    dim FL()
    SFTP->Dir(PATH,FL)
Reply all
Reply to author
Forward
0 new messages