Skip to main content

SFTP est le sous-système FTP qui fait partie de SSH, il vous permet d'effectuer des transferts de fichiers cryptés. Au cours de la semaine dernière, j'ai eu deux problèmes concernant SFTP qui ne transférait pas correctement les fichiers. Dans un cas, OpenVOS était la source du fichier et dans l'autre cas, OpenVOS recevait le fichier. Dans les deux cas, les fichiers contenaient des données ASCII et les problèmes étaient liés aux différences entre la façon dont Microsoft Windows et OpenVOS terminent les lignes dans un fichier texte.

Commençons avec OpenVOS comme source. Si vous créez un fichier texte en utilisant votre éditeur préféré, vous créez un fichier séquentiel. Par exemple

d test
%phx_vos#m16_mas>SysAdmin>Noah_Davids>test  10-09-05 08:13:49 mst
12345
67890

ready 08:13:49

Figure 1 - affichage d'un fichier texte
La commande display_file_status montre qu'il s'agit d'un fichier séquentiel et que, bien que le nombre d'octets de données soit de 10, il y a en réalité 20 octets dans le fichier.
display_file_status test
name: %phx_vos#m16_mas>SysAdmin>Noah_Davids>test
file organization: sequential file
. . .
next byte:                 20
blocks used: 1
. . .
record count: 2
data byte count:           10

ready 08:14:01

Figure 2 - état du fichier d'affichage
La commande dump_file montre la structure réelle du fichier. Chaque "ligne" est précédée et terminée par 2 octets qui indiquent sa longueur. Ces octets de longueur doivent commencer sur une frontière d'octets pairs, il y a donc également un octet de remplissage. Ce qu'il faut remarquer, c'est qu'il n'y a pas de caractères typiques de fin de ligne, que ce soit un saut de ligne (0x0A) ou une séquence de retour chariot (0x0D0A).
dump_file test%phx_vos#m16_mas>SysAdmin>Noah_Davids>test 10-09-05 08:14:07 mst
Numéro de bloc 1000  00053132 333435FF 00050005 36373839 |..12345…..6789|010 30FF0005 FFFFFFFF FFFFFFFF FFFFFFFF |0...............|020 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|

=

FF0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|

prêt 08:14:07

Figure 3 - dump_file montrant la structure réelle du fichier

 

Lorsque vous transférez le fichier en utilisant SFTP, OpenVOS supprime les octets de longueur de la ligne et ajoute un caractère de saut de ligne. Le résultat est que, alors que le fichier original contenait 10 types de données, le fichier transféré en contient 12.
C:Documents and SettingsnoahMy Documentstemp>"C:Program FilesPuTTYpsftp" nd@164.152.77.128
Using username "nd".
nd@164.152.77.128's password:
Remote working directory is /SysAdmin/Noah_Davids
psftp> get test test.txt
remote:/SysAdmin/Noah_Davids/test => local:test.txt
psftp> quit
C:Documents and SettingsnoahMy Documentstemp>dir
Volume in drive C has no label.
Volume Serial Number is 38B1-9C13
Directory of C:Documents and SettingsnoahMy Documentstempblog - sftp
08/27/2010 01:50 PM <DIR> .
08/27/2010 01:50 PM <DIR> ..
08/27/2010 01:50 PM 12 test.txt
1 File(s) 12 bytes
2 Dir(s) 39,471,644,672 bytes free
Figure 4 - La longueur du fichier transféré ne correspond pas à celle du fichier source
En outre, si vous affichez le fichier dans quelque chose comme le Bloc-notes, il s'affiche sur une seule ligne avec des symboles bizarres là où les lignes devraient se terminer.
Figure 5 - affichage du fichier dans Notepad
Si vous utilisez un utilitaire pour obtenir un vidage hexadécimal du fichier, vous verrez qu'à la fin de chaque ligne se trouve un caractère de saut de ligne (0x0A). La séquence de fin de ligne standard de Microsoft Windows est le retour chariot et le saut de ligne (0x0D0A). Notepad ne sait pas comment interpréter le caractère de saut de ligne, mais il existe d'autres éditeurs qui affichent le fichier correctement.

 

Figure 6 - vidage hexadécimal du fichier transféré
Le résultat est que le fichier transféré semble être corrompu, la longueur est différente et vous ne pouvez pas l'afficher - du moins dans Notepad. En convertissant le fichier en fichier de flux avant de le transférer, vous corrigerez le problème de longueur ; les deux fichiers afficheront désormais la même longueur, mais le problème de terminaison de ligne subsistera.

 

Maintenant, que se passe-t-il si OpenVOS reçoit un fichier d'un système Microsoft Windows ? Comme je l'ai déjà dit, Microsoft Windows utilise une séquence de retour chariot et de saut de ligne pour terminer une ligne.
Figure 7 - vidage hexadécimal d'un fichier créé sur un système Microsoft Windows
Le sous-système SFTP d'OpenVOS va créer un fichier de flux. Les caractères de saut de ligne seront considérés comme des caractères de fin de ligne et les caractères de retour chariot seront traités comme faisant partie des données de la ligne.

dump_file pc1.txt

%phx_vos#m16_mas>SysAdmin>Noah_Davids>pc1.txt 10-09-05 08:52:21 mst
Bloc numéro 1

000 61626364650D0A666768696A 0D0AFFFF|abcde..fghij....|

010 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|

=

FF0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|

prêt 08:52:21

Figure 8 - Fichier dump du fichier transféré
La commande display affichera le fichier correctement.

d pc1.txt

%phx_vos#m16_mas>SysAdmin>Noah_Davids>pc1.txt 10-09-05 08:54:25 mst

abcde

fghij

prêt 08:54:25

Figure 9 - affichage du fichier transféré
Mais lorsque vous lisez le fichier, le caractère retour chariot apparaît à la fin de chaque ligne.
test_system_calls
tsc: s$attach_port p pc1.txt
tsc: s$open
tsc: s$seq_read p
Buffer length = 6
00000000 61626364 650D |abcde. |
tsc: s$seq_read p
Buffer length = 6
00000000 66676869 6A0D |fghij. |

tsc:

Figure 10 - les caractères de retour de chariot apparaissent lorsque vous lisez le fichier
Là encore, le résultat est que le fichier semble être corrompu.
Le script Perl suivant peut être utilisé pour ajouter ou supprimer les caractères de retour chariot. Vous souhaitez les ajouter avant de transférer le fichier vers un système Microsoft Windows et les supprimer après avoir transféré le fichier depuis le système Microsoft Windows.
# cr.pl begins here
#
# cr
# version 1.0 10-08-27
# Noah.Davids@stratus.com
#
use strict;
use warnings;
use Getopt::Long;
my ($inFile, $outFile, @files, $add, $remove);
my ($INFILE);
my ($result, $count, $verbose, $addremove);
$result = GetOptions ('in=s' => $inFile,
'out=s' => $outFile,
'add' => $add,
'remove' => $remove,
'verbose=s' => $verbose);
if (($result != 1) || !defined ($inFile) || !defined ($outFile))
{
print "nnUsage:n";
print "perl cr.pl -in PATH -out PATH [[-add] | [-remove]] [-verbose]}n";
exit;
}
if (defined ($add) && defined ($remove))
{
print "You can only specify -add or -remove not bothnn";
print "nnUsage:n";
print "perl cr.pl -in PATH -out PATH [[-add] | [-remove]] [-verbose]}n";
exit;
}
@files = glob ($inFile);
if (@files < 1) {print "nNo files found for " . $inFile . "nn";}
if (@files > 1) {print "nMore than 1 file found for " . $inFile . "nn";}
open (OUT, ">".$outFile) || die "Can't open output file " . $outFile . "nn";
open ($INFILE, $files[0]) || die "Can't open input file " . $files[0] . "nn";
if (!defined ($verbose)) { $verbose = -1; }
$count = 0;
while ($_ = <$INFILE>)
{
if (defined ($remove))
{
s/r//;
print OUT $_ ;
}
else
{
s/n//;
print OUT $_ . "rn";
}
$count++;
if (($verbose > 0) && ($count % $verbose) == 0)
{ print "Line " . $count . " of " . $files[0] . " processedn"; }
}
close $INFILE;
#

# cr ends here

Figure 11 - Script Perl pour supprimer ou ajouter des caractères de retour chariot
Pourquoi le FTP semble-t-il fonctionner ? FTP a deux modes, ASCII et binaire. En mode ASCII, les transferts d'un système Microsoft Windows vers OpenVOS se traduisent par un fichier séquentiel dans lequel les caractères de retour chariot et de saut de ligne sont supprimés des enregistrements. Les transferts en mode binaire d'un système Microsoft Windows vers OpenVOS résultent en un fichier de flux avec les caractères de retour chariot et de saut de ligne présents - exactement comme le transfert en mode binaire de SFTP. Les transferts en mode ASCII depuis OpenVOS vers un système Microsoft Windows résultent en un fichier avec les caractères de retour chariot et de saut de ligne à la fin de chaque ligne alors que les transferts en mode binaire résultent en un fichier avec seulement le caractère de saut de ligne à la fin de chaque ligne. Encore une fois, tout comme le transfert en mode binaire de SFTP. La RFC FTP explique en détail comment terminer les lignes, mais l'essentiel est qu'en mode ASCII, le client et le serveur sont libres de terminer les lignes selon les besoins du système d'exploitation local, alors qu'en mode binaire, le client et le serveur n'ont pas cette liberté.

2020 Stratus Technologies.