OSDN Git Service

Modify documents.
[ffftp/ffftp.git] / connect.c
1 /*=============================================================================\r
2 *\r
3 *                                                               ホストへの接続/切断\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 #define STRICT\r
31 #include <stdio.h>\r
32 #include <stddef.h>\r
33 #include <stdlib.h>\r
34 #include <stdarg.h>\r
35 #include <string.h>\r
36 #include <mbstring.h>\r
37 #include <time.h>\r
38 // IPv6対応\r
39 //#include <winsock.h>\r
40 #include <winsock2.h>\r
41 // 切断対策\r
42 #include <mstcpip.h>\r
43 #include <windowsx.h>\r
44 #include <commctrl.h>\r
45 \r
46 #include "common.h"\r
47 #include "resource.h"\r
48 \r
49 #include <htmlhelp.h>\r
50 #include "helpid.h"\r
51 \r
52 // UTF-8対応\r
53 #undef __MBSWRAPPER_H__\r
54 #include "mbswrapper.h"\r
55 \r
56 \r
57 /*===== プロトタイプ =====*/\r
58 \r
59 // 64ビット対応\r
60 //static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
61 static INT_PTR CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
62 // 同時接続対応\r
63 //static int SendInitCommand(char *Cmd);\r
64 static int SendInitCommand(SOCKET Socket, char *Cmd, int *CancelCheckWork);\r
65 static void AskUseFireWall(char *Host, int *Fire, int *Pasv, int *List);\r
66 static void SaveCurrentSetToHistory(void);\r
67 static int ReConnectSkt(SOCKET *Skt);\r
68 // 暗号化通信対応\r
69 // 同時接続対応\r
70 //static SOCKET DoConnect(char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security);\r
71 static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork);\r
72 static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork);\r
73 static int CheckOneTimePassword(char *Pass, char *Reply, int Type);\r
74 static BOOL CALLBACK BlkHookFnc(void);\r
75 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port);\r
76 // IPv6対応\r
77 static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port);\r
78 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork);\r
79 // 同時接続対応\r
80 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet);\r
81 static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork);\r
82 // 同時接続対応\r
83 //static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet);\r
84 static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork);\r
85 static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork);\r
86 \r
87 /*===== 外部参照 =====*/\r
88 \r
89 extern char FilterStr[FILTER_EXT_LEN+1];\r
90 extern char TitleHostName[HOST_ADRS_LEN+1];\r
91 extern int CancelFlg;\r
92 \r
93 /* 設定値 */\r
94 extern char UserMailAdrs[USER_MAIL_LEN+1];\r
95 extern char FwallHost[HOST_ADRS_LEN+1];\r
96 extern char FwallUser[USER_NAME_LEN+1];\r
97 extern char FwallPass[PASSWORD_LEN+1];\r
98 extern int FwallPort;\r
99 extern int FwallType;\r
100 extern int FwallDefault;\r
101 extern int FwallSecurity;\r
102 extern int FwallResolve;\r
103 extern int FwallLower;\r
104 extern int FwallDelimiter;\r
105 extern int PasvDefault;\r
106 extern int QuickAnonymous;\r
107 // 切断対策\r
108 extern int TimeOut;\r
109 // UPnP対応\r
110 extern int UPnPEnabled;\r
111 \r
112 /*===== ローカルなワーク =====*/\r
113 \r
114 static int Anonymous;\r
115 static int TryConnect = NO;\r
116 static SOCKET CmdCtrlSocket = INVALID_SOCKET;\r
117 static SOCKET TrnCtrlSocket = INVALID_SOCKET;\r
118 static HOSTDATA CurHost;\r
119 \r
120 /* 接続中の接続先、SOCKSサーバのアドレス情報を保存しておく */\r
121 /* この情報はlistenソケットを取得する際に用いる */\r
122 // IPv6対応\r
123 //static struct sockaddr_in SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
124 //static struct sockaddr_in CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
125 \r
126 static int UseIPadrs;\r
127 static char DomainName[HOST_ADRS_LEN+1];\r
128 \r
129 #if defined(HAVE_TANDEM)\r
130 static int Oss = NO;  /* OSS ファイルシステムへアクセスしている場合は YES */\r
131 #endif\r
132 \r
133 \r
134 \r
135 /*----- ホスト一覧を使ってホストへ接続 ----------------------------------------\r
136 *\r
137 *       Parameter\r
138 *               int Type : ダイアログのタイプ (DLG_TYPE_xxx)\r
139 *               int Num : 接続するホスト番号(0~, -1=ダイアログを出す)\r
140 \r
141 *       Return Value\r
142 *               なし\r
143 *----------------------------------------------------------------------------*/\r
144 \r
145 void ConnectProc(int Type, int Num)\r
146 {\r
147         int Save;\r
148         int LFSort;\r
149         int LDSort;\r
150         int RFSort;\r
151         int RDSort;\r
152 \r
153         SaveBookMark();\r
154         SaveCurrentSetToHost();\r
155 \r
156         if((Num >= 0) || (SelectHost(Type) == YES))\r
157         {\r
158                 if(Num >= 0)\r
159                         SetCurrentHost(Num);\r
160 \r
161                 /* 接続中なら切断する */\r
162                 if(CmdCtrlSocket != INVALID_SOCKET)\r
163                         DisconnectProc();\r
164 \r
165                 SetTaskMsg("----------------------------");\r
166 \r
167                 InitPWDcommand();\r
168                 CopyHostFromList(AskCurrentHost(), &CurHost);\r
169                 // UTF-8対応\r
170                 CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
171                 // IPv6対応\r
172                 CurHost.CurNetType = CurHost.NetType;\r
173 \r
174                 if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS)\r
175                 {\r
176                         SetHostKanaCnvImm(CurHost.KanaCnv);\r
177                         SetHostKanjiCodeImm(CurHost.KanjiCode);\r
178                         SetSyncMoveMode(CurHost.SyncMove);\r
179 \r
180                         if((AskSaveSortToHost() == YES) && (CurHost.Sort != SORT_NOTSAVED))\r
181                         {\r
182                                 DecomposeSortType(CurHost.Sort, &LFSort, &LDSort, &RFSort, &RDSort);\r
183                                 SetSortTypeImm(LFSort, LDSort, RFSort, RDSort);\r
184                                 ReSortDispList(WIN_LOCAL, &CancelFlg);\r
185                         }\r
186 \r
187                         Save = NO;\r
188                         if(strlen(CurHost.PassWord) > 0)\r
189                                 Save = YES;\r
190 \r
191                         DisableUserOpe();\r
192                         // 暗号化通信対応\r
193                         // 同時接続対応\r
194 //                      CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security);\r
195                         CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security, &CancelFlg);\r
196                         TrnCtrlSocket = CmdCtrlSocket;\r
197 \r
198                         if(CmdCtrlSocket != INVALID_SOCKET)\r
199                         {\r
200                                 // 暗号化通信対応\r
201                                 switch(CurHost.CryptMode)\r
202                                 {\r
203                                 case CRYPT_NONE:\r
204                                         if(CurHost.UseFTPIS != NO || CurHost.UseSFTP != NO)\r
205                                         {\r
206                                                 if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
207                                                         SetHostEncryption(AskCurrentHost(), CurHost.UseNoEncryption, CurHost.UseFTPES, NO, NO);\r
208                                         }\r
209                                         break;\r
210                                 case CRYPT_FTPES:\r
211                                         if(CurHost.UseNoEncryption != NO || CurHost.UseFTPIS != NO || CurHost.UseSFTP != NO)\r
212                                         {\r
213                                                 if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
214                                                         SetHostEncryption(AskCurrentHost(), NO, CurHost.UseFTPES, NO, NO);\r
215                                         }\r
216                                         break;\r
217                                 case CRYPT_FTPIS:\r
218                                         if(CurHost.UseNoEncryption != NO || CurHost.UseFTPES != NO || CurHost.UseSFTP != NO)\r
219                                         {\r
220                                                 if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
221                                                         SetHostEncryption(AskCurrentHost(), NO, NO, CurHost.UseFTPIS, NO);\r
222                                         }\r
223                                         break;\r
224                                 case CRYPT_SFTP:\r
225                                         if(CurHost.UseNoEncryption != NO || CurHost.UseFTPES != NO || CurHost.UseFTPIS != NO)\r
226                                         {\r
227                                                 if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
228                                                         SetHostEncryption(AskCurrentHost(), NO, NO, NO, CurHost.UseSFTP);\r
229                                         }\r
230                                         break;\r
231                                 }\r
232 \r
233                                 // UTF-8対応\r
234                                 if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
235                                 {\r
236                                         if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
237                                                 CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
238                                         switch(CurHost.CurNameKanjiCode)\r
239                                         {\r
240                                         case KANJI_SJIS:\r
241                                                 SetTaskMsg(MSGJPN343, MSGJPN345);\r
242                                                 break;\r
243                                         case KANJI_JIS:\r
244                                                 SetTaskMsg(MSGJPN343, MSGJPN346);\r
245                                                 break;\r
246                                         case KANJI_EUC:\r
247                                                 SetTaskMsg(MSGJPN343, MSGJPN347);\r
248                                                 break;\r
249                                         case KANJI_UTF8N:\r
250                                                 SetTaskMsg(MSGJPN343, MSGJPN348);\r
251                                                 break;\r
252                                         case KANJI_UTF8HFSX:\r
253                                                 SetTaskMsg(MSGJPN343, MSGJPN349);\r
254                                                 break;\r
255                                         default:\r
256                                                 SetTaskMsg(MSGJPN344);\r
257                                                 break;\r
258                                         }\r
259                                 }\r
260 \r
261                                 strcpy(TitleHostName, CurHost.HostName);\r
262                                 DispWindowTitle();\r
263                                 SoundPlay(SND_CONNECT);\r
264 \r
265                                 SendInitCommand(CmdCtrlSocket, CurHost.InitCmd, &CancelFlg);\r
266 \r
267                                 if(strlen(CurHost.LocalInitDir) > 0)\r
268                                 {\r
269                                         DoLocalCWD(CurHost.LocalInitDir);\r
270                                         GetLocalDirForWnd();\r
271                                 }\r
272                                 InitTransCurDir();\r
273                                 DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
274 \r
275                                 LoadBookMark();\r
276                                 GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
277                         }\r
278                         else\r
279                                 SoundPlay(SND_ERROR);\r
280 \r
281                         EnableUserOpe();\r
282                 }\r
283                 else\r
284                         SetTaskMsg(MSGJPN001);\r
285         }\r
286         return;\r
287 }\r
288 \r
289 \r
290 /*----- ホスト名を入力してホストへ接続 ----------------------------------------\r
291 *\r
292 *       Parameter\r
293 *               なし\r
294 *\r
295 *       Return Value\r
296 *               なし\r
297 *----------------------------------------------------------------------------*/\r
298 \r
299 void QuickConnectProc(void)\r
300 {\r
301         char Tmp[FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1 + 2];\r
302         char File[FMAX_PATH+1];\r
303 \r
304         SaveBookMark();\r
305         SaveCurrentSetToHost();\r
306 \r
307         if(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(hostname_dlg), GetMainHwnd(), QuickConDialogCallBack, (LPARAM)Tmp) == YES)\r
308         {\r
309                 /* 接続中なら切断する */\r
310                 if(CmdCtrlSocket != INVALID_SOCKET)\r
311                         DisconnectProc();\r
312 \r
313                 SetTaskMsg("----------------------------");\r
314 \r
315                 InitPWDcommand();\r
316                 CopyDefaultHost(&CurHost);\r
317                 // UTF-8対応\r
318                 CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
319                 // IPv6対応\r
320                 CurHost.CurNetType = CurHost.NetType;\r
321                 if(SplitUNCpath(Tmp, CurHost.HostAdrs, CurHost.RemoteInitDir, File, CurHost.UserName, CurHost.PassWord, &CurHost.Port) == FFFTP_SUCCESS)\r
322                 {\r
323                         if(strlen(CurHost.UserName) == 0)\r
324                         {\r
325                                 strcpy(CurHost.UserName, Tmp + FMAX_PATH+1);\r
326                                 strcpy(CurHost.PassWord, Tmp + FMAX_PATH+1 + USER_NAME_LEN+1);\r
327                         }\r
328 \r
329                         SetCurrentHost(HOSTNUM_NOENTRY);\r
330                         AskUseFireWall(CurHost.HostAdrs, &CurHost.FireWall, &CurHost.Pasv, &CurHost.ListCmdOnly);\r
331                         CurHost.FireWall = (int)Tmp[FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1];\r
332                         CurHost.Pasv = (int)Tmp[FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1 + 1];\r
333 \r
334                         SetHostKanaCnvImm(CurHost.KanaCnv);\r
335                         SetHostKanjiCodeImm(CurHost.KanjiCode);\r
336                         SetSyncMoveMode(CurHost.SyncMove);\r
337 \r
338                         DisableUserOpe();\r
339                         // 暗号化通信対応\r
340                         // 同時接続対応\r
341 //                      CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security);\r
342                         CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
343                         TrnCtrlSocket = CmdCtrlSocket;\r
344 \r
345                         if(CmdCtrlSocket != INVALID_SOCKET)\r
346                         {\r
347                                 // UTF-8対応\r
348                                 if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
349                                 {\r
350                                         if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
351                                                 CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
352                                         switch(CurHost.CurNameKanjiCode)\r
353                                         {\r
354                                         case KANJI_SJIS:\r
355                                                 SetTaskMsg(MSGJPN343, MSGJPN345);\r
356                                                 break;\r
357                                         case KANJI_JIS:\r
358                                                 SetTaskMsg(MSGJPN343, MSGJPN346);\r
359                                                 break;\r
360                                         case KANJI_EUC:\r
361                                                 SetTaskMsg(MSGJPN343, MSGJPN347);\r
362                                                 break;\r
363                                         case KANJI_UTF8N:\r
364                                                 SetTaskMsg(MSGJPN343, MSGJPN348);\r
365                                                 break;\r
366                                         case KANJI_UTF8HFSX:\r
367                                                 SetTaskMsg(MSGJPN343, MSGJPN349);\r
368                                                 break;\r
369                                         default:\r
370                                                 SetTaskMsg(MSGJPN344);\r
371                                                 break;\r
372                                         }\r
373                                 }\r
374 \r
375                                 strcpy(TitleHostName, CurHost.HostAdrs);\r
376                                 DispWindowTitle();\r
377                                 SoundPlay(SND_CONNECT);\r
378 \r
379                                 InitTransCurDir();\r
380                                 DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
381 \r
382                                 GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
383                                 EnableUserOpe();\r
384 \r
385                                 if(strlen(File) > 0)\r
386                                         DirectDownloadProc(File);\r
387                         }\r
388                         else\r
389                         {\r
390                                 SoundPlay(SND_ERROR);\r
391                                 EnableUserOpe();\r
392                         }\r
393                 }\r
394         }\r
395         return;\r
396 }\r
397 \r
398 \r
399 /*----- クイック接続ダイアログのコールバック ----------------------------------\r
400 *\r
401 *       Parameter\r
402 *               HWND hDlg : ウインドウハンドル\r
403 *               UINT message : メッセージ番号\r
404 *               WPARAM wParam : メッセージの WPARAM 引数\r
405 *               LPARAM lParam : メッセージの LPARAM 引数\r
406 *\r
407 *       Return Value\r
408 *               BOOL TRUE/FALSE\r
409 *----------------------------------------------------------------------------*/\r
410 \r
411 // 64ビット対応\r
412 //static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
413 static INT_PTR CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
414 {\r
415         static char *Buf;\r
416         int i;\r
417         HISTORYDATA Tmp;\r
418 \r
419 //char Str[HOST_ADRS_LEN+USER_NAME_LEN+INIT_DIR_LEN+5+1];\r
420 \r
421         switch (iMessage)\r
422         {\r
423                 case WM_INITDIALOG :\r
424                         SendDlgItemMessage(hDlg, QHOST_HOST, CB_LIMITTEXT, FMAX_PATH, 0);\r
425                         SendDlgItemMessage(hDlg, QHOST_HOST, WM_SETTEXT, 0, (LPARAM)"");\r
426                         SendDlgItemMessage(hDlg, QHOST_USER, EM_LIMITTEXT, USER_NAME_LEN, 0);\r
427                         if(QuickAnonymous == YES)\r
428                         {\r
429                                 SendDlgItemMessage(hDlg, QHOST_USER, WM_SETTEXT, 0, (LPARAM)"anonymous");\r
430                                 SendDlgItemMessage(hDlg, QHOST_PASS, WM_SETTEXT, 0, (LPARAM)UserMailAdrs);\r
431                         }\r
432                         else\r
433                         {\r
434                                 SendDlgItemMessage(hDlg, QHOST_USER, WM_SETTEXT, 0, (LPARAM)"");\r
435                                 SendDlgItemMessage(hDlg, QHOST_PASS, WM_SETTEXT, 0, (LPARAM)"");\r
436                         }\r
437                         SendDlgItemMessage(hDlg, QHOST_PASS, EM_LIMITTEXT, PASSWORD_LEN, 0);\r
438                         SendDlgItemMessage(hDlg, QHOST_FWALL, BM_SETCHECK, FwallDefault, 0);\r
439                         SendDlgItemMessage(hDlg, QHOST_PASV, BM_SETCHECK, PasvDefault, 0);\r
440                         for(i = 0; i < HISTORY_MAX; i++)\r
441                         {\r
442                                 if(GetHistoryByNum(i, &Tmp) == FFFTP_SUCCESS)\r
443                                 {\r
444 //sprintf(Str, "%s (%s) %s", Tmp.HostAdrs, Tmp.UserName, Tmp.RemoteInitDir);\r
445 //SendDlgItemMessage(hDlg, QHOST_HOST, CB_ADDSTRING, 0, (LPARAM)Str);\r
446                                         SendDlgItemMessage(hDlg, QHOST_HOST, CB_ADDSTRING, 0, (LPARAM)Tmp.HostAdrs);\r
447                                 }\r
448                         }\r
449                         Buf = (char *)lParam;\r
450                         return(TRUE);\r
451 \r
452                 case WM_COMMAND :\r
453                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
454                         {\r
455                                 case IDOK :\r
456                                         SendDlgItemMessage(hDlg, QHOST_HOST, WM_GETTEXT, FMAX_PATH+1, (LPARAM)Buf);\r
457                                         SendDlgItemMessage(hDlg, QHOST_USER, WM_GETTEXT, USER_NAME_LEN+1, (LPARAM)Buf + FMAX_PATH+1);\r
458                                         SendDlgItemMessage(hDlg, QHOST_PASS, WM_GETTEXT, PASSWORD_LEN+1, (LPARAM)Buf + FMAX_PATH+1 + USER_NAME_LEN+1);\r
459                                         *(Buf + FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1) = (char)SendDlgItemMessage(hDlg, QHOST_FWALL, BM_GETCHECK, 0, 0);\r
460                                         *(Buf + FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1+1) = (char)SendDlgItemMessage(hDlg, QHOST_PASV, BM_GETCHECK, 0, 0);\r
461                                         EndDialog(hDlg, YES);\r
462                                         break;\r
463 \r
464                                 case IDCANCEL :\r
465                                         EndDialog(hDlg, NO);\r
466                                         break;\r
467 \r
468 //                              case QHOST_HOST :\r
469 //                                      if(HIWORD(wParam) == CBN_EDITCHANGE)\r
470 //                                              DoPrintf("EDIT");\r
471 //                                      break;\r
472                         }\r
473             return(TRUE);\r
474         }\r
475         return(FALSE);\r
476 }\r
477 \r
478 \r
479 /*----- 指定したホスト名でホストへ接続 ----------------------------------------\r
480 *\r
481 *       Parameter\r
482 *               char *unc : UNC文字列\r
483 *               int Kanji : ホストの漢字コード (KANJI_xxx)\r
484 *               int Kana : 半角かな→全角変換モード (YES/NO)\r
485 *               int Fkanji : ファイル名の漢字コード (KANJI_xxx)\r
486 *               int TrMode : 転送モード (TYPE_xx)\r
487 *\r
488 *       Return Value\r
489 *               なし\r
490 *----------------------------------------------------------------------------*/\r
491 \r
492 void DirectConnectProc(char *unc, int Kanji, int Kana, int Fkanji, int TrMode)\r
493 {\r
494         char Host[HOST_ADRS_LEN+1];\r
495         char Path[FMAX_PATH+1];\r
496         char File[FMAX_PATH+1];\r
497         char User[USER_NAME_LEN+1];\r
498         char Pass[PASSWORD_LEN+1];\r
499         int Port;\r
500 \r
501         SaveBookMark();\r
502         SaveCurrentSetToHost();\r
503 \r
504         /* 接続中なら切断する */\r
505         if(CmdCtrlSocket != INVALID_SOCKET)\r
506                 DisconnectProc();\r
507 \r
508         SetTaskMsg("----------------------------");\r
509 \r
510         InitPWDcommand();\r
511         if(SplitUNCpath(unc, Host, Path, File, User, Pass, &Port) == FFFTP_SUCCESS)\r
512         {\r
513                 if(strlen(User) == 0)\r
514                 {\r
515                         strcpy(User, "anonymous");\r
516                         strcpy(Pass, UserMailAdrs);\r
517                 }\r
518 \r
519                 CopyDefaultHost(&CurHost);\r
520 \r
521                 SetCurrentHost(HOSTNUM_NOENTRY);\r
522                 strcpy(CurHost.HostAdrs, Host);\r
523                 strcpy(CurHost.UserName, User);\r
524                 strcpy(CurHost.PassWord, Pass);\r
525                 strcpy(CurHost.RemoteInitDir, Path);\r
526                 AskUseFireWall(CurHost.HostAdrs, &CurHost.FireWall, &CurHost.Pasv, &CurHost.ListCmdOnly);\r
527                 CurHost.Port = Port;\r
528                 CurHost.KanjiCode = Kanji;\r
529                 CurHost.KanaCnv = Kana;\r
530                 CurHost.NameKanjiCode = Fkanji;\r
531                 CurHost.KanaCnv = YES;                  /* とりあえず */\r
532                 // UTF-8対応\r
533                 CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
534                 // IPv6対応\r
535                 CurHost.CurNetType = CurHost.NetType;\r
536 \r
537                 SetHostKanaCnvImm(CurHost.KanaCnv);\r
538                 SetHostKanjiCodeImm(CurHost.KanjiCode);\r
539                 SetSyncMoveMode(CurHost.SyncMove);\r
540 \r
541                 if(TrMode != TYPE_DEFAULT)\r
542                 {\r
543                         SetTransferTypeImm(TrMode);\r
544                         DispTransferType();\r
545                 }\r
546 \r
547                 DisableUserOpe();\r
548                 // 暗号化通信対応\r
549                 // 同時接続対応\r
550 //              CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security);\r
551                 CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
552                 TrnCtrlSocket = CmdCtrlSocket;\r
553 \r
554                 if(CmdCtrlSocket != INVALID_SOCKET)\r
555                 {\r
556                         // UTF-8対応\r
557                         if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
558                         {\r
559                                 if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
560                                         CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
561                                 switch(CurHost.CurNameKanjiCode)\r
562                                 {\r
563                                 case KANJI_SJIS:\r
564                                         SetTaskMsg(MSGJPN343, MSGJPN345);\r
565                                         break;\r
566                                 case KANJI_JIS:\r
567                                         SetTaskMsg(MSGJPN343, MSGJPN346);\r
568                                         break;\r
569                                 case KANJI_EUC:\r
570                                         SetTaskMsg(MSGJPN343, MSGJPN347);\r
571                                         break;\r
572                                 case KANJI_UTF8N:\r
573                                         SetTaskMsg(MSGJPN343, MSGJPN348);\r
574                                         break;\r
575                                 case KANJI_UTF8HFSX:\r
576                                         SetTaskMsg(MSGJPN343, MSGJPN349);\r
577                                         break;\r
578                                 default:\r
579                                         SetTaskMsg(MSGJPN344);\r
580                                         break;\r
581                                 }\r
582                         }\r
583 \r
584                         strcpy(TitleHostName, CurHost.HostAdrs);\r
585                         DispWindowTitle();\r
586                         SoundPlay(SND_CONNECT);\r
587 \r
588                         InitTransCurDir();\r
589                         DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
590 \r
591                         GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
592                         EnableUserOpe();\r
593 \r
594                         if(strlen(File) > 0)\r
595                                 DirectDownloadProc(File);\r
596                         else\r
597                                 ResetAutoExitFlg();\r
598                 }\r
599                 else\r
600                 {\r
601                         SoundPlay(SND_ERROR);\r
602                         EnableUserOpe();\r
603                 }\r
604         }\r
605         return;\r
606 }\r
607 \r
608 \r
609 /*----- ホストのヒストリで指定されたホストへ接続 ------------------------------\r
610 *\r
611 *       Parameter\r
612 *               int MenuCmd : 取り出すヒストリに割り当てられたメニューコマンド\r
613 *\r
614 *       Return Value\r
615 *               なし\r
616 *----------------------------------------------------------------------------*/\r
617 \r
618 void HistoryConnectProc(int MenuCmd)\r
619 {\r
620         HISTORYDATA Hist;\r
621         int LFSort;\r
622         int LDSort;\r
623         int RFSort;\r
624         int RDSort;\r
625 \r
626         if(GetHistoryByCmd(MenuCmd, &Hist) == FFFTP_SUCCESS)\r
627         {\r
628                 SaveBookMark();\r
629                 SaveCurrentSetToHost();\r
630 \r
631                 /* 接続中なら切断する */\r
632                 if(CmdCtrlSocket != INVALID_SOCKET)\r
633                         DisconnectProc();\r
634 \r
635                 SetTaskMsg("----------------------------");\r
636 \r
637                 InitPWDcommand();\r
638                 CopyHistoryToHost(&Hist, &CurHost);\r
639                 // UTF-8対応\r
640                 CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
641                 // IPv6対応\r
642                 CurHost.CurNetType = CurHost.NetType;\r
643 \r
644                 if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS)\r
645                 {\r
646                         SetCurrentHost(HOSTNUM_NOENTRY);\r
647                         SetHostKanaCnvImm(CurHost.KanaCnv);\r
648                         SetHostKanjiCodeImm(CurHost.KanjiCode);\r
649                         SetSyncMoveMode(CurHost.SyncMove);\r
650 \r
651                         DecomposeSortType(CurHost.Sort, &LFSort, &LDSort, &RFSort, &RDSort);\r
652                         SetSortTypeImm(LFSort, LDSort, RFSort, RDSort);\r
653                         ReSortDispList(WIN_LOCAL, &CancelFlg);\r
654 \r
655                         SetTransferTypeImm(Hist.Type);\r
656                         DispTransferType();\r
657 \r
658                         DisableUserOpe();\r
659                         // 暗号化通信対応\r
660                         // 同時接続対応\r
661 //                      CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security);\r
662                         CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
663                         TrnCtrlSocket = CmdCtrlSocket;\r
664 \r
665                         if(CmdCtrlSocket != INVALID_SOCKET)\r
666                         {\r
667                                 // UTF-8対応\r
668                                 if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
669                                 {\r
670                                         if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
671                                                 CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
672                                         switch(CurHost.CurNameKanjiCode)\r
673                                         {\r
674                                         case KANJI_SJIS:\r
675                                                 SetTaskMsg(MSGJPN343, MSGJPN345);\r
676                                                 break;\r
677                                         case KANJI_JIS:\r
678                                                 SetTaskMsg(MSGJPN343, MSGJPN346);\r
679                                                 break;\r
680                                         case KANJI_EUC:\r
681                                                 SetTaskMsg(MSGJPN343, MSGJPN347);\r
682                                                 break;\r
683                                         case KANJI_UTF8N:\r
684                                                 SetTaskMsg(MSGJPN343, MSGJPN348);\r
685                                                 break;\r
686                                         case KANJI_UTF8HFSX:\r
687                                                 SetTaskMsg(MSGJPN343, MSGJPN349);\r
688                                                 break;\r
689                                         default:\r
690                                                 SetTaskMsg(MSGJPN344);\r
691                                                 break;\r
692                                         }\r
693                                 }\r
694 \r
695                                 strcpy(TitleHostName, CurHost.HostAdrs);\r
696                                 DispWindowTitle();\r
697                                 SoundPlay(SND_CONNECT);\r
698 \r
699                                 SendInitCommand(CmdCtrlSocket, CurHost.InitCmd, &CancelFlg);\r
700 \r
701                                 DoLocalCWD(CurHost.LocalInitDir);\r
702                                 GetLocalDirForWnd();\r
703 \r
704                                 InitTransCurDir();\r
705                                 DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
706 \r
707                                 GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
708                         }\r
709                         else\r
710                                 SoundPlay(SND_ERROR);\r
711 \r
712                         EnableUserOpe();\r
713                 }\r
714                 else\r
715                         SetTaskMsg(MSGJPN002);\r
716         }\r
717         else\r
718                 SoundPlay(SND_ERROR);\r
719 \r
720         return;\r
721 }\r
722 \r
723 \r
724 /*----- ホストの初期化コマンドを送る ------------------------------------------\r
725 *\r
726 *       Parameter\r
727 *               int Cmd : 初期化コマンドス\r
728 *\r
729 *       Return Value\r
730 *               なし\r
731 *\r
732 *       NOte\r
733 *               初期化コマンドは以下のようなフォーマットであること\r
734 *                       cmd1\0\r
735 *                       cmd1\r\ncmd2\r\n\0\r
736 *----------------------------------------------------------------------------*/\r
737 \r
738 // 同時接続対応\r
739 //static int SendInitCommand(char *Cmd)\r
740 static int SendInitCommand(SOCKET Socket, char *Cmd, int *CancelCheckWork)\r
741 {\r
742         char Tmp[INITCMD_LEN+1];\r
743         char *Pos;\r
744 \r
745         while(strlen(Cmd) > 0)\r
746         {\r
747                 strcpy(Tmp, Cmd);\r
748                 if((Pos = strchr(Tmp, '\r')) != NULL)\r
749                         *Pos = NUL;\r
750                 if(strlen(Tmp) > 0)\r
751 //                      DoQUOTE(Tmp);\r
752                         DoQUOTE(Socket, Tmp, CancelCheckWork);\r
753 \r
754                 if((Cmd = strchr(Cmd, '\n')) != NULL)\r
755                         Cmd++;\r
756                 else\r
757                         break;\r
758         }\r
759         return(0);\r
760 }\r
761 \r
762 \r
763 /*----- 指定のホストはFireWallを使う設定かどうかを返す ------------------------\r
764 *\r
765 *       Parameter\r
766 *               char *Hots : ホスト名\r
767 *               int *Fire : FireWallを使うかどうかを返すワーク\r
768 *               int *Pasv : PASVモードを返すワーク\r
769 *               int *List : LISTコマンドのみ使用フラグ\r
770 *\r
771 *       Return Value\r
772 *               なし\r
773 *----------------------------------------------------------------------------*/\r
774 \r
775 static void AskUseFireWall(char *Host, int *Fire, int *Pasv, int *List)\r
776 {\r
777         int i;\r
778         HOSTDATA Tmp;\r
779 \r
780         *Fire = FwallDefault;\r
781         *Pasv = PasvDefault;\r
782         // NLSTを送ってしまうバグ修正(ただしNLSTを使うべきホストへクイック接続できなくなる)\r
783 //      *List = NO;\r
784 \r
785         i = 0;\r
786         while(CopyHostFromList(i, &Tmp) == FFFTP_SUCCESS)\r
787         {\r
788                 if(strcmp(Host, Tmp.HostAdrs) == 0)\r
789                 {\r
790                         *Fire = Tmp.FireWall;\r
791                         *Pasv = Tmp.Pasv;\r
792                         *List = Tmp.ListCmdOnly;\r
793                         break;\r
794                 }\r
795                 i++;\r
796         }\r
797         return;\r
798 }\r
799 \r
800 \r
801 /*----- 接続しているホストのアドレスを返す ------------------------------------\r
802 *\r
803 *       Parameter\r
804 *               なし\r
805 *\r
806 *       Return Value\r
807 *               char *ホストのアドレス\r
808 *----------------------------------------------------------------------------*/\r
809 \r
810 char *AskHostAdrs(void)\r
811 {\r
812         return(CurHost.HostAdrs);\r
813 }\r
814 \r
815 \r
816 /*----- 接続しているホストのポートを返す --------------------------------------\r
817 *\r
818 *       Parameter\r
819 *               なし\r
820 *\r
821 *       Return Value\r
822 *               int ホストのポート\r
823 *----------------------------------------------------------------------------*/\r
824 \r
825 int AskHostPort(void)\r
826 {\r
827         return(CurHost.Port);\r
828 }\r
829 \r
830 /*----- 接続しているホストのファイル名の漢字コードを返す ----------------------\r
831 *\r
832 *       Parameter\r
833 *               なし\r
834 *\r
835 *       Return Value\r
836 *               int 漢字コード (KANJI_xxx)\r
837 *----------------------------------------------------------------------------*/\r
838 \r
839 int AskHostNameKanji(void)\r
840 {\r
841         // UTF-8対応\r
842 //      if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
843 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
844 //\r
845 //      return(CurHost.NameKanjiCode);\r
846         return(CurHost.CurNameKanjiCode);\r
847 }\r
848 \r
849 \r
850 /*----- 接続しているホストのファイル名の半角カナ変換フラグを返す --------------\r
851 *\r
852 *       Parameter\r
853 *               なし\r
854 *\r
855 *       Return Value\r
856 *               int 半角カナを全角に変換するかどうか (YES/NO)\r
857 *----------------------------------------------------------------------------*/\r
858 \r
859 int AskHostNameKana(void)\r
860 {\r
861         // 同時接続対応\r
862         HOSTDATA TmpHost;\r
863         TmpHost = CurHost;\r
864 \r
865         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
866                 // 同時接続対応\r
867 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
868                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
869 \r
870         // 同時接続対応\r
871 //      return(CurHost.NameKanaCnv);\r
872         return(TmpHost.NameKanaCnv);\r
873 }\r
874 \r
875 \r
876 /*----- 接続しているホストのLISTコマンドモードを返す --------------------------\r
877 *\r
878 *       Parameter\r
879 *               なし\r
880 *\r
881 *       Return Value\r
882 *               int LISTコマンドモード (YES/NO)\r
883 *----------------------------------------------------------------------------*/\r
884 \r
885 int AskListCmdMode(void)\r
886 {\r
887         // 同時接続対応\r
888         HOSTDATA TmpHost;\r
889         TmpHost = CurHost;\r
890 \r
891         if(CurHost.HostType == HTYPE_VMS)\r
892                 return(YES);\r
893         else\r
894         {\r
895                 if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
896                         // 同時接続対応\r
897 //                      CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
898                         CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
899                 // 同時接続対応\r
900 //              return(CurHost.ListCmdOnly);\r
901                 return(TmpHost.ListCmdOnly);\r
902         }\r
903 }\r
904 \r
905 \r
906 /*----- 接続しているホストでNLST -Rを使うかどうかを返す ------------------------\r
907 *\r
908 *       Parameter\r
909 *               なし\r
910 *\r
911 *       Return Value\r
912 *               int NLST -Rを使うかどうか (YES/NO)\r
913 *----------------------------------------------------------------------------*/\r
914 \r
915 int AskUseNLST_R(void)\r
916 {\r
917         // 同時接続対応\r
918         HOSTDATA TmpHost;\r
919         TmpHost = CurHost;\r
920 \r
921         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
922                 // 同時接続対応\r
923 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
924                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
925 \r
926         // 同時接続対応\r
927 //      return(CurHost.UseNLST_R);\r
928         return(TmpHost.UseNLST_R);\r
929 }\r
930 \r
931 \r
932 /*----- 接続しているホストのChmodコマンドを返す -------------------------------\r
933 *\r
934 *       Parameter\r
935 *               なし\r
936 *\r
937 *       Return Value\r
938 *               char *Chmodコマンド\r
939 *----------------------------------------------------------------------------*/\r
940 \r
941 char *AskHostChmodCmd(void)\r
942 {\r
943         // 同時接続対応\r
944         HOSTDATA TmpHost;\r
945         TmpHost = CurHost;\r
946 \r
947         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
948                 // 同時接続対応\r
949 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
950                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
951 \r
952         // 同時接続対応\r
953 //      return(CurHost.ChmodCmd);\r
954         return(TmpHost.ChmodCmd);\r
955 }\r
956 \r
957 \r
958 /*----- 接続しているホストのタイムゾーンを返す --------------------------------\r
959 *\r
960 *       Parameter\r
961 *               なし\r
962 *\r
963 *       Return Value\r
964 *               int タイムゾーン\r
965 *----------------------------------------------------------------------------*/\r
966 \r
967 int AskHostTimeZone(void)\r
968 {\r
969         // 同時接続対応\r
970         HOSTDATA TmpHost;\r
971         TmpHost = CurHost;\r
972 \r
973         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
974                 // 同時接続対応\r
975 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
976                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
977 \r
978         // 同時接続対応\r
979 //      return(CurHost.TimeZone);\r
980         return(TmpHost.TimeZone);\r
981 }\r
982 \r
983 \r
984 /*----- 接続しているホストのPASVモードを返す ----------------------------------\r
985 *\r
986 *       Parameter\r
987 *               なし\r
988 *\r
989 *       Return Value\r
990 *               int PASVモードかどうか (YES/NO)\r
991 *----------------------------------------------------------------------------*/\r
992 \r
993 int AskPasvMode(void)\r
994 {\r
995         return(CurHost.Pasv);\r
996 }\r
997 \r
998 \r
999 /*----- 接続しているホストのLNSTファイル名を返す ------------------------------\r
1000 *\r
1001 *       Parameter\r
1002 *               なし\r
1003 *\r
1004 *       Return Value\r
1005 *               char *ファイル名/オプション\r
1006 *----------------------------------------------------------------------------*/\r
1007 \r
1008 char *AskHostLsName(void)\r
1009 {\r
1010         // 同時接続対応\r
1011         HOSTDATA TmpHost;\r
1012         TmpHost = CurHost;\r
1013 \r
1014         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
1015                 // 同時接続対応\r
1016 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
1017                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
1018 \r
1019         // 同時接続対応\r
1020 //      return(CurHost.LsName);\r
1021         return(TmpHost.LsName);\r
1022 }\r
1023 \r
1024 \r
1025 /*----- 接続しているホストのホストタイプを返す --------------------------------\r
1026 *\r
1027 *       Parameter\r
1028 *               なし\r
1029 *\r
1030 *       Return Value\r
1031 *               char *ファイル名/オプション\r
1032 *----------------------------------------------------------------------------*/\r
1033 \r
1034 int AskHostType(void)\r
1035 {\r
1036         // 同時接続対応\r
1037         HOSTDATA TmpHost;\r
1038         TmpHost = CurHost;\r
1039 \r
1040         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
1041                 // 同時接続対応\r
1042 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
1043                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
1044 \r
1045 #if defined(HAVE_TANDEM)\r
1046         /* OSS ファイルシステムは UNIX ファイルシステムと同じでいいので AUTO を返す\r
1047            ただし、Guardian ファイルシステムに戻ったときにおかしくならないように\r
1048            CurHost.HostType 変数は更新しない */\r
1049         if(CurHost.HostType == HTYPE_TANDEM && Oss == YES)\r
1050                 return(HTYPE_AUTO);\r
1051 #endif\r
1052 \r
1053         // 同時接続対応\r
1054 //      return(CurHost.HostType);\r
1055         return(TmpHost.HostType);\r
1056 }\r
1057 \r
1058 \r
1059 /*----- 接続しているホストはFireWallを使うホストかどうかを返す ----------------\r
1060 *\r
1061 *       Parameter\r
1062 *               なし\r
1063 *\r
1064 *       Return Value\r
1065 *               int FireWallを使うかどうか (YES/NO)\r
1066 *----------------------------------------------------------------------------*/\r
1067 \r
1068 int AskHostFireWall(void)\r
1069 {\r
1070         return(CurHost.FireWall);\r
1071 }\r
1072 \r
1073 \r
1074 /*----- 接続しているホストでフルパスでファイルアクセスしないかどうかを返す ----\r
1075 *\r
1076 *       Parameter\r
1077 *               なし\r
1078 *\r
1079 *       Return Value\r
1080 *               int フルパスでアクセスしない (YES=フルパス禁止/NO)\r
1081 *----------------------------------------------------------------------------*/\r
1082 \r
1083 int AskNoFullPathMode(void)\r
1084 {\r
1085         if(CurHost.HostType == HTYPE_VMS)\r
1086                 return(YES);\r
1087         else\r
1088                 return(CurHost.NoFullPath);\r
1089 }\r
1090 \r
1091 \r
1092 /*----- 接続しているユーザ名を返す --------------------------------------------\r
1093 *\r
1094 *       Parameter\r
1095 *               なし\r
1096 *\r
1097 *       Return Value\r
1098 *               char *ユーザ名\r
1099 *----------------------------------------------------------------------------*/\r
1100 \r
1101 char *AskHostUserName(void)\r
1102 {\r
1103         return(CurHost.UserName);\r
1104 }\r
1105 \r
1106 \r
1107 /*----- 現在の設定をホストの設定にセットする ----------------------------------\r
1108 *\r
1109 *       Parameter\r
1110 *               なし\r
1111 *\r
1112 *       Return Value\r
1113 *               なし\r
1114 *\r
1115 *       Note\r
1116 *               カレントディレクトリ、ソート方法をホストの設定にセットする\r
1117 *----------------------------------------------------------------------------*/\r
1118 \r
1119 void SaveCurrentSetToHost(void)\r
1120 {\r
1121         int Host;\r
1122         char LocDir[FMAX_PATH+1];\r
1123         char HostDir[FMAX_PATH+1];\r
1124         // 同時接続対応\r
1125         HOSTDATA TmpHost;\r
1126         TmpHost = CurHost;\r
1127 \r
1128         if(TrnCtrlSocket != INVALID_SOCKET)\r
1129         {\r
1130                 if((Host = AskCurrentHost()) != HOSTNUM_NOENTRY)\r
1131                 {\r
1132                         // 同時接続対応\r
1133 //                      CopyHostFromListInConnect(Host, &CurHost);\r
1134 //                      if(CurHost.LastDir == YES)\r
1135                         CopyHostFromListInConnect(Host, &TmpHost);\r
1136                         if(TmpHost.LastDir == YES)\r
1137                         {\r
1138                                 AskLocalCurDir(LocDir, FMAX_PATH);\r
1139                                 AskRemoteCurDir(HostDir, FMAX_PATH);\r
1140                                 SetHostDir(AskCurrentHost(), LocDir, HostDir);\r
1141                         }\r
1142                         SetHostSort(AskCurrentHost(), AskSortType(ITEM_LFILE), AskSortType(ITEM_LDIR), AskSortType(ITEM_RFILE), AskSortType(ITEM_RDIR));\r
1143                 }\r
1144         }\r
1145         return;\r
1146 }\r
1147 \r
1148 \r
1149 /*----- 現在の設定をヒストリにセットする --------------------------------------\r
1150 *\r
1151 *       Parameter\r
1152 *               なし\r
1153 *\r
1154 *       Return Value\r
1155 *               なし\r
1156 *----------------------------------------------------------------------------*/\r
1157 \r
1158 static void SaveCurrentSetToHistory(void)\r
1159 {\r
1160         char LocDir[FMAX_PATH+1];\r
1161         char HostDir[FMAX_PATH+1];\r
1162 \r
1163         AskLocalCurDir(LocDir, FMAX_PATH);\r
1164         AskRemoteCurDir(HostDir, FMAX_PATH);\r
1165         strcpy(CurHost.LocalInitDir, LocDir);\r
1166         strcpy(CurHost.RemoteInitDir, HostDir);\r
1167 \r
1168         CurHost.Sort = AskSortType(ITEM_LFILE) * 0x1000000 | AskSortType(ITEM_LDIR) * 0x10000 | AskSortType(ITEM_RFILE) * 0x100 | AskSortType(ITEM_RDIR);\r
1169 \r
1170         CurHost.KanjiCode = AskHostKanjiCode();\r
1171         CurHost.KanaCnv = AskHostKanaCnv();\r
1172 \r
1173         CurHost.SyncMove = AskSyncMoveMode();\r
1174 \r
1175         AddHostToHistory(&CurHost, AskTransferType());\r
1176         SetAllHistoryToMenu();\r
1177 \r
1178         return;\r
1179 }\r
1180 \r
1181 \r
1182 /*----- コマンドコントロールソケットの再接続 ----------------------------------\r
1183 *\r
1184 *       Parameter\r
1185 *               なし\r
1186 *\r
1187 *       Return Value\r
1188 *               int ステータス\r
1189 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1190 *----------------------------------------------------------------------------*/\r
1191 \r
1192 int ReConnectCmdSkt(void)\r
1193 {\r
1194         int Sts;\r
1195 \r
1196 \r
1197         // 同時接続対応\r
1198 //      if(CmdCtrlSocket != TrnCtrlSocket)\r
1199 //              do_closesocket(TrnCtrlSocket);\r
1200 //      TrnCtrlSocket = INVALID_SOCKET;\r
1201         if(CmdCtrlSocket == TrnCtrlSocket)\r
1202                 TrnCtrlSocket = INVALID_SOCKET;\r
1203 \r
1204         Sts = ReConnectSkt(&CmdCtrlSocket);\r
1205 \r
1206         // 同時接続対応\r
1207 //      TrnCtrlSocket = CmdCtrlSocket;\r
1208         if(TrnCtrlSocket == INVALID_SOCKET)\r
1209                 TrnCtrlSocket = CmdCtrlSocket;\r
1210 \r
1211         return(Sts);\r
1212 }\r
1213 \r
1214 \r
1215 /*----- 転送コントロールソケットの再接続 --------------------------------------\r
1216 *\r
1217 *       Parameter\r
1218 *               なし\r
1219 *\r
1220 *       Return Value\r
1221 *               int ステータス\r
1222 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1223 *----------------------------------------------------------------------------*/\r
1224 \r
1225 //int ReConnectTrnSkt(void)\r
1226 //{\r
1227 //      return(ReConnectSkt(&TrnCtrlSocket));\r
1228 //}\r
1229 // 同時接続対応\r
1230 int ReConnectTrnSkt(SOCKET *Skt, int *CancelCheckWork)\r
1231 {\r
1232 //      char Path[FMAX_PATH+1];\r
1233         int Sts;\r
1234         // 暗号化通信対応\r
1235         HOSTDATA HostData;\r
1236 \r
1237         Sts = FFFTP_FAIL;\r
1238 \r
1239         SetTaskMsg(MSGJPN003);\r
1240 \r
1241 //      DisableUserOpe();\r
1242         /* 現在のソケットは切断 */\r
1243         if(*Skt != INVALID_SOCKET)\r
1244                 do_closesocket(*Skt);\r
1245         /* 再接続 */\r
1246         // 暗号化通信対応\r
1247         HostData = CurHost;\r
1248         if(HostData.CryptMode != CRYPT_NONE)\r
1249                 HostData.UseNoEncryption = NO;\r
1250         if(HostData.CryptMode != CRYPT_FTPES)\r
1251                 HostData.UseFTPES = NO;\r
1252         if(HostData.CryptMode != CRYPT_FTPIS)\r
1253                 HostData.UseFTPIS = NO;\r
1254         if(HostData.CryptMode != CRYPT_SFTP)\r
1255                 HostData.UseSFTP = NO;\r
1256         // UTF-8対応\r
1257         HostData.CurNameKanjiCode = HostData.NameKanjiCode;\r
1258         // IPv6対応\r
1259         HostData.CurNetType = HostData.NetType;\r
1260         // 同時接続対応\r
1261         HostData.NoDisplayUI = YES;\r
1262         // 暗号化通信対応\r
1263         // 同時接続対応\r
1264 //      if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
1265         if((*Skt = DoConnect(&HostData, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, CancelCheckWork)) != INVALID_SOCKET)\r
1266         {\r
1267                 SendInitCommand(*Skt, CurHost.InitCmd, CancelCheckWork);\r
1268 //              AskRemoteCurDir(Path, FMAX_PATH);\r
1269 //              DoCWD(Path, YES, YES, YES);\r
1270                 Sts = FFFTP_SUCCESS;\r
1271         }\r
1272         else\r
1273                 SoundPlay(SND_ERROR);\r
1274 \r
1275 //      EnableUserOpe();\r
1276         return(Sts);\r
1277 }\r
1278 \r
1279 \r
1280 /*----- 回線の再接続 ----------------------------------------------------------\r
1281 *\r
1282 *       Parameter\r
1283 *               SOCKET *Skt : 接続したソケットを返すワーク\r
1284 *\r
1285 *       Return Value\r
1286 *               int ステータス\r
1287 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1288 *----------------------------------------------------------------------------*/\r
1289 \r
1290 static int ReConnectSkt(SOCKET *Skt)\r
1291 {\r
1292         char Path[FMAX_PATH+1];\r
1293         int Sts;\r
1294 \r
1295         Sts = FFFTP_FAIL;\r
1296 \r
1297         SetTaskMsg(MSGJPN003);\r
1298 \r
1299         DisableUserOpe();\r
1300         /* 現在のソケットは切断 */\r
1301         if(*Skt != INVALID_SOCKET)\r
1302                 do_closesocket(*Skt);\r
1303         /* 再接続 */\r
1304         // 暗号化通信対応\r
1305         // 同時接続対応\r
1306 //      if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
1307         if((*Skt = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg)) != INVALID_SOCKET)\r
1308         {\r
1309                 SendInitCommand(*Skt, CurHost.InitCmd, &CancelFlg);\r
1310                 AskRemoteCurDir(Path, FMAX_PATH);\r
1311                 DoCWD(Path, YES, YES, YES);\r
1312                 Sts = FFFTP_SUCCESS;\r
1313         }\r
1314         else\r
1315                 SoundPlay(SND_ERROR);\r
1316 \r
1317         EnableUserOpe();\r
1318         return(Sts);\r
1319 }\r
1320 \r
1321 \r
1322 /*----- コマンドコントロールソケットを返す ------------------------------------\r
1323 *\r
1324 *       Parameter\r
1325 *               なし\r
1326 *\r
1327 *       Return Value\r
1328 *               SOCKET コマンドコントロールソケット\r
1329 *----------------------------------------------------------------------------*/\r
1330 \r
1331 SOCKET AskCmdCtrlSkt(void)\r
1332 {\r
1333         return(CmdCtrlSocket);\r
1334 }\r
1335 \r
1336 \r
1337 /*----- 転送コントロールソケットを返す ----------------------------------------\r
1338 *\r
1339 *       Parameter\r
1340 *               なし\r
1341 *\r
1342 *       Return Value\r
1343 *               SOCKET 転送コントロールソケット\r
1344 *----------------------------------------------------------------------------*/\r
1345 \r
1346 SOCKET AskTrnCtrlSkt(void)\r
1347 {\r
1348         return(TrnCtrlSocket);\r
1349 }\r
1350 \r
1351 \r
1352 /*----- コマンド/転送コントロールソケットの共有を解除 ------------------------\r
1353 *\r
1354 *       Parameter\r
1355 *               なし\r
1356 *\r
1357 *       Return Value\r
1358 *               なし\r
1359 *----------------------------------------------------------------------------*/\r
1360 \r
1361 void SktShareProh(void)\r
1362 {\r
1363         if(CmdCtrlSocket == TrnCtrlSocket)\r
1364         {\r
1365 \r
1366 //SetTaskMsg("############### SktShareProh");\r
1367 \r
1368                 // 同時接続対応\r
1369 //              CmdCtrlSocket = INVALID_SOCKET;\r
1370 //              ReConnectSkt(&CmdCtrlSocket);\r
1371                 if(CurHost.ReuseCmdSkt == YES)\r
1372                 {\r
1373                         CurHost.ReuseCmdSkt = NO;\r
1374                         CmdCtrlSocket = INVALID_SOCKET;\r
1375                         ReConnectSkt(&CmdCtrlSocket);\r
1376                 }\r
1377         }\r
1378         return;\r
1379 }\r
1380 \r
1381 \r
1382 /*----- コマンド/転送コントロールソケットの共有が解除されているかチェック ----\r
1383 *\r
1384 *       Parameter\r
1385 *               なし\r
1386 *\r
1387 *       Return Value\r
1388 *               int ステータス\r
1389 *                       YES=共有解除/NO=共有\r
1390 *----------------------------------------------------------------------------*/\r
1391 \r
1392 int AskShareProh(void)\r
1393 {\r
1394         int Sts;\r
1395 \r
1396         Sts = YES;\r
1397         // 同時接続対応\r
1398 //      if(CmdCtrlSocket == TrnCtrlSocket)\r
1399         if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET)\r
1400                 Sts = NO;\r
1401 \r
1402         return(Sts);\r
1403 }\r
1404 \r
1405 \r
1406 /*----- ホストから切断 --------------------------------------------------------\r
1407 *\r
1408 *       Parameter\r
1409 *               なし\r
1410 *\r
1411 *       Return Value\r
1412 *               なし\r
1413 *----------------------------------------------------------------------------*/\r
1414 \r
1415 void DisconnectProc(void)\r
1416 {\r
1417 \r
1418 //SetTaskMsg("############### Disconnect Cmd=%x, Trn=%x", CmdCtrlSocket,TrnCtrlSocket);\r
1419 \r
1420         if((CmdCtrlSocket != INVALID_SOCKET) && (CmdCtrlSocket != TrnCtrlSocket))\r
1421         {\r
1422                 // 同時接続対応\r
1423 //              DoQUIT(CmdCtrlSocket);\r
1424                 DoQUIT(CmdCtrlSocket, &CancelFlg);\r
1425                 DoClose(CmdCtrlSocket);\r
1426         }\r
1427 \r
1428         if(TrnCtrlSocket != INVALID_SOCKET)\r
1429         {\r
1430                 // 同時接続対応\r
1431 //              DoQUIT(TrnCtrlSocket);\r
1432                 DoQUIT(TrnCtrlSocket, &CancelFlg);\r
1433                 DoClose(TrnCtrlSocket);\r
1434 \r
1435                 SaveCurrentSetToHistory();\r
1436 \r
1437                 EraseRemoteDirForWnd();\r
1438                 SetTaskMsg(MSGJPN004);\r
1439         }\r
1440 \r
1441         TrnCtrlSocket = INVALID_SOCKET;\r
1442         CmdCtrlSocket = INVALID_SOCKET;\r
1443 \r
1444         DispWindowTitle();\r
1445         MakeButtonsFocus();\r
1446         ClearBookMark();\r
1447 \r
1448         return;\r
1449 }\r
1450 \r
1451 \r
1452 /*----- ソケットが強制切断されたときの処理 ------------------------------------\r
1453 *\r
1454 *       Parameter\r
1455 *               なし\r
1456 *\r
1457 *       Return Value\r
1458 *               なし\r
1459 *----------------------------------------------------------------------------*/\r
1460 \r
1461 void DisconnectSet(void)\r
1462 {\r
1463         CmdCtrlSocket = INVALID_SOCKET;\r
1464         TrnCtrlSocket = INVALID_SOCKET;\r
1465 \r
1466         EraseRemoteDirForWnd();\r
1467         DispWindowTitle();\r
1468         MakeButtonsFocus();\r
1469         SetTaskMsg(MSGJPN005);\r
1470         return;\r
1471 }\r
1472 \r
1473 \r
1474 /*----- ホストに接続中かどうかを返す ------------------------------------------\r
1475 *\r
1476 *       Parameter\r
1477 *               なし\r
1478 *\r
1479 *       Return Value\r
1480 *               int ステータス (YES/NO)\r
1481 *----------------------------------------------------------------------------*/\r
1482 \r
1483 int AskConnecting(void)\r
1484 {\r
1485         int Sts;\r
1486 \r
1487         Sts = NO;\r
1488         if(TrnCtrlSocket != INVALID_SOCKET)\r
1489                 Sts = YES;\r
1490 \r
1491         return(Sts);\r
1492 }\r
1493 \r
1494 \r
1495 #if defined(HAVE_TANDEM)\r
1496 /*----- 接続している本当のホストのホストタイプを返す --------------------------\r
1497 *\r
1498 *       Parameter\r
1499 *               なし\r
1500 *\r
1501 *       Return Value\r
1502 *               char *ファイル名/オプション\r
1503 *----------------------------------------------------------------------------*/\r
1504 \r
1505 int AskRealHostType(void)\r
1506 {\r
1507         // 同時接続対応\r
1508         HOSTDATA TmpHost;\r
1509         TmpHost = CurHost;\r
1510 \r
1511         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
1512                 // 同時接続対応\r
1513 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
1514                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
1515 \r
1516         // 同時接続対応\r
1517 //      return(CurHost.HostType);\r
1518         return(TmpHost.HostType);\r
1519 }\r
1520 \r
1521 /*----- OSS ファイルシステムにアクセスしているかどうかのフラグを変更する ------\r
1522 *\r
1523 *       Parameter\r
1524 *               int ステータス (YES/NO)\r
1525 *\r
1526 *       Return Value\r
1527 *               int ステータス (YES/NO)\r
1528 *----------------------------------------------------------------------------*/\r
1529 \r
1530 int SetOSS(int wkOss)\r
1531 {\r
1532         if(Oss != wkOss) {\r
1533                 if (wkOss == YES) {\r
1534                         strcpy(CurHost.InitCmd, "OSS");\r
1535                 } else {\r
1536                         strcpy(CurHost.InitCmd, "GUARDIAN");\r
1537                 }\r
1538         }\r
1539         Oss = wkOss;\r
1540         return(Oss);\r
1541 }\r
1542 \r
1543 /*----- OSS ファイルシステムにアクセスしているかどうかを返す ------------------\r
1544 *\r
1545 *       Parameter\r
1546 *               なし\r
1547 *\r
1548 *       Return Value\r
1549 *               int ステータス (YES/NO)\r
1550 *----------------------------------------------------------------------------*/\r
1551 \r
1552 int AskOSS(void)\r
1553 {\r
1554         return(Oss);\r
1555 }\r
1556 #endif /* HAVE_TANDEM */\r
1557 \r
1558 \r
1559 /*----- ホストへ接続する ------------------------------------------------------\r
1560 *\r
1561 *       Parameter\r
1562 *               char *Host : ホスト名\r
1563 *               char *User : ユーザ名\r
1564 *               char *Pass : パスワード\r
1565 *               char *Acct : アカウント\r
1566 *               int Port : ポート\r
1567 *               int Fwall : FireWallを使うかどうか (YES/NO)\r
1568 *               int SavePass : パスワードを再入力した時に保存するかどうか (YES/NO)\r
1569 *               int Security : セキュリティ (SECURITY_xxx, MDx)\r
1570 *\r
1571 *       Return Value\r
1572 *               SOCKET ソケット\r
1573 *\r
1574 *       Note\r
1575 *               ホスト名、ユーザ名、パスワードが指定されていなかったときは、接続に使用\r
1576 *               したものをコピーしてかえす\r
1577 *                       char *Host : ホスト名\r
1578 *                       char *User : ユーザ名\r
1579 *                       char *Pass : パスワード\r
1580 *                       char *Acct : アカウント\r
1581 *\r
1582 *               FireWallは次のように動作する\r
1583 *                       TYPE1   Connect fire → USER user(f) → PASS pass(f) → SITE host → USER user(h) →      PASS pass(h) → ACCT acct\r
1584 *                       TYPE2   Connect fire → USER user(f) → PASS pass(f) →              USER user(h)@host → PASS pass(h) → ACCT acct\r
1585 *                       TYPE3   Connect fire →                                              USER user(h)@host → PASS pass(h) → ACCT acct\r
1586 *                       TYPE4   Connect fire →                                 OPEN host → USER user(h) →      PASS pass(h) → ACCT acct\r
1587 *                       TYPE5   SOCKS4\r
1588 *                       none    Connect host →                                              USER user(h) →      PASS pass(h) → ACCT acct\r
1589 *----------------------------------------------------------------------------*/\r
1590 \r
1591 // 暗号化通信対応\r
1592 static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
1593 {\r
1594         int Sts;\r
1595         int Flg;\r
1596         int Anony;\r
1597         SOCKET ContSock;\r
1598         char Buf[1024];\r
1599         char Reply[1024];\r
1600         int Continue;\r
1601         int ReInPass;\r
1602         char *Tmp;\r
1603         int HostPort;\r
1604         static const char *SiteTbl[4] = { "SITE", "site", "OPEN", "open" };\r
1605         char TmpBuf[ONELINE_BUF_SIZE];\r
1606         struct linger LingerOpt;\r
1607         struct tcp_keepalive KeepAlive;\r
1608         DWORD dwTmp;\r
1609 \r
1610         // 暗号化通信対応\r
1611         ContSock = INVALID_SOCKET;\r
1612 \r
1613         if(CryptMode == CRYPT_NONE || CryptMode == CRYPT_FTPES || CryptMode == CRYPT_FTPIS)\r
1614         {\r
1615                 if(Fwall == YES)\r
1616                         Fwall = FwallType;\r
1617                 else\r
1618                         Fwall = FWALL_NONE;\r
1619 \r
1620                 TryConnect = YES;\r
1621                 // 暗号化通信対応\r
1622 //              CancelFlg = NO;\r
1623 #if 0\r
1624 //              WSASetBlockingHook(BlkHookFnc);\r
1625 #endif\r
1626 \r
1627                 ContSock = INVALID_SOCKET;\r
1628 \r
1629                 HostPort = Port;\r
1630                 Tmp = Host;\r
1631                 if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1632                    (Fwall == FWALL_SIDEWINDER) ||\r
1633                    (Fwall == FWALL_FU_FP))\r
1634                 {\r
1635                         Tmp = FwallHost;\r
1636                         Port = FwallPort;\r
1637                 }\r
1638 \r
1639                 if(strlen(Tmp) != 0)\r
1640                 {\r
1641                         // 同時接続対応\r
1642 //                      if((ContSock = connectsock(Tmp, Port, "", &CancelFlg)) != INVALID_SOCKET)\r
1643                         if((ContSock = connectsock(Tmp, Port, "", CancelCheckWork)) != INVALID_SOCKET)\r
1644                         {\r
1645                                 // バッファを無効\r
1646 #ifdef DISABLE_CONTROL_NETWORK_BUFFERS\r
1647                                 int BufferSize = 0;\r
1648                                 setsockopt(ContSock, SOL_SOCKET, SO_SNDBUF, (char*)&BufferSize, sizeof(int));\r
1649                                 setsockopt(ContSock, SOL_SOCKET, SO_RCVBUF, (char*)&BufferSize, sizeof(int));\r
1650 #endif\r
1651                                 // FTPIS対応\r
1652 //                              while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM)\r
1653 //                                      ;\r
1654                                 if(CryptMode == CRYPT_FTPIS)\r
1655                                 {\r
1656                                         if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork, HostData->NoWeakEncryption))\r
1657                                         {\r
1658                                                 while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
1659                                                         ;\r
1660                                         }\r
1661                                         else\r
1662                                                 Sts = FTP_ERROR;\r
1663                                 }\r
1664                                 else\r
1665                                 {\r
1666                                         while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
1667                                                 ;\r
1668                                 }\r
1669 \r
1670                                 if(Sts == FTP_COMPLETE)\r
1671                                 {\r
1672                                         Flg = 1;\r
1673                                         if(setsockopt(ContSock, SOL_SOCKET, SO_OOBINLINE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1674                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1675                                         // データ転送用ソケットのTCP遅延転送が無効されているので念のため\r
1676                                         if(setsockopt(ContSock, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1677                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1678 //#pragma aaa\r
1679                                         Flg = 1;\r
1680                                         if(setsockopt(ContSock, SOL_SOCKET, SO_KEEPALIVE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1681                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1682                                         // 切断対策\r
1683                                         if(TimeOut > 0)\r
1684                                         {\r
1685                                                 KeepAlive.onoff = 1;\r
1686                                                 KeepAlive.keepalivetime = TimeOut * 1000;\r
1687                                                 KeepAlive.keepaliveinterval = 1000;\r
1688                                                 if(WSAIoctl(ContSock, SIO_KEEPALIVE_VALS, &KeepAlive, sizeof(struct tcp_keepalive), NULL, 0, &dwTmp, NULL, NULL) == SOCKET_ERROR)\r
1689                                                         ReportWSError("WSAIoctl", WSAGetLastError());\r
1690                                         }\r
1691                                         LingerOpt.l_onoff = 1;\r
1692                                         LingerOpt.l_linger = 90;\r
1693                                         if(setsockopt(ContSock, SOL_SOCKET, SO_LINGER, (LPSTR)&LingerOpt, sizeof(LingerOpt)) == SOCKET_ERROR)\r
1694                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1695 ///////\r
1696 \r
1697 \r
1698                                         /*===== 認証を行なう =====*/\r
1699 \r
1700                                         Sts = FTP_COMPLETE;\r
1701                                         if((Fwall == FWALL_FU_FP_SITE) ||\r
1702                                            (Fwall == FWALL_FU_FP_USER) ||\r
1703                                            (Fwall == FWALL_FU_FP))\r
1704                                         {\r
1705                                                 // 同時接続対応\r
1706 //                                              if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
1707                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
1708                                                 {\r
1709                                                         CheckOneTimePassword(FwallPass, Reply, FwallSecurity);\r
1710                                                         // 同時接続対応\r
1711 //                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1712                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1713                                                 }\r
1714                                         }\r
1715                                         else if(Fwall == FWALL_SIDEWINDER)\r
1716                                         {\r
1717                                                 // 同時接続対応\r
1718 //                                              Sts = command(ContSock, Reply, &CancelFlg, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
1719                                                 Sts = command(ContSock, Reply, CancelCheckWork, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
1720                                         }\r
1721                                         if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
1722                                         {\r
1723                                                 SetTaskMsg(MSGJPN006);\r
1724                                                 DoClose(ContSock);\r
1725                                                 ContSock = INVALID_SOCKET;\r
1726                                         }\r
1727                                         else\r
1728                                         {\r
1729                                                 if((Fwall == FWALL_FU_FP_SITE) || (Fwall == FWALL_OPEN))\r
1730                                                 {\r
1731                                                         Flg = 0;\r
1732                                                         if(Fwall == FWALL_OPEN)\r
1733                                                                 Flg = 2;\r
1734                                                         if(FwallLower == YES)\r
1735                                                                 Flg++;\r
1736 \r
1737                                                         if(HostPort == PORT_NOR)\r
1738                                                                 // 同時接続対応\r
1739 //                                                              Sts = command(ContSock, NULL, &CancelFlg, "%s %s", SiteTbl[Flg], Host) / 100;\r
1740                                                                 Sts = command(ContSock, NULL, CancelCheckWork, "%s %s", SiteTbl[Flg], Host) / 100;\r
1741                                                         else\r
1742                                                                 // 同時接続対応\r
1743 //                                                              Sts = command(ContSock, NULL, &CancelFlg, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
1744                                                                 Sts = command(ContSock, NULL, CancelCheckWork, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
1745                                                 }\r
1746 \r
1747                                                 if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
1748                                                 {\r
1749                                                         SetTaskMsg(MSGJPN007, Host);\r
1750                                                         DoClose(ContSock);\r
1751                                                         ContSock = INVALID_SOCKET;\r
1752                                                 }\r
1753                                                 else\r
1754                                                 {\r
1755                                                         Anony = NO;\r
1756                                                         // 同時接続対応\r
1757 //                                                      if((strlen(User) != 0) || \r
1758 //                                                         (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1759                                                         if((strlen(User) != 0) || \r
1760                                                            ((HostData->NoDisplayUI == NO) && (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1761                                                         {\r
1762                                                                 if(Anony == YES)\r
1763                                                                 {\r
1764                                                                         strcpy(User, "anonymous");\r
1765                                                                         strcpy(Pass, UserMailAdrs);\r
1766                                                                 }\r
1767 \r
1768                                                                 if((Fwall == FWALL_FU_FP_USER) || (Fwall == FWALL_USER))\r
1769                                                                 {\r
1770                                                                         if(HostPort == PORT_NOR)\r
1771                                                                                 sprintf(Buf, "%s%c%s", User, FwallDelimiter, Host);\r
1772                                                                         else\r
1773                                                                                 sprintf(Buf, "%s%c%s %d", User, FwallDelimiter, Host, HostPort);\r
1774                                                                 }\r
1775                                                                 else\r
1776                                                                         strcpy(Buf, User);\r
1777 \r
1778                                                                 // FTPES対応\r
1779                                                                 if(CryptMode == CRYPT_FTPES)\r
1780                                                                 {\r
1781                                                                         if(IsOpenSSLLoaded() && ((Sts = command(ContSock, Reply, CancelCheckWork, "AUTH TLS")) == 234 || (Sts = command(ContSock, Reply, CancelCheckWork, "AUTH SSL")) == 234))\r
1782                                                                         {\r
1783                                                                                 if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork, HostData->NoWeakEncryption))\r
1784                                                                                 {\r
1785                                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1786                                                                                         {\r
1787                                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1788                                                                                                 {\r
1789                                                                                                 }\r
1790                                                                                                 else\r
1791                                                                                                         Sts = FTP_ERROR;\r
1792                                                                                         }\r
1793                                                                                         else\r
1794                                                                                                 Sts = FTP_ERROR;\r
1795                                                                                 }\r
1796                                                                                 else\r
1797                                                                                         Sts = FTP_ERROR;\r
1798                                                                         }\r
1799                                                                         else\r
1800                                                                                 Sts = FTP_ERROR;\r
1801                                                                 }\r
1802 \r
1803                                                                 // FTPIS対応\r
1804                                                                 // "PBSZ 0"と"PROT P"は黙示的に設定されているはずだが念のため\r
1805                                                                 if(CryptMode == CRYPT_FTPIS)\r
1806                                                                 {\r
1807                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1808                                                                         {\r
1809                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1810                                                                                 {\r
1811                                                                                 }\r
1812                                                                         }\r
1813                                                                 }\r
1814 \r
1815                                                                 ReInPass = NO;\r
1816                                                                 do\r
1817                                                                 {\r
1818                                                                         // FTPES対応\r
1819                                                                         if(Sts == FTP_ERROR)\r
1820                                                                                 break;\r
1821                                                                         Continue = NO;\r
1822                                                                         // 同時接続対応\r
1823 //                                                                      if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1824                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1825                                                                         {\r
1826                                                                                 // 同時接続対応\r
1827 //                                                                              if((strlen(Pass) != 0) || \r
1828 //                                                                                 (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1829                                                                                 if((strlen(Pass) != 0) || \r
1830                                                                                    ((HostData->NoDisplayUI == NO) && (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1831                                                                                 {\r
1832                                                                                         CheckOneTimePassword(Pass, Reply, Security);\r
1833 \r
1834                                                                                         /* パスワードがスペース1個の時はパスワードの実体なしとする */\r
1835                                                                                         if(strcmp(Reply, " ") == 0)\r
1836                                                                                                 strcpy(Reply, "");\r
1837 \r
1838                                                                                         // 同時接続対応\r
1839 //                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1840                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1841                                                                                         if(Sts == FTP_ERROR)\r
1842                                                                                         {\r
1843                                                                                                 strcpy(Pass, "");\r
1844                                                                                                 // 同時接続対応\r
1845 //                                                                                              if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1846                                                                                                 if(HostData->NoDisplayUI == NO && InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1847                                                                                                         Continue = YES;\r
1848                                                                                                 else\r
1849                                                                                                         DoPrintf("No password specified.");\r
1850                                                                                                 ReInPass = YES;\r
1851                                                                                         }\r
1852                                                                                         else if(Sts == FTP_CONTINUE)\r
1853                                                                                         {\r
1854                                                                                                 // 同時接続対応\r
1855 //                                                                                              if((strlen(Acct) != 0) || \r
1856 //                                                                                                 (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1857                                                                                                 if((strlen(Acct) != 0) || \r
1858                                                                                                    ((HostData->NoDisplayUI == NO) && (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1859                                                                                                 {\r
1860                                                                                                         // 同時接続対応\r
1861 //                                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100;\r
1862                                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "ACCT %s", Acct) / 100;\r
1863                                                                                                 }\r
1864                                                                                                 else\r
1865                                                                                                         DoPrintf("No account specified");\r
1866                                                                                         }\r
1867                                                                                 }\r
1868                                                                                 else\r
1869                                                                                 {\r
1870                                                                                         Sts = FTP_ERROR;\r
1871                                                                                         DoPrintf("No password specified.");\r
1872                                                                                 }\r
1873                                                                         }\r
1874                                                                         // FTPES対応\r
1875                                                                         if(Continue == YES)\r
1876                                                                                 Sts = FTP_COMPLETE;\r
1877                                                                 }\r
1878                                                                 while(Continue == YES);\r
1879                                                         }\r
1880                                                         else\r
1881                                                         {\r
1882                                                                 Sts = FTP_ERROR;\r
1883                                                                 DoPrintf("No user name specified");\r
1884                                                         }\r
1885 \r
1886                                                         if(Sts != FTP_COMPLETE)\r
1887                                                         {\r
1888                                                                 SetTaskMsg(MSGJPN008, Host);\r
1889                                                                 DoClose(ContSock);\r
1890                                                                 ContSock = INVALID_SOCKET;\r
1891                                                         }\r
1892                                                         else if((SavePass == YES) && (ReInPass == YES))\r
1893                                                         {\r
1894                                                                 // 同時接続対応\r
1895 //                                                              if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1896                                                                 if(HostData->NoDisplayUI == NO && DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1897                                                                         SetHostPassword(AskCurrentHost(), Pass);\r
1898                                                         }\r
1899                                                 }\r
1900                                         }\r
1901                                 }\r
1902                                 else\r
1903                                 {\r
1904 //#pragma aaa\r
1905                                         SetTaskMsg(MSGJPN009/*"接続できません(1) %x", ContSock*/);\r
1906                                         DoClose(ContSock);\r
1907                                         ContSock = INVALID_SOCKET;\r
1908                                 }\r
1909                         }\r
1910                 }\r
1911                 else\r
1912                 {\r
1913 \r
1914                         if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1915                            (Fwall == FWALL_FU_FP))\r
1916                                 SetTaskMsg(MSGJPN010);\r
1917                         else\r
1918                                 SetTaskMsg(MSGJPN011);\r
1919                 }\r
1920 \r
1921 #if 0\r
1922 //              WSAUnhookBlockingHook();\r
1923 #endif\r
1924                 TryConnect = NO;\r
1925 \r
1926                 // FEAT対応\r
1927                 // ホストの機能を確認\r
1928                 if(ContSock != INVALID_SOCKET)\r
1929                 {\r
1930                         if((Sts = command(ContSock, Reply, CancelCheckWork, "FEAT")) == 211)\r
1931                         {\r
1932                                 // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用\r
1933                                 // UTF-8対応\r
1934                                 if(strstr(Reply, " UTF8 "))\r
1935                                         HostData->Feature |= FEATURE_UTF8;\r
1936                                 // MLST対応\r
1937                                 if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD "))\r
1938                                         HostData->Feature |= FEATURE_MLSD;\r
1939                                 // IPv6対応\r
1940                                 if(strstr(Reply, " EPRT ") || strstr(Reply, " EPSV "))\r
1941                                         HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV;\r
1942                                 // ホスト側の日時取得\r
1943                                 if(strstr(Reply, " MDTM "))\r
1944                                         HostData->Feature |= FEATURE_MDTM;\r
1945                                 // ホスト側の日時設定\r
1946                                 if(strstr(Reply, " MFMT "))\r
1947                                         HostData->Feature |= FEATURE_MFMT;\r
1948                         }\r
1949                         // UTF-8対応\r
1950                         if(HostData->CurNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
1951                         {\r
1952                                 // UTF-8を指定した場合も自動判別を行う\r
1953 //                              if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200)\r
1954 //                                      HostData->CurNameKanjiCode = KANJI_UTF8N;\r
1955                                 command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON");\r
1956                         }\r
1957                 }\r
1958         }\r
1959 \r
1960         return(ContSock);\r
1961 }\r
1962 \r
1963 // 同時接続対応\r
1964 //static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security)\r
1965 static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
1966 {\r
1967         SOCKET ContSock;\r
1968         ContSock = INVALID_SOCKET;\r
1969         *CancelCheckWork = NO;\r
1970         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
1971         {\r
1972                 SetTaskMsg(MSGJPN316);\r
1973                 if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1974                         HostData->CryptMode = CRYPT_FTPIS;\r
1975         }\r
1976         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES)\r
1977         {\r
1978                 SetTaskMsg(MSGJPN315);\r
1979                 if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1980                         HostData->CryptMode = CRYPT_FTPES;\r
1981         }\r
1982         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES)\r
1983         {\r
1984                 SetTaskMsg(MSGJPN314);\r
1985                 if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1986                         HostData->CryptMode = CRYPT_NONE;\r
1987         }\r
1988         return ContSock;\r
1989 }\r
1990 \r
1991 \r
1992 /*----- ワンタイムパスワードのチェック ----------------------------------------\r
1993 *\r
1994 *       Parameter\r
1995 *               chat *Pass : パスワード/パスフレーズ\r
1996 *               char *Reply : USERコマンドを送ったあとのリプライ文字列\r
1997 *                                               /PASSコマンドで送るパスワードを返すバッファ\r
1998 *               int Type : タイプ (SECURITY_xxx, MDx)\r
1999 *\r
2000 *       Return Value\r
2001 *               int ステータス\r
2002 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2003 *\r
2004 *       Note\r
2005 *               ワンタイムパスワードでない時はPassをそのままReplyにコピー\r
2006 *----------------------------------------------------------------------------*/\r
2007 \r
2008 static int CheckOneTimePassword(char *Pass, char *Reply, int Type)\r
2009 {\r
2010         int Sts;\r
2011         char *Pos;\r
2012         int Seq;\r
2013         char Seed[MAX_SEED_LEN+1];\r
2014         int i;\r
2015 \r
2016         Sts = FFFTP_SUCCESS;\r
2017         Pos = NULL;\r
2018 \r
2019         if(Type == SECURITY_AUTO)\r
2020         {\r
2021                 if((Pos = stristr(Reply, "otp-md5")) != NULL)\r
2022                 {\r
2023                         Type = MD5;\r
2024                         SetTaskMsg(MSGJPN012);\r
2025                 }\r
2026                 else if((Pos = stristr(Reply, "otp-sha1")) != NULL)\r
2027                 {\r
2028                         Type = SHA1;\r
2029                         SetTaskMsg(MSGJPN013);\r
2030                 }\r
2031                 else if(((Pos = stristr(Reply, "otp-md4")) != NULL) || ((Pos = stristr(Reply, "s/key")) != NULL))\r
2032                 {\r
2033                         Type = MD4;\r
2034                         SetTaskMsg(MSGJPN014);\r
2035                 }\r
2036         }\r
2037         else\r
2038                 Pos = GetNextField(Reply);\r
2039 \r
2040         if((Type == MD4) || (Type == MD5) || (Type == SHA1))\r
2041         {\r
2042                 /* シーケンス番号を見つけるループ */\r
2043                 DoPrintf("Analyze OTP");\r
2044                 DoPrintf("%s", Pos);\r
2045                 Sts = FFFTP_FAIL;\r
2046                 while((Pos = GetNextField(Pos)) != NULL)\r
2047                 {\r
2048                         if(IsDigit(*Pos))\r
2049                         {\r
2050                                 Seq = atoi(Pos);\r
2051                                 DoPrintf("Sequence=%d", Seq);\r
2052 \r
2053                                 /* Seed */\r
2054                                 if((Pos = GetNextField(Pos)) != NULL)\r
2055                                 {\r
2056                                         if(GetOneField(Pos, Seed, MAX_SEED_LEN) == FFFTP_SUCCESS)\r
2057                                         {\r
2058                                                 /* Seedは英数字のみ有効とする */\r
2059                                                 for(i = strlen(Seed)-1; i >= 0; i--)\r
2060                                                 {\r
2061                                                         if((IsAlpha(Seed[i]) == 0) && (IsDigit(Seed[i]) == 0))\r
2062                                                                 Seed[i] = NUL;\r
2063                                                 }\r
2064                                                 if(strlen(Seed) > 0)\r
2065                                                 {\r
2066                                                         DoPrintf("Seed=%s", Seed);\r
2067                                                         Make6WordPass(Seq, Seed, Pass, Type, Reply);\r
2068                                                         DoPrintf("Response=%s", Reply);\r
2069 \r
2070                                                         /* シーケンス番号のチェックと警告 */\r
2071                                                         if(Seq <= 10)\r
2072                                                                 DialogBox(GetFtpInst(), MAKEINTRESOURCE(otp_notify_dlg), GetMainHwnd(), ExeEscDialogProc);\r
2073 \r
2074                                                         Sts = FFFTP_SUCCESS;\r
2075                                                 }\r
2076                                         }\r
2077                                 }\r
2078                                 break;\r
2079                         }\r
2080                 }\r
2081 \r
2082                 if(Sts == FFFTP_FAIL)\r
2083                         SetTaskMsg(MSGJPN015);\r
2084         }\r
2085         else\r
2086         {\r
2087                 strcpy(Reply, Pass);\r
2088                 DoPrintf("No OTP used.");\r
2089         }\r
2090         return(Sts);\r
2091 }\r
2092 \r
2093 \r
2094 \r
2095 \r
2096 \r
2097 \r
2098 \r
2099 \r
2100 \r
2101 \r
2102 \r
2103 \r
2104 \r
2105 \r
2106 /*----- ソケットを接続する ----------------------------------------------------\r
2107 *\r
2108 *       Parameter\r
2109 *               char *host : ホスト名\r
2110 *               int port : ポート番号\r
2111 *               char *PreMsg : メッセージの前半部分\r
2112 *\r
2113 *       Return Value\r
2114 *               SOCKET ソケット\r
2115 *----------------------------------------------------------------------------*/\r
2116 \r
2117 // IPv6対応\r
2118 typedef SOCKET (__cdecl* LPCONNECTSOCK)(char*, int, char*, int*);\r
2119 \r
2120 typedef struct\r
2121 {\r
2122         HANDLE h;\r
2123         DWORD ExitCode;\r
2124         char *host;\r
2125         int port;\r
2126         char *PreMsg;\r
2127         int CancelCheckWork;\r
2128         LPCONNECTSOCK f;\r
2129         SOCKET s;\r
2130 } CONNECTSOCKDATA;\r
2131 \r
2132 DWORD WINAPI connectsockThreadProc(LPVOID lpParameter)\r
2133 {\r
2134         CONNECTSOCKDATA* pData;\r
2135         pData = (CONNECTSOCKDATA*)lpParameter;\r
2136         pData->s = pData->f(pData->host, pData->port, pData->PreMsg, &pData->CancelCheckWork);\r
2137         return 0;\r
2138 }\r
2139 \r
2140 // IPv6対応\r
2141 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2142 {\r
2143         SOCKET Result;\r
2144         CONNECTSOCKDATA DataIPv4;\r
2145         CONNECTSOCKDATA DataIPv6;\r
2146         Result = INVALID_SOCKET;\r
2147         switch(CurHost.CurNetType)\r
2148         {\r
2149         case NTYPE_AUTO:\r
2150 //              if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
2151 //                      CurHost.CurNetType = NTYPE_IPV4;\r
2152 //              else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
2153 //                      CurHost.CurNetType = NTYPE_IPV6;\r
2154                 DataIPv4.host = host;\r
2155                 DataIPv4.port = port;\r
2156                 DataIPv4.PreMsg = PreMsg;\r
2157                 DataIPv4.CancelCheckWork = *CancelCheckWork;\r
2158                 DataIPv4.f = connectsockIPv4;\r
2159                 DataIPv4.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv4, 0, NULL);\r
2160                 DataIPv6.host = host;\r
2161                 DataIPv6.port = port;\r
2162                 DataIPv6.PreMsg = PreMsg;\r
2163                 DataIPv6.CancelCheckWork = *CancelCheckWork;\r
2164                 DataIPv6.f = connectsockIPv6;\r
2165                 DataIPv6.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv6, 0, NULL);\r
2166                 while(1)\r
2167                 {\r
2168                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode))\r
2169                         {\r
2170                                 if(DataIPv4.ExitCode != STILL_ACTIVE)\r
2171                                 {\r
2172                                         if(DataIPv4.s != INVALID_SOCKET)\r
2173                                         {\r
2174                                                 Result = DataIPv4.s;\r
2175                                                 CurHost.CurNetType = NTYPE_IPV4;\r
2176                                                 break;\r
2177                                         }\r
2178                                 }\r
2179                         }\r
2180                         if(GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2181                         {\r
2182                                 if(DataIPv6.ExitCode != STILL_ACTIVE)\r
2183                                 {\r
2184                                         if(DataIPv6.s != INVALID_SOCKET)\r
2185                                         {\r
2186                                                 Result = DataIPv6.s;\r
2187                                                 CurHost.CurNetType = NTYPE_IPV6;\r
2188                                                 break;\r
2189                                         }\r
2190                                 }\r
2191                         }\r
2192                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2193                         {\r
2194                                 if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
2195                                 {\r
2196                                         if(DataIPv4.s == INVALID_SOCKET && DataIPv6.s == INVALID_SOCKET)\r
2197                                                 break;\r
2198                                 }\r
2199                         }\r
2200                         DataIPv4.CancelCheckWork = *CancelCheckWork;\r
2201                         DataIPv6.CancelCheckWork = *CancelCheckWork;\r
2202                         BackgrndMessageProc();\r
2203                         Sleep(1);\r
2204                 }\r
2205                 while(1)\r
2206                 {\r
2207                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2208                         {\r
2209                                 if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
2210                                 {\r
2211                                         CloseHandle(DataIPv4.h);\r
2212                                         CloseHandle(DataIPv6.h);\r
2213                                         break;\r
2214                                 }\r
2215                         }\r
2216                         DataIPv4.CancelCheckWork = YES;\r
2217                         DataIPv6.CancelCheckWork = YES;\r
2218                         BackgrndMessageProc();\r
2219                         Sleep(1);\r
2220                 }\r
2221                 break;\r
2222         case NTYPE_IPV4:\r
2223                 Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
2224                 CurHost.CurNetType = NTYPE_IPV4;\r
2225                 break;\r
2226         case NTYPE_IPV6:\r
2227                 Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
2228                 CurHost.CurNetType = NTYPE_IPV6;\r
2229                 break;\r
2230         }\r
2231         return Result;\r
2232 }\r
2233 \r
2234 \r
2235 // IPv6対応\r
2236 //SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2237 SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2238 {\r
2239         // IPv6対応\r
2240         struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
2241         struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
2242         struct sockaddr_in saSockAddr;\r
2243         char HostEntry[MAXGETHOSTSTRUCT];\r
2244         struct hostent *pHostEntry;\r
2245         SOCKET sSocket;\r
2246         int Len;\r
2247         int Fwall;\r
2248         SOCKS4CMD Socks4Cmd;\r
2249         SOCKS4REPLY Socks4Reply;\r
2250         SOCKS5REQUEST Socks5Cmd;\r
2251         SOCKS5REPLY Socks5Reply;\r
2252 \r
2253         //////////////////////////////\r
2254         // ホスト名解決と接続の準備\r
2255         //////////////////////////////\r
2256 \r
2257         Fwall = FWALL_NONE;\r
2258         if(AskHostFireWall() == YES)\r
2259                 Fwall = FwallType;\r
2260 \r
2261         sSocket = INVALID_SOCKET;\r
2262 \r
2263         UseIPadrs = YES;\r
2264         strcpy(DomainName, host);\r
2265         memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2266         CurSockAddr.sin_port = htons((u_short)port);\r
2267         CurSockAddr.sin_family = AF_INET;\r
2268         if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
2269         {\r
2270                 // ホスト名が指定された\r
2271                 // ホスト名からアドレスを求める\r
2272                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2273                    (FwallResolve == YES))\r
2274                 {\r
2275                         // ホスト名解決はSOCKSサーバに任せる\r
2276                         pHostEntry = NULL;\r
2277                 }\r
2278                 else\r
2279                 {\r
2280                         // アドレスを取得\r
2281                         // IPv6対応\r
2282 //                      SetTaskMsg(MSGJPN016, DomainName);\r
2283                         SetTaskMsg(MSGJPN016, DomainName, MSGJPN333);\r
2284                         // IPv6対応\r
2285 //                      pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2286                         pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2287                 }\r
2288 \r
2289                 if(pHostEntry != NULL)\r
2290                 {\r
2291                         memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2292                         // IPv6対応\r
2293 //                      SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2294                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2295                 }\r
2296                 else\r
2297                 {\r
2298                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2299                         {\r
2300                                 UseIPadrs = NO;\r
2301                                 // IPv6対応\r
2302 //                              SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
2303                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2304                         }\r
2305                         else\r
2306                         {\r
2307                                 // IPv6対応\r
2308 //                              SetTaskMsg(MSGJPN019, host);\r
2309                                 SetTaskMsg(MSGJPN019, host, MSGJPN333);\r
2310                                 return(INVALID_SOCKET);\r
2311                         }\r
2312                 }\r
2313         }\r
2314         else\r
2315                 // IPv6対応\r
2316 //              SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2317                 SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2318 \r
2319         if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2320         {\r
2321                 // SOCKSを使う\r
2322                 // SOCKSに接続する準備\r
2323                 if(Fwall == FWALL_SOCKS4)\r
2324                 {\r
2325                         Socks4Cmd.Ver = SOCKS4_VER;\r
2326                         Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
2327                         Socks4Cmd.Port = CurSockAddr.sin_port;\r
2328                         Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2329                         strcpy(Socks4Cmd.UserID, FwallUser);\r
2330                         Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2331                 }\r
2332                 else\r
2333                 {\r
2334                         Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2335                 }\r
2336 \r
2337                 memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2338                 if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
2339                 {\r
2340                         // IPv6対応\r
2341 //                      if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2342                         if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2343                                 memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2344                         else\r
2345                         {\r
2346                                 // IPv6対応\r
2347 //                              SetTaskMsg(MSGJPN021, FwallHost);\r
2348                                 SetTaskMsg(MSGJPN021, FwallHost, MSGJPN333);\r
2349                                 return INVALID_SOCKET;\r
2350                         }\r
2351                 }\r
2352                 SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
2353                 SocksSockAddr.sin_family = AF_INET;\r
2354                 // IPv6対応\r
2355 //              SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
2356                 SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port), MSGJPN333);\r
2357                 // connectで接続する先はSOCKSサーバ\r
2358                 memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2359         }\r
2360         else\r
2361         {\r
2362                 // connectで接続するのは接続先のホスト\r
2363                 memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2364         }\r
2365 \r
2366         /////////////\r
2367         // 接続実行\r
2368         /////////////\r
2369 \r
2370         if((sSocket = do_socket(AF_INET, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2371         {\r
2372                 // ソケットにデータを付与\r
2373                 SetAsyncTableDataIPv4(sSocket, &CurSockAddr, &SocksSockAddr);\r
2374                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2375                 {\r
2376                         if(Fwall == FWALL_SOCKS4)\r
2377                         {\r
2378                                 Socks4Reply.Result = -1;\r
2379                                 // 同時接続対応\r
2380 //                              if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2381 //                                 (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || \r
2382 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2383                                 if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2384                                    (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2385                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2386                                 {\r
2387                                         // IPv6対応\r
2388 //                                      SetTaskMsg(MSGJPN023, Socks4Reply.Result);\r
2389                                         SetTaskMsg(MSGJPN023, Socks4Reply.Result, MSGJPN333);\r
2390                                         DoClose(sSocket);\r
2391                                         sSocket = INVALID_SOCKET;\r
2392                                 }\r
2393                         }\r
2394                         else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2395                         {\r
2396                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2397                                 {\r
2398                                         DoClose(sSocket);\r
2399                                         sSocket = INVALID_SOCKET;\r
2400                                 }\r
2401 \r
2402                                 Socks5Reply.Result = -1;\r
2403                                 // 同時接続対応\r
2404 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2405 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2406 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2407                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2408                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2409                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2410                                 {\r
2411                                         // IPv6対応\r
2412 //                                      SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2413                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN333);\r
2414                                         DoClose(sSocket);\r
2415                                         sSocket = INVALID_SOCKET;\r
2416                                 }\r
2417 \r
2418                         }\r
2419 \r
2420                         if(sSocket != INVALID_SOCKET)\r
2421                                 // IPv6対応\r
2422 //                              SetTaskMsg(MSGJPN025);\r
2423                                 SetTaskMsg(MSGJPN025, MSGJPN333);\r
2424                 }\r
2425                 else\r
2426                 {\r
2427 //#pragma aaa\r
2428                         // IPv6対応\r
2429 //                      SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2430                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN333);\r
2431                         DoClose(sSocket);\r
2432                         sSocket = INVALID_SOCKET;\r
2433                 }\r
2434         }\r
2435         else\r
2436                 // IPv6対応\r
2437 //              SetTaskMsg(MSGJPN027);\r
2438                 SetTaskMsg(MSGJPN027, MSGJPN333);\r
2439 \r
2440         return(sSocket);\r
2441 }\r
2442 \r
2443 \r
2444 SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2445 {\r
2446         struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
2447         struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
2448         struct sockaddr_in6 saSockAddr;\r
2449         char HostEntry[MAXGETHOSTSTRUCT];\r
2450         struct hostent *pHostEntry;\r
2451         SOCKET sSocket;\r
2452         int Len;\r
2453         int Fwall;\r
2454         SOCKS5REQUEST Socks5Cmd;\r
2455         SOCKS5REPLY Socks5Reply;\r
2456 \r
2457         //////////////////////////////\r
2458         // ホスト名解決と接続の準備\r
2459         //////////////////////////////\r
2460 \r
2461         Fwall = FWALL_NONE;\r
2462         if(AskHostFireWall() == YES)\r
2463                 Fwall = FwallType;\r
2464 \r
2465         sSocket = INVALID_SOCKET;\r
2466 \r
2467         UseIPadrs = YES;\r
2468         strcpy(DomainName, host);\r
2469         memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2470         CurSockAddr.sin6_port = htons((u_short)port);\r
2471         CurSockAddr.sin6_family = AF_INET6;\r
2472         CurSockAddr.sin6_addr = inet6_addr(host);\r
2473         if(memcmp(&CurSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2474         {\r
2475                 // ホスト名が指定された\r
2476                 // ホスト名からアドレスを求める\r
2477                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2478                    (FwallResolve == YES))\r
2479                 {\r
2480                         // ホスト名解決はSOCKSサーバに任せる\r
2481                         pHostEntry = NULL;\r
2482                 }\r
2483                 else\r
2484                 {\r
2485                         // アドレスを取得\r
2486                         SetTaskMsg(MSGJPN016, DomainName, MSGJPN334);\r
2487                         pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2488                 }\r
2489 \r
2490                 if(pHostEntry != NULL)\r
2491                 {\r
2492                         memcpy((char *)&CurSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2493                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2494                 }\r
2495                 else\r
2496                 {\r
2497                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2498                         {\r
2499                                 UseIPadrs = NO;\r
2500                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2501                         }\r
2502                         else\r
2503                         {\r
2504                                 SetTaskMsg(MSGJPN019, host, MSGJPN334);\r
2505                                 return(INVALID_SOCKET);\r
2506                         }\r
2507                 }\r
2508         }\r
2509         else\r
2510                 SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2511 \r
2512         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2513         {\r
2514                 // SOCKSを使う\r
2515                 // SOCKSに接続する準備\r
2516                 {\r
2517                         Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
2518                 }\r
2519 \r
2520                 memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2521                 SocksSockAddr.sin6_addr = inet6_addr(FwallHost);\r
2522                 if(memcmp(&SocksSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2523                 {\r
2524                         if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2525                                 memcpy((char *)&SocksSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2526                         else\r
2527                         {\r
2528                                 SetTaskMsg(MSGJPN021, FwallHost, MSGJPN334);\r
2529                                 return INVALID_SOCKET;\r
2530                         }\r
2531                 }\r
2532                 SocksSockAddr.sin6_port = htons((u_short)FwallPort);\r
2533                 SocksSockAddr.sin6_family = AF_INET6;\r
2534                 SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddr.sin6_addr), ntohs(SocksSockAddr.sin6_port), MSGJPN334);\r
2535                 // connectで接続する先はSOCKSサーバ\r
2536                 memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2537         }\r
2538         else\r
2539         {\r
2540                 // connectで接続するのは接続先のホスト\r
2541                 memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2542         }\r
2543 \r
2544         /////////////\r
2545         // 接続実行\r
2546         /////////////\r
2547 \r
2548         if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2549         {\r
2550                 // ソケットにデータを付与\r
2551                 SetAsyncTableDataIPv6(sSocket, &CurSockAddr, &SocksSockAddr);\r
2552                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2553                 {\r
2554                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2555                         {\r
2556                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2557                                 {\r
2558                                         DoClose(sSocket);\r
2559                                         sSocket = INVALID_SOCKET;\r
2560                                 }\r
2561 \r
2562                                 Socks5Reply.Result = -1;\r
2563                                 // 同時接続対応\r
2564 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2565 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2566 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2567                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2568                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2569                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2570                                 {\r
2571                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN334);\r
2572                                         DoClose(sSocket);\r
2573                                         sSocket = INVALID_SOCKET;\r
2574                                 }\r
2575 \r
2576                         }\r
2577 \r
2578                         if(sSocket != INVALID_SOCKET)\r
2579                                 SetTaskMsg(MSGJPN025, MSGJPN334);\r
2580                 }\r
2581                 else\r
2582                 {\r
2583 //#pragma aaa\r
2584                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN334);\r
2585                         DoClose(sSocket);\r
2586                         sSocket = INVALID_SOCKET;\r
2587                 }\r
2588         }\r
2589         else\r
2590                 SetTaskMsg(MSGJPN027, MSGJPN334);\r
2591 \r
2592         return(sSocket);\r
2593 }\r
2594 \r
2595 \r
2596 /*----- リッスンソケットを取得 ------------------------------------------------\r
2597 *\r
2598 *       Parameter\r
2599 *               SOCKET ctrl_skt : コントロールソケット\r
2600 *\r
2601 *       Return Value\r
2602 *               SOCKET リッスンソケット\r
2603 *----------------------------------------------------------------------------*/\r
2604 \r
2605 // IPv6対応\r
2606 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2607 {\r
2608         SOCKET Result;\r
2609         Result = INVALID_SOCKET;\r
2610         switch(CurHost.CurNetType)\r
2611         {\r
2612         case NTYPE_IPV4:\r
2613                 Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
2614                 break;\r
2615         case NTYPE_IPV6:\r
2616                 Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
2617                 break;\r
2618         }\r
2619         return Result;\r
2620 }\r
2621 \r
2622 \r
2623 // IPv6対応\r
2624 //SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2625 SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
2626 {\r
2627         // IPv6対応\r
2628         struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
2629         struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
2630     SOCKET listen_skt;\r
2631     int iLength;\r
2632     char *a,*p;\r
2633         struct sockaddr_in saCtrlAddr;\r
2634         struct sockaddr_in saTmpAddr;\r
2635         SOCKS4CMD Socks4Cmd;\r
2636         SOCKS4REPLY Socks4Reply;\r
2637         SOCKS5REQUEST Socks5Cmd;\r
2638         SOCKS5REPLY Socks5Reply;\r
2639 \r
2640         int Len;\r
2641         int Fwall;\r
2642 \r
2643         // UPnP対応\r
2644         char Adrs[16];\r
2645         int Port;\r
2646         char ExtAdrs[40];\r
2647 \r
2648         // ソケットにデータを付与\r
2649         GetAsyncTableDataIPv4(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
2650 \r
2651         Fwall = FWALL_NONE;\r
2652         if(AskHostFireWall() == YES)\r
2653                 Fwall = FwallType;\r
2654 \r
2655         if((listen_skt = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2656         {\r
2657                 if(Fwall == FWALL_SOCKS4)\r
2658                 {\r
2659                         /*===== SOCKS4を使う =====*/\r
2660                         DoPrintf("Use SOCKS4 BIND");\r
2661                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2662                         {\r
2663                                 Socks4Cmd.Ver = SOCKS4_VER;\r
2664                                 Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
2665                                 Socks4Cmd.Port = CurSockAddr.sin_port;\r
2666                                 Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2667                                 strcpy(Socks4Cmd.UserID, FwallUser);\r
2668                                 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2669 \r
2670                                 Socks4Reply.Result = -1;\r
2671                                 // 同時接続対応\r
2672 //                              if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2673 //                                 (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || \r
2674 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2675                                 if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2676                                    (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2677                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2678                                 {\r
2679                                         // IPv6対応\r
2680 //                                      SetTaskMsg(MSGJPN028, Socks4Reply.Result);\r
2681                                         SetTaskMsg(MSGJPN028, Socks4Reply.Result, MSGJPN333);\r
2682                                         DoClose(listen_skt);\r
2683                                         listen_skt = INVALID_SOCKET;\r
2684                                 }\r
2685 \r
2686                                 if(Socks4Reply.AdrsInt == 0)\r
2687                                         Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2688 \r
2689                                 a = (char *)&Socks4Reply.AdrsInt;\r
2690                                 p = (char *)&Socks4Reply.Port;\r
2691                         }\r
2692                 }\r
2693                 else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2694                 {\r
2695                         /*===== SOCKS5を使う =====*/\r
2696                         DoPrintf("Use SOCKS5 BIND");\r
2697                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2698                         {\r
2699                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2700                                 {\r
2701                                         DoClose(listen_skt);\r
2702                                         listen_skt = INVALID_SOCKET;\r
2703                                         return(listen_skt);\r
2704                                 }\r
2705 \r
2706                                 Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2707 \r
2708                                 Socks5Reply.Result = -1;\r
2709                                 // 同時接続対応\r
2710 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2711 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2712 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2713                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2714                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2715                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2716                                 {\r
2717                                         // IPv6対応\r
2718 //                                      SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2719                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN333);\r
2720                                         DoClose(listen_skt);\r
2721                                         listen_skt = INVALID_SOCKET;\r
2722                                 }\r
2723 \r
2724                                 // IPv6対応\r
2725 //                              if(Socks5Reply.AdrsInt == 0)\r
2726 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2727 \r
2728                                 // IPv6対応\r
2729 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2730 //                              p = (char *)&Socks5Reply.Port;\r
2731                                 a = (char *)&Socks5Reply._dummy[0];\r
2732                                 p = (char *)&Socks5Reply._dummy[4];\r
2733                         }\r
2734                 }\r
2735                 else\r
2736                 {\r
2737                         /*===== SOCKSを使わない =====*/\r
2738                         DoPrintf("Use normal BIND");\r
2739                         saCtrlAddr.sin_port = htons(0);\r
2740                         saCtrlAddr.sin_family = AF_INET;\r
2741                         saCtrlAddr.sin_addr.s_addr = 0;\r
2742 \r
2743                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr)) != SOCKET_ERROR)\r
2744                         {\r
2745                                 iLength = sizeof(saCtrlAddr);\r
2746                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2747                                 {\r
2748                                         if(do_listen(listen_skt, 1) == 0)\r
2749                                         {\r
2750                                                 iLength = sizeof(saTmpAddr);\r
2751                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2752                                                         ReportWSError("getsockname", WSAGetLastError());\r
2753 \r
2754                                                 a = (char *)&saTmpAddr.sin_addr;\r
2755                                                 p = (char *)&saCtrlAddr.sin_port;\r
2756                                                 // UPnP対応\r
2757                                                 if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
2758                                                 {\r
2759                                                         if(AddPortMapping(AddressToStringIPv4(Adrs, &saTmpAddr.sin_addr), ntohs(saCtrlAddr.sin_port), ExtAdrs) == FFFTP_SUCCESS)\r
2760                                                         {\r
2761                                                                 saTmpAddr.sin_addr.s_addr = inet_addr(ExtAdrs);\r
2762                                                                 SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin_port));\r
2763                                                         }\r
2764                                                 }\r
2765                                         }\r
2766                                         else\r
2767                                         {\r
2768                                                 ReportWSError("listen", WSAGetLastError());\r
2769                                                 do_closesocket(listen_skt);\r
2770                                                 listen_skt = INVALID_SOCKET;\r
2771                                         }\r
2772                                 }\r
2773                                 else\r
2774                                 {\r
2775                                         ReportWSError("getsockname", WSAGetLastError());\r
2776                                         do_closesocket(listen_skt);\r
2777                                         listen_skt = INVALID_SOCKET;\r
2778                                 }\r
2779                         }\r
2780                         else\r
2781                         {\r
2782                                 ReportWSError("bind", WSAGetLastError());\r
2783                                 do_closesocket(listen_skt);\r
2784                                 listen_skt = INVALID_SOCKET;\r
2785                         }\r
2786 \r
2787                         if(listen_skt == INVALID_SOCKET)\r
2788                                 // IPv6対応\r
2789 //                              SetTaskMsg(MSGJPN030);\r
2790                                 SetTaskMsg(MSGJPN030, MSGJPN333);\r
2791                 }\r
2792         }\r
2793         else\r
2794                 ReportWSError("socket create", WSAGetLastError());\r
2795 \r
2796         if(listen_skt != INVALID_SOCKET)\r
2797         {\r
2798 #define  UC(b)  (((int)b)&0xff)\r
2799                 // 同時接続対応\r
2800 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2801 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2802 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2803                 if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d",\r
2804                                 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2805                                 UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2806                 {\r
2807                         // IPv6対応\r
2808 //                      SetTaskMsg(MSGJPN031);\r
2809                         SetTaskMsg(MSGJPN031, MSGJPN333);\r
2810                         // UPnP対応\r
2811                         if(IsUPnPLoaded() == YES)\r
2812                         {\r
2813                                 if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
2814                                         RemovePortMapping(Port);\r
2815                         }\r
2816                         do_closesocket(listen_skt);\r
2817                         listen_skt = INVALID_SOCKET;\r
2818                 }\r
2819 //              else\r
2820 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2821         }\r
2822 \r
2823         return(listen_skt);\r
2824 }\r
2825 \r
2826 \r
2827 SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
2828 {\r
2829         struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
2830         struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
2831     SOCKET listen_skt;\r
2832     int iLength;\r
2833     char *a,*p;\r
2834         struct sockaddr_in6 saCtrlAddr;\r
2835         struct sockaddr_in6 saTmpAddr;\r
2836         SOCKS5REQUEST Socks5Cmd;\r
2837         SOCKS5REPLY Socks5Reply;\r
2838 \r
2839         int Len;\r
2840         int Fwall;\r
2841 \r
2842         char Adrs[40];\r
2843         // UPnP対応\r
2844         int Port;\r
2845         char ExtAdrs[40];\r
2846 \r
2847         // ソケットにデータを付与\r
2848         GetAsyncTableDataIPv6(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
2849 \r
2850         Fwall = FWALL_NONE;\r
2851         if(AskHostFireWall() == YES)\r
2852                 Fwall = FwallType;\r
2853 \r
2854         if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2855         {\r
2856                 if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2857                 {\r
2858                         /*===== SOCKS5を使う =====*/\r
2859                         DoPrintf("Use SOCKS5 BIND");\r
2860                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2861                         {\r
2862                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2863                                 {\r
2864                                         DoClose(listen_skt);\r
2865                                         listen_skt = INVALID_SOCKET;\r
2866                                         return(listen_skt);\r
2867                                 }\r
2868 \r
2869                                 Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
2870 \r
2871                                 Socks5Reply.Result = -1;\r
2872                                 // 同時接続対応\r
2873 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2874 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2875 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2876                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2877                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2878                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2879                                 {\r
2880                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN334);\r
2881                                         DoClose(listen_skt);\r
2882                                         listen_skt = INVALID_SOCKET;\r
2883                                 }\r
2884 \r
2885                                 // IPv6対応\r
2886 //                              if(Socks5Reply.AdrsInt == 0)\r
2887 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2888 \r
2889                                 // IPv6対応\r
2890 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2891 //                              p = (char *)&Socks5Reply.Port;\r
2892                                 a = (char *)&Socks5Reply._dummy[0];\r
2893                                 p = (char *)&Socks5Reply._dummy[16];\r
2894                         }\r
2895                 }\r
2896                 else\r
2897                 {\r
2898                         /*===== SOCKSを使わない =====*/\r
2899                         DoPrintf("Use normal BIND");\r
2900                         saCtrlAddr.sin6_port = htons(0);\r
2901                         saCtrlAddr.sin6_family = AF_INET6;\r
2902                         memset(&saCtrlAddr.sin6_addr, 0, 16);\r
2903                         saCtrlAddr.sin6_flowinfo = 0;\r
2904                         saCtrlAddr.sin6_scope_id = 0;\r
2905 \r
2906                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
2907                         {\r
2908                                 iLength = sizeof(saCtrlAddr);\r
2909                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2910                                 {\r
2911                                         if(do_listen(listen_skt, 1) == 0)\r
2912                                         {\r
2913                                                 iLength = sizeof(saTmpAddr);\r
2914                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2915                                                         ReportWSError("getsockname", WSAGetLastError());\r
2916 \r
2917                                                 a = (char *)&saTmpAddr.sin6_addr;\r
2918                                                 p = (char *)&saCtrlAddr.sin6_port;\r
2919                                                 // UPnP対応\r
2920                                                 if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
2921                                                 {\r
2922                                                         if(AddPortMapping(AddressToStringIPv6(Adrs, &saTmpAddr.sin6_addr), ntohs(saCtrlAddr.sin6_port), ExtAdrs) == FFFTP_SUCCESS)\r
2923                                                         {\r
2924                                                                 saTmpAddr.sin6_addr = inet6_addr(ExtAdrs);\r
2925                                                                 SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin6_port));\r
2926                                                         }\r
2927                                                 }\r
2928                                         }\r
2929                                         else\r
2930                                         {\r
2931                                                 ReportWSError("listen", WSAGetLastError());\r
2932                                                 do_closesocket(listen_skt);\r
2933                                                 listen_skt = INVALID_SOCKET;\r
2934                                         }\r
2935                                 }\r
2936                                 else\r
2937                                 {\r
2938                                         ReportWSError("getsockname", WSAGetLastError());\r
2939                                         do_closesocket(listen_skt);\r
2940                                         listen_skt = INVALID_SOCKET;\r
2941                                 }\r
2942                         }\r
2943                         else\r
2944                         {\r
2945                                 ReportWSError("bind", WSAGetLastError());\r
2946                                 do_closesocket(listen_skt);\r
2947                                 listen_skt = INVALID_SOCKET;\r
2948                         }\r
2949 \r
2950                         if(listen_skt == INVALID_SOCKET)\r
2951                                 SetTaskMsg(MSGJPN030, MSGJPN334);\r
2952                 }\r
2953         }\r
2954         else\r
2955                 ReportWSError("socket create", WSAGetLastError());\r
2956 \r
2957         if(listen_skt != INVALID_SOCKET)\r
2958         {\r
2959 #define  UC(b)  (((int)b)&0xff)\r
2960                 // 同時接続対応\r
2961 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2962 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2963 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2964                 if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
2965                                 AddressToStringIPv6(Adrs, a),\r
2966                                 (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE)\r
2967                 {\r
2968                         SetTaskMsg(MSGJPN031, MSGJPN334);\r
2969                         // UPnP対応\r
2970                         if(IsUPnPLoaded() == YES)\r
2971                         {\r
2972                                 if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
2973                                         RemovePortMapping(Port);\r
2974                         }\r
2975                         do_closesocket(listen_skt);\r
2976                         listen_skt = INVALID_SOCKET;\r
2977                 }\r
2978 //              else\r
2979 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2980         }\r
2981 \r
2982         return(listen_skt);\r
2983 }\r
2984 \r
2985 \r
2986 /*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
2987 *\r
2988 *       Parameter\r
2989 *               なし\r
2990 *\r
2991 *       Return Value\r
2992 *               int ステータス\r
2993 *                       YES/NO\r
2994 *----------------------------------------------------------------------------*/\r
2995 \r
2996 int AskTryingConnect(void)\r
2997 {\r
2998         return(TryConnect);\r
2999 }\r
3000 \r
3001 \r
3002 #if 0\r
3003 ///*----- ブロッキングコールのフックコールバック --------------------------------\r
3004 //*\r
3005 //*     Parameter\r
3006 //*             なし\r
3007 //*\r
3008 //*     Return Value\r
3009 //*             BOOL FALSE\r
3010 //*----------------------------------------------------------------------------*/\r
3011 //\r
3012 //static BOOL CALLBACK BlkHookFnc(void)\r
3013 //{\r
3014 //      BackgrndMessageProc();\r
3015 //\r
3016 //      if(CancelFlg == YES)\r
3017 //      {\r
3018 //              SetTaskMsg(MSGJPN032);\r
3019 //              WSACancelBlockingCall();\r
3020 //              CancelFlg = NO;\r
3021 //      }\r
3022 //      return(FALSE);\r
3023 //}\r
3024 #endif\r
3025 \r
3026 \r
3027 \r
3028 /*----- SOCKS5のコマンドパケットを作成する ------------------------------------\r
3029 *\r
3030 *       Parameter\r
3031 *               SOCKS5REQUEST *Packet : パケットを作成するワーク\r
3032 *               char Cmd : コマンド\r
3033 *               int ValidIP : IPアドレスを使うかどうか(YES/NO)\r
3034 *               ulong IP : IPアドレス\r
3035 *               char *Host : ホスト名\r
3036 *               ushort Port : ポート\r
3037 *\r
3038 *       Return Value\r
3039 *               int コマンドパケットの長さ\r
3040 *----------------------------------------------------------------------------*/\r
3041 \r
3042 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port)\r
3043 {\r
3044         uchar *Pos;\r
3045         int Len;\r
3046         int TotalLen;\r
3047 \r
3048         Pos = (uchar *)Packet;\r
3049         Pos += SOCKS5REQUEST_SIZE;\r
3050         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
3051 \r
3052         Packet->Ver = SOCKS5_VER;\r
3053         Packet->Cmd = Cmd;\r
3054         Packet->Rsv = 0;\r
3055         if(ValidIP == YES)\r
3056         {\r
3057                 /* IPアドレスを指定 */\r
3058                 Packet->Type = SOCKS5_ADRS_IPV4;\r
3059                 *((ulong *)Pos) = IP;\r
3060                 Pos += 4;\r
3061                 TotalLen += 4;\r
3062         }\r
3063         else\r
3064         {\r
3065                 /* ホスト名を指定 */\r
3066                 Packet->Type = SOCKS5_ADRS_NAME;\r
3067                 Len = strlen(Host);\r
3068                 *Pos++ = Len;\r
3069                 strcpy(Pos, Host);\r
3070                 Pos += Len;\r
3071                 TotalLen += Len + 1;\r
3072         }\r
3073         *((ushort *)Pos) = Port;\r
3074 \r
3075         return(TotalLen);\r
3076 }\r
3077 \r
3078 \r
3079 // IPv6対応\r
3080 static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
3081 {\r
3082         uchar *Pos;\r
3083         int Len;\r
3084         int TotalLen;\r
3085 \r
3086         Pos = (uchar *)Packet;\r
3087         Pos += SOCKS5REQUEST_SIZE;\r
3088         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
3089 \r
3090         Packet->Ver = SOCKS5_VER;\r
3091         Packet->Cmd = Cmd;\r
3092         Packet->Rsv = 0;\r
3093         if(ValidIP == YES)\r
3094         {\r
3095                 /* IPアドレスを指定 */\r
3096                 Packet->Type = SOCKS5_ADRS_IPV6;\r
3097                 memcpy(Pos, IP, 16);\r
3098                 Pos += 16;\r
3099                 TotalLen += 16;\r
3100         }\r
3101         else\r
3102         {\r
3103                 /* ホスト名を指定 */\r
3104                 Packet->Type = SOCKS5_ADRS_NAME;\r
3105                 Len = strlen(Host);\r
3106                 *Pos++ = Len;\r
3107                 strcpy(Pos, Host);\r
3108                 Pos += Len;\r
3109                 TotalLen += Len + 1;\r
3110         }\r
3111         *((ushort *)Pos) = Port;\r
3112 \r
3113         return(TotalLen);\r
3114 }\r
3115 \r
3116 \r
3117 /*----- SOCKSのコマンドを送る -------------------------------------------------\r
3118 *\r
3119 *       Parameter\r
3120 *               SOCKET Socket : ソケット\r
3121 *               void *Data : 送るデータ\r
3122 *               int Size : サイズ\r
3123 *\r
3124 *       Return Value\r
3125 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3126 *----------------------------------------------------------------------------*/\r
3127 \r
3128 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork)\r
3129 {\r
3130         int Ret;\r
3131 \r
3132         Ret = SendData(Socket, (char *)Data, Size, 0, CancelCheckWork);\r
3133 \r
3134         if(Ret != FFFTP_SUCCESS)\r
3135                 SetTaskMsg(MSGJPN033, *((short *)Data));\r
3136 \r
3137         return(Ret);\r
3138 }\r
3139 \r
3140 \r
3141 /*----- SOCKS5のコマンドに対するリプライパケットを受信する --------------------\r
3142 *\r
3143 *       Parameter\r
3144 *               SOCKET Socket : ソケット\r
3145 *               SOCKS5REPLY *Packet : パケット\r
3146 *\r
3147 *       Return Value\r
3148 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3149 *----------------------------------------------------------------------------*/\r
3150 \r
3151 // 同時接続対応\r
3152 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet)\r
3153 static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork)\r
3154 {\r
3155         uchar *Pos;\r
3156         int Len;\r
3157         int Ret;\r
3158 \r
3159         Pos = (uchar *)Packet;\r
3160         Pos += SOCKS5REPLY_SIZE;\r
3161 \r
3162         // 同時接続対応\r
3163 //      if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS)\r
3164         if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, CancelCheckWork)) == FFFTP_SUCCESS)\r
3165         {\r
3166                 if(Packet->Type == SOCKS5_ADRS_IPV4)\r
3167                         Len = 4 + 2;\r
3168                 else if(Packet->Type == SOCKS5_ADRS_IPV6)\r
3169                         Len = 16 + 2;\r
3170                 else\r
3171                 {\r
3172                         // 同時接続対応\r
3173 //                      if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS)\r
3174                         if((Ret = ReadNchar(Socket, (char *)Pos, 1, CancelCheckWork)) == FFFTP_SUCCESS)\r
3175                         {\r
3176                                 Len = *Pos + 2;\r
3177                                 Pos++;\r
3178                         }\r
3179                 }\r
3180 \r
3181                 if(Ret == FFFTP_SUCCESS)\r
3182                         // 同時接続対応\r
3183 //                      Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg);\r
3184                         Ret = ReadNchar(Socket, (char *)Pos, Len, CancelCheckWork);\r
3185         }\r
3186 \r
3187         if(Ret != FFFTP_SUCCESS)\r
3188                 SetTaskMsg(MSGJPN034);\r
3189 \r
3190         return(Ret);\r
3191 }\r
3192 \r
3193 \r
3194 /*----- SOCKS4のコマンドに対するリプライパケットを受信する --------------------\r
3195 *\r
3196 *       Parameter\r
3197 *               SOCKET Socket : ソケット\r
3198 *               SOCKS5REPLY *Packet : パケット\r
3199 *\r
3200 *       Return Value\r
3201 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3202 *----------------------------------------------------------------------------*/\r
3203 \r
3204 // 同時接続対応\r
3205 //static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet)\r
3206 static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork)\r
3207 {\r
3208         int Ret;\r
3209 \r
3210         // 同時接続対応\r
3211 //      Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg);\r
3212         Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, CancelCheckWork);\r
3213 \r
3214         if(Ret != FFFTP_SUCCESS)\r
3215                 DoPrintf(MSGJPN035);\r
3216 \r
3217         return(Ret);\r
3218 }\r
3219 \r
3220 \r
3221 /*----- SOCKS5の認証を行う ----------------------------------------------------\r
3222 *\r
3223 *       Parameter\r
3224 *               SOCKET Socket : ソケット\r
3225 *\r
3226 *       Return Value\r
3227 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3228 *----------------------------------------------------------------------------*/\r
3229 \r
3230 static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork)\r
3231 {\r
3232         int Ret;\r
3233         SOCKS5METHODREQUEST Socks5Method;\r
3234         SOCKS5METHODREPLY Socks5MethodReply;\r
3235         SOCKS5USERPASSSTATUS Socks5Status;\r
3236         char Buf[USER_NAME_LEN + PASSWORD_LEN + 4];\r
3237         int Len;\r
3238         int Len2;\r
3239 \r
3240         Ret = FFFTP_SUCCESS;\r
3241         Socks5Method.Ver = SOCKS5_VER;\r
3242         Socks5Method.Num = 1;\r
3243         if(FwallType == FWALL_SOCKS5_NOAUTH)\r
3244                 Socks5Method.Methods[0] = SOCKS5_AUTH_NONE;\r
3245         else\r
3246                 Socks5Method.Methods[0] = SOCKS5_AUTH_USER;\r
3247 \r
3248         // 同時接続対応\r
3249 //      if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3250 //         (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
3251 //         (Socks5MethodReply.Method == (uchar)0xFF))\r
3252         if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3253            (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3254            (Socks5MethodReply.Method == (uchar)0xFF))\r
3255         {\r
3256                 SetTaskMsg(MSGJPN036);\r
3257                 Ret = FFFTP_FAIL;\r
3258         }\r
3259         else if(Socks5MethodReply.Method == SOCKS5_AUTH_USER)\r
3260         {\r
3261                 DoPrintf("SOCKS5 User/Pass Authentication");\r
3262                 Buf[0] = SOCKS5_USERAUTH_VER;\r
3263                 Len = strlen(FwallUser);\r
3264                 Len2 = strlen(FwallPass);\r
3265                 Buf[1] = Len;\r
3266                 strcpy(Buf+2, FwallUser);\r
3267                 Buf[2 + Len] = Len2;\r
3268                 strcpy(Buf+3+Len, FwallPass);\r
3269 \r
3270                 // 同時接続対応\r
3271 //              if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3272 //                 (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
3273 //                 (Socks5Status.Status != 0))\r
3274                 if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3275                    (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3276                    (Socks5Status.Status != 0))\r
3277                 {\r
3278                         SetTaskMsg(MSGJPN037);\r
3279                         Ret = FFFTP_FAIL;\r
3280                 }\r
3281         }\r
3282         else\r
3283                 DoPrintf("SOCKS5 No Authentication");\r
3284 \r
3285         return(Ret);\r
3286 }\r
3287 \r
3288 \r
3289 /*----- SOCKSのBINDの第2リプライメッセージを受け取る -------------------------\r
3290 *\r
3291 *       Parameter\r
3292 *               SOCKET Socket : ソケット\r
3293 *               SOCKET *Data : データソケットを返すワーク\r
3294 *\r
3295 *       Return Value\r
3296 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3297 *----------------------------------------------------------------------------*/\r
3298 \r
3299 // 同時接続対応\r
3300 //int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data)\r
3301 int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data, int *CancelCheckWork)\r
3302 {\r
3303         int Ret;\r
3304         char Buf[300];\r
3305 \r
3306         Ret = FFFTP_FAIL;\r
3307         if((AskHostFireWall() == YES) && (FwallType == FWALL_SOCKS4))\r
3308         {\r
3309                 // 同時接続対応\r
3310 //              Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf);\r
3311                 Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf, CancelCheckWork);\r
3312                 *Data = Socket;\r
3313                 Ret = FFFTP_SUCCESS;\r
3314         }\r
3315         else if((AskHostFireWall() == YES) &&\r
3316                         ((FwallType == FWALL_SOCKS5_NOAUTH) || (FwallType == FWALL_SOCKS5_USER)))\r
3317         {\r
3318                 // 同時接続対応\r
3319 //              Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf);\r
3320                 Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf, CancelCheckWork);\r
3321                 *Data = Socket;\r
3322                 Ret = FFFTP_SUCCESS;\r
3323         }\r
3324         return(Ret);\r
3325 }\r
3326 \r
3327 \r
3328 \r
3329 // 暗号化通信対応\r
3330 int AskCryptMode(void)\r
3331 {\r
3332         return(CurHost.CryptMode);\r
3333 }\r
3334 \r
3335 int AskUseNoEncryption(void)\r
3336 {\r
3337         return(CurHost.UseNoEncryption);\r
3338 }\r
3339 \r
3340 int AskUseFTPES(void)\r
3341 {\r
3342         return(CurHost.UseFTPES);\r
3343 }\r
3344 \r
3345 int AskUseFTPIS(void)\r
3346 {\r
3347         return(CurHost.UseFTPIS);\r
3348 }\r
3349 \r
3350 int AskUseSFTP(void)\r
3351 {\r
3352         return(CurHost.UseSFTP);\r
3353 }\r
3354 \r
3355 char *AskPrivateKey(void)\r
3356 {\r
3357         return(CurHost.PrivateKey);\r
3358 }\r
3359 \r
3360 // 同時接続対応\r
3361 int AskMaxThreadCount(void)\r
3362 {\r
3363         return(CurHost.MaxThreadCount);\r
3364 }\r
3365 \r
3366 int AskReuseCmdSkt(void)\r
3367 {\r
3368         return(CurHost.ReuseCmdSkt);\r
3369 }\r
3370 \r
3371 // FEAT対応\r
3372 int AskHostFeature(void)\r
3373 {\r
3374         return(CurHost.Feature);\r
3375 }\r
3376 \r
3377 // MLSD対応\r
3378 int AskUseMLSD(void)\r
3379 {\r
3380         return(CurHost.UseMLSD);\r
3381 }\r
3382 \r
3383 // IPv6対応\r
3384 int AskCurNetType(void)\r
3385 {\r
3386         return(CurHost.CurNetType);\r
3387 }\r
3388 \r
3389 // 自動切断対策\r
3390 int AskNoopInterval(void)\r
3391 {\r
3392         return(CurHost.NoopInterval);\r
3393 }\r
3394 \r
3395 // 再転送対応\r
3396 int AskTransferErrorMode(void)\r
3397 {\r
3398         return(CurHost.TransferErrorMode);\r
3399 }\r
3400 \r
3401 int AskTransferErrorNotify(void)\r
3402 {\r
3403         return(CurHost.TransferErrorNotify);\r
3404 }\r
3405 \r
3406 // セッションあたりの転送量制限対策\r
3407 int AskErrorReconnect(void)\r
3408 {\r
3409         return(CurHost.TransferErrorReconnect);\r
3410 }\r
3411 \r