OSDN Git Service

Change the algorithm to encrypt all settings.
[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(MSGJPN344, MSGJPN346);\r
242                                                 break;\r
243                                         case KANJI_JIS:\r
244                                                 SetTaskMsg(MSGJPN344, MSGJPN347);\r
245                                                 break;\r
246                                         case KANJI_EUC:\r
247                                                 SetTaskMsg(MSGJPN344, MSGJPN348);\r
248                                                 break;\r
249                                         case KANJI_UTF8N:\r
250                                                 SetTaskMsg(MSGJPN344, MSGJPN349);\r
251                                                 break;\r
252                                         case KANJI_UTF8HFSX:\r
253                                                 SetTaskMsg(MSGJPN344, MSGJPN350);\r
254                                                 break;\r
255                                         default:\r
256                                                 SetTaskMsg(MSGJPN345);\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(MSGJPN344, MSGJPN346);\r
356                                                 break;\r
357                                         case KANJI_JIS:\r
358                                                 SetTaskMsg(MSGJPN344, MSGJPN347);\r
359                                                 break;\r
360                                         case KANJI_EUC:\r
361                                                 SetTaskMsg(MSGJPN344, MSGJPN348);\r
362                                                 break;\r
363                                         case KANJI_UTF8N:\r
364                                                 SetTaskMsg(MSGJPN344, MSGJPN349);\r
365                                                 break;\r
366                                         case KANJI_UTF8HFSX:\r
367                                                 SetTaskMsg(MSGJPN344, MSGJPN350);\r
368                                                 break;\r
369                                         default:\r
370                                                 SetTaskMsg(MSGJPN345);\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(MSGJPN344, MSGJPN346);\r
565                                         break;\r
566                                 case KANJI_JIS:\r
567                                         SetTaskMsg(MSGJPN344, MSGJPN347);\r
568                                         break;\r
569                                 case KANJI_EUC:\r
570                                         SetTaskMsg(MSGJPN344, MSGJPN348);\r
571                                         break;\r
572                                 case KANJI_UTF8N:\r
573                                         SetTaskMsg(MSGJPN344, MSGJPN349);\r
574                                         break;\r
575                                 case KANJI_UTF8HFSX:\r
576                                         SetTaskMsg(MSGJPN344, MSGJPN350);\r
577                                         break;\r
578                                 default:\r
579                                         SetTaskMsg(MSGJPN345);\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(MSGJPN344, MSGJPN346);\r
676                                                 break;\r
677                                         case KANJI_JIS:\r
678                                                 SetTaskMsg(MSGJPN344, MSGJPN347);\r
679                                                 break;\r
680                                         case KANJI_EUC:\r
681                                                 SetTaskMsg(MSGJPN344, MSGJPN348);\r
682                                                 break;\r
683                                         case KANJI_UTF8N:\r
684                                                 SetTaskMsg(MSGJPN344, MSGJPN349);\r
685                                                 break;\r
686                                         case KANJI_UTF8HFSX:\r
687                                                 SetTaskMsg(MSGJPN344, MSGJPN350);\r
688                                                 break;\r
689                                         default:\r
690                                                 SetTaskMsg(MSGJPN345);\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))\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))\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         else if(CryptMode == CRYPT_SFTP)\r
1960         {\r
1961                 // TODO:\r
1962                 // テストコード\r
1963                 // ログイン成功を確認\r
1964 #define strrcmp(_Str1, _Str2) (strcmp(strstr(_Str1, _Str2) ? strstr(_Str1, _Str2) : "", _Str2))\r
1965                 size_t r;\r
1966                 ContSock = SFTP_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
1967                 SFTP_SetTimeoutCallback(ContSock, SSLTimeoutCallback);\r
1968                 while(1)\r
1969                 {\r
1970                         r = SFTP_recv(ContSock, Reply, 1024, 0);\r
1971                         if(r == SOCKET_ERROR)\r
1972                                 break;\r
1973                         if(r <= 0)\r
1974                                 continue;\r
1975                         Reply[r] = '\0';\r
1976                         SetTaskMsg("%s", Reply);\r
1977                         if(strrcmp(Reply, "psftp> ") == 0)\r
1978                                 break;\r
1979                 }\r
1980                 r = SFTP_send(ContSock, "open \"", strlen("open \""), 0);\r
1981                 r = SFTP_send(ContSock, Host, strlen(Host), 0);\r
1982                 r = SFTP_send(ContSock, "\"\r\n", strlen("\"\r\n"), 0);\r
1983                 while(1)\r
1984                 {\r
1985                         r = SFTP_recv(ContSock, Reply, 1024, 0);\r
1986                         if(r == SOCKET_ERROR)\r
1987                                 break;\r
1988                         if(r <= 0)\r
1989                                 continue;\r
1990                         Reply[r] = '\0';\r
1991                         SetTaskMsg("%s", Reply);\r
1992                         if(strrcmp(Reply, "Store key in cache? (y/n) ") == 0)\r
1993                         {\r
1994                                 r = SFTP_send(ContSock, "n\r\n", strlen("n\r\n"), 0);\r
1995                         }\r
1996                         if(strrcmp(Reply, "Update cached key? (y/n, Return cancels connection) ") == 0)\r
1997                         {\r
1998                                 r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
1999                         }\r
2000                         if(strrcmp(Reply, "login as: ") == 0)\r
2001                         {\r
2002                                 r = SFTP_send(ContSock, User, strlen(User), 0);\r
2003                                 r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
2004                         }\r
2005                         if(strrcmp(Reply, "password: ") == 0)\r
2006                         {\r
2007                                 r = SFTP_send(ContSock, Pass, strlen(Pass), 0);\r
2008                                 r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
2009                         }\r
2010                         if(strrcmp(Reply, "psftp> ") == 0)\r
2011                                 break;\r
2012                         Sleep(1);\r
2013                 }\r
2014                 SFTP_closesocket(ContSock);\r
2015                 ContSock = INVALID_SOCKET;\r
2016         }\r
2017 \r
2018         return(ContSock);\r
2019 }\r
2020 \r
2021 // 同時接続対応\r
2022 //static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security)\r
2023 static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
2024 {\r
2025         SOCKET ContSock;\r
2026         ContSock = INVALID_SOCKET;\r
2027         *CancelCheckWork = NO;\r
2028         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)\r
2029         {\r
2030                 SetTaskMsg(MSGJPN317);\r
2031                 if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
2032                         HostData->CryptMode = CRYPT_SFTP;\r
2033         }\r
2034         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
2035         {\r
2036                 SetTaskMsg(MSGJPN316);\r
2037                 if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
2038                         HostData->CryptMode = CRYPT_FTPIS;\r
2039         }\r
2040         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES)\r
2041         {\r
2042                 SetTaskMsg(MSGJPN315);\r
2043                 if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
2044                         HostData->CryptMode = CRYPT_FTPES;\r
2045         }\r
2046         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES)\r
2047         {\r
2048                 SetTaskMsg(MSGJPN314);\r
2049                 if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
2050                         HostData->CryptMode = CRYPT_NONE;\r
2051         }\r
2052         return ContSock;\r
2053 }\r
2054 \r
2055 \r
2056 /*----- ワンタイムパスワードのチェック ----------------------------------------\r
2057 *\r
2058 *       Parameter\r
2059 *               chat *Pass : パスワード/パスフレーズ\r
2060 *               char *Reply : USERコマンドを送ったあとのリプライ文字列\r
2061 *                                               /PASSコマンドで送るパスワードを返すバッファ\r
2062 *               int Type : タイプ (SECURITY_xxx, MDx)\r
2063 *\r
2064 *       Return Value\r
2065 *               int ステータス\r
2066 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2067 *\r
2068 *       Note\r
2069 *               ワンタイムパスワードでない時はPassをそのままReplyにコピー\r
2070 *----------------------------------------------------------------------------*/\r
2071 \r
2072 static int CheckOneTimePassword(char *Pass, char *Reply, int Type)\r
2073 {\r
2074         int Sts;\r
2075         char *Pos;\r
2076         int Seq;\r
2077         char Seed[MAX_SEED_LEN+1];\r
2078         int i;\r
2079 \r
2080         Sts = FFFTP_SUCCESS;\r
2081         Pos = NULL;\r
2082 \r
2083         if(Type == SECURITY_AUTO)\r
2084         {\r
2085                 if((Pos = stristr(Reply, "otp-md5")) != NULL)\r
2086                 {\r
2087                         Type = MD5;\r
2088                         SetTaskMsg(MSGJPN012);\r
2089                 }\r
2090                 else if((Pos = stristr(Reply, "otp-sha1")) != NULL)\r
2091                 {\r
2092                         Type = SHA1;\r
2093                         SetTaskMsg(MSGJPN013);\r
2094                 }\r
2095                 else if(((Pos = stristr(Reply, "otp-md4")) != NULL) || ((Pos = stristr(Reply, "s/key")) != NULL))\r
2096                 {\r
2097                         Type = MD4;\r
2098                         SetTaskMsg(MSGJPN014);\r
2099                 }\r
2100         }\r
2101         else\r
2102                 Pos = GetNextField(Reply);\r
2103 \r
2104         if((Type == MD4) || (Type == MD5) || (Type == SHA1))\r
2105         {\r
2106                 /* シーケンス番号を見つけるループ */\r
2107                 DoPrintf("Analyze OTP");\r
2108                 DoPrintf("%s", Pos);\r
2109                 Sts = FFFTP_FAIL;\r
2110                 while((Pos = GetNextField(Pos)) != NULL)\r
2111                 {\r
2112                         if(IsDigit(*Pos))\r
2113                         {\r
2114                                 Seq = atoi(Pos);\r
2115                                 DoPrintf("Sequence=%d", Seq);\r
2116 \r
2117                                 /* Seed */\r
2118                                 if((Pos = GetNextField(Pos)) != NULL)\r
2119                                 {\r
2120                                         if(GetOneField(Pos, Seed, MAX_SEED_LEN) == FFFTP_SUCCESS)\r
2121                                         {\r
2122                                                 /* Seedは英数字のみ有効とする */\r
2123                                                 for(i = strlen(Seed)-1; i >= 0; i--)\r
2124                                                 {\r
2125                                                         if((IsAlpha(Seed[i]) == 0) && (IsDigit(Seed[i]) == 0))\r
2126                                                                 Seed[i] = NUL;\r
2127                                                 }\r
2128                                                 if(strlen(Seed) > 0)\r
2129                                                 {\r
2130                                                         DoPrintf("Seed=%s", Seed);\r
2131                                                         Make6WordPass(Seq, Seed, Pass, Type, Reply);\r
2132                                                         DoPrintf("Response=%s", Reply);\r
2133 \r
2134                                                         /* シーケンス番号のチェックと警告 */\r
2135                                                         if(Seq <= 10)\r
2136                                                                 DialogBox(GetFtpInst(), MAKEINTRESOURCE(otp_notify_dlg), GetMainHwnd(), ExeEscDialogProc);\r
2137 \r
2138                                                         Sts = FFFTP_SUCCESS;\r
2139                                                 }\r
2140                                         }\r
2141                                 }\r
2142                                 break;\r
2143                         }\r
2144                 }\r
2145 \r
2146                 if(Sts == FFFTP_FAIL)\r
2147                         SetTaskMsg(MSGJPN015);\r
2148         }\r
2149         else\r
2150         {\r
2151                 strcpy(Reply, Pass);\r
2152                 DoPrintf("No OTP used.");\r
2153         }\r
2154         return(Sts);\r
2155 }\r
2156 \r
2157 \r
2158 \r
2159 \r
2160 \r
2161 \r
2162 \r
2163 \r
2164 \r
2165 \r
2166 \r
2167 \r
2168 \r
2169 \r
2170 /*----- ソケットを接続する ----------------------------------------------------\r
2171 *\r
2172 *       Parameter\r
2173 *               char *host : ホスト名\r
2174 *               int port : ポート番号\r
2175 *               char *PreMsg : メッセージの前半部分\r
2176 *\r
2177 *       Return Value\r
2178 *               SOCKET ソケット\r
2179 *----------------------------------------------------------------------------*/\r
2180 \r
2181 // IPv6対応\r
2182 typedef SOCKET (__cdecl* LPCONNECTSOCK)(char*, int, char*, int*);\r
2183 \r
2184 typedef struct\r
2185 {\r
2186         HANDLE h;\r
2187         DWORD ExitCode;\r
2188         char *host;\r
2189         int port;\r
2190         char *PreMsg;\r
2191         int CancelCheckWork;\r
2192         LPCONNECTSOCK f;\r
2193         SOCKET s;\r
2194 } CONNECTSOCKDATA;\r
2195 \r
2196 DWORD WINAPI connectsockThreadProc(LPVOID lpParameter)\r
2197 {\r
2198         CONNECTSOCKDATA* pData;\r
2199         pData = (CONNECTSOCKDATA*)lpParameter;\r
2200         pData->s = pData->f(pData->host, pData->port, pData->PreMsg, &pData->CancelCheckWork);\r
2201         return 0;\r
2202 }\r
2203 \r
2204 // IPv6対応\r
2205 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2206 {\r
2207         SOCKET Result;\r
2208         CONNECTSOCKDATA DataIPv4;\r
2209         CONNECTSOCKDATA DataIPv6;\r
2210         Result = INVALID_SOCKET;\r
2211         switch(CurHost.CurNetType)\r
2212         {\r
2213         case NTYPE_AUTO:\r
2214 //              if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
2215 //                      CurHost.CurNetType = NTYPE_IPV4;\r
2216 //              else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
2217 //                      CurHost.CurNetType = NTYPE_IPV6;\r
2218                 DataIPv4.host = host;\r
2219                 DataIPv4.port = port;\r
2220                 DataIPv4.PreMsg = PreMsg;\r
2221                 DataIPv4.CancelCheckWork = *CancelCheckWork;\r
2222                 DataIPv4.f = connectsockIPv4;\r
2223                 DataIPv4.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv4, 0, NULL);\r
2224                 DataIPv6.host = host;\r
2225                 DataIPv6.port = port;\r
2226                 DataIPv6.PreMsg = PreMsg;\r
2227                 DataIPv6.CancelCheckWork = *CancelCheckWork;\r
2228                 DataIPv6.f = connectsockIPv6;\r
2229                 DataIPv6.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv6, 0, NULL);\r
2230                 while(1)\r
2231                 {\r
2232                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode))\r
2233                         {\r
2234                                 if(DataIPv4.ExitCode != STILL_ACTIVE)\r
2235                                 {\r
2236                                         if(DataIPv4.s != INVALID_SOCKET)\r
2237                                         {\r
2238                                                 Result = DataIPv4.s;\r
2239                                                 CurHost.CurNetType = NTYPE_IPV4;\r
2240                                                 break;\r
2241                                         }\r
2242                                 }\r
2243                         }\r
2244                         if(GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2245                         {\r
2246                                 if(DataIPv6.ExitCode != STILL_ACTIVE)\r
2247                                 {\r
2248                                         if(DataIPv6.s != INVALID_SOCKET)\r
2249                                         {\r
2250                                                 Result = DataIPv6.s;\r
2251                                                 CurHost.CurNetType = NTYPE_IPV6;\r
2252                                                 break;\r
2253                                         }\r
2254                                 }\r
2255                         }\r
2256                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2257                         {\r
2258                                 if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
2259                                 {\r
2260                                         if(DataIPv4.s == INVALID_SOCKET && DataIPv6.s == INVALID_SOCKET)\r
2261                                                 break;\r
2262                                 }\r
2263                         }\r
2264                         DataIPv4.CancelCheckWork = *CancelCheckWork;\r
2265                         DataIPv6.CancelCheckWork = *CancelCheckWork;\r
2266                         BackgrndMessageProc();\r
2267                         Sleep(1);\r
2268                 }\r
2269                 while(1)\r
2270                 {\r
2271                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2272                         {\r
2273                                 if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
2274                                 {\r
2275                                         CloseHandle(DataIPv4.h);\r
2276                                         CloseHandle(DataIPv6.h);\r
2277                                         break;\r
2278                                 }\r
2279                         }\r
2280                         DataIPv4.CancelCheckWork = YES;\r
2281                         DataIPv6.CancelCheckWork = YES;\r
2282                         BackgrndMessageProc();\r
2283                         Sleep(1);\r
2284                 }\r
2285                 break;\r
2286         case NTYPE_IPV4:\r
2287                 Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
2288                 CurHost.CurNetType = NTYPE_IPV4;\r
2289                 break;\r
2290         case NTYPE_IPV6:\r
2291                 Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
2292                 CurHost.CurNetType = NTYPE_IPV6;\r
2293                 break;\r
2294         }\r
2295         return Result;\r
2296 }\r
2297 \r
2298 \r
2299 // IPv6対応\r
2300 //SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2301 SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2302 {\r
2303         // IPv6対応\r
2304         struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
2305         struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
2306         struct sockaddr_in saSockAddr;\r
2307         char HostEntry[MAXGETHOSTSTRUCT];\r
2308         struct hostent *pHostEntry;\r
2309         SOCKET sSocket;\r
2310         int Len;\r
2311         int Fwall;\r
2312         SOCKS4CMD Socks4Cmd;\r
2313         SOCKS4REPLY Socks4Reply;\r
2314         SOCKS5REQUEST Socks5Cmd;\r
2315         SOCKS5REPLY Socks5Reply;\r
2316 \r
2317         //////////////////////////////\r
2318         // ホスト名解決と接続の準備\r
2319         //////////////////////////////\r
2320 \r
2321         Fwall = FWALL_NONE;\r
2322         if(AskHostFireWall() == YES)\r
2323                 Fwall = FwallType;\r
2324 \r
2325         sSocket = INVALID_SOCKET;\r
2326 \r
2327         UseIPadrs = YES;\r
2328         strcpy(DomainName, host);\r
2329         memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2330         CurSockAddr.sin_port = htons((u_short)port);\r
2331         CurSockAddr.sin_family = AF_INET;\r
2332         if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
2333         {\r
2334                 // ホスト名が指定された\r
2335                 // ホスト名からアドレスを求める\r
2336                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2337                    (FwallResolve == YES))\r
2338                 {\r
2339                         // ホスト名解決はSOCKSサーバに任せる\r
2340                         pHostEntry = NULL;\r
2341                 }\r
2342                 else\r
2343                 {\r
2344                         // アドレスを取得\r
2345                         // IPv6対応\r
2346 //                      SetTaskMsg(MSGJPN016, DomainName);\r
2347                         SetTaskMsg(MSGJPN016, DomainName, MSGJPN333);\r
2348                         // IPv6対応\r
2349 //                      pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2350                         pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2351                 }\r
2352 \r
2353                 if(pHostEntry != NULL)\r
2354                 {\r
2355                         memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2356                         // IPv6対応\r
2357 //                      SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2358                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2359                 }\r
2360                 else\r
2361                 {\r
2362                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2363                         {\r
2364                                 UseIPadrs = NO;\r
2365                                 // IPv6対応\r
2366 //                              SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
2367                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2368                         }\r
2369                         else\r
2370                         {\r
2371                                 // IPv6対応\r
2372 //                              SetTaskMsg(MSGJPN019, host);\r
2373                                 SetTaskMsg(MSGJPN019, host, MSGJPN333);\r
2374                                 return(INVALID_SOCKET);\r
2375                         }\r
2376                 }\r
2377         }\r
2378         else\r
2379                 // IPv6対応\r
2380 //              SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2381                 SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2382 \r
2383         if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2384         {\r
2385                 // SOCKSを使う\r
2386                 // SOCKSに接続する準備\r
2387                 if(Fwall == FWALL_SOCKS4)\r
2388                 {\r
2389                         Socks4Cmd.Ver = SOCKS4_VER;\r
2390                         Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
2391                         Socks4Cmd.Port = CurSockAddr.sin_port;\r
2392                         Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2393                         strcpy(Socks4Cmd.UserID, FwallUser);\r
2394                         Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2395                 }\r
2396                 else\r
2397                 {\r
2398                         Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2399                 }\r
2400 \r
2401                 memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2402                 if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
2403                 {\r
2404                         // IPv6対応\r
2405 //                      if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2406                         if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2407                                 memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2408                         else\r
2409                         {\r
2410                                 // IPv6対応\r
2411 //                              SetTaskMsg(MSGJPN021, FwallHost);\r
2412                                 SetTaskMsg(MSGJPN021, FwallHost, MSGJPN333);\r
2413                                 return INVALID_SOCKET;\r
2414                         }\r
2415                 }\r
2416                 SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
2417                 SocksSockAddr.sin_family = AF_INET;\r
2418                 // IPv6対応\r
2419 //              SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
2420                 SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port), MSGJPN333);\r
2421                 // connectで接続する先はSOCKSサーバ\r
2422                 memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2423         }\r
2424         else\r
2425         {\r
2426                 // connectで接続するのは接続先のホスト\r
2427                 memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2428         }\r
2429 \r
2430         /////////////\r
2431         // 接続実行\r
2432         /////////////\r
2433 \r
2434         if((sSocket = do_socket(AF_INET, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2435         {\r
2436                 // ソケットにデータを付与\r
2437                 SetAsyncTableDataIPv4(sSocket, &CurSockAddr, &SocksSockAddr);\r
2438                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2439                 {\r
2440                         if(Fwall == FWALL_SOCKS4)\r
2441                         {\r
2442                                 Socks4Reply.Result = -1;\r
2443                                 // 同時接続対応\r
2444 //                              if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2445 //                                 (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || \r
2446 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2447                                 if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2448                                    (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2449                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2450                                 {\r
2451                                         // IPv6対応\r
2452 //                                      SetTaskMsg(MSGJPN023, Socks4Reply.Result);\r
2453                                         SetTaskMsg(MSGJPN023, Socks4Reply.Result, MSGJPN333);\r
2454                                         DoClose(sSocket);\r
2455                                         sSocket = INVALID_SOCKET;\r
2456                                 }\r
2457                         }\r
2458                         else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2459                         {\r
2460                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2461                                 {\r
2462                                         DoClose(sSocket);\r
2463                                         sSocket = INVALID_SOCKET;\r
2464                                 }\r
2465 \r
2466                                 Socks5Reply.Result = -1;\r
2467                                 // 同時接続対応\r
2468 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2469 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2470 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2471                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2472                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2473                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2474                                 {\r
2475                                         // IPv6対応\r
2476 //                                      SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2477                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN333);\r
2478                                         DoClose(sSocket);\r
2479                                         sSocket = INVALID_SOCKET;\r
2480                                 }\r
2481 \r
2482                         }\r
2483 \r
2484                         if(sSocket != INVALID_SOCKET)\r
2485                                 // IPv6対応\r
2486 //                              SetTaskMsg(MSGJPN025);\r
2487                                 SetTaskMsg(MSGJPN025, MSGJPN333);\r
2488                 }\r
2489                 else\r
2490                 {\r
2491 //#pragma aaa\r
2492                         // IPv6対応\r
2493 //                      SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2494                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN333);\r
2495                         DoClose(sSocket);\r
2496                         sSocket = INVALID_SOCKET;\r
2497                 }\r
2498         }\r
2499         else\r
2500                 // IPv6対応\r
2501 //              SetTaskMsg(MSGJPN027);\r
2502                 SetTaskMsg(MSGJPN027, MSGJPN333);\r
2503 \r
2504         return(sSocket);\r
2505 }\r
2506 \r
2507 \r
2508 SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2509 {\r
2510         struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
2511         struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
2512         struct sockaddr_in6 saSockAddr;\r
2513         char HostEntry[MAXGETHOSTSTRUCT];\r
2514         struct hostent *pHostEntry;\r
2515         SOCKET sSocket;\r
2516         int Len;\r
2517         int Fwall;\r
2518         SOCKS5REQUEST Socks5Cmd;\r
2519         SOCKS5REPLY Socks5Reply;\r
2520 \r
2521         //////////////////////////////\r
2522         // ホスト名解決と接続の準備\r
2523         //////////////////////////////\r
2524 \r
2525         Fwall = FWALL_NONE;\r
2526         if(AskHostFireWall() == YES)\r
2527                 Fwall = FwallType;\r
2528 \r
2529         sSocket = INVALID_SOCKET;\r
2530 \r
2531         UseIPadrs = YES;\r
2532         strcpy(DomainName, host);\r
2533         memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2534         CurSockAddr.sin6_port = htons((u_short)port);\r
2535         CurSockAddr.sin6_family = AF_INET6;\r
2536         CurSockAddr.sin6_addr = inet6_addr(host);\r
2537         if(memcmp(&CurSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2538         {\r
2539                 // ホスト名が指定された\r
2540                 // ホスト名からアドレスを求める\r
2541                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2542                    (FwallResolve == YES))\r
2543                 {\r
2544                         // ホスト名解決はSOCKSサーバに任せる\r
2545                         pHostEntry = NULL;\r
2546                 }\r
2547                 else\r
2548                 {\r
2549                         // アドレスを取得\r
2550                         SetTaskMsg(MSGJPN016, DomainName, MSGJPN334);\r
2551                         pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2552                 }\r
2553 \r
2554                 if(pHostEntry != NULL)\r
2555                 {\r
2556                         memcpy((char *)&CurSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2557                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2558                 }\r
2559                 else\r
2560                 {\r
2561                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2562                         {\r
2563                                 UseIPadrs = NO;\r
2564                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2565                         }\r
2566                         else\r
2567                         {\r
2568                                 SetTaskMsg(MSGJPN019, host, MSGJPN334);\r
2569                                 return(INVALID_SOCKET);\r
2570                         }\r
2571                 }\r
2572         }\r
2573         else\r
2574                 SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2575 \r
2576         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2577         {\r
2578                 // SOCKSを使う\r
2579                 // SOCKSに接続する準備\r
2580                 {\r
2581                         Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
2582                 }\r
2583 \r
2584                 memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2585                 SocksSockAddr.sin6_addr = inet6_addr(FwallHost);\r
2586                 if(memcmp(&SocksSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2587                 {\r
2588                         if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2589                                 memcpy((char *)&SocksSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2590                         else\r
2591                         {\r
2592                                 SetTaskMsg(MSGJPN021, FwallHost, MSGJPN334);\r
2593                                 return INVALID_SOCKET;\r
2594                         }\r
2595                 }\r
2596                 SocksSockAddr.sin6_port = htons((u_short)FwallPort);\r
2597                 SocksSockAddr.sin6_family = AF_INET6;\r
2598                 SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddr.sin6_addr), ntohs(SocksSockAddr.sin6_port), MSGJPN334);\r
2599                 // connectで接続する先はSOCKSサーバ\r
2600                 memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2601         }\r
2602         else\r
2603         {\r
2604                 // connectで接続するのは接続先のホスト\r
2605                 memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2606         }\r
2607 \r
2608         /////////////\r
2609         // 接続実行\r
2610         /////////////\r
2611 \r
2612         if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2613         {\r
2614                 // ソケットにデータを付与\r
2615                 SetAsyncTableDataIPv6(sSocket, &CurSockAddr, &SocksSockAddr);\r
2616                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2617                 {\r
2618                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2619                         {\r
2620                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2621                                 {\r
2622                                         DoClose(sSocket);\r
2623                                         sSocket = INVALID_SOCKET;\r
2624                                 }\r
2625 \r
2626                                 Socks5Reply.Result = -1;\r
2627                                 // 同時接続対応\r
2628 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2629 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2630 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2631                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2632                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2633                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2634                                 {\r
2635                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN334);\r
2636                                         DoClose(sSocket);\r
2637                                         sSocket = INVALID_SOCKET;\r
2638                                 }\r
2639 \r
2640                         }\r
2641 \r
2642                         if(sSocket != INVALID_SOCKET)\r
2643                                 SetTaskMsg(MSGJPN025, MSGJPN334);\r
2644                 }\r
2645                 else\r
2646                 {\r
2647 //#pragma aaa\r
2648                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN334);\r
2649                         DoClose(sSocket);\r
2650                         sSocket = INVALID_SOCKET;\r
2651                 }\r
2652         }\r
2653         else\r
2654                 SetTaskMsg(MSGJPN027, MSGJPN334);\r
2655 \r
2656         return(sSocket);\r
2657 }\r
2658 \r
2659 \r
2660 /*----- リッスンソケットを取得 ------------------------------------------------\r
2661 *\r
2662 *       Parameter\r
2663 *               SOCKET ctrl_skt : コントロールソケット\r
2664 *\r
2665 *       Return Value\r
2666 *               SOCKET リッスンソケット\r
2667 *----------------------------------------------------------------------------*/\r
2668 \r
2669 // IPv6対応\r
2670 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2671 {\r
2672         SOCKET Result;\r
2673         Result = INVALID_SOCKET;\r
2674         switch(CurHost.CurNetType)\r
2675         {\r
2676         case NTYPE_IPV4:\r
2677                 Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
2678                 break;\r
2679         case NTYPE_IPV6:\r
2680                 Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
2681                 break;\r
2682         }\r
2683         return Result;\r
2684 }\r
2685 \r
2686 \r
2687 // IPv6対応\r
2688 //SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2689 SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
2690 {\r
2691         // IPv6対応\r
2692         struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
2693         struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
2694     SOCKET listen_skt;\r
2695     int iLength;\r
2696     char *a,*p;\r
2697         struct sockaddr_in saCtrlAddr;\r
2698         struct sockaddr_in saTmpAddr;\r
2699         SOCKS4CMD Socks4Cmd;\r
2700         SOCKS4REPLY Socks4Reply;\r
2701         SOCKS5REQUEST Socks5Cmd;\r
2702         SOCKS5REPLY Socks5Reply;\r
2703 \r
2704         int Len;\r
2705         int Fwall;\r
2706 \r
2707         // UPnP対応\r
2708         char Adrs[16];\r
2709         int Port;\r
2710 \r
2711         // ソケットにデータを付与\r
2712         GetAsyncTableDataIPv4(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
2713 \r
2714         Fwall = FWALL_NONE;\r
2715         if(AskHostFireWall() == YES)\r
2716                 Fwall = FwallType;\r
2717 \r
2718         if((listen_skt = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2719         {\r
2720                 if(Fwall == FWALL_SOCKS4)\r
2721                 {\r
2722                         /*===== SOCKS4を使う =====*/\r
2723                         DoPrintf("Use SOCKS4 BIND");\r
2724                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2725                         {\r
2726                                 Socks4Cmd.Ver = SOCKS4_VER;\r
2727                                 Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
2728                                 Socks4Cmd.Port = CurSockAddr.sin_port;\r
2729                                 Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2730                                 strcpy(Socks4Cmd.UserID, FwallUser);\r
2731                                 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2732 \r
2733                                 Socks4Reply.Result = -1;\r
2734                                 // 同時接続対応\r
2735 //                              if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2736 //                                 (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || \r
2737 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2738                                 if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2739                                    (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2740                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2741                                 {\r
2742                                         // IPv6対応\r
2743 //                                      SetTaskMsg(MSGJPN028, Socks4Reply.Result);\r
2744                                         SetTaskMsg(MSGJPN028, Socks4Reply.Result, MSGJPN333);\r
2745                                         DoClose(listen_skt);\r
2746                                         listen_skt = INVALID_SOCKET;\r
2747                                 }\r
2748 \r
2749                                 if(Socks4Reply.AdrsInt == 0)\r
2750                                         Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2751 \r
2752                                 a = (char *)&Socks4Reply.AdrsInt;\r
2753                                 p = (char *)&Socks4Reply.Port;\r
2754                         }\r
2755                 }\r
2756                 else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2757                 {\r
2758                         /*===== SOCKS5を使う =====*/\r
2759                         DoPrintf("Use SOCKS5 BIND");\r
2760                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2761                         {\r
2762                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2763                                 {\r
2764                                         DoClose(listen_skt);\r
2765                                         listen_skt = INVALID_SOCKET;\r
2766                                         return(listen_skt);\r
2767                                 }\r
2768 \r
2769                                 Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2770 \r
2771                                 Socks5Reply.Result = -1;\r
2772                                 // 同時接続対応\r
2773 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2774 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2775 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2776                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2777                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2778                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2779                                 {\r
2780                                         // IPv6対応\r
2781 //                                      SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2782                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN333);\r
2783                                         DoClose(listen_skt);\r
2784                                         listen_skt = INVALID_SOCKET;\r
2785                                 }\r
2786 \r
2787                                 // IPv6対応\r
2788 //                              if(Socks5Reply.AdrsInt == 0)\r
2789 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2790 \r
2791                                 // IPv6対応\r
2792 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2793 //                              p = (char *)&Socks5Reply.Port;\r
2794                                 a = (char *)&Socks5Reply._dummy[0];\r
2795                                 p = (char *)&Socks5Reply._dummy[4];\r
2796                         }\r
2797                 }\r
2798                 else\r
2799                 {\r
2800                         /*===== SOCKSを使わない =====*/\r
2801                         DoPrintf("Use normal BIND");\r
2802                         saCtrlAddr.sin_port = htons(0);\r
2803                         saCtrlAddr.sin_family = AF_INET;\r
2804                         saCtrlAddr.sin_addr.s_addr = 0;\r
2805 \r
2806                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr)) != SOCKET_ERROR)\r
2807                         {\r
2808                                 iLength = sizeof(saCtrlAddr);\r
2809                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2810                                 {\r
2811                                         if(do_listen(listen_skt, 1) == 0)\r
2812                                         {\r
2813                                                 iLength = sizeof(saTmpAddr);\r
2814                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2815                                                         ReportWSError("getsockname", WSAGetLastError());\r
2816 \r
2817                                                 a = (char *)&saTmpAddr.sin_addr;\r
2818                                                 p = (char *)&saCtrlAddr.sin_port;\r
2819                                                 // UPnP対応\r
2820                                                 if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
2821                                                 {\r
2822                                                         if(AddPortMapping(AddressToStringIPv4(Adrs, &saTmpAddr.sin_addr), ntohs(saCtrlAddr.sin_port)) == FFFTP_SUCCESS)\r
2823                                                                 SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin_port));\r
2824                                                 }\r
2825                                         }\r
2826                                         else\r
2827                                         {\r
2828                                                 ReportWSError("listen", WSAGetLastError());\r
2829                                                 do_closesocket(listen_skt);\r
2830                                                 listen_skt = INVALID_SOCKET;\r
2831                                         }\r
2832                                 }\r
2833                                 else\r
2834                                 {\r
2835                                         ReportWSError("getsockname", WSAGetLastError());\r
2836                                         do_closesocket(listen_skt);\r
2837                                         listen_skt = INVALID_SOCKET;\r
2838                                 }\r
2839                         }\r
2840                         else\r
2841                         {\r
2842                                 ReportWSError("bind", WSAGetLastError());\r
2843                                 do_closesocket(listen_skt);\r
2844                                 listen_skt = INVALID_SOCKET;\r
2845                         }\r
2846 \r
2847                         if(listen_skt == INVALID_SOCKET)\r
2848                                 // IPv6対応\r
2849 //                              SetTaskMsg(MSGJPN030);\r
2850                                 SetTaskMsg(MSGJPN030, MSGJPN333);\r
2851                 }\r
2852         }\r
2853         else\r
2854                 ReportWSError("socket create", WSAGetLastError());\r
2855 \r
2856         if(listen_skt != INVALID_SOCKET)\r
2857         {\r
2858 #define  UC(b)  (((int)b)&0xff)\r
2859                 // 同時接続対応\r
2860 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2861 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2862 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2863                 if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d",\r
2864                                 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2865                                 UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2866                 {\r
2867                         // IPv6対応\r
2868 //                      SetTaskMsg(MSGJPN031);\r
2869                         SetTaskMsg(MSGJPN031, MSGJPN333);\r
2870                         // UPnP対応\r
2871                         if(IsUPnPLoaded() == YES)\r
2872                         {\r
2873                                 if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
2874                                         RemovePortMapping(Port);\r
2875                         }\r
2876                         do_closesocket(listen_skt);\r
2877                         listen_skt = INVALID_SOCKET;\r
2878                 }\r
2879 //              else\r
2880 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2881         }\r
2882 \r
2883         return(listen_skt);\r
2884 }\r
2885 \r
2886 \r
2887 SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
2888 {\r
2889         struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
2890         struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
2891     SOCKET listen_skt;\r
2892     int iLength;\r
2893     char *a,*p;\r
2894         struct sockaddr_in6 saCtrlAddr;\r
2895         struct sockaddr_in6 saTmpAddr;\r
2896         SOCKS5REQUEST Socks5Cmd;\r
2897         SOCKS5REPLY Socks5Reply;\r
2898 \r
2899         int Len;\r
2900         int Fwall;\r
2901 \r
2902         char Adrs[40];\r
2903         // UPnP対応\r
2904         int Port;\r
2905 \r
2906         // ソケットにデータを付与\r
2907         GetAsyncTableDataIPv6(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
2908 \r
2909         Fwall = FWALL_NONE;\r
2910         if(AskHostFireWall() == YES)\r
2911                 Fwall = FwallType;\r
2912 \r
2913         if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2914         {\r
2915                 if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2916                 {\r
2917                         /*===== SOCKS5を使う =====*/\r
2918                         DoPrintf("Use SOCKS5 BIND");\r
2919                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2920                         {\r
2921                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2922                                 {\r
2923                                         DoClose(listen_skt);\r
2924                                         listen_skt = INVALID_SOCKET;\r
2925                                         return(listen_skt);\r
2926                                 }\r
2927 \r
2928                                 Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
2929 \r
2930                                 Socks5Reply.Result = -1;\r
2931                                 // 同時接続対応\r
2932 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2933 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2934 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2935                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2936                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2937                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2938                                 {\r
2939                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN334);\r
2940                                         DoClose(listen_skt);\r
2941                                         listen_skt = INVALID_SOCKET;\r
2942                                 }\r
2943 \r
2944                                 // IPv6対応\r
2945 //                              if(Socks5Reply.AdrsInt == 0)\r
2946 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2947 \r
2948                                 // IPv6対応\r
2949 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2950 //                              p = (char *)&Socks5Reply.Port;\r
2951                                 a = (char *)&Socks5Reply._dummy[0];\r
2952                                 p = (char *)&Socks5Reply._dummy[16];\r
2953                         }\r
2954                 }\r
2955                 else\r
2956                 {\r
2957                         /*===== SOCKSを使わない =====*/\r
2958                         DoPrintf("Use normal BIND");\r
2959                         saCtrlAddr.sin6_port = htons(0);\r
2960                         saCtrlAddr.sin6_family = AF_INET6;\r
2961                         memset(&saCtrlAddr.sin6_addr, 0, 16);\r
2962 \r
2963                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
2964                         {\r
2965                                 iLength = sizeof(saCtrlAddr);\r
2966                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2967                                 {\r
2968                                         if(do_listen(listen_skt, 1) == 0)\r
2969                                         {\r
2970                                                 iLength = sizeof(saTmpAddr);\r
2971                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2972                                                         ReportWSError("getsockname", WSAGetLastError());\r
2973 \r
2974                                                 a = (char *)&saTmpAddr.sin6_addr;\r
2975                                                 p = (char *)&saCtrlAddr.sin6_port;\r
2976                                                 // UPnP対応\r
2977                                                 if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
2978                                                 {\r
2979                                                         if(AddPortMapping(AddressToStringIPv6(Adrs, &saTmpAddr.sin6_addr), ntohs(saCtrlAddr.sin6_port)) == FFFTP_SUCCESS)\r
2980                                                                 SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin6_port));\r
2981                                                 }\r
2982                                         }\r
2983                                         else\r
2984                                         {\r
2985                                                 ReportWSError("listen", WSAGetLastError());\r
2986                                                 do_closesocket(listen_skt);\r
2987                                                 listen_skt = INVALID_SOCKET;\r
2988                                         }\r
2989                                 }\r
2990                                 else\r
2991                                 {\r
2992                                         ReportWSError("getsockname", WSAGetLastError());\r
2993                                         do_closesocket(listen_skt);\r
2994                                         listen_skt = INVALID_SOCKET;\r
2995                                 }\r
2996                         }\r
2997                         else\r
2998                         {\r
2999                                 ReportWSError("bind", WSAGetLastError());\r
3000                                 do_closesocket(listen_skt);\r
3001                                 listen_skt = INVALID_SOCKET;\r
3002                         }\r
3003 \r
3004                         if(listen_skt == INVALID_SOCKET)\r
3005                                 SetTaskMsg(MSGJPN030, MSGJPN334);\r
3006                 }\r
3007         }\r
3008         else\r
3009                 ReportWSError("socket create", WSAGetLastError());\r
3010 \r
3011         if(listen_skt != INVALID_SOCKET)\r
3012         {\r
3013 #define  UC(b)  (((int)b)&0xff)\r
3014                 // 同時接続対応\r
3015 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
3016 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
3017 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
3018                 if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
3019                                 AddressToStringIPv6(Adrs, a),\r
3020                                 (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE)\r
3021                 {\r
3022                         SetTaskMsg(MSGJPN031, MSGJPN334);\r
3023                         // UPnP対応\r
3024                         if(IsUPnPLoaded() == YES)\r
3025                         {\r
3026                                 if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
3027                                         RemovePortMapping(Port);\r
3028                         }\r
3029                         do_closesocket(listen_skt);\r
3030                         listen_skt = INVALID_SOCKET;\r
3031                 }\r
3032 //              else\r
3033 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
3034         }\r
3035 \r
3036         return(listen_skt);\r
3037 }\r
3038 \r
3039 \r
3040 /*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
3041 *\r
3042 *       Parameter\r
3043 *               なし\r
3044 *\r
3045 *       Return Value\r
3046 *               int ステータス\r
3047 *                       YES/NO\r
3048 *----------------------------------------------------------------------------*/\r
3049 \r
3050 int AskTryingConnect(void)\r
3051 {\r
3052         return(TryConnect);\r
3053 }\r
3054 \r
3055 \r
3056 #if 0\r
3057 ///*----- ブロッキングコールのフックコールバック --------------------------------\r
3058 //*\r
3059 //*     Parameter\r
3060 //*             なし\r
3061 //*\r
3062 //*     Return Value\r
3063 //*             BOOL FALSE\r
3064 //*----------------------------------------------------------------------------*/\r
3065 //\r
3066 //static BOOL CALLBACK BlkHookFnc(void)\r
3067 //{\r
3068 //      BackgrndMessageProc();\r
3069 //\r
3070 //      if(CancelFlg == YES)\r
3071 //      {\r
3072 //              SetTaskMsg(MSGJPN032);\r
3073 //              WSACancelBlockingCall();\r
3074 //              CancelFlg = NO;\r
3075 //      }\r
3076 //      return(FALSE);\r
3077 //}\r
3078 #endif\r
3079 \r
3080 \r
3081 \r
3082 /*----- SOCKS5のコマンドパケットを作成する ------------------------------------\r
3083 *\r
3084 *       Parameter\r
3085 *               SOCKS5REQUEST *Packet : パケットを作成するワーク\r
3086 *               char Cmd : コマンド\r
3087 *               int ValidIP : IPアドレスを使うかどうか(YES/NO)\r
3088 *               ulong IP : IPアドレス\r
3089 *               char *Host : ホスト名\r
3090 *               ushort Port : ポート\r
3091 *\r
3092 *       Return Value\r
3093 *               int コマンドパケットの長さ\r
3094 *----------------------------------------------------------------------------*/\r
3095 \r
3096 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port)\r
3097 {\r
3098         uchar *Pos;\r
3099         int Len;\r
3100         int TotalLen;\r
3101 \r
3102         Pos = (uchar *)Packet;\r
3103         Pos += SOCKS5REQUEST_SIZE;\r
3104         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
3105 \r
3106         Packet->Ver = SOCKS5_VER;\r
3107         Packet->Cmd = Cmd;\r
3108         Packet->Rsv = 0;\r
3109         if(ValidIP == YES)\r
3110         {\r
3111                 /* IPアドレスを指定 */\r
3112                 Packet->Type = SOCKS5_ADRS_IPV4;\r
3113                 *((ulong *)Pos) = IP;\r
3114                 Pos += 4;\r
3115                 TotalLen += 4;\r
3116         }\r
3117         else\r
3118         {\r
3119                 /* ホスト名を指定 */\r
3120                 Packet->Type = SOCKS5_ADRS_NAME;\r
3121                 Len = strlen(Host);\r
3122                 *Pos++ = Len;\r
3123                 strcpy(Pos, Host);\r
3124                 Pos += Len;\r
3125                 TotalLen += Len + 1;\r
3126         }\r
3127         *((ushort *)Pos) = Port;\r
3128 \r
3129         return(TotalLen);\r
3130 }\r
3131 \r
3132 \r
3133 // IPv6対応\r
3134 static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
3135 {\r
3136         uchar *Pos;\r
3137         int Len;\r
3138         int TotalLen;\r
3139 \r
3140         Pos = (uchar *)Packet;\r
3141         Pos += SOCKS5REQUEST_SIZE;\r
3142         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
3143 \r
3144         Packet->Ver = SOCKS5_VER;\r
3145         Packet->Cmd = Cmd;\r
3146         Packet->Rsv = 0;\r
3147         if(ValidIP == YES)\r
3148         {\r
3149                 /* IPアドレスを指定 */\r
3150                 Packet->Type = SOCKS5_ADRS_IPV6;\r
3151                 memcpy(Pos, IP, 16);\r
3152                 Pos += 16;\r
3153                 TotalLen += 16;\r
3154         }\r
3155         else\r
3156         {\r
3157                 /* ホスト名を指定 */\r
3158                 Packet->Type = SOCKS5_ADRS_NAME;\r
3159                 Len = strlen(Host);\r
3160                 *Pos++ = Len;\r
3161                 strcpy(Pos, Host);\r
3162                 Pos += Len;\r
3163                 TotalLen += Len + 1;\r
3164         }\r
3165         *((ushort *)Pos) = Port;\r
3166 \r
3167         return(TotalLen);\r
3168 }\r
3169 \r
3170 \r
3171 /*----- SOCKSのコマンドを送る -------------------------------------------------\r
3172 *\r
3173 *       Parameter\r
3174 *               SOCKET Socket : ソケット\r
3175 *               void *Data : 送るデータ\r
3176 *               int Size : サイズ\r
3177 *\r
3178 *       Return Value\r
3179 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3180 *----------------------------------------------------------------------------*/\r
3181 \r
3182 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork)\r
3183 {\r
3184         int Ret;\r
3185 \r
3186         Ret = SendData(Socket, (char *)Data, Size, 0, CancelCheckWork);\r
3187 \r
3188         if(Ret != FFFTP_SUCCESS)\r
3189                 SetTaskMsg(MSGJPN033, *((short *)Data));\r
3190 \r
3191         return(Ret);\r
3192 }\r
3193 \r
3194 \r
3195 /*----- SOCKS5のコマンドに対するリプライパケットを受信する --------------------\r
3196 *\r
3197 *       Parameter\r
3198 *               SOCKET Socket : ソケット\r
3199 *               SOCKS5REPLY *Packet : パケット\r
3200 *\r
3201 *       Return Value\r
3202 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3203 *----------------------------------------------------------------------------*/\r
3204 \r
3205 // 同時接続対応\r
3206 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet)\r
3207 static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork)\r
3208 {\r
3209         uchar *Pos;\r
3210         int Len;\r
3211         int Ret;\r
3212 \r
3213         Pos = (uchar *)Packet;\r
3214         Pos += SOCKS5REPLY_SIZE;\r
3215 \r
3216         // 同時接続対応\r
3217 //      if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS)\r
3218         if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, CancelCheckWork)) == FFFTP_SUCCESS)\r
3219         {\r
3220                 if(Packet->Type == SOCKS5_ADRS_IPV4)\r
3221                         Len = 4 + 2;\r
3222                 else if(Packet->Type == SOCKS5_ADRS_IPV6)\r
3223                         Len = 16 + 2;\r
3224                 else\r
3225                 {\r
3226                         // 同時接続対応\r
3227 //                      if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS)\r
3228                         if((Ret = ReadNchar(Socket, (char *)Pos, 1, CancelCheckWork)) == FFFTP_SUCCESS)\r
3229                         {\r
3230                                 Len = *Pos + 2;\r
3231                                 Pos++;\r
3232                         }\r
3233                 }\r
3234 \r
3235                 if(Ret == FFFTP_SUCCESS)\r
3236                         // 同時接続対応\r
3237 //                      Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg);\r
3238                         Ret = ReadNchar(Socket, (char *)Pos, Len, CancelCheckWork);\r
3239         }\r
3240 \r
3241         if(Ret != FFFTP_SUCCESS)\r
3242                 SetTaskMsg(MSGJPN034);\r
3243 \r
3244         return(Ret);\r
3245 }\r
3246 \r
3247 \r
3248 /*----- SOCKS4のコマンドに対するリプライパケットを受信する --------------------\r
3249 *\r
3250 *       Parameter\r
3251 *               SOCKET Socket : ソケット\r
3252 *               SOCKS5REPLY *Packet : パケット\r
3253 *\r
3254 *       Return Value\r
3255 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3256 *----------------------------------------------------------------------------*/\r
3257 \r
3258 // 同時接続対応\r
3259 //static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet)\r
3260 static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork)\r
3261 {\r
3262         int Ret;\r
3263 \r
3264         // 同時接続対応\r
3265 //      Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg);\r
3266         Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, CancelCheckWork);\r
3267 \r
3268         if(Ret != FFFTP_SUCCESS)\r
3269                 DoPrintf(MSGJPN035);\r
3270 \r
3271         return(Ret);\r
3272 }\r
3273 \r
3274 \r
3275 /*----- SOCKS5の認証を行う ----------------------------------------------------\r
3276 *\r
3277 *       Parameter\r
3278 *               SOCKET Socket : ソケット\r
3279 *\r
3280 *       Return Value\r
3281 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3282 *----------------------------------------------------------------------------*/\r
3283 \r
3284 static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork)\r
3285 {\r
3286         int Ret;\r
3287         SOCKS5METHODREQUEST Socks5Method;\r
3288         SOCKS5METHODREPLY Socks5MethodReply;\r
3289         SOCKS5USERPASSSTATUS Socks5Status;\r
3290         char Buf[USER_NAME_LEN + PASSWORD_LEN + 4];\r
3291         int Len;\r
3292         int Len2;\r
3293 \r
3294         Ret = FFFTP_SUCCESS;\r
3295         Socks5Method.Ver = SOCKS5_VER;\r
3296         Socks5Method.Num = 1;\r
3297         if(FwallType == FWALL_SOCKS5_NOAUTH)\r
3298                 Socks5Method.Methods[0] = SOCKS5_AUTH_NONE;\r
3299         else\r
3300                 Socks5Method.Methods[0] = SOCKS5_AUTH_USER;\r
3301 \r
3302         // 同時接続対応\r
3303 //      if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3304 //         (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
3305 //         (Socks5MethodReply.Method == (uchar)0xFF))\r
3306         if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3307            (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3308            (Socks5MethodReply.Method == (uchar)0xFF))\r
3309         {\r
3310                 SetTaskMsg(MSGJPN036);\r
3311                 Ret = FFFTP_FAIL;\r
3312         }\r
3313         else if(Socks5MethodReply.Method == SOCKS5_AUTH_USER)\r
3314         {\r
3315                 DoPrintf("SOCKS5 User/Pass Authentication");\r
3316                 Buf[0] = SOCKS5_USERAUTH_VER;\r
3317                 Len = strlen(FwallUser);\r
3318                 Len2 = strlen(FwallPass);\r
3319                 Buf[1] = Len;\r
3320                 strcpy(Buf+2, FwallUser);\r
3321                 Buf[2 + Len] = Len2;\r
3322                 strcpy(Buf+3+Len, FwallPass);\r
3323 \r
3324                 // 同時接続対応\r
3325 //              if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3326 //                 (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
3327 //                 (Socks5Status.Status != 0))\r
3328                 if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3329                    (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3330                    (Socks5Status.Status != 0))\r
3331                 {\r
3332                         SetTaskMsg(MSGJPN037);\r
3333                         Ret = FFFTP_FAIL;\r
3334                 }\r
3335         }\r
3336         else\r
3337                 DoPrintf("SOCKS5 No Authentication");\r
3338 \r
3339         return(Ret);\r
3340 }\r
3341 \r
3342 \r
3343 /*----- SOCKSのBINDの第2リプライメッセージを受け取る -------------------------\r
3344 *\r
3345 *       Parameter\r
3346 *               SOCKET Socket : ソケット\r
3347 *               SOCKET *Data : データソケットを返すワーク\r
3348 *\r
3349 *       Return Value\r
3350 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3351 *----------------------------------------------------------------------------*/\r
3352 \r
3353 // 同時接続対応\r
3354 //int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data)\r
3355 int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data, int *CancelCheckWork)\r
3356 {\r
3357         int Ret;\r
3358         char Buf[300];\r
3359 \r
3360         Ret = FFFTP_FAIL;\r
3361         if((AskHostFireWall() == YES) && (FwallType == FWALL_SOCKS4))\r
3362         {\r
3363                 // 同時接続対応\r
3364 //              Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf);\r
3365                 Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf, CancelCheckWork);\r
3366                 *Data = Socket;\r
3367                 Ret = FFFTP_SUCCESS;\r
3368         }\r
3369         else if((AskHostFireWall() == YES) &&\r
3370                         ((FwallType == FWALL_SOCKS5_NOAUTH) || (FwallType == FWALL_SOCKS5_USER)))\r
3371         {\r
3372                 // 同時接続対応\r
3373 //              Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf);\r
3374                 Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf, CancelCheckWork);\r
3375                 *Data = Socket;\r
3376                 Ret = FFFTP_SUCCESS;\r
3377         }\r
3378         return(Ret);\r
3379 }\r
3380 \r
3381 \r
3382 \r
3383 // 暗号化通信対応\r
3384 int AskCryptMode(void)\r
3385 {\r
3386         return(CurHost.CryptMode);\r
3387 }\r
3388 \r
3389 int AskUseNoEncryption(void)\r
3390 {\r
3391         return(CurHost.UseNoEncryption);\r
3392 }\r
3393 \r
3394 int AskUseFTPES(void)\r
3395 {\r
3396         return(CurHost.UseFTPES);\r
3397 }\r
3398 \r
3399 int AskUseFTPIS(void)\r
3400 {\r
3401         return(CurHost.UseFTPIS);\r
3402 }\r
3403 \r
3404 int AskUseSFTP(void)\r
3405 {\r
3406         return(CurHost.UseSFTP);\r
3407 }\r
3408 \r
3409 char *AskPrivateKey(void)\r
3410 {\r
3411         return(CurHost.PrivateKey);\r
3412 }\r
3413 \r
3414 // 同時接続対応\r
3415 int AskMaxThreadCount(void)\r
3416 {\r
3417         return(CurHost.MaxThreadCount);\r
3418 }\r
3419 \r
3420 int AskReuseCmdSkt(void)\r
3421 {\r
3422         return(CurHost.ReuseCmdSkt);\r
3423 }\r
3424 \r
3425 // FEAT対応\r
3426 int AskHostFeature(void)\r
3427 {\r
3428         return(CurHost.Feature);\r
3429 }\r
3430 \r
3431 // MLSD対応\r
3432 int AskUseMLSD(void)\r
3433 {\r
3434         return(CurHost.UseMLSD);\r
3435 }\r
3436 \r
3437 // IPv6対応\r
3438 int AskCurNetType(void)\r
3439 {\r
3440         return(CurHost.CurNetType);\r
3441 }\r
3442 \r
3443 // 自動切断対策\r
3444 int AskNoopInterval(void)\r
3445 {\r
3446         return(CurHost.NoopInterval);\r
3447 }\r
3448 \r
3449 // 再転送対応\r
3450 int AskTransferErrorMode(void)\r
3451 {\r
3452         return(CurHost.TransferErrorMode);\r
3453 }\r
3454 \r
3455 int AskTransferErrorNotify(void)\r
3456 {\r
3457         return(CurHost.TransferErrorNotify);\r
3458 }\r
3459 \r
3460 // セッションあたりの転送量制限対策\r
3461 int AskErrorReconnect(void)\r
3462 {\r
3463         return(CurHost.TransferErrorReconnect);\r
3464 }\r
3465 \r