Return code 0 with a "put" when file already exists

Discussion of Co:Z sftp, a port of OpenSSH sftp for z/OS
Post Reply
rjchavez
Posts: 8
Joined: Tue Aug 06, 2019 7:07 am

Return code 0 with a "put" when file already exists

Post by rjchavez »

When running the following to "put" a file on the Windows server, if the file already exists, it is replaced instead of returning an error or bad condition code:

user=user1
host=server1
lfile="COUNT2.txt"
rfile="COUNT2.txt"
sftp_opts="$sftp_opts"

. $script_dir/sftp_connect.sh <<EOB
lzopts $lzopts mode=text
ls -l
put $lfile $rfile
ls -l
EOB


How can we disallow the put to be issued when the file already exists?
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Re: Return code 0 with a "put" when file already exists

Post by dovetail »

As you have seen, the OpenSSH sftp command "put" doesn't care if the remote file exists. There is a Co:Z option "NOReplace", but unfortunately this only works for files *on* the Co:Z client or Co:Z server. So, if the remote server is not Co:Z SFTP, "put localfile remotefile" will not fail with an existing file even with NOReplace set.

See this documentation under the "replace" option:
https://dovetail.com/docs/sftp/options. ... ns_general

There is, however, a good approach for dealing with this requirement.
What you do is to put the file to a unique remote file name, and then if that works then you rename it to the real name.
The rename will fail if the target file exists. This also has the important advantage of eliminating the possibility that a remote application will try to process the file while it is being uploaded, which is a common problem with distributed systems

Here's an example:

Code: Select all

user=user1
host=server1
lfile="COUNT2.txt"
rfile="COUNT2.txt"
sftp_opts="$sftp_opts"        # this just sets it to itself
lzopts="$lzopts,mode=text"    # you need commas between options not spaces
tstamp=$(date +%y-%m-%d.%T)   # yy-mm-dd.hh:mm:ss  

. $script_dir/sftp_connect.sh <<EOB
lzopts $lzopts
ls -l
put $lfile $rfile.$tstamp
rename $rfile.$tstamp  $rfile
ls -l
EOB
rjchavez
Posts: 8
Joined: Tue Aug 06, 2019 7:07 am

Re: Return code 0 with a "put" when file already exists

Post by rjchavez »

Thanks for the resolution but the rename was successful even when the file existed.

I also had to change the %%T in the timestamp since this is a Windows server and it does not like colon in the file name.

Here's the output from the CC=0 run:

Executing: /tools/coz621/bin/cozsftp -oConnectTimeout=60 -oServerAliveInterval=60 -oNumberOfPasswordPrompts=1 -oStrictHostKeyChecki
ng=yes -b- 'user1@server1'
Co:Z SFTP version: 6.2.1 (7.6p1) 2021-01-15
Copyright (C) Dovetailed Technologies, LLC. 2008-2021. All rights reserved.
Connecting to server1...
Connected to server1.
Connection established, local_addr=99.99.99.99 local_port=27328 remote_addr=88.88.88.88 remote_port=22
ZosSettings: Transfer options: clientcp=IBM-1047,gdgnt,mode=text,servercp=ISO8859-1,trim
ZosDataset: Opening dataset DD:MYDD for read
ZosDataset: Closing dataset //mvs-filename - 480 records read, 1875223 bytes sent
CoZBatch[N]: version: 6.2.1 2021-01-15
CoZBatch[N]: Copyright (C) Dovetailed Technologies, LLC. 2005-2021. All rights reserved.
<- ()
CoZBatch: executing progname=login-shell="-/bin/sh"
CoZBatch: returning rc=exitcode=0
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Re: Return code 0 with a "put" when file already exists

Post by dovetail »

Rename is something implemented differently by different servers.

To request that the server rename with the original SFTP RFC meaning, use the "-l" (lower case L) flag on the rename subcommand:


rename -l oldpath newpath

this *should* be implemented by all SFTP servers to fail if newpath exists.
Post Reply