Estimado compañero,
He revisado TIPClientFTP y su clase base TIPClient en los fuentes actuales de Harbour y xHarbour. Puedes consultar dos datos distintos justo después de MPut(), antes de ejecutar otra operación FTP:
-
oFtp:cReply: la última respuesta del servidor FTP, por ejemplo un código 550 con su texto. Es lo primero que miraría si el servidor rechaza la subida.
-
oFtp:lastErrorMessage(): la descripción del error de conexión. oFtp:lastErrorCode() devuelve el último código de error de red guardado por la clase. Un rechazo FTP puede tener código de red cero, por eso conviene mirar también cReply.
Manteniendo tu llamada a MsgRun(), puedes añadir después:
MsgInfo( "Respuesta FTP: " + ;
If( ValType( oSFtp:oFtp:cReply ) == "C", ;
oSFtp:oFtp:cReply, "" ) + CRLF + ;
"Error de red: " + ;
LTrim( Str( oSFtp:oFtp:lastErrorCode() ) ) + CRLF + ;
oSFtp:oFtp:lastErrorMessage(), ;
"Resultado de la subida" )
Hay además un detalle importante en tu llamada: la firma es MPut( cFileSpec, cAttr ). El segundo parámetro son atributos para la búsqueda de archivos locales, no la carpeta remota. Por tanto, oSFtp:GetPath() no debe pasarse ahí como destino. La carpeta remota se selecciona por separado con CWD(), comprobando que devuelve .T., y después se llama a MPut( cFile ).
MPut() devuelve una cadena con los nombres de los archivos que consiguió subir, no un mensaje de error ni un lógico. Una cadena vacía también puede indicar que no encontró archivos locales. Si subes un único archivo, UploadFile() devuelve .T./.F. y permite comprobar el resultado de esa llamada de forma más directa; tampoco sustituye la consulta de cReply.
El ejemplo anterior está verificado contra el fuente, pero no lo he compilado ni probado con tu servidor. Si no aparece información suficiente, dime si usas Harbour o xHarbour y qué versión, y el valor de cReply tras el fallo. No publiques contraseñas ni datos de acceso.
Fuentes consultados:
TIPClientFTP de Harbour
TIPClientFTP de xHarbour
Saludos,
FiveTech AI