Problème avec ftp_send, le retour =p

cs_megatchu Messages postés 9 Date d'inscription jeudi 26 octobre 2006 Statut Membre Dernière intervention 28 février 2009 - 28 févr. 2009 à 14:44
speedbast Messages postés 4 Date d'inscription mardi 27 juin 2006 Statut Membre Dernière intervention 12 octobre 2011 - 10 mai 2011 à 16:32
Bonjour,
J'avais déja eu un problème avec le très bon script ftp_send ( voirici ), et la réponse de uaip m'avais permis de faire fonctionner le script, cependant depuis hier, l'envois des logs continue a se saccader, de sorte que l'envois se coupe en plein upload, et qu'il manque un bout de fichier.

J'ai regarder et le fichier ne bug pas au début, mais seulement après une certaine limite de taille ( que je n'ai pas pu déterminer. ).

Je vous laisse donc mon script avec les modification apporté :

;; /ftp_send
;   déclenche l'envoi du fichier spéficié sur le serveur ftp donné.
;   (les informations sont à modifier ci-dessous..)
alias ftp_send_logshtml {
  var %sock = $+(ftpsend_a,$ticks)
  ftpdata_create %sock
  ;;informations à modifier;;
  ; ci dessous, le fichier à envoyer (spécifier le chemin complet)
  var %fichier = XXXXX

  ; l'adresse du serveur ftp
  var %serveur = XXXXX
  ; le port du serveur ftp
  var %port = 21
  ; le nom d'utilisateur
  var %login = XXXXX
  ; le mot de passe associé au nom d'utilisateur
  var %pass = XXXXX
  ; le répertoire distant dans lequel sera déposé le fichier
  var %rep = /XXXXX
  ;;=================================================================;;

  ; inscription des données en mémoire.. (hash)
  ftpdata_add %sock file %fichier
  ftpdata_add %sock host %serveur
  ftpdata_add %sock port %port
  ftpdata_add %sock user %login
  ftpdata_add %sock pass %pass
  ftpdata_add %sock cwd %rep
  ftpdata_add %sock pos 0

  sockclose %sock $ftpdata_get(%sock,host) $ftpdata_get(%sock,port)

  sockopen %sock $ftpdata_get(%sock,host) $ftpdata_get(%sock,port)
}

;; gestion des données en mémoire (une hash associée à chaque socket)
alias -l ftpdata_create { var %hash = $$1 | if !$hget(%hash) { hmake %hash 5 } }
alias -l ftpdata_clear { var %hash = $$1 | if $hget(%hash) { hfree %hash } }
alias -l ftpdata_add { var %hash = $1 | if $hget(%hash) { hadd %hash $2 $$3- } }
alias -l ftpdata_get { var %hash = $1 | return $iif($hget(%hash),$hget(%hash,$2)) }

;;=====================================;;
;   gestion des sockets                 ;
;;=====================================;;
;------ - ------------- - ---   ---;
;   canal de commande               ;
;----------- ----- --    ----------;
; gestion de l'ouverture du socket
on *:sockopen:ftpsend_*:{ if $sockerr { echo 4 -ta ..ftp�2;send�2;: erreur lors de la connexion au serveur. envoi annulé. | ftpdata_clear $sockname | return } }

; lecture des données
on *:sockread:ftpsend_*:{
  if $sockerr { return }
  sockread %temp
  while $sockbr {
    ; affichage des données reçues
    ;echo -ta ..ftp�2;send�2;: $sockname -> %temp
    ; traitement du code reçu
    var %code = $gettok(%temp,1,32)
    ftpsend_treatcode $sockname %code $gettok(%temp,2-,32)
    ; lecture du prochain paquet..
    sockread %temp
  }
}

;------ - ------------- - ---   ---;
;   canal de données                 ;
;----------- ----- --    ----------;
; envoi des données du fichier

on *:sockopen:t_ftp_send_*:{
  if $sockerr { echo 4 -a erreur | return }
  ;echo -a canal de données ouvert
  set %test $ftpdata_get(%sock,pos)
}
on *:sockwrite:t_ftpsend_*:{
  if $sockerr { return }  var %sock $remove($sockname,t_) , %pos $ftpdata_get(%sock,pos) , %file = $quoted($ftpdata_get(%sock,file))

  ; pour un affichage éventuel des données..
  var %pourcent = $+($round($calc((%pos * 100)/ $file(%file).size),1),%)
  var %size = ( $+ $bytes(%pos,3).suf $+ / $+ $bytes($file(%file).size,3).suf $+ )
  ;echo -ta ..ftp�2;send�2;: $nopath($longfn(%file)) : %pourcent : %size

  ; tant que la totalité du fichier n'a pas été envoyée..
  if (%pos < $file(%file).size) {
    bread %file %pos $iif($calc($file(%file).size - %pos) < 8182,$v1,$v2) &data
    sockwrite $sockname &data
    ftpdata_add %sock pos $calc(%pos + $bvar(&data,0))
  }

  ; sinon, le transfert du fichier est complet. on ferme socket de données et session.
  else { sockclose $sockname | sockwrite -n %sock QUIT }
}

;------ - ------------- - ---   ---;
;   gestion des codes reçus     ;
;----------- ----- --    ----------;

;; /ftpsend_treatcode <socket> <code> [données]
;   exécute l'action associée au code de réponse <code> du serveur ftp
alias -l ftpsend_treatcode {  var %sock $1 , %code $$2 , %data = $3-
  ; nom d'utilisateur
  if (%code == 220) { sockwrite -n %sock user $ftpdata_get(%sock,user) }
  ; mot de passe
  elseif (%code == 331) { sockwrite -n %sock pass $ftpdata_get(%sock,pass) }
  ; logged in
  elseif (%code == 230) { sockwrite -n $sockname TYPE I }
  ; type *image* OK
  elseif (%code == 200) { sockwrite -n %sock PASV }
  ; mode passif OK.
  elseif (%code == 227) {
    ; tentative d'ouverture du canal de données, suivant les informations fournies
    var %addr = $remove($gettok(%data,-1,32),$chr(40),$chr(41))
    var %host = $replace($gettok(%addr,1-4,44),$chr(44),$chr(46))    var %hport $gettok(%addr,5,44) , %lport $gettok(%addr,6,44) , %port = $calc(%hport * 2^8 + %lport)

    sockopen $+(t_,%sock) %host %port
    ; on change le répertoire courant
    sockwrite -n %sock CWD $iif($ftpdata_get(%sock,cwd),$ifmatch,/)
  }
  ; changement de répertoire courant OK.
  elseif (%code == 250) {
    ; commande d'envoi du fichier de données, via la canal de commande
    var %file = $ftpdata_get(%sock,file)
    sockwrite -n %sock STOR $nopath($longfn(%file))
  }
  ; le canal de donnée est ouvert. on envoie le fichier.
  elseif (%code == 150) {    var %pos $ftpdata_get(%sock,pos) , %file $ftpdata_get(%sock,file)
    bread %file %pos $calc($file(%file).size - %pos) &data
    sockwrite $+(t_,%sock) &data
    ftpdata_add %sock pos $calc(%pos + $bvar(&data,0))
    echo -a Le fichier a été envoyé <<
  }
  ; session terminée.
  elseif (%code == 221) { ftpdata_clear %sock }
}

;------ - ------------- - ---   ---;
;   librairie                       ;
;----------- ----- --    ----------;
;; $quoted(chemin/fichier)
;   renvoie une chaine "chemin/fichier" (pour les chemins contenant des espaces)
alias -l quoted return $iif(" isin $$1-,$$1-,$+(",$$1-,"))

J'espère avoir été assez clair et je vous remercie de vos prochaine réponse.

1 réponse

speedbast Messages postés 4 Date d'inscription mardi 27 juin 2006 Statut Membre Dernière intervention 12 octobre 2011
10 mai 2011 à 16:32
j'ai deja eu ce genre de probleme, je les ai resolu comme ceci

au lieu de

; sinon, le transfert du fichier est complet. on ferme socket de données et session.
else { sockclose $sockname | sockwrite -n %sock QUIT }

mettre
else { sockclose $sockname }

et dans la partie "gestion des codes reçus"
en dessous de
elseif (%code == 200) { sockwrite -n %sock PASV }
rajouter
elseif (%code == 226) { sockwrite -n %sock QUIT }

les serveur FTP free par exemple n'enregistre pas le dernier paquet envoyer si on coupe le socket avant l'envoie du code 226 par le serveur, il manque donc toujours un bout du fichier.
0
Rejoignez-nous