ただし、CygTermのみはCygwinのgccでコンパイルをします。ゆえに、CygTermはgccの機能を使った実装になっています。言語はC++です。
Tera TermのメインエンジンはC++で実装されていますが、C言語的なコーディングがなされているため、Tera Termのソースコードを読み解くには、C言語に関する基礎知識があれば問題ないと言えます。ただし、Microsoft Visual C++(VC++)はANSI C準拠(C89)とはいえ、C99には未対応であるために、本来のC99相当の機能が独自に拡張されている部分もあります。そうした独自拡張された関数には、頭文字にアンダースコア(_)が付いているために、区別が付けやすくなっています。たとえば、VC++の_snprintf()は、ANSI C(C99)のsnprintf()とは似て非なるものです。
高度な機能を実現するために、フルスクラッチで実装することは効率がいいとは言えません。Tera Termでは開発効率化を図るために、オープンソースのライブラリを積極的に利用しています。ただし、オープンソース製品のライセンスによる競合には注意を払う必要があります(特にGPL)。
下図に、オープンソースのライブラリをリンクしているモジュールと、そのリンク状況を示します。
Tera Termマクロプログラムは、正規表現ライブラリ"Oniguruma"をリンクしています。"waitregex","strmatch","strreplace"コマンドにおいて正規表現を利用するためです。
Tera Term本体では、バージョンダイアログにOnigurumaのバージョンを表示するためだけにリンクをしています。
Tera Termマクロプログラムは、疑似乱数生成器"SFMT"をリンクしています。"random"コマンドにおいて乱数の生成に利用されています。
SSHモジュールであるTTSSHは、暗号処理を行うために"OpenSSL"をリンクしています。OpenSSLというネーミングからWebアクセスに使われるSSL(Secure Socket Layer)プロトコル専用のライブラリかと思われがちですが、そうではありません。OpenSSLは基本的な暗号アルゴリズムをサポートしており、TTSSHではOpenSSLに含まれる暗号化/復号ルーチンのみを利用しています。このことは、すなわちOpenSSLライブラリにSSL関連のセキュリティホールが発見されたとしても、TTSSHへの影響は極めて低いということです。
SSHモジュールであるTTSSHは、SSHパケットの圧縮を行うために圧縮ライブラリ"zlib"をリンクしています。ただし、ダイヤルアップ回線などの低速度なネットワークにおいては、パケット圧縮は有効ですが、昨今の高速回線ではむしろ速度低下を招く足かせとなります。ゆえに、デフォルトではパケット圧縮機能は無効化されています。
SSHモジュールであるTTSSHは、端末エミュレータ"PuTTY"をリンクしています。PuTTYにはPageantと呼ばれるSSH認証エージェントがあるのですが、TTSSHでPageantによる公開鍵認証をサポートするために、PuTTYのソースコードを利用しています。PuTTYの通信部分および端末エミュレーション部分のソースコードは利用していません。
なお、いずれのライブラリも静的リンク(static link)としています。ライブラリのコンパイルオプションには"/MT"を付加しています。動的リンク(dynamic link)を行うと、一部のユーザ環境でTera Termが起動できないという現象が発生したために、現在では動的リンクは行っていません。
モジュール | オーダー |
---|---|
TTProxy | 0 |
TTSSH | 2500 |
TTX Kanji Menu | 5000 |
static TTXExports Exports = { /* This must contain the size of the structure. See below for its usage. */ sizeof(TTXExports), /* This is the load order number of this DLL. */ ORDER, /* Now we just list the functions that we've implemented. */ TTXInit, NULL, /* TTXGetUIHooks */ NULL, /* TTXGetSetupHooks */ NULL, /* TTXOpenTCP */ NULL, /* TTXCloseTCP */ NULL, /* TTXSetWinSize */ TTXModifyMenu, TTXModifyPopupMenu, TTXProcessCommand, NULL, /* TTXEnd */ NULL /* TTXSetCommandLine */ };原則、プラグインのエクスポート関数は、他のプラグインと干渉しないように設計をするべきです。また、Tera Term本体側からの呼び出しが、自分宛てであるかどうかを判断する必要がある場合もあります。
関数 | 意味 |
---|---|
TTXBind | 一番始めに呼び出される関数であり、エクスポート関数のテーブルを渡す。 |
TTXInit | TTXBind()の呼び出し後にすぐに実行される関数で、Tera Term本体のグローバル変数(ts, cv)を受け取り、プラグインの初期化を行う。 |
TTXGetUIHooks | ダイアログのハンドルをフックするための関数。Tera Term本体のダイアログインターフェイスを変更したい場合に使う。フック対象の関数は以下のとおり。 &SetupTerminal, &SetupWin, &SetupKeyboard, &SetupSerialPort, &SetupTCPIP, &GetHostName, &ChangeDirectory, &AboutDialog, &ChooseFontDlg, &SetupGeneral, &WindowWindow |
TTXGetSetupHooks | セットアップルーチンをフックするための関数。フックした側は、元の関数も責任を持って呼び出す必要がある。複数のプラグインが存在する場合、関数がチェインされていく。フック対象の関数は以下のとおり。 &ReadIniFile, &WriteIniFile, &ReadKeyboardCnf, &CopyHostList, &AddHostToList, &ParseParam |
TTXOpenTCP | TCP接続を行うときに呼び出される関数。シリアル接続のときは呼び出されない。また、以下のソケットインターフェイスをフックすることもできる。 &Pclosesocket, &Pconnect, &Phtonl, &Phtons, &Pinet_addr, &Pioctlsocket, &Precv, &Pselect, &Psend, &Psetsockopt, &Psocket, &PWSAAsyncSelect, &PWSAAsyncGetHostByName, &PWSACancelAsyncRequest, &PWSAGetLastError |
TTXCloseTCP | TCPコネクションが切断されるときに呼び出される関数。シリアル接続のときは呼び出されない。下記のうちフックしたインターフェイスがあるならば、元に戻す必要がある。 &Pclosesocket, &Pconnect, &Phtonl, &Phtons, &Pinet_addr, &Pioctlsocket, &Precv, &Pselect, &Psend, &Psetsockopt, &Psocket, &PWSAAsyncSelect, &PWSAAsyncGetHostByName, &PWSACancelAsyncRequest, &PWSAGetLastError |
TTXSetWinSize | Tera Termウィンドウの画面サイズが変更されたときに呼び出される関数。 |
TTXModifyMenu | Tera Termのメニューが初期化されるときに呼び出される関数。プラグイン用のメニューを挿入したい場合に使われる。 |
TTXModifyPopupMenu | Tera Termのポップアップメニューが初期化されるときに呼び出される関数。プラグイン用のポップアップメニューを挿入したい場合に使われる。 |
TTXProcessCommand | メニューが呼び出されたときに実行される関数。プラグイン用のメニューを処理したいときに使われる。 |
TTXEnd | Tera Term本体が終了するときに呼び出される関数。 |
TTXSetCommandLine | 新規接続やセッションの複製を行うときに、コマンドラインパラメータの処理を行うときに呼び出される関数。プラグイン独自のオプションを追加したときは、ここで処理される。 |
ts->ConfirmChangePaste = GetOnOff(Section, "ConfirmChangePaste", FName, TRUE);WriteIniFile()#ttset.c に設定を書き込みするようにします。
WriteOnOff(Section, "ConfirmChangePaste", FName, ts->ConfirmChangePaste);エントリに文字列を設定する場合は、Win32APIのGetPrivateProfileString()とWritePrivateProfileString()を使います。数値を扱いたい場合は、GetPrivateProfileInt()とWriteInt()を使います。
旧 | 新 |
---|---|
sprintf(), _snprintf() | _snprintf_s() |
strcat(), strncat() | strncat_s() |
strcpy(), strncpy() | strncpy_s() |
以下に、strncpy_s()の使用例を示します。strncpy_s()の第2引数(numberOfElements)には、ナル文字(\0)も含めたバッファサイズを指定します。書き込み先のバッファは3バイトしかないので、第3引数(strSource)で指定した5バイトのデータは、2バイトに切り詰められ、buf[]には"he\0"が格納されます。
char buf[3]; strncpy_s(buf, sizeof(buf), "hello", _TRUNCATE);次に、strncat_s()の使用例を示します。当該関数は、すでに存在する文字列に、さらに文字列を連結するものであるため、第1引数(strDest)はかならずnull-terminateしている必要性があります。strncpy_s()の第2引数(numberOfElements)には、ナル文字(\0)も含めたバッファサイズを指定します。以下の例では、最初の関数を実行すると、5バイト(4文字+ナル文字)が格納されます。2つめの関数を実行する際、残り2バイトしかないので、2文字だけがコピーされ、最終的に"TeraTe"(4文字+2文字+ナル文字)となります。
char str[7]; str[0] = '\0'; strncat_s(str, sizeof(str), "Tera", _TRUNCATE); strncat_s(str, sizeof(str), "Term", _TRUNCATE);最後に、_snprintf_s()です。紛らわしいのが _snprintf() という関数であり、この関数はnull-terminateされないケースがあるため、使用禁止です。以下に、_snprintf_s()の使用例を示します。以下の例では、buf[]には"ab\0"が格納されます。
char buf[3]; _snprintf_s(buf, sizeof(buf), _TRUNCATE, "abcdef");
static BOOL MySetLayeredWindowAttributes(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags) { typedef BOOL (WINAPI *func)(HWND,COLORREF,BYTE,DWORD); static HMODULE g_hmodUser32 = NULL; static func g_pSetLayeredWindowAttributes = NULL; if (g_hmodUser32 == NULL) { g_hmodUser32 = LoadLibrary("user32.dll"); if (g_hmodUser32 == NULL) return FALSE; g_pSetLayeredWindowAttributes = (func)GetProcAddress(g_hmodUser32, "SetLayeredWindowAttributes"); } if (g_pSetLayeredWindowAttributes == NULL) return FALSE; return g_pSetLayeredWindowAttributes(hwnd, crKey, bAlpha, dwFlags); }いちいち、手で関数プロトタイプを書いていくのは面倒である場合は、「DLLの遅延読み込み」というしくみを利用すると、上記のような手順は不要です。いきなり、関数を呼び出すことができます。ダイレクトに呼び出したい関数がある場合、それが古いWindowsではサポートされていないものであるならば、Visual Studioのプロジェクト設定で、「DLLの遅延読み込み」に該当するDLLを指定しておきます。
現在、Tera TermではVisual Studio 2005によりビルドされていますが、とある工夫により Windows 95 でも動作するようになっています。もちろん、Microsoft非公認の方法であるため、Microsoftからの正式なサポートは受けられません。
そもそも、Visual Studio 2005 でビルドされたバイナリは、デフォルトで IsDebuggerPresent 関数にリンクしてしまっています。当該関数は Windows 98 からサポートされたAPIであるため、Windows 95ではリンクエラーとなるわけです。
そこで、Windows 95において、ダミーで IsDebuggerPresent 関数のシンボルを定義してあげれば、プログラムの起動時にエラーになることはなくなるのです。詳細は"comapt_w95.h"ヘッダを参照してください。
void OutputDebugPrintf(char *fmt, ...) { char tmp[1024]; va_list arg; va_start(arg, fmt); _vsnprintf(tmp, sizeof(tmp), fmt, arg); OutputDebugString(tmp); }
#ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endifなお、Windowsのように仮想記憶で動くアプリケーションプログラムに関しては、プログラムの終了時に解放されていないメモリが存在した場合、OSが面倒を見て、メモリが解放されるようになっています。
生成箇所 | ソースファイル |
---|---|
シリアル接続 | CommStart()#commlib.c |
TELNETキープアライブ | TelStartKeepAliveThread()#telnet.c |
IPv4/v6ソケットの生成 | WSAAsyncGetAddrInfo()#WSAAsyncGetAddrInfo.c |
生成箇所 | ソースファイル |
---|---|
SSHキープアライブ | start_ssh_heartbeat_thread()#ssh.c |
SCP送信処理 | SSH2_scp_tolocal()#ssh.c |
SCP受信処理 | SSH2_scp_fromremote()#ssh.c |
#define WM_SEND_HEARTBEAT (WM_USER + 1) static LRESULT CALLBACK telnet_heartbeat_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_INITDIALOG: return FALSE; case WM_SEND_HEARTBEAT: TelSendNOP(); return TRUE; break; case WM_COMMAND: break; case WM_CLOSE: return TRUE; case WM_DESTROY: return TRUE; default: return FALSE; } return TRUE; } static unsigned _stdcall TelKeepAliveThread(void *dummy) { static int instance = 0; if (instance > 0) return 0; instance++; while (cv.Open && nop_interval > 0) { if (time(NULL) >= cv.LastSendTime + nop_interval) { SendMessage(keepalive_dialog, WM_SEND_HEARTBEAT, 0, 0); } Sleep(100); } instance--; return 0; } void TelStartKeepAliveThread() { unsigned tid; if (ts.TelKeepAliveInterval > 0) { nop_interval = ts.TelKeepAliveInterval; keepalive_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BROADCAST_DIALOG), HVTWin, (DLGPROC)telnet_heartbeat_dlg_proc); keepalive_thread = (HANDLE)_beginthreadex(NULL, 0, TelKeepAliveThread, NULL, 0, &tid); if (keepalive_thread == (HANDLE)-1) { nop_interval = 0; } } }
DDEは、TCPによるネットワーク通信と似ており、サーバとクライアント間を一対一で接続し、通信を行います。アプリケーションがDDEによる通信を行うために、DDEML(Dynamic Data Exchange Management Library)と呼ばれるライブラリをWin32 APIとして提供されています。
タイプ | 意味 |
---|---|
XTYP_ADVREQ | DDEサーバがクライアントへデータを送るために、DDEサーバが自分自身に送るメッセージ。 |
XTYP_POKE | DDEクライアントからサーバへデータを送る。 |
XTYP_ADVSTART | DDEサーバに対してアドバイズループの開始を指示する。 |
XTYP_ADVDATA | DDEクライアントにデータを定期的に送る。 |
XTYP_EXECUTE | DDEサーバに文字列を送り、何らかの処理をサーバに指示する。 |
関数名 | 機能 |
---|---|
DdeInitialize | DDEを初期化し、コールバック関数を登録する。初期化できるとインスタンスを返す。 |
DdeCreateStringHandle | 文字列リテラルからハンドルを作成する。ハンドルはサーバとクライアントの通信用に使われる。 |
DdeNameService | インスタンスとサービス名("TERATERM")をサーバに登録する。登録後、XTYP_REGISTERトランザクションがクライアントへ送られる。登録解除する際にも使われる。 |
DdeCmpStringHandles | 2つの文字列ハンドルを比較する。 |
DdeClientTransaction | クライアントからサーバへトランザクションを送ることができる。トランザクションタイプとして、XTYP_REQUEST・XTYP_EXECUTE・XTYP_ADVSTART・XTYP_POKEなどが指定できる。サーバからのACKを待つまでのタイムアウト時間を指定することができ、Tera Termではほとんど"1000ミリ秒(1秒)"が指定されている。ただし、ACKを確認するケースにおいては"5000ミリ秒(5秒)"が指定されている。 |
DdeAccessData | DDEハンドルから実際のデータへのポインタを取得する。データの取り出しが終わったら、DdeUnaccessData()を呼び出すこと。 |
DdeCreateDataHandle | DDEオブジェクトを作成し、ハンドルを返す。DDEサーバのアドバイズループや、XTYP_REQUESTトランザクション受信時に、DDEクライアントへデータを送るために使われている。 |
DdeGetData | DDEオブジェクトからバッファへコピーする。 |
DdeDisconnect | DDE通信を終了する |
DdePostAdvise | DDEサーバ側で使われる関数で、自分自身に XTYP_ADVREQ トランザクションを送る。 |
SetTopic(); if (! InitDDE()) return; strncpy_s(Cmnd, sizeof(Cmnd),"TTPMACRO /D=", _TRUNCATE); strncat_s(Cmnd,sizeof(Cmnd),TopicName,_TRUNCATE);DDEサーバに、DDEクライアントからトランザクションが送られてきたときは、DdeCallbackProcコールバック関数が呼び出されます。コールバック関数は、DdeInitialize()でDDEの初期化を行うときに登録されます。
ConvH = DdeConnect(Inst, Service, Topic, NULL); if (ConvH == 0) return FALSE; Linked = TRUE; Cmd[0] = CmdSetHWnd; w = HIWORD(HWin); Word2HexStr(w,&(Cmd[1])); w = LOWORD(HWin); Word2HexStr(w,&(Cmd[5])); DdeClientTransaction(Cmd,strlen(Cmd)+1,ConvH,0, CF_OEMTEXT,XTYP_EXECUTE,1000,NULL); DdeClientTransaction(NULL,0,ConvH,Item, CF_OEMTEXT,XTYP_ADVSTART,1000,NULL);
buffer_t *msg; int len; char *s; unsigned char *outmsg; msg = buffer_init(); if (msg != NULL) { buffer_put_int(msg, SSH2_DISCONNECT_PROTOCOL_ERROR); s = "disconnected by server request"; buffer_put_string(msg, s, strlen(s)); s = ""; buffer_put_string(msg, s, strlen(s)); len = buffer_len(msg); outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len); memcpy(outmsg, buffer_ptr(msg), len); finish_send_packet(pvar); buffer_free(msg); }SSH通信に載せられて、実際にパケットが送出されるのは、finish_send_packet()から呼び出される finish_send_packet_special() です。パケットを送信するときのフォーマットについて、以下に示します。共通鍵暗号でパケットデータを暗号化する前に、ヘッダとフッタを付ける必要があります。
・SSH2の場合
SSH2_MSG_CHANNEL_REQUEST をサーバへ送るときに、"pty-req"の代わりに"exec"をサービス名として指定すると、外部コマンドを実行することができます。ユーザ認証成功後 ----> SSH2_MSG_CHANNEL_OPEN(90) <---- SSH2_MSG_CHANNEL_OPEN_CONFIRMATION(91) ----> SSH2_MSG_CHANNEL_REQUEST(98) サービス名"exec"で外部コマンド送信("scp -f") <---- SSH2_MSG_CHANNEL_WINDOW_ADJUST (remote_window+=131072バイト) <---- SSH2_MSG_CHANNEL_EXTENDED_DATA (local_window-=36バイト) <---- SSH2_MSG_CHANNEL_DATA(94)
・SSH1の場合
セッションを開くときに、SSH_CMSG_EXEC_CMD をサーバへ送ると、外部コマンドを実行することができます。・外部コマンドの書式
* "scp [-v] [-r] [-p] [-d] -t ファイル名" ローカルからリモートへのコピー * "scp [-v] [-r] [-p] [-d] -f ファイル名" リモートからローカルへのコピー -v verbose -r リカーシブ -p タイムスタンプ保持 -d ディレクトリ -t Local-to-Remoteへコピー -f Remote-to-Localへコピー
・データ転送
外部コマンドの送信が完了したあとに、ファイルの内容を送信および受信することができます。1.送信の流れ ・"Tタイムスタンプ 0 タイムスタンプ 0"を送信(オプション) ・"C0666 サイズ ファイル名"を送信 ・ファイルの内容を送信 ・セッションクローズ 2.受信の流れ ・"Tタイムスタンプ 0 タイムスタンプ 0"を受信(オプション) ・0を送信 ・"C0666 サイズ ファイル名"を受信 ・0を送信 ・ファイルの内容を受信 ・ファイルのタイムスタンプを設定(オプション) ・0を送信 ・セッションクローズ
・注意事項
ファイル名にディレクトリが含まれるときは、パスの区切りは「/」となります。「\」は受け付けないので、変換が必要です。[TTSSH] DefaultForwarding=XSSHサーバのほうは、OpenSSHを例に挙げると、"sshd_config"に下記の設定が必要です。デフォルトは"no"になっているため、通常はデフォルトではX11転送が使えません。
X11Forwarding=yesTera TermはX11転送が有効であると、spec.typeに"FWD_REMOTE_X11_TO_LOCAL"を設定します。これはSSHサーバ側からTera Term側に向かって、X11転送を行うことを意味します。Tera Termは、リモートホストにSSH接続する際、セッションオープン後の"SSH2_MSG_CHANNEL_OPEN_CONFIRMATION"において、X11転送の初期化を行います。
if (c->type == TYPE_SHELL) { // ポートフォワーディングの準備 (2005.2.26, 2005.6.21 yutaka) // シェルオープンしたあとに X11 の要求を出さなくてはならない。(2005.7.3 yutaka) FWD_prep_forwarding(pvar); FWD_enter_interactive_mode(pvar); }FWD_prep_forwarding()では、"x11-req"サービス名と"MIT-MAGIC-COOKIE-1"をSSHサーバに送信し、SSHサーバ側のX11転送の初期化を促します。SSH接続時にX11の初期化が完了すると、SSHサーバ側に環境変数"DISPLAY"が自動的に設定されます。
# echo $DISPLAY DISPLAY=localhost:10.0ここまで準備が整うと、SSHサーバ上でXアプリケーションを起動させることができます。XアプリケーションからXサーバ、すなわちSSHサーバからTera Termへ送られてくるデータは、SSH2_MSG_CHANNEL_DATA メッセージ形式となります。当該メッセージは FWD_received_data() で処理され、Xサーバ(TCP/6000)へ送られます。Xサーバのソケットは channel->local_socket で、ノンブロッキングモードで扱われます。そのため、一度でパケットを全部送れない場合があるため、送れなかったデータは内部バッファに溜めておく必要があります。また、channel->local_socket にパケットをsendすることにより、FD_WRITE メッセージが発生し、write_local_connection_buffer() が呼び出されます。ここでは、前回送れなかったデータがあれば、内部バッファから取り出し、再度Xサーバへの送信を試みます。
#define MAXNESTLEVEL 10 /* 扱えるファイル数(includeは9つまで)*/ static int INest; /* 現在のネスト位置 */ static HANDLE BuffHandle[MAXNESTLEVEL]; /* GlobalAlloc()によるバッファ */ static PCHAR Buff[MAXNESTLEVEL]; /* バッファ領域 */ static BINT BuffLen[MAXNESTLEVEL]; /* ファイルサイズ(バッファサイズ) */ static BINT BuffPtr[MAXNESTLEVEL]; /* バッファのオフセット(読み込み位置)*/
条件 | 処理 |
---|---|
TTLStatus==IdTTLEnd | マクロプログラムを終了する |
送信データがある場合(OutLen > 0) | Tera Term本体へデータを送る |
TTLStatus==IdTTLRun | 一行ずつマクロを実行する |
TTLStatus==IdTTLWait | ウェイトする('wait'コマンド) |
TTLStatus==IdTTLWaitLn | ウェイトする('waitln'コマンド) |
TTLStatus==IdTTLWaitNL | 一行受信する('recvln'コマンド) |
TTLStatus==IdTTLWait2 | 文字列を待つ('waitrecv'コマンド) |
char LineBuff[MaxLineLen]; /* 1つの行は500バイトまで格納可能 */ WORD LinePtr; /* バッファオフセット */ WORD LineLen; /* バッファサイズ */Exec()から呼ばれる ExecCmnd() で、字句解析を行います。字句解析は単純な文字列検索であり、LineBuff[]を1バイトずつ参照していきます。大まかな処理の流れは以下のとおりです。
システムは 1 つのキューにつき 1 つのキャレットを提供します。ウィンドウが キーボードフォーカスを備えているとき、またはアクティブな状態のときにだけ、 キャレットを作成するべきです。また、キーボードフォーカスを失ったり非アク ティブになる前に、キャレットを破棄するべきです。とあるため、ウィンドウがアクティブになったタイミングで CreateCaret() を呼び出し、フォーカスが外れ、非アクティブになるタイミングで DestroyCaret() を呼び出す必要があることを意味しています。
void CaretKillFocus(BOOL show) { int CaretX, CaretY; POINT p[5]; HPEN oldpen; HDC hdc; DispInitDC(); hdc = VTDC; CaretX = (CursorX-WinOrgX)*FontWidth; CaretY = (CursorY-WinOrgY)*FontHeight; p[0].x = CaretX; p[0].y = CaretY; p[1].x = CaretX; p[1].y = CaretY + FontHeight - 1; if (CursorOnDBCS) p[2].x = CaretX + FontWidth*2 - 1; else p[2].x = CaretX + FontWidth - 1; p[2].y = CaretY + FontHeight - 1; if (CursorOnDBCS) p[3].x = CaretX + FontWidth*2 - 1; else p[3].x = CaretX + FontWidth - 1; p[3].y = CaretY; p[4].x = CaretX; p[4].y = CaretY; if (show) { // ポリゴンカーソルを表示(非フォーカス時) oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, ts.VTColor[0])); } else { oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, ts.VTColor[1])); } Polyline(VTDC, p, 5); oldpen = SelectObject(hdc, oldpen); DeleteObject(oldpen); DispReleaseDC(); }
if (((h = GetModuleHandle("kernel32.dll")) != NULL) && (GetProcAddress(h, "QueryDosDeviceA") != NULL) && (QueryDosDevice(NULL, devicesBuff, 65535) != 0)) { p = devicesBuff; while (*p != '\0') { if (strncmp(p, "COM", 3) == 0 && p[3] != '\0') { ComPortTable[comports++] = atoi(p+3); if (comports >= ComPortMax) break; } p += (strlen(p)+1); }
static void ListupSerialPort(LPWORD ComPortTable, int comports, char **ComPortDesc, int ComPortMax) { GUID ClassGuid[1]; DWORD dwRequiredSize; BOOL bRet; HDEVINFO DeviceInfoSet = NULL; SP_DEVINFO_DATA DeviceInfoData; DWORD dwMemberIndex = 0; int i; DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); bRet = SetupDiClassGuidsFromName(_T("PORTS"), (LPGUID) & ClassGuid, 1, &dwRequiredSize); if (!bRet) { goto cleanup; } DeviceInfoSet = SetupDiGetClassDevs(&ClassGuid[0], NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE); if (DeviceInfoSet) { dwMemberIndex = 0; while (SetupDiEnumDeviceInfo (DeviceInfoSet, dwMemberIndex++, &DeviceInfoData)) { TCHAR szFriendlyName[MAX_PATH]; TCHAR szPortName[MAX_PATH]; DWORD dwReqSize = 0; DWORD dwPropType; DWORD dwType = REG_SZ; HKEY hKey = NULL; bRet = SetupDiGetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_FRIENDLYNAME, &dwPropType, (LPBYTE) szFriendlyName, sizeof(szFriendlyName), &dwReqSize); hKey = SetupDiOpenDevRegKey(DeviceInfoSet, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (hKey) { long lRet; dwReqSize = sizeof(szPortName); lRet = RegQueryValueEx(hKey, _T("PortName"), 0, &dwType, (LPBYTE) & szPortName, &dwReqSize); RegCloseKey(hKey); } if (_strnicmp(szPortName, "COM", 3) == 0) { // COMポートドライバを発見 int port = atoi(&szPortName[3]); int i; for (i = 0 ; i < comports ; i++) { if (ComPortTable[i] == port) { // 接続を確認 ComPortDesc[i] = _strdup(szFriendlyName); break; } } } } } cleanup: SetupDiDestroyDeviceInfoList(DeviceInfoSet); }
+-------------------------------------------------------+ |ttermpro.exe (filesys.cpp) | +-------------------------------------------------------+ |ttpfile.dll (ttfile.c) | +-------+--------+--------+--------+--------+-----------+ |Kermit | XMODEM | YMODEM | ZMODEM | B-Plus | Quick-VAN | +-------+--------+--------+--------+--------+-----------+たとえば、XMODEMの送信メニューを選択した場合、処理のフローは以下のようになります。
filesys.cpp: OnFileXSend() -> XMODEMStart() -> OpenProtoDlg() -> ttfile.c: ProtoInit() -> xmodem.c: XInit()ZMODEMの受信メニューの処理に関しては、以下のとおりです。
filesys.cpp: OnFileZRcv() -> ZMODEMStart() -> OpenProtoDlg() -> ttfile.c: ProtoInit() -> zmodem.c: ZInit()
関数 | 意味 |
---|---|
XInit | 初期化 |
XSendPacket | ファイル送信 |
XReadPacket | ファイル受信 |
XTimeOutProc | タイムアウト処理 |
XCancel | キャンセル処理 |
関数 | 意味 |
---|---|
ZInit | 初期化 |
ZParse | ファイル送信 |
ZParse | ファイル受信 |
ZTimeOutProc | タイムアウト処理 |
ZCancel | キャンセル処理 |
Oct Dec Hex Char Oct Dec Hex Char ------------------------------------------------------------------------ 001 1 01 SOH (start of heading) 101 65 41 A 002 2 02 STX (start of text) 102 66 42 B 004 4 04 EOT (end of transmission) 104 68 44 D 006 6 06 ACK (acknowledge) 106 70 46 F 025 21 15 NAK (negative ack.) 125 85 55 U 030 24 18 CAN (cancel) 130 88 58 X
; XMODEM log XmodemLog=on簡単な例として、Tera Term(COM10)からRLogin(COM11)に対して、67バイトのファイルを送信した場合の通信ログを示します。「<<<」行はTera Termがホストから受信したデータで、「>>>」行はTera Termが送信したデータです。
<<< 15 . >>> 01 01 FE 23 0D 0A 23 20 6B 6E 6F 77 6E 5F 68 6F ...#..# known_ho 73 74 73 20 66 69 6C 65 20 66 6F 72 20 54 54 53 sts file for TTS 53 48 28 41 6E 20 53 53 48 20 45 78 74 65 6E 73 SH(An SSH Extens 69 6F 6E 20 74 6F 20 54 65 72 61 20 54 65 72 6D ion to Tera Term 29 0D 0A 23 0D 0A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A )..#............ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A EC .... <<< 06 . >>> 04 . <<< 06上記ログの意味は以下のとおりです。
<<< 15 . >>> 01 01 FE 3B 20 73 61 6D 70 6C 65 20 6D 61 63 72 ...; sample macr 6F 20 6F 66 20 54 65 72 61 20 54 65 72 6D 0D 0A o of Tera Term.. 3B 0D 0A 3B 20 46 69 6C 65 3A 20 73 63 72 65 65 ;..; File: scree 6E 63 61 70 74 75 72 65 2E 74 74 6C 0D 0A 3B 20 ncapture.ttl..; 44 65 73 63 72 69 70 74 69 6F 6E 3A 20 63 61 70 Description: cap 74 75 72 65 20 73 63 72 65 65 6E 20 63 6F 6E 74 ture screen cont 65 6E 74 73 20 61 6E 64 20 77 72 69 74 65 20 74 ents and write t 6F 20 66 69 6C 65 0D 0A 3B 20 45 6E 76 69 72 6F o file..; Enviro 6E 6D 65 F4 nme. <<< 06 . >>> 01 02 FD 6E 74 3A 20 67 65 6E 65 72 69 63 0D 0A ...nt: generic.. 3B 20 55 70 64 61 74 65 3A 20 32 30 30 37 2F 31 ; Update: 2007/1 31 2F 32 35 2C 20 31 32 2F 35 2C 20 32 30 30 38 1/25, 12/5, 2008 2F 30 31 2F 33 30 0D 0A 3B 20 41 75 74 68 6F 72 /01/30..; Author 3A 20 49 57 41 4D 4F 54 4F 20 4B 6F 75 69 63 68 : IWAMOTO Kouich 69 20 28 64 6F 64 61 29 2C 20 59 75 74 61 6B 61 i (doda), Yutaka 20 48 69 72 61 74 61 0D 0A 3B 20 54 69 70 73 3A Hirata..; Tips: 0D 0A 3B 20 20 20 49 74 20 69 73 20 72 65 63 6F ..; It is reco 6D 6D 65 CA mme. <<< 06 . >>> 01 03 FC 6E 64 65 64 20 74 68 61 74 20 79 6F 75 ...nded that you 20 77 69 6C 6C 20 61 64 64 20 69 6E 20 74 68 65 will add in the 20 66 6F 6C 6C 6F 77 69 6E 67 20 65 6E 74 72 79 following entry 0D 0A 3B 20 20 20 69 6E 20 60 4B 45 59 42 4F 41 ..; in `KEYBOA 52 44 2E 43 4E 46 27 20 66 69 6C 65 20 62 65 63 RD.CNF' file bec 61 75 73 65 20 79 6F 75 20 63 61 6E 20 63 61 70 ause you can cap 74 75 72 65 20 79 6F 75 72 20 73 63 72 65 65 6E ture your screen 0D 0A 3B 20 20 20 61 74 20 6F 6E 65 27 73 20 66 ..; at one's f 69 6E 67 9C ing. : : : <<< 06 . >>> 01 0E F1 73 70 72 69 6E 74 66 20 22 73 63 72 65 ...sprintf "scre 65 6E 63 61 70 74 75 72 65 5F 25 73 25 73 25 73 encapture_%s%s%s 2D 25 73 25 73 25 73 2E 74 78 74 22 20 44 61 74 -%s%s%s.txt" Dat 65 59 20 44 61 74 65 4D 20 44 61 74 65 44 20 54 eY DateM DateD T 69 6D 65 48 20 54 69 6D 65 4D 20 54 69 6D 65 53 imeH TimeM TimeS 0D 0A 66 69 6C 65 6E 61 6D 65 20 3D 20 69 6E 70 ..filename = inp 75 74 73 74 72 0D 0A 72 65 74 75 72 6E 0D 0A 1A utstr..return... 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 75 ...u <<< 06 . >>> 04 . <<< 06
; YMODEM log YmodemLog=on簡単な例として、Tera Term(COM10)からRLogin(COM11)に対して、67バイトのファイルを送信した場合の通信ログを示します。「<<<」行はTera Termがホストから受信したデータで、「>>>」行はTera Termが送信したデータです。
<<< 43 C >>> 02 00 FF 73 73 68 5F 6B 6E 6F 77 6E 5F 68 6F 73 ...ssh_known_hos 74 73 00 36 37 20 31 31 31 36 32 32 30 30 31 30 ts.67 1116220010 30 20 31 30 30 36 34 34 00 00 00 00 00 00 00 00 0 100644........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 1B 08 ..... <<< 06 43 .C >>> 02 01 FE 23 0D 0A 23 20 6B 6E 6F 77 6E 5F 68 6F ...#..# known_ho 73 74 73 20 66 69 6C 65 20 66 6F 72 20 54 54 53 sts file for TTS 53 48 28 41 6E 20 53 53 48 20 45 78 74 65 6E 73 SH(An SSH Extens 69 6F 6E 20 74 6F 20 54 65 72 61 20 54 65 72 6D ion to Tera Term 29 0D 0A 23 0D 0A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A )..#............ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 1A 1A 1A 6D 7A ...mz <<< 06 . >>> 04 . <<< 06 43 .C >>> 02 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 ..... <<< 06上記ログの意味は以下のとおりです。
; Kermit log KmtLog=onKERMITは元々低速なシリアル通信を想定しているため、一度に送れるデータサイズはせいぜい94バイトです。ただし、拡張オプションで数千バイトのデータを扱うことはできますが、クライアントとサーバの両方が当該機能をサポートしている必要があります。
Basic Kermit Packet Layout |<------Included in CHECK------>| | | +------+-----+-----+------+------ - - -+-------+ | MARK | LEN | SEQ | TYPE | DATA | CHECK |<terminator> +------+-----+-----+------+------ - - -+-------+ | | |<--------LEN-32 characters------>| MARK パケットの先頭。CTRL-A(0x01)が入る。 LEN パケットサイズ+32。"LEN+2"バイトが全体サイズとなる。 SEQ 「シーケンス番号+32」の剰余64。シーケンス番号は0〜63まで。 TYPE 大文字アルファベットでパケットの種別を表す。 DATA データ CHECK 加算チェックサム。1,2,3バイトのいずれかの形式を選べる。 <terminator> 制御コード以下は拡張形式です。
Kermit Extended Packet Layout |<-------------------------Included in CHECK------------->| | | |<-------Included in HCHECK------->| | | | | +------+-----+-----+------+-------+-------+--------+----- - - - -+-------+ | MARK | | SEQ | TYPE | LENX1 | LENX2 | HCHECK | DATA | CHECK | +------+-----+-----+------+-------+-------+--------+----- - - - -+-------+ blank | | |<------------------->| LX1=LENX1-32, LX2=LX2-32 95 x LX1 + LX2 chars HCHECK is a single-character type 1 checksum拡張形式では94バイト以上のデータを一度に送れるようにするため、データサイズを表現する領域が2バイトに増えています。基本形式の"LEN"は常にゼロです(32を加算するので、ASCIIコードの空白になる)。また、ヘッダサイズが3バイト増えており、ヘッダ用のチェックサムが追加されています。
Initialization String 1 2 3 4 5 6 7 8 9 10 +-------+-------+-------+-------+-------+-------+-------+-------+-------+- - | MAXL | TIME | NPAD | PADC | EOL | QCTL | QBIN | CHKT | REPT | +-------+-------+-------+-------+-------+-------+-------+-------+-------+- - 10 CAPAS+1 CAPAS+2 CAPAS+3 - --+-------+ - -+--------+--------+--------+- - | CAPAS ... 0| WINDO | MAXLX1 | MAXLX1 | - --+-------+- -+--------+--------+--------+- - MAXL Maximum length (0-94) +32 TIME Timeout, seconds (0-94) +32 NPAD Number of pad characters (0-94) +32 EOL Packet terminator (0-63) +32 QCTL Control prefix, literal QBIN 8th bit prefix, literal CHKT Block check type {1,2,3}, literal REPT Repeat count prefix, literal CAPAS Extendable capabilities mask, ends when value-32 is even WINDO Window size (0-31) +32 MAXLX1 High part of extended packet maximum length (int(max/95)+32) MAXLX2 Low part of extended packet maximum length (mod(max,95)+32)下記はパケット種別です。
Packet Types Y Acknowledgment (ACK). Data according to what kind of packet is being acknowledged. N Negative Acknowledgment (NAK). Data field always empty. S Send Initiation. Data field contains unencoded initialization string. Tells receiver to expect files. ACK to this packet also contains unencoded initialization string. I Initialize. Data field contains unencoded initialization string. Sent to server to set parameters prior to a command. ACK to this packet also contains unencoded initialization string. F File Header. Indicates file data about to arrive for named file. Data field contains encoded file name. ACK to this packet may contain encoded name receiver will store file under. X Text Header. Indicates screen data about to arrive. Data field contains encoded heading for display. A File Attributes. Data field contains unencoded attributes. ACK may contain unencoded corresponding agreement or refusal, per attribute. D Data Packet. Data field contains encoded file or screen data. ACK may contain X to interrupt sending this file, Z to interrupt entire transaction. Z End of file. Data field may contain D for Discard. B Break transmission. E Error. Data field contains encoded error message. R Receive Initiate. Data field contains encoded file name. C Host Command. Data field contains encoded command for host's command processor. K Kermit Command. Data field contains encoded command for Kermit command processor. T Timeout psuedopacket, for internal use. Q Block check error psuedopacket, for internal use. G Generic Kermit Command. Data field contains a single character subcommand, followed by zero or more length-encoded operands, encoded after formation: I Login [<%user[%password[%account]]>] C CWD, Change Working Directory [<%directory[%password]>] L Logout, Bye F Finish (Shut down the server, but don't logout). D Directory [<%filespec>] U Disk Usage Query [<%area>] E Erase (delete) <%filespec> T Type <%filespec> R Rename <%oldname%newname> K Copy <%source%destination> W Who's logged in? [<%user ID or network host[%options]>] M Send a short Message <%destination%text> H Help [<%topic>] Q Server Status Query P Program <%[program-filespec][%program-commands]> J Journal <%command[%argument]> V Variable <%command[%argument[%argument]]>