OSDN Git Service

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