Zum Hauptinhalt springen

SFTP ist das FTP-Subsystem, das Teil von SSH ist und verschlüsselte Dateiübertragungen ermöglicht. In der letzten Woche hatte ich 2 Probleme mit SFTP, das Dateien nicht richtig übertragen konnte. In einem Fall war OpenVOS die Quelle der Datei und im anderen Fall war OpenVOS der Empfänger der Datei. In beiden Fällen enthielten die Dateien ASCII-Daten und die Probleme hatten mit den Unterschieden zwischen Microsoft Windows und OpenVOS bei der Beendigung von Zeilen in einer Textdatei zu tun.

Beginnen wir mit OpenVOS als Quelle. Wenn Sie eine Textdatei mit Ihrem Lieblingseditor erstellen, erzeugen Sie eine sequentielle Datei. Zum Beispiel

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

ready 08:13:49

Abbildung 1 - Anzeige einer Textdatei
Der Befehl display_file_status zeigt, dass es sich um eine sequentielle Datei handelt und dass die Datei 20 Bytes enthält, obwohl die Anzahl der Datenbytes 10 beträgt.
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

Abbildung 2 - display_file status
Der Befehl dump_file zeigt die tatsächliche Struktur der Datei an. Jeder "Zeile" werden 2 Bytes vorangestellt und beendet, die ihre Länge angeben. Diese Längenbytes müssen auf einer geraden Bytegrenze beginnen, daher gibt es auch ein Füllbyte. Auffallend ist, dass es keine typischen Zeilenabschlusszeichen gibt, weder einen Zeilenvorschub (0x0A) noch einen Wagenrücklauf (0x0D0A).
dump_file test%phx_vos#m16_mas>SysAdmin>Noah_Davids>test 10-09-05 08:14:07 mst
Blocknummer 1000  00053132 333435FF 00050005 36373839 |..12345…..6789|010 30FF0005 FFFFFFFF FFFFFFFF FFFFFFFF |0...............|020 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFF |................|

=

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

bereit 08:14:07

Abbildung 3 - dump_file zeigt die tatsächliche Struktur der Datei

 

Wenn Sie die Datei mit SFTP übertragen, entfernt OpenVOS die Längenbytes aus der Zeile und fügt ein Zeilenvorschubzeichen an. Das Ergebnis ist, dass die ursprüngliche Datei 10 Datentypen enthielt, während die übertragene Datei 12 enthält.
C:Documents and SettingsnoahMy Documentstemp>"C:Program FilesPuTTYpsftp" [email protected]
Using username "nd".
[email protected]'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
Abbildung 4 - Die Länge der übertragenen Datei stimmt nicht mit der Länge der Quelldatei überein
Wenn Sie die Datei in einem Programm wie Notepad anzeigen, wird sie außerdem als eine Zeile mit komischen Symbolen an den Stellen angezeigt, an denen die Zeilen enden sollten.
Abbildung 5 - Anzeige der Datei in Notepad
Wenn Sie ein Dienstprogramm verwenden, um einen Hex-Dump der Datei zu erhalten, werden Sie sehen, dass am Ende jeder Zeile ein Zeilenvorschubzeichen (0x0A) steht. Die Standard-Zeilenabschlusssequenz von Microsoft Windows ist Wagenrücklauf-Zeilenvorschub (0x0D0A). Notepad weiß nicht, wie es nur das Zeilenvorschubzeichen interpretieren soll, obwohl es andere Editoren gibt, die die Datei korrekt anzeigen.

 

Abbildung 6 - Hex-Dump der übertragenen Datei
Das Ergebnis ist, dass die übertragene Datei beschädigt zu sein scheint, die Länge unterschiedlich ist und Sie sie nicht anzeigen können - zumindest in Notepad. Wenn Sie die Datei vor der Übertragung in eine Stream-Datei konvertieren, wird das Längenproblem behoben; beide Dateien weisen nun dieselbe Länge auf, das Problem mit dem Zeilenende bleibt jedoch bestehen.

 

Was passiert nun, wenn OpenVOS eine Datei von einem Microsoft Windows System empfängt? Wie ich bereits sagte, verwendet Microsoft Windows eine Wagenrücklauf-Zeilenvorschubsequenz, um eine Zeile zu beenden.
Abbildung 7 - Hex-Dump einer auf einem Microsoft Windows-System erstellten Datei
Das OpenVOS-SFTP-Subsystem erstellt eine Stream-Datei. Die Zeilenvorschub-Zeichen werden als Zeilenende-Zeichen betrachtet und die Wagenrücklauf-Zeichen werden als Teil der Zeilendaten behandelt.

dump_file pc1.txt

%phx_vos#m16_mas>SysAdmin>Noah_Davids>pc1.txt 10-09-05 08:52:21 mst
Block Nummer 1

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

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

=

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

bereit 08:52:21

Abbildung 8 - Dump-Datei der übertragenen Datei
Mit dem Befehl display wird die Datei korrekt angezeigt.

d pc1.txt

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

abcde

fghij

bereit 08:54:25

Abbildung 9 - Anzeige der übertragenen Datei
Wenn Sie die Datei jedoch tatsächlich lesen wollen, wird am Ende jeder Zeile ein Wagenrücklaufzeichen angezeigt.
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:

Abbildung 10 - Wagenrücklaufzeichen werden beim Lesen der Datei angezeigt
Auch hier ist das Ergebnis, dass die Datei anscheinend beschädigt ist.
Das folgende Perl-Skript kann verwendet werden, um die Wagenrücklaufzeichen hinzuzufügen oder zu entfernen. Sie möchten sie hinzufügen, bevor Sie die Datei auf ein Microsoft Windows-System übertragen, und sie entfernen, nachdem Sie die Datei vom Microsoft Windows-System übertragen haben.
# cr.pl begins here
#
# cr
# version 1.0 10-08-27
#
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

Abbildung 11 - Perl-Skript zum Entfernen oder Hinzufügen von Wagenrücklaufzeichen
Warum scheint FTP zu funktionieren? FTP hat zwei Modi, ASCII und binär. Im ASCII-Modus führen Übertragungen von einem Microsoft Windows-System zu OpenVOS zu einer sequentiellen Datei, bei der die Carriage Return- und Line Feed-Zeichen aus den Datensätzen entfernt sind. Übertragungen im Binärmodus von einem Microsoft-Windows-System zu OpenVOS ergeben eine Stream-Datei, in der die Wagenrücklauf- und Zeilenvorschubzeichen vorhanden sind - genau wie bei der Übertragung im Binärmodus von SFTP. Übertragungen im ASCII-Modus von OpenVOS zu einem Microsoft-Windows-System ergeben eine Datei mit Wagenrücklauf- und Zeilenvorschubzeichen am Ende jeder Zeile, während Übertragungen im Binärmodus zu einer Datei führen, die nur das Zeilenvorschubzeichen am Ende jeder Zeile enthält. Wiederum genau wie bei der Übertragung im Binärmodus von SFTP. Im FTP-RFC wird detailliert beschrieben, wie Zeilen zu beenden sind, aber unterm Strich steht es sowohl dem Client als auch dem Server im ASCII-Modus frei, die Zeilen so zu beenden, wie es für das lokale Betriebssystem erforderlich ist, während Client und Server im Binärmodus keinen solchen Ermessensspielraum haben.

© 2024 Stratus Technologies.