; Macros to use instead of PUT /UNIQUE, which is not reliable
; due to differing or missing server implementations of STOU,
; plus the the fact that there is no consistent or reliable
; way of finding out the unique name chosen by STOU even when
; it works.
;
; These macros assume an FTP connection is already open
; and the server is CD'd to the desired directory.  They can
; not be guaranteed to work if two or more people are using
; them at the same time for the same filename in the same
; directory of the same server.
;
; Requires: C-Kermit 8.0 or later or K95 2.0 or later
;
; Author: F. da Cruz, Columbia University, Oct 2002

local nameused

; Macro USEND -- sends the given file to an FTP server,
; guaranteeing that it will not overwrite an existing file
; sending the file under a name that is unique to the server.
; Call with: name of single file to send.
; Returns: 0 on success, 1 on error or any kind of failure.
; On success, sets \m(nameused) to the name that was used.
;
define USEND {
    undef nameused
    assign filename \fcontents(\%1)
    if not def filename end 1
    if not \v(ftp_connected) end 1
    ftp check \m(filename)
    if success {
	for \%i 1 100 1 {
	    ftp check \m(filename).\%i
	    if fail {
                assign namused \m(filename).\%i
                ftp put /as-name:\m(nameused) \m(filename)
                end \v(status)                
            }
	}
	end 1 ERROR: No unique name found
    } else {
	ftp put \m(filename)
        end \v(status)
    }
}

; Macro USENDR - like USEND except instead of sending the local file
; under a unique name, it renames the existing file on the server to a
; a unique name and then sends the local file under its own name.
; On success, sets \m(nameused) to the name that was used, which is
; the same as the original name.
;
define USENDR {
    undef nameused
    assign filename \fcontents(\%1)
    if not def filename end 1
    if not \v(ftp_connected) end 1
    ftp check \m(filename)
    if success {
	for \%i 1 100 1 {
	    ftp check \m(filename).\%i
	    if fail {
		ftp rename \m(filename) \m(filename).\%i
		if fail end 1
                assign namused \m(filename)
		ftp put \m(filename)                
		end \v(status)
	    }
	}
	end 1 ERROR: No unique name found
    } else {
	ftp put \m(filename)
	end \v(status)
    }
}
end 0 ; Remove this statement to proceed.

; Sample of use...

set ftp debug on                           ; Watch what happens
ftp open somehost.xyzcorp.com /user:olga   ; Open FTP connection and log in
if fail stop 1                             ; Check if open
if not \v(ftp_loggedin) stop 1             ; Check if logged in
set xfer display brief                     ; Brief (one-line) file xfer display
ftp cd tmp                                 ; CD to desired server directory
if fail stop 1 CD failed                   ; Check

; Send the same file several times (substitute USENDR if preferred)...

define filetosend foo                      ; Name of an existing file

for \%i 1 10 1 {                           ; Send it 10 times
    usend \m(filetosend)
    if fail stop 1 USEND failed.
    echo SENT \m(filetosend) AS \m(nameused) OK.
}
ftp directory \m(filetosend)*              ; See results on server

ftp bye
