주요 콘텐츠로 건너뛰기

SFTP는 SSH의 일부인 FTP 하위 시스템으로 암호화된 파일 전송을 수행할 수 있습니다. 지난 주에 나는 제대로 파일을 전송하지 SFTP에 대한 2 문제가 있었다. 한 경우 OpenVOS는 파일의 출처였고 다른 경우에는 OpenVOS가 파일을 수신했습니다. 두 경우 모두 ASCII 데이터가 포함된 파일과 Microsoft Windows와 OpenVOS가 텍스트 파일에서 선을 종료하는 방식의 차이점과 관련이 있었습니다.

OpenVOS를 소스로 시작해 보겠습니다. 즐겨찾는 편집기로 텍스트 파일을 만들면 순차적인 파일을 만듭니다. 예를 들어

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

ready 08:13:49

그림 1 – 텍스트 파일 표시
display_file_status 명령은 순차적인 파일이며 데이터 바이트 수가 10개이지만 파일에 실제로 20바이트가 있음을 보여 주습니다.
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

그림 2 – display_file 상태
dump_file 명령은 파일의 실제 구조를 표시합니다. 각 "선"이 앞에 있고 길이를 나타내는 2바이트로 종료됩니다. 이러한 길이 바이트는 필러 바이트도 있으므로 균일한 바이트 경계에서 시작해야 합니다. 중요한 점은 선 피드(0x0A) 또는 캐리지 리턴 라인 피드(0x0D0A) 시퀀스가 없는 일반적인 줄 종료 문자가 없다는 것입니다.
dump_file test%phx_vos#m16_mas>SysAdmin>Noah_Davids>test 10-09-05 08:14:07 mst
블록 번호 1000  00053132 333435FF 로 00050005 36373839 |.. 12345....6789|010 30FF 로0005 FFFFFF FFFFFF FFFFFF FFFFFF |0...| 020 FFFFFF FFFFFF FFFF FFFF FFFF FFFF FFFF |...|

=

FF0 FFFFFF |...............|

준비 완료 08:14:07

그림 3 – 파일의 실제 구조를 보여주는 dump_file

 

SFTP를 사용하여 파일을 전송할 때 OpenVOS는 줄에서 길이 바이트를 제거하고 줄 피드 문자를 더합니다. 그 결과 원본 파일에 10개의 데이터 형식이 포함되어 있지만 전송된 파일에는 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
그림 4 – 전송된 파일 길이가 소스 파일 길이와 일치하지 않습니다.
또한 Notepad와 같은 파일에 파일을 표시하면 선이 종료되어야 하는 재미있는 기호가 있는 한 줄로 표시됩니다.
그림 5 – 메모장에 파일 표시
유틸리티를 사용하여 파일의 헥스 덤프를 받으면 각 줄의 끝에 줄 피드 문자(0x0A)가 있음을 알 수 있습니다. 표준 Microsoft Windows 선 종료 순서는 캐리지 반환 회선 피드(0x0D0A) 이며, Notepad는 파일을 올바르게 표시하는 다른 편집기가 있지만 라인 피드 문자를 해석하는 방법을 알지 못합니다.

 

그림 6 – 전송된 파일의 헥스 덤프
그 결과 전송된 파일이 손상된 것처럼 보이고 길이가 다르며 적어도 Notepad에서 표시할 수 없습니다. 파일을 전송하기 전에 스트림 파일로 변환하면 길이 문제가 해결됩니다. 이제 두 파일 모두 동일한 길이를 표시하지만 줄 종료 문제는 유지됩니다.

 

OpenVOS가 Microsoft Windows 시스템에서 파일을 수신하는 경우 어떻게 해야 합니까? 내가 이미 말했듯이, 마이크로소프트 윈도 선 라인을 종료 하는 캐리지 반환 회선 피드 시퀀스를 사용 하 여.
그림 7 – 마이크로소프트 윈도우 시스템에서 만든 파일의 Hex 덤프
OpenVOS SFTP 하위 시스템은 스트림 파일을 만듭니다. 라인 피드 문자는 줄 종료 문자로 이동되며 캐리지 반환 문자는 줄 데이터의 일부로 처리됩니다.

dump_file pc1.txt

%phx_vos#m16_mas>SysAdmin>Noah_Davids>pc1.txt 10-09-05 08:52:21 mst
블록 번호 1

000 61626364 650D0A66 6768696A 0D0AFFFF |abcde.. fghij....|

010 FFFFFF FFFFFF |...|

=

FF0 FFFFFF |...............|

준비 완료 08:52:21

그림 8 – 전송된 파일의 덤프 파일
표시 명령에 파일이 올바르게 표시됩니다.

d pc1.txt

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

abcde

fghij

준비 완료 08:54:25

그림 9 – 전송된 파일 의 표시
그러나 실제로 파일을 읽으러 가면 캐리지 반환 문자가 모든 줄의 끝에 표시됩니다.
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:

그림 10 – 파일을 읽을 때 캐리지 반환 문자가 표시됩니다.
다시 말하지만, 결과는 파일이 손상된 것으로 보인다.
다음 Perl 스크립트를 사용하여 캐리지 반환 문자를 추가하거나 제거할 수 있습니다. 파일을 Microsoft Windows 시스템으로 전송하기 전에 추가하고 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

그림 11 – 캐리지 반환 문자를 제거하거나 추가하는 펄 스크립트
FTP가 작동하는 이유는 무엇입니까? FTP에는 ASCII와 바이너리 두 가지 모드가 있습니다. ASCII 모드에서 Microsoft Windows 시스템에서 OpenVOS로 전송하면 캐리지 리턴과 라인 피드 문자가 모두 레코드에서 제거된 순차적인 파일이 생성됩니다. 이진 모드는 Microsoft Windows 시스템에서 열기 VOS로 전송되어 캐리지 리턴및 라인 피드 문자가 있는 스트림 파일이 SFTP의 바이너리 모드 전송과 정확히 유사합니다. ASCII 모드는 OpenVOS에서 Microsoft Windows 시스템으로 전송하면 각 줄의 끝에 캐리지 리턴 및 라인 피드 문자가 있는 파일이 생성되며 이진 모드 전송은 각 줄의 끝에 선 피드 문자만 있는 파일이 생성됩니다. 다시 그냥 SFTP의 바이너리 모드 전송처럼. FTP RFC는 라인을 종료하는 방법에 대해 자세히 설명하지만 결론은 ASCII 모드에서 클라이언트와 서버 가루 모드 클라이언트및 서버에서 이러한 재량이없는 동안 로컬 운영 체제에 필요한 라인을 종료 할 수 있다는 것입니다.