OSDN Git Service

Modify documents.
[ffftp/ffftp.git] / src / 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 \r
1212         // 同時接続対応\r
1213 //      Sts = ReConnectSkt(&CmdCtrlSocket);\r
1214         if(AskShareProh() == YES && AskTransferNow() == YES)\r
1215                 SktShareProh();\r
1216         else\r
1217         {\r
1218                 if(CmdCtrlSocket == TrnCtrlSocket)\r
1219                         TrnCtrlSocket = INVALID_SOCKET;\r
1220                 Sts = ReConnectSkt(&CmdCtrlSocket);\r
1221         }\r
1222 \r
1223         // 同時接続対応\r
1224 //      TrnCtrlSocket = CmdCtrlSocket;\r
1225         if(TrnCtrlSocket == INVALID_SOCKET)\r
1226                 TrnCtrlSocket = CmdCtrlSocket;\r
1227 \r
1228         return(Sts);\r
1229 }\r
1230 \r
1231 \r
1232 /*----- 転送コントロールソケットの再接続 --------------------------------------\r
1233 *\r
1234 *       Parameter\r
1235 *               なし\r
1236 *\r
1237 *       Return Value\r
1238 *               int ステータス\r
1239 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1240 *----------------------------------------------------------------------------*/\r
1241 \r
1242 //int ReConnectTrnSkt(void)\r
1243 //{\r
1244 //      return(ReConnectSkt(&TrnCtrlSocket));\r
1245 //}\r
1246 // 同時接続対応\r
1247 int ReConnectTrnSkt(SOCKET *Skt, int *CancelCheckWork)\r
1248 {\r
1249 //      char Path[FMAX_PATH+1];\r
1250         int Sts;\r
1251         // 暗号化通信対応\r
1252         HOSTDATA HostData;\r
1253 \r
1254         Sts = FFFTP_FAIL;\r
1255 \r
1256         SetTaskMsg(MSGJPN003);\r
1257 \r
1258 //      DisableUserOpe();\r
1259         /* 現在のソケットは切断 */\r
1260         if(*Skt != INVALID_SOCKET)\r
1261                 do_closesocket(*Skt);\r
1262         /* 再接続 */\r
1263         // 暗号化通信対応\r
1264         HostData = CurHost;\r
1265         if(HostData.CryptMode != CRYPT_NONE)\r
1266                 HostData.UseNoEncryption = NO;\r
1267         if(HostData.CryptMode != CRYPT_FTPES)\r
1268                 HostData.UseFTPES = NO;\r
1269         if(HostData.CryptMode != CRYPT_FTPIS)\r
1270                 HostData.UseFTPIS = NO;\r
1271         if(HostData.CryptMode != CRYPT_SFTP)\r
1272                 HostData.UseSFTP = NO;\r
1273         // UTF-8対応\r
1274         HostData.CurNameKanjiCode = HostData.NameKanjiCode;\r
1275         // IPv6対応\r
1276         HostData.CurNetType = HostData.NetType;\r
1277         // 同時接続対応\r
1278         HostData.NoDisplayUI = YES;\r
1279         // 暗号化通信対応\r
1280         // 同時接続対応\r
1281 //      if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
1282         if((*Skt = DoConnect(&HostData, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, CancelCheckWork)) != INVALID_SOCKET)\r
1283         {\r
1284                 SendInitCommand(*Skt, CurHost.InitCmd, CancelCheckWork);\r
1285 //              AskRemoteCurDir(Path, FMAX_PATH);\r
1286 //              DoCWD(Path, YES, YES, YES);\r
1287                 Sts = FFFTP_SUCCESS;\r
1288         }\r
1289         else\r
1290                 SoundPlay(SND_ERROR);\r
1291 \r
1292 //      EnableUserOpe();\r
1293         return(Sts);\r
1294 }\r
1295 \r
1296 \r
1297 /*----- 回線の再接続 ----------------------------------------------------------\r
1298 *\r
1299 *       Parameter\r
1300 *               SOCKET *Skt : 接続したソケットを返すワーク\r
1301 *\r
1302 *       Return Value\r
1303 *               int ステータス\r
1304 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1305 *----------------------------------------------------------------------------*/\r
1306 \r
1307 static int ReConnectSkt(SOCKET *Skt)\r
1308 {\r
1309         char Path[FMAX_PATH+1];\r
1310         int Sts;\r
1311 \r
1312         Sts = FFFTP_FAIL;\r
1313 \r
1314         SetTaskMsg(MSGJPN003);\r
1315 \r
1316         DisableUserOpe();\r
1317         /* 現在のソケットは切断 */\r
1318         if(*Skt != INVALID_SOCKET)\r
1319                 do_closesocket(*Skt);\r
1320         /* 再接続 */\r
1321         // 暗号化通信対応\r
1322         // 同時接続対応\r
1323 //      if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
1324         if((*Skt = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg)) != INVALID_SOCKET)\r
1325         {\r
1326                 SendInitCommand(*Skt, CurHost.InitCmd, &CancelFlg);\r
1327                 AskRemoteCurDir(Path, FMAX_PATH);\r
1328                 DoCWD(Path, YES, YES, YES);\r
1329                 Sts = FFFTP_SUCCESS;\r
1330         }\r
1331         else\r
1332                 SoundPlay(SND_ERROR);\r
1333 \r
1334         EnableUserOpe();\r
1335         return(Sts);\r
1336 }\r
1337 \r
1338 \r
1339 /*----- コマンドコントロールソケットを返す ------------------------------------\r
1340 *\r
1341 *       Parameter\r
1342 *               なし\r
1343 *\r
1344 *       Return Value\r
1345 *               SOCKET コマンドコントロールソケット\r
1346 *----------------------------------------------------------------------------*/\r
1347 \r
1348 SOCKET AskCmdCtrlSkt(void)\r
1349 {\r
1350         return(CmdCtrlSocket);\r
1351 }\r
1352 \r
1353 \r
1354 /*----- 転送コントロールソケットを返す ----------------------------------------\r
1355 *\r
1356 *       Parameter\r
1357 *               なし\r
1358 *\r
1359 *       Return Value\r
1360 *               SOCKET 転送コントロールソケット\r
1361 *----------------------------------------------------------------------------*/\r
1362 \r
1363 SOCKET AskTrnCtrlSkt(void)\r
1364 {\r
1365         return(TrnCtrlSocket);\r
1366 }\r
1367 \r
1368 \r
1369 /*----- コマンド/転送コントロールソケットの共有を解除 ------------------------\r
1370 *\r
1371 *       Parameter\r
1372 *               なし\r
1373 *\r
1374 *       Return Value\r
1375 *               なし\r
1376 *----------------------------------------------------------------------------*/\r
1377 \r
1378 void SktShareProh(void)\r
1379 {\r
1380         if(CmdCtrlSocket == TrnCtrlSocket)\r
1381         {\r
1382 \r
1383 //SetTaskMsg("############### SktShareProh");\r
1384 \r
1385                 // 同時接続対応\r
1386 //              CmdCtrlSocket = INVALID_SOCKET;\r
1387 //              ReConnectSkt(&CmdCtrlSocket);\r
1388                 if(CurHost.ReuseCmdSkt == YES)\r
1389                 {\r
1390                         CurHost.ReuseCmdSkt = NO;\r
1391                         CmdCtrlSocket = INVALID_SOCKET;\r
1392                         ReConnectSkt(&CmdCtrlSocket);\r
1393                 }\r
1394         }\r
1395         return;\r
1396 }\r
1397 \r
1398 \r
1399 /*----- コマンド/転送コントロールソケットの共有が解除されているかチェック ----\r
1400 *\r
1401 *       Parameter\r
1402 *               なし\r
1403 *\r
1404 *       Return Value\r
1405 *               int ステータス\r
1406 *                       YES=共有解除/NO=共有\r
1407 *----------------------------------------------------------------------------*/\r
1408 \r
1409 int AskShareProh(void)\r
1410 {\r
1411         int Sts;\r
1412 \r
1413         Sts = YES;\r
1414         // 同時接続対応\r
1415 //      if(CmdCtrlSocket == TrnCtrlSocket)\r
1416         if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET)\r
1417                 Sts = NO;\r
1418 \r
1419         return(Sts);\r
1420 }\r
1421 \r
1422 \r
1423 /*----- ホストから切断 --------------------------------------------------------\r
1424 *\r
1425 *       Parameter\r
1426 *               なし\r
1427 *\r
1428 *       Return Value\r
1429 *               なし\r
1430 *----------------------------------------------------------------------------*/\r
1431 \r
1432 void DisconnectProc(void)\r
1433 {\r
1434 \r
1435 //SetTaskMsg("############### Disconnect Cmd=%x, Trn=%x", CmdCtrlSocket,TrnCtrlSocket);\r
1436 \r
1437         // 同時接続対応\r
1438         AbortAllTransfer();\r
1439 \r
1440         if((CmdCtrlSocket != INVALID_SOCKET) && (CmdCtrlSocket != TrnCtrlSocket))\r
1441         {\r
1442                 // 同時接続対応\r
1443 //              DoQUIT(CmdCtrlSocket);\r
1444                 DoQUIT(CmdCtrlSocket, &CancelFlg);\r
1445                 DoClose(CmdCtrlSocket);\r
1446         }\r
1447 \r
1448         if(TrnCtrlSocket != INVALID_SOCKET)\r
1449         {\r
1450                 // 同時接続対応\r
1451 //              DoQUIT(TrnCtrlSocket);\r
1452                 DoQUIT(TrnCtrlSocket, &CancelFlg);\r
1453                 DoClose(TrnCtrlSocket);\r
1454 \r
1455                 SaveCurrentSetToHistory();\r
1456 \r
1457                 EraseRemoteDirForWnd();\r
1458                 SetTaskMsg(MSGJPN004);\r
1459         }\r
1460 \r
1461         TrnCtrlSocket = INVALID_SOCKET;\r
1462         CmdCtrlSocket = INVALID_SOCKET;\r
1463 \r
1464         DispWindowTitle();\r
1465         MakeButtonsFocus();\r
1466         ClearBookMark();\r
1467 \r
1468         return;\r
1469 }\r
1470 \r
1471 \r
1472 /*----- ソケットが強制切断されたときの処理 ------------------------------------\r
1473 *\r
1474 *       Parameter\r
1475 *               なし\r
1476 *\r
1477 *       Return Value\r
1478 *               なし\r
1479 *----------------------------------------------------------------------------*/\r
1480 \r
1481 void DisconnectSet(void)\r
1482 {\r
1483         CmdCtrlSocket = INVALID_SOCKET;\r
1484         TrnCtrlSocket = INVALID_SOCKET;\r
1485 \r
1486         EraseRemoteDirForWnd();\r
1487         DispWindowTitle();\r
1488         MakeButtonsFocus();\r
1489         SetTaskMsg(MSGJPN005);\r
1490         return;\r
1491 }\r
1492 \r
1493 \r
1494 /*----- ホストに接続中かどうかを返す ------------------------------------------\r
1495 *\r
1496 *       Parameter\r
1497 *               なし\r
1498 *\r
1499 *       Return Value\r
1500 *               int ステータス (YES/NO)\r
1501 *----------------------------------------------------------------------------*/\r
1502 \r
1503 int AskConnecting(void)\r
1504 {\r
1505         int Sts;\r
1506 \r
1507         Sts = NO;\r
1508         if(TrnCtrlSocket != INVALID_SOCKET)\r
1509                 Sts = YES;\r
1510 \r
1511         return(Sts);\r
1512 }\r
1513 \r
1514 \r
1515 #if defined(HAVE_TANDEM)\r
1516 /*----- 接続している本当のホストのホストタイプを返す --------------------------\r
1517 *\r
1518 *       Parameter\r
1519 *               なし\r
1520 *\r
1521 *       Return Value\r
1522 *               char *ファイル名/オプション\r
1523 *----------------------------------------------------------------------------*/\r
1524 \r
1525 int AskRealHostType(void)\r
1526 {\r
1527         // 同時接続対応\r
1528         HOSTDATA TmpHost;\r
1529         TmpHost = CurHost;\r
1530 \r
1531         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
1532                 // 同時接続対応\r
1533 //              CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
1534                 CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
1535 \r
1536         // 同時接続対応\r
1537 //      return(CurHost.HostType);\r
1538         return(TmpHost.HostType);\r
1539 }\r
1540 \r
1541 /*----- OSS ファイルシステムにアクセスしているかどうかのフラグを変更する ------\r
1542 *\r
1543 *       Parameter\r
1544 *               int ステータス (YES/NO)\r
1545 *\r
1546 *       Return Value\r
1547 *               int ステータス (YES/NO)\r
1548 *----------------------------------------------------------------------------*/\r
1549 \r
1550 int SetOSS(int wkOss)\r
1551 {\r
1552         if(Oss != wkOss) {\r
1553                 if (wkOss == YES) {\r
1554                         strcpy(CurHost.InitCmd, "OSS");\r
1555                 } else {\r
1556                         strcpy(CurHost.InitCmd, "GUARDIAN");\r
1557                 }\r
1558         }\r
1559         Oss = wkOss;\r
1560         return(Oss);\r
1561 }\r
1562 \r
1563 /*----- OSS ファイルシステムにアクセスしているかどうかを返す ------------------\r
1564 *\r
1565 *       Parameter\r
1566 *               なし\r
1567 *\r
1568 *       Return Value\r
1569 *               int ステータス (YES/NO)\r
1570 *----------------------------------------------------------------------------*/\r
1571 \r
1572 int AskOSS(void)\r
1573 {\r
1574         return(Oss);\r
1575 }\r
1576 #endif /* HAVE_TANDEM */\r
1577 \r
1578 \r
1579 /*----- ホストへ接続する ------------------------------------------------------\r
1580 *\r
1581 *       Parameter\r
1582 *               char *Host : ホスト名\r
1583 *               char *User : ユーザ名\r
1584 *               char *Pass : パスワード\r
1585 *               char *Acct : アカウント\r
1586 *               int Port : ポート\r
1587 *               int Fwall : FireWallを使うかどうか (YES/NO)\r
1588 *               int SavePass : パスワードを再入力した時に保存するかどうか (YES/NO)\r
1589 *               int Security : セキュリティ (SECURITY_xxx, MDx)\r
1590 *\r
1591 *       Return Value\r
1592 *               SOCKET ソケット\r
1593 *\r
1594 *       Note\r
1595 *               ホスト名、ユーザ名、パスワードが指定されていなかったときは、接続に使用\r
1596 *               したものをコピーしてかえす\r
1597 *                       char *Host : ホスト名\r
1598 *                       char *User : ユーザ名\r
1599 *                       char *Pass : パスワード\r
1600 *                       char *Acct : アカウント\r
1601 *\r
1602 *               FireWallは次のように動作する\r
1603 *                       TYPE1   Connect fire → USER user(f) → PASS pass(f) → SITE host → USER user(h) →      PASS pass(h) → ACCT acct\r
1604 *                       TYPE2   Connect fire → USER user(f) → PASS pass(f) →              USER user(h)@host → PASS pass(h) → ACCT acct\r
1605 *                       TYPE3   Connect fire →                                              USER user(h)@host → PASS pass(h) → ACCT acct\r
1606 *                       TYPE4   Connect fire →                                 OPEN host → USER user(h) →      PASS pass(h) → ACCT acct\r
1607 *                       TYPE5   SOCKS4\r
1608 *                       none    Connect host →                                              USER user(h) →      PASS pass(h) → ACCT acct\r
1609 *----------------------------------------------------------------------------*/\r
1610 \r
1611 // 暗号化通信対応\r
1612 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
1613 {\r
1614         int Sts;\r
1615         int Flg;\r
1616         int Anony;\r
1617         SOCKET ContSock;\r
1618         char Buf[1024];\r
1619         char Reply[1024];\r
1620         int Continue;\r
1621         int ReInPass;\r
1622         char *Tmp;\r
1623         int HostPort;\r
1624         static const char *SiteTbl[4] = { "SITE", "site", "OPEN", "open" };\r
1625         char TmpBuf[ONELINE_BUF_SIZE];\r
1626         struct linger LingerOpt;\r
1627         struct tcp_keepalive KeepAlive;\r
1628         DWORD dwTmp;\r
1629 \r
1630         // 暗号化通信対応\r
1631         ContSock = INVALID_SOCKET;\r
1632 \r
1633         if(CryptMode == CRYPT_NONE || CryptMode == CRYPT_FTPES || CryptMode == CRYPT_FTPIS)\r
1634         {\r
1635                 if(Fwall == YES)\r
1636                         Fwall = FwallType;\r
1637                 else\r
1638                         Fwall = FWALL_NONE;\r
1639 \r
1640                 TryConnect = YES;\r
1641                 // 暗号化通信対応\r
1642 //              CancelFlg = NO;\r
1643 #if 0\r
1644 //              WSASetBlockingHook(BlkHookFnc);\r
1645 #endif\r
1646 \r
1647                 ContSock = INVALID_SOCKET;\r
1648 \r
1649                 HostPort = Port;\r
1650                 Tmp = Host;\r
1651                 if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1652                    (Fwall == FWALL_SIDEWINDER) ||\r
1653                    (Fwall == FWALL_FU_FP))\r
1654                 {\r
1655                         Tmp = FwallHost;\r
1656                         Port = FwallPort;\r
1657                 }\r
1658 \r
1659                 if(strlen(Tmp) != 0)\r
1660                 {\r
1661                         // 同時接続対応\r
1662 //                      if((ContSock = connectsock(Tmp, Port, "", &CancelFlg)) != INVALID_SOCKET)\r
1663                         if((ContSock = connectsock(Tmp, Port, "", CancelCheckWork)) != INVALID_SOCKET)\r
1664                         {\r
1665                                 // バッファを無効\r
1666 #ifdef DISABLE_CONTROL_NETWORK_BUFFERS\r
1667                                 int BufferSize = 0;\r
1668                                 setsockopt(ContSock, SOL_SOCKET, SO_SNDBUF, (char*)&BufferSize, sizeof(int));\r
1669                                 setsockopt(ContSock, SOL_SOCKET, SO_RCVBUF, (char*)&BufferSize, sizeof(int));\r
1670 #endif\r
1671                                 // FTPIS対応\r
1672 //                              while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM)\r
1673 //                                      ;\r
1674                                 if(CryptMode == CRYPT_FTPIS)\r
1675                                 {\r
1676                                         if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork, HostData->NoWeakEncryption, Host))\r
1677                                         {\r
1678                                                 while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
1679                                                         ;\r
1680                                         }\r
1681                                         else\r
1682                                                 Sts = FTP_ERROR;\r
1683                                 }\r
1684                                 else\r
1685                                 {\r
1686                                         while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
1687                                                 ;\r
1688                                 }\r
1689 \r
1690                                 if(Sts == FTP_COMPLETE)\r
1691                                 {\r
1692                                         Flg = 1;\r
1693                                         if(setsockopt(ContSock, SOL_SOCKET, SO_OOBINLINE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1694                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1695                                         // データ転送用ソケットのTCP遅延転送が無効されているので念のため\r
1696                                         if(setsockopt(ContSock, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1697                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1698 //#pragma aaa\r
1699                                         Flg = 1;\r
1700                                         if(setsockopt(ContSock, SOL_SOCKET, SO_KEEPALIVE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1701                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1702                                         // 切断対策\r
1703                                         if(TimeOut > 0)\r
1704                                         {\r
1705                                                 KeepAlive.onoff = 1;\r
1706                                                 KeepAlive.keepalivetime = TimeOut * 1000;\r
1707                                                 KeepAlive.keepaliveinterval = 1000;\r
1708                                                 if(WSAIoctl(ContSock, SIO_KEEPALIVE_VALS, &KeepAlive, sizeof(struct tcp_keepalive), NULL, 0, &dwTmp, NULL, NULL) == SOCKET_ERROR)\r
1709                                                         ReportWSError("WSAIoctl", WSAGetLastError());\r
1710                                         }\r
1711                                         LingerOpt.l_onoff = 1;\r
1712                                         LingerOpt.l_linger = 90;\r
1713                                         if(setsockopt(ContSock, SOL_SOCKET, SO_LINGER, (LPSTR)&LingerOpt, sizeof(LingerOpt)) == SOCKET_ERROR)\r
1714                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1715 ///////\r
1716 \r
1717 \r
1718                                         /*===== 認証を行なう =====*/\r
1719 \r
1720                                         Sts = FTP_COMPLETE;\r
1721                                         if((Fwall == FWALL_FU_FP_SITE) ||\r
1722                                            (Fwall == FWALL_FU_FP_USER) ||\r
1723                                            (Fwall == FWALL_FU_FP))\r
1724                                         {\r
1725                                                 // 同時接続対応\r
1726 //                                              if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
1727                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
1728                                                 {\r
1729                                                         CheckOneTimePassword(FwallPass, Reply, FwallSecurity);\r
1730                                                         // 同時接続対応\r
1731 //                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1732                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1733                                                 }\r
1734                                         }\r
1735                                         else if(Fwall == FWALL_SIDEWINDER)\r
1736                                         {\r
1737                                                 // 同時接続対応\r
1738 //                                              Sts = command(ContSock, Reply, &CancelFlg, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
1739                                                 Sts = command(ContSock, Reply, CancelCheckWork, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
1740                                         }\r
1741                                         if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
1742                                         {\r
1743                                                 SetTaskMsg(MSGJPN006);\r
1744                                                 DoClose(ContSock);\r
1745                                                 ContSock = INVALID_SOCKET;\r
1746                                         }\r
1747                                         else\r
1748                                         {\r
1749                                                 if((Fwall == FWALL_FU_FP_SITE) || (Fwall == FWALL_OPEN))\r
1750                                                 {\r
1751                                                         Flg = 0;\r
1752                                                         if(Fwall == FWALL_OPEN)\r
1753                                                                 Flg = 2;\r
1754                                                         if(FwallLower == YES)\r
1755                                                                 Flg++;\r
1756 \r
1757                                                         if(HostPort == PORT_NOR)\r
1758                                                                 // 同時接続対応\r
1759 //                                                              Sts = command(ContSock, NULL, &CancelFlg, "%s %s", SiteTbl[Flg], Host) / 100;\r
1760                                                                 Sts = command(ContSock, NULL, CancelCheckWork, "%s %s", SiteTbl[Flg], Host) / 100;\r
1761                                                         else\r
1762                                                                 // 同時接続対応\r
1763 //                                                              Sts = command(ContSock, NULL, &CancelFlg, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
1764                                                                 Sts = command(ContSock, NULL, CancelCheckWork, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
1765                                                 }\r
1766 \r
1767                                                 if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
1768                                                 {\r
1769                                                         SetTaskMsg(MSGJPN007, Host);\r
1770                                                         DoClose(ContSock);\r
1771                                                         ContSock = INVALID_SOCKET;\r
1772                                                 }\r
1773                                                 else\r
1774                                                 {\r
1775                                                         Anony = NO;\r
1776                                                         // 同時接続対応\r
1777 //                                                      if((strlen(User) != 0) || \r
1778 //                                                         (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1779                                                         if((strlen(User) != 0) || \r
1780                                                            ((HostData->NoDisplayUI == NO) && (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1781                                                         {\r
1782                                                                 if(Anony == YES)\r
1783                                                                 {\r
1784                                                                         strcpy(User, "anonymous");\r
1785                                                                         strcpy(Pass, UserMailAdrs);\r
1786                                                                 }\r
1787 \r
1788                                                                 if((Fwall == FWALL_FU_FP_USER) || (Fwall == FWALL_USER))\r
1789                                                                 {\r
1790                                                                         if(HostPort == PORT_NOR)\r
1791                                                                                 sprintf(Buf, "%s%c%s", User, FwallDelimiter, Host);\r
1792                                                                         else\r
1793                                                                                 sprintf(Buf, "%s%c%s %d", User, FwallDelimiter, Host, HostPort);\r
1794                                                                 }\r
1795                                                                 else\r
1796                                                                         strcpy(Buf, User);\r
1797 \r
1798                                                                 // FTPES対応\r
1799                                                                 if(CryptMode == CRYPT_FTPES)\r
1800                                                                 {\r
1801                                                                         if(IsOpenSSLLoaded() && ((Sts = command(ContSock, Reply, CancelCheckWork, "AUTH TLS")) == 234 || (Sts = command(ContSock, Reply, CancelCheckWork, "AUTH SSL")) == 234))\r
1802                                                                         {\r
1803                                                                                 if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork, HostData->NoWeakEncryption, Host))\r
1804                                                                                 {\r
1805                                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1806                                                                                         {\r
1807                                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1808                                                                                                 {\r
1809                                                                                                 }\r
1810                                                                                                 else\r
1811                                                                                                         Sts = FTP_ERROR;\r
1812                                                                                         }\r
1813                                                                                         else\r
1814                                                                                                 Sts = FTP_ERROR;\r
1815                                                                                 }\r
1816                                                                                 else\r
1817                                                                                         Sts = FTP_ERROR;\r
1818                                                                         }\r
1819                                                                         else\r
1820                                                                                 Sts = FTP_ERROR;\r
1821                                                                 }\r
1822 \r
1823                                                                 // FTPIS対応\r
1824                                                                 // "PBSZ 0"と"PROT P"は黙示的に設定されているはずだが念のため\r
1825                                                                 if(CryptMode == CRYPT_FTPIS)\r
1826                                                                 {\r
1827                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1828                                                                         {\r
1829                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1830                                                                                 {\r
1831                                                                                 }\r
1832                                                                         }\r
1833                                                                 }\r
1834 \r
1835                                                                 ReInPass = NO;\r
1836                                                                 do\r
1837                                                                 {\r
1838                                                                         // FTPES対応\r
1839                                                                         if(Sts == FTP_ERROR)\r
1840                                                                                 break;\r
1841                                                                         Continue = NO;\r
1842                                                                         // 同時接続対応\r
1843 //                                                                      if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1844                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1845                                                                         {\r
1846                                                                                 // 同時接続対応\r
1847 //                                                                              if((strlen(Pass) != 0) || \r
1848 //                                                                                 (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1849                                                                                 if((strlen(Pass) != 0) || \r
1850                                                                                    ((HostData->NoDisplayUI == NO) && (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1851                                                                                 {\r
1852                                                                                         CheckOneTimePassword(Pass, Reply, Security);\r
1853 \r
1854                                                                                         /* パスワードがスペース1個の時はパスワードの実体なしとする */\r
1855                                                                                         if(strcmp(Reply, " ") == 0)\r
1856                                                                                                 strcpy(Reply, "");\r
1857 \r
1858                                                                                         // 同時接続対応\r
1859 //                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1860                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1861                                                                                         if(Sts == FTP_ERROR)\r
1862                                                                                         {\r
1863                                                                                                 strcpy(Pass, "");\r
1864                                                                                                 // 同時接続対応\r
1865 //                                                                                              if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1866                                                                                                 if(HostData->NoDisplayUI == NO && InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1867                                                                                                         Continue = YES;\r
1868                                                                                                 else\r
1869                                                                                                         DoPrintf("No password specified.");\r
1870                                                                                                 ReInPass = YES;\r
1871                                                                                         }\r
1872                                                                                         else if(Sts == FTP_CONTINUE)\r
1873                                                                                         {\r
1874                                                                                                 // 同時接続対応\r
1875 //                                                                                              if((strlen(Acct) != 0) || \r
1876 //                                                                                                 (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1877                                                                                                 if((strlen(Acct) != 0) || \r
1878                                                                                                    ((HostData->NoDisplayUI == NO) && (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1879                                                                                                 {\r
1880                                                                                                         // 同時接続対応\r
1881 //                                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100;\r
1882                                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "ACCT %s", Acct) / 100;\r
1883                                                                                                 }\r
1884                                                                                                 else\r
1885                                                                                                         DoPrintf("No account specified");\r
1886                                                                                         }\r
1887                                                                                 }\r
1888                                                                                 else\r
1889                                                                                 {\r
1890                                                                                         Sts = FTP_ERROR;\r
1891                                                                                         DoPrintf("No password specified.");\r
1892                                                                                 }\r
1893                                                                         }\r
1894                                                                         // FTPES対応\r
1895                                                                         if(Continue == YES)\r
1896                                                                                 Sts = FTP_COMPLETE;\r
1897                                                                 }\r
1898                                                                 while(Continue == YES);\r
1899                                                         }\r
1900                                                         else\r
1901                                                         {\r
1902                                                                 Sts = FTP_ERROR;\r
1903                                                                 DoPrintf("No user name specified");\r
1904                                                         }\r
1905 \r
1906                                                         if(Sts != FTP_COMPLETE)\r
1907                                                         {\r
1908                                                                 SetTaskMsg(MSGJPN008, Host);\r
1909                                                                 DoClose(ContSock);\r
1910                                                                 ContSock = INVALID_SOCKET;\r
1911                                                         }\r
1912                                                         else if((SavePass == YES) && (ReInPass == YES))\r
1913                                                         {\r
1914                                                                 // 同時接続対応\r
1915 //                                                              if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1916                                                                 if(HostData->NoDisplayUI == NO && DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1917                                                                         SetHostPassword(AskCurrentHost(), Pass);\r
1918                                                         }\r
1919                                                 }\r
1920                                         }\r
1921                                 }\r
1922                                 else\r
1923                                 {\r
1924 //#pragma aaa\r
1925                                         SetTaskMsg(MSGJPN009/*"接続できません(1) %x", ContSock*/);\r
1926                                         DoClose(ContSock);\r
1927                                         ContSock = INVALID_SOCKET;\r
1928                                 }\r
1929                         }\r
1930                 }\r
1931                 else\r
1932                 {\r
1933 \r
1934                         if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1935                            (Fwall == FWALL_FU_FP))\r
1936                                 SetTaskMsg(MSGJPN010);\r
1937                         else\r
1938                                 SetTaskMsg(MSGJPN011);\r
1939                 }\r
1940 \r
1941 #if 0\r
1942 //              WSAUnhookBlockingHook();\r
1943 #endif\r
1944                 TryConnect = NO;\r
1945 \r
1946                 // FEAT対応\r
1947                 // ホストの機能を確認\r
1948                 if(ContSock != INVALID_SOCKET)\r
1949                 {\r
1950                         if((Sts = command(ContSock, Reply, CancelCheckWork, "FEAT")) == 211)\r
1951                         {\r
1952                                 // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用\r
1953                                 // UTF-8対応\r
1954                                 if(strstr(Reply, " UTF8 "))\r
1955                                         HostData->Feature |= FEATURE_UTF8;\r
1956                                 // MLST対応\r
1957                                 if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD "))\r
1958                                         HostData->Feature |= FEATURE_MLSD;\r
1959                                 // IPv6対応\r
1960                                 if(strstr(Reply, " EPRT ") || strstr(Reply, " EPSV "))\r
1961                                         HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV;\r
1962                                 // ホスト側の日時取得\r
1963                                 if(strstr(Reply, " MDTM "))\r
1964                                         HostData->Feature |= FEATURE_MDTM;\r
1965                                 // ホスト側の日時設定\r
1966                                 if(strstr(Reply, " MFMT "))\r
1967                                         HostData->Feature |= FEATURE_MFMT;\r
1968                         }\r
1969                         // UTF-8対応\r
1970                         if(HostData->CurNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
1971                         {\r
1972                                 // UTF-8を指定した場合も自動判別を行う\r
1973 //                              if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200)\r
1974 //                                      HostData->CurNameKanjiCode = KANJI_UTF8N;\r
1975                                 command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON");\r
1976                         }\r
1977                 }\r
1978         }\r
1979 \r
1980         return(ContSock);\r
1981 }\r
1982 \r
1983 // 同時接続対応\r
1984 //static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security)\r
1985 static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
1986 {\r
1987         SOCKET ContSock;\r
1988         ContSock = INVALID_SOCKET;\r
1989         *CancelCheckWork = NO;\r
1990         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
1991         {\r
1992                 SetTaskMsg(MSGJPN316);\r
1993                 if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1994                         HostData->CryptMode = CRYPT_FTPIS;\r
1995         }\r
1996         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES)\r
1997         {\r
1998                 SetTaskMsg(MSGJPN315);\r
1999                 if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
2000                         HostData->CryptMode = CRYPT_FTPES;\r
2001         }\r
2002         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES)\r
2003         {\r
2004                 SetTaskMsg(MSGJPN314);\r
2005                 if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
2006                         HostData->CryptMode = CRYPT_NONE;\r
2007         }\r
2008         return ContSock;\r
2009 }\r
2010 \r
2011 \r
2012 /*----- ワンタイムパスワードのチェック ----------------------------------------\r
2013 *\r
2014 *       Parameter\r
2015 *               chat *Pass : パスワード/パスフレーズ\r
2016 *               char *Reply : USERコマンドを送ったあとのリプライ文字列\r
2017 *                                               /PASSコマンドで送るパスワードを返すバッファ\r
2018 *               int Type : タイプ (SECURITY_xxx, MDx)\r
2019 *\r
2020 *       Return Value\r
2021 *               int ステータス\r
2022 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
2023 *\r
2024 *       Note\r
2025 *               ワンタイムパスワードでない時はPassをそのままReplyにコピー\r
2026 *----------------------------------------------------------------------------*/\r
2027 \r
2028 static int CheckOneTimePassword(char *Pass, char *Reply, int Type)\r
2029 {\r
2030         int Sts;\r
2031         char *Pos;\r
2032         int Seq;\r
2033         char Seed[MAX_SEED_LEN+1];\r
2034         int i;\r
2035 \r
2036         Sts = FFFTP_SUCCESS;\r
2037         Pos = NULL;\r
2038 \r
2039         if(Type == SECURITY_AUTO)\r
2040         {\r
2041                 if((Pos = stristr(Reply, "otp-md5")) != NULL)\r
2042                 {\r
2043                         Type = MD5;\r
2044                         SetTaskMsg(MSGJPN012);\r
2045                 }\r
2046                 else if((Pos = stristr(Reply, "otp-sha1")) != NULL)\r
2047                 {\r
2048                         Type = SHA1;\r
2049                         SetTaskMsg(MSGJPN013);\r
2050                 }\r
2051                 else if(((Pos = stristr(Reply, "otp-md4")) != NULL) || ((Pos = stristr(Reply, "s/key")) != NULL))\r
2052                 {\r
2053                         Type = MD4;\r
2054                         SetTaskMsg(MSGJPN014);\r
2055                 }\r
2056         }\r
2057         else\r
2058                 Pos = GetNextField(Reply);\r
2059 \r
2060         if((Type == MD4) || (Type == MD5) || (Type == SHA1))\r
2061         {\r
2062                 /* シーケンス番号を見つけるループ */\r
2063                 DoPrintf("Analyze OTP");\r
2064                 DoPrintf("%s", Pos);\r
2065                 Sts = FFFTP_FAIL;\r
2066                 while((Pos = GetNextField(Pos)) != NULL)\r
2067                 {\r
2068                         if(IsDigit(*Pos))\r
2069                         {\r
2070                                 Seq = atoi(Pos);\r
2071                                 DoPrintf("Sequence=%d", Seq);\r
2072 \r
2073                                 /* Seed */\r
2074                                 if((Pos = GetNextField(Pos)) != NULL)\r
2075                                 {\r
2076                                         if(GetOneField(Pos, Seed, MAX_SEED_LEN) == FFFTP_SUCCESS)\r
2077                                         {\r
2078                                                 /* Seedは英数字のみ有効とする */\r
2079                                                 for(i = strlen(Seed)-1; i >= 0; i--)\r
2080                                                 {\r
2081                                                         if((IsAlpha(Seed[i]) == 0) && (IsDigit(Seed[i]) == 0))\r
2082                                                                 Seed[i] = NUL;\r
2083                                                 }\r
2084                                                 if(strlen(Seed) > 0)\r
2085                                                 {\r
2086                                                         DoPrintf("Seed=%s", Seed);\r
2087                                                         Make6WordPass(Seq, Seed, Pass, Type, Reply);\r
2088                                                         DoPrintf("Response=%s", Reply);\r
2089 \r
2090                                                         /* シーケンス番号のチェックと警告 */\r
2091                                                         if(Seq <= 10)\r
2092                                                                 DialogBox(GetFtpInst(), MAKEINTRESOURCE(otp_notify_dlg), GetMainHwnd(), ExeEscDialogProc);\r
2093 \r
2094                                                         Sts = FFFTP_SUCCESS;\r
2095                                                 }\r
2096                                         }\r
2097                                 }\r
2098                                 break;\r
2099                         }\r
2100                 }\r
2101 \r
2102                 if(Sts == FFFTP_FAIL)\r
2103                         SetTaskMsg(MSGJPN015);\r
2104         }\r
2105         else\r
2106         {\r
2107                 strcpy(Reply, Pass);\r
2108                 DoPrintf("No OTP used.");\r
2109         }\r
2110         return(Sts);\r
2111 }\r
2112 \r
2113 \r
2114 \r
2115 \r
2116 \r
2117 \r
2118 \r
2119 \r
2120 \r
2121 \r
2122 \r
2123 \r
2124 \r
2125 \r
2126 /*----- ソケットを接続する ----------------------------------------------------\r
2127 *\r
2128 *       Parameter\r
2129 *               char *host : ホスト名\r
2130 *               int port : ポート番号\r
2131 *               char *PreMsg : メッセージの前半部分\r
2132 *\r
2133 *       Return Value\r
2134 *               SOCKET ソケット\r
2135 *----------------------------------------------------------------------------*/\r
2136 \r
2137 // IPv6対応\r
2138 typedef SOCKET (__cdecl* LPCONNECTSOCK)(char*, int, char*, int*);\r
2139 \r
2140 typedef struct\r
2141 {\r
2142         HANDLE h;\r
2143         DWORD ExitCode;\r
2144         char *host;\r
2145         int port;\r
2146         char *PreMsg;\r
2147         int CancelCheckWork;\r
2148         LPCONNECTSOCK f;\r
2149         SOCKET s;\r
2150 } CONNECTSOCKDATA;\r
2151 \r
2152 DWORD WINAPI connectsockThreadProc(LPVOID lpParameter)\r
2153 {\r
2154         CONNECTSOCKDATA* pData;\r
2155         pData = (CONNECTSOCKDATA*)lpParameter;\r
2156         pData->s = pData->f(pData->host, pData->port, pData->PreMsg, &pData->CancelCheckWork);\r
2157         return 0;\r
2158 }\r
2159 \r
2160 // IPv6対応\r
2161 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2162 {\r
2163         SOCKET Result;\r
2164         CONNECTSOCKDATA DataIPv4;\r
2165         CONNECTSOCKDATA DataIPv6;\r
2166         Result = INVALID_SOCKET;\r
2167         switch(CurHost.CurNetType)\r
2168         {\r
2169         case NTYPE_AUTO:\r
2170 //              if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
2171 //                      CurHost.CurNetType = NTYPE_IPV4;\r
2172 //              else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
2173 //                      CurHost.CurNetType = NTYPE_IPV6;\r
2174                 DataIPv4.host = host;\r
2175                 DataIPv4.port = port;\r
2176                 DataIPv4.PreMsg = PreMsg;\r
2177                 DataIPv4.CancelCheckWork = *CancelCheckWork;\r
2178                 DataIPv4.f = connectsockIPv4;\r
2179                 DataIPv4.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv4, 0, NULL);\r
2180                 DataIPv6.host = host;\r
2181                 DataIPv6.port = port;\r
2182                 DataIPv6.PreMsg = PreMsg;\r
2183                 DataIPv6.CancelCheckWork = *CancelCheckWork;\r
2184                 DataIPv6.f = connectsockIPv6;\r
2185                 DataIPv6.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv6, 0, NULL);\r
2186                 while(1)\r
2187                 {\r
2188                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode))\r
2189                         {\r
2190                                 if(DataIPv4.ExitCode != STILL_ACTIVE)\r
2191                                 {\r
2192                                         if(DataIPv4.s != INVALID_SOCKET)\r
2193                                         {\r
2194                                                 Result = DataIPv4.s;\r
2195                                                 CurHost.CurNetType = NTYPE_IPV4;\r
2196                                                 break;\r
2197                                         }\r
2198                                 }\r
2199                         }\r
2200                         if(GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2201                         {\r
2202                                 if(DataIPv6.ExitCode != STILL_ACTIVE)\r
2203                                 {\r
2204                                         if(DataIPv6.s != INVALID_SOCKET)\r
2205                                         {\r
2206                                                 Result = DataIPv6.s;\r
2207                                                 CurHost.CurNetType = NTYPE_IPV6;\r
2208                                                 break;\r
2209                                         }\r
2210                                 }\r
2211                         }\r
2212                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2213                         {\r
2214                                 if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
2215                                 {\r
2216                                         if(DataIPv4.s == INVALID_SOCKET && DataIPv6.s == INVALID_SOCKET)\r
2217                                                 break;\r
2218                                 }\r
2219                         }\r
2220                         DataIPv4.CancelCheckWork = *CancelCheckWork;\r
2221                         DataIPv6.CancelCheckWork = *CancelCheckWork;\r
2222                         BackgrndMessageProc();\r
2223                         Sleep(1);\r
2224                 }\r
2225                 while(1)\r
2226                 {\r
2227                         if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
2228                         {\r
2229                                 if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
2230                                 {\r
2231                                         CloseHandle(DataIPv4.h);\r
2232                                         CloseHandle(DataIPv6.h);\r
2233                                         break;\r
2234                                 }\r
2235                         }\r
2236                         DataIPv4.CancelCheckWork = YES;\r
2237                         DataIPv6.CancelCheckWork = YES;\r
2238                         BackgrndMessageProc();\r
2239                         Sleep(1);\r
2240                 }\r
2241                 break;\r
2242         case NTYPE_IPV4:\r
2243                 Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
2244                 CurHost.CurNetType = NTYPE_IPV4;\r
2245                 break;\r
2246         case NTYPE_IPV6:\r
2247                 Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
2248                 CurHost.CurNetType = NTYPE_IPV6;\r
2249                 break;\r
2250         }\r
2251         return Result;\r
2252 }\r
2253 \r
2254 \r
2255 // IPv6対応\r
2256 //SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2257 SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2258 {\r
2259         // IPv6対応\r
2260         struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
2261         struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
2262         struct sockaddr_in saSockAddr;\r
2263         char HostEntry[MAXGETHOSTSTRUCT];\r
2264         struct hostent *pHostEntry;\r
2265         SOCKET sSocket;\r
2266         int Len;\r
2267         int Fwall;\r
2268         SOCKS4CMD Socks4Cmd;\r
2269         SOCKS4REPLY Socks4Reply;\r
2270         SOCKS5REQUEST Socks5Cmd;\r
2271         SOCKS5REPLY Socks5Reply;\r
2272 \r
2273         //////////////////////////////\r
2274         // ホスト名解決と接続の準備\r
2275         //////////////////////////////\r
2276 \r
2277         Fwall = FWALL_NONE;\r
2278         if(AskHostFireWall() == YES)\r
2279                 Fwall = FwallType;\r
2280 \r
2281         sSocket = INVALID_SOCKET;\r
2282 \r
2283         UseIPadrs = YES;\r
2284         strcpy(DomainName, host);\r
2285         memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2286         CurSockAddr.sin_port = htons((u_short)port);\r
2287         CurSockAddr.sin_family = AF_INET;\r
2288         if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
2289         {\r
2290                 // ホスト名が指定された\r
2291                 // ホスト名からアドレスを求める\r
2292                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2293                    (FwallResolve == YES))\r
2294                 {\r
2295                         // ホスト名解決はSOCKSサーバに任せる\r
2296                         pHostEntry = NULL;\r
2297                 }\r
2298                 else\r
2299                 {\r
2300                         // アドレスを取得\r
2301                         // IPv6対応\r
2302 //                      SetTaskMsg(MSGJPN016, DomainName);\r
2303                         SetTaskMsg(MSGJPN016, DomainName, MSGJPN333);\r
2304                         // IPv6対応\r
2305 //                      pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2306                         pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2307                 }\r
2308 \r
2309                 if(pHostEntry != NULL)\r
2310                 {\r
2311                         memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2312                         // IPv6対応\r
2313 //                      SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2314                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2315                 }\r
2316                 else\r
2317                 {\r
2318                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2319                         {\r
2320                                 UseIPadrs = NO;\r
2321                                 // IPv6対応\r
2322 //                              SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
2323                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2324                         }\r
2325                         else\r
2326                         {\r
2327                                 // IPv6対応\r
2328 //                              SetTaskMsg(MSGJPN019, host);\r
2329                                 SetTaskMsg(MSGJPN019, host, MSGJPN333);\r
2330                                 return(INVALID_SOCKET);\r
2331                         }\r
2332                 }\r
2333         }\r
2334         else\r
2335                 // IPv6対応\r
2336 //              SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2337                 SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
2338 \r
2339         if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2340         {\r
2341                 // SOCKSを使う\r
2342                 // SOCKSに接続する準備\r
2343                 if(Fwall == FWALL_SOCKS4)\r
2344                 {\r
2345                         Socks4Cmd.Ver = SOCKS4_VER;\r
2346                         Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
2347                         Socks4Cmd.Port = CurSockAddr.sin_port;\r
2348                         Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2349                         strcpy(Socks4Cmd.UserID, FwallUser);\r
2350                         Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2351                 }\r
2352                 else\r
2353                 {\r
2354                         Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2355                 }\r
2356 \r
2357                 memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2358                 if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
2359                 {\r
2360                         // IPv6対応\r
2361 //                      if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2362                         if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2363                                 memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2364                         else\r
2365                         {\r
2366                                 // IPv6対応\r
2367 //                              SetTaskMsg(MSGJPN021, FwallHost);\r
2368                                 SetTaskMsg(MSGJPN021, FwallHost, MSGJPN333);\r
2369                                 return INVALID_SOCKET;\r
2370                         }\r
2371                 }\r
2372                 SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
2373                 SocksSockAddr.sin_family = AF_INET;\r
2374                 // IPv6対応\r
2375 //              SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
2376                 SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port), MSGJPN333);\r
2377                 // connectで接続する先はSOCKSサーバ\r
2378                 memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2379         }\r
2380         else\r
2381         {\r
2382                 // connectで接続するのは接続先のホスト\r
2383                 memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2384         }\r
2385 \r
2386         /////////////\r
2387         // 接続実行\r
2388         /////////////\r
2389 \r
2390         if((sSocket = do_socket(AF_INET, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2391         {\r
2392                 // ソケットにデータを付与\r
2393                 SetAsyncTableDataIPv4(sSocket, &CurSockAddr, &SocksSockAddr);\r
2394                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2395                 {\r
2396                         if(Fwall == FWALL_SOCKS4)\r
2397                         {\r
2398                                 Socks4Reply.Result = -1;\r
2399                                 // 同時接続対応\r
2400 //                              if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2401 //                                 (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || \r
2402 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2403                                 if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2404                                    (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2405                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2406                                 {\r
2407                                         // IPv6対応\r
2408 //                                      SetTaskMsg(MSGJPN023, Socks4Reply.Result);\r
2409                                         SetTaskMsg(MSGJPN023, Socks4Reply.Result, MSGJPN333);\r
2410                                         DoClose(sSocket);\r
2411                                         sSocket = INVALID_SOCKET;\r
2412                                 }\r
2413                         }\r
2414                         else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2415                         {\r
2416                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2417                                 {\r
2418                                         DoClose(sSocket);\r
2419                                         sSocket = INVALID_SOCKET;\r
2420                                 }\r
2421 \r
2422                                 Socks5Reply.Result = -1;\r
2423                                 // 同時接続対応\r
2424 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2425 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2426 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2427                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2428                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2429                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2430                                 {\r
2431                                         // IPv6対応\r
2432 //                                      SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2433                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN333);\r
2434                                         DoClose(sSocket);\r
2435                                         sSocket = INVALID_SOCKET;\r
2436                                 }\r
2437 \r
2438                         }\r
2439 \r
2440                         if(sSocket != INVALID_SOCKET)\r
2441                                 // IPv6対応\r
2442 //                              SetTaskMsg(MSGJPN025);\r
2443                                 SetTaskMsg(MSGJPN025, MSGJPN333);\r
2444                 }\r
2445                 else\r
2446                 {\r
2447 //#pragma aaa\r
2448                         // IPv6対応\r
2449 //                      SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2450                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN333);\r
2451                         DoClose(sSocket);\r
2452                         sSocket = INVALID_SOCKET;\r
2453                 }\r
2454         }\r
2455         else\r
2456                 // IPv6対応\r
2457 //              SetTaskMsg(MSGJPN027);\r
2458                 SetTaskMsg(MSGJPN027, MSGJPN333);\r
2459 \r
2460         return(sSocket);\r
2461 }\r
2462 \r
2463 \r
2464 SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2465 {\r
2466         struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
2467         struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
2468         struct sockaddr_in6 saSockAddr;\r
2469         char HostEntry[MAXGETHOSTSTRUCT];\r
2470         struct hostent *pHostEntry;\r
2471         SOCKET sSocket;\r
2472         int Len;\r
2473         int Fwall;\r
2474         SOCKS5REQUEST Socks5Cmd;\r
2475         SOCKS5REPLY Socks5Reply;\r
2476 \r
2477         //////////////////////////////\r
2478         // ホスト名解決と接続の準備\r
2479         //////////////////////////////\r
2480 \r
2481         Fwall = FWALL_NONE;\r
2482         if(AskHostFireWall() == YES)\r
2483                 Fwall = FwallType;\r
2484 \r
2485         sSocket = INVALID_SOCKET;\r
2486 \r
2487         UseIPadrs = YES;\r
2488         strcpy(DomainName, host);\r
2489         memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2490         CurSockAddr.sin6_port = htons((u_short)port);\r
2491         CurSockAddr.sin6_family = AF_INET6;\r
2492         CurSockAddr.sin6_addr = inet6_addr(host);\r
2493         if(memcmp(&CurSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2494         {\r
2495                 // ホスト名が指定された\r
2496                 // ホスト名からアドレスを求める\r
2497                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2498                    (FwallResolve == YES))\r
2499                 {\r
2500                         // ホスト名解決はSOCKSサーバに任せる\r
2501                         pHostEntry = NULL;\r
2502                 }\r
2503                 else\r
2504                 {\r
2505                         // アドレスを取得\r
2506                         SetTaskMsg(MSGJPN016, DomainName, MSGJPN334);\r
2507                         pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2508                 }\r
2509 \r
2510                 if(pHostEntry != NULL)\r
2511                 {\r
2512                         memcpy((char *)&CurSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2513                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2514                 }\r
2515                 else\r
2516                 {\r
2517                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2518                         {\r
2519                                 UseIPadrs = NO;\r
2520                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2521                         }\r
2522                         else\r
2523                         {\r
2524                                 SetTaskMsg(MSGJPN019, host, MSGJPN334);\r
2525                                 return(INVALID_SOCKET);\r
2526                         }\r
2527                 }\r
2528         }\r
2529         else\r
2530                 SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
2531 \r
2532         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2533         {\r
2534                 // SOCKSを使う\r
2535                 // SOCKSに接続する準備\r
2536                 {\r
2537                         Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
2538                 }\r
2539 \r
2540                 memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2541                 SocksSockAddr.sin6_addr = inet6_addr(FwallHost);\r
2542                 if(memcmp(&SocksSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2543                 {\r
2544                         if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2545                                 memcpy((char *)&SocksSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2546                         else\r
2547                         {\r
2548                                 SetTaskMsg(MSGJPN021, FwallHost, MSGJPN334);\r
2549                                 return INVALID_SOCKET;\r
2550                         }\r
2551                 }\r
2552                 SocksSockAddr.sin6_port = htons((u_short)FwallPort);\r
2553                 SocksSockAddr.sin6_family = AF_INET6;\r
2554                 SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddr.sin6_addr), ntohs(SocksSockAddr.sin6_port), MSGJPN334);\r
2555                 // connectで接続する先はSOCKSサーバ\r
2556                 memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2557         }\r
2558         else\r
2559         {\r
2560                 // connectで接続するのは接続先のホスト\r
2561                 memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2562         }\r
2563 \r
2564         /////////////\r
2565         // 接続実行\r
2566         /////////////\r
2567 \r
2568         if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2569         {\r
2570                 // ソケットにデータを付与\r
2571                 SetAsyncTableDataIPv6(sSocket, &CurSockAddr, &SocksSockAddr);\r
2572                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2573                 {\r
2574                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2575                         {\r
2576                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2577                                 {\r
2578                                         DoClose(sSocket);\r
2579                                         sSocket = INVALID_SOCKET;\r
2580                                 }\r
2581 \r
2582                                 Socks5Reply.Result = -1;\r
2583                                 // 同時接続対応\r
2584 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2585 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2586 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2587                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2588                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2589                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2590                                 {\r
2591                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN334);\r
2592                                         DoClose(sSocket);\r
2593                                         sSocket = INVALID_SOCKET;\r
2594                                 }\r
2595 \r
2596                         }\r
2597 \r
2598                         if(sSocket != INVALID_SOCKET)\r
2599                                 SetTaskMsg(MSGJPN025, MSGJPN334);\r
2600                 }\r
2601                 else\r
2602                 {\r
2603 //#pragma aaa\r
2604                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN334);\r
2605                         DoClose(sSocket);\r
2606                         sSocket = INVALID_SOCKET;\r
2607                 }\r
2608         }\r
2609         else\r
2610                 SetTaskMsg(MSGJPN027, MSGJPN334);\r
2611 \r
2612         return(sSocket);\r
2613 }\r
2614 \r
2615 \r
2616 /*----- リッスンソケットを取得 ------------------------------------------------\r
2617 *\r
2618 *       Parameter\r
2619 *               SOCKET ctrl_skt : コントロールソケット\r
2620 *\r
2621 *       Return Value\r
2622 *               SOCKET リッスンソケット\r
2623 *----------------------------------------------------------------------------*/\r
2624 \r
2625 // IPv6対応\r
2626 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2627 {\r
2628         SOCKET Result;\r
2629         Result = INVALID_SOCKET;\r
2630         switch(CurHost.CurNetType)\r
2631         {\r
2632         case NTYPE_IPV4:\r
2633                 Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
2634                 break;\r
2635         case NTYPE_IPV6:\r
2636                 Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
2637                 break;\r
2638         }\r
2639         return Result;\r
2640 }\r
2641 \r
2642 \r
2643 // IPv6対応\r
2644 //SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2645 SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
2646 {\r
2647         // IPv6対応\r
2648         struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
2649         struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
2650         SOCKET listen_skt;\r
2651         int iLength;\r
2652         char *a,*p;\r
2653         struct sockaddr_in saCtrlAddr;\r
2654         struct sockaddr_in saTmpAddr;\r
2655         SOCKS4CMD Socks4Cmd;\r
2656         SOCKS4REPLY Socks4Reply;\r
2657         SOCKS5REQUEST Socks5Cmd;\r
2658         SOCKS5REPLY Socks5Reply;\r
2659 \r
2660         int Len;\r
2661         int Fwall;\r
2662 \r
2663         // UPnP対応\r
2664         char Adrs[16];\r
2665         int Port;\r
2666         char ExtAdrs[40];\r
2667 \r
2668         // ソケットにデータを付与\r
2669         GetAsyncTableDataIPv4(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
2670 \r
2671         Fwall = FWALL_NONE;\r
2672         if(AskHostFireWall() == YES)\r
2673                 Fwall = FwallType;\r
2674 \r
2675         if((listen_skt = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2676         {\r
2677                 if(Fwall == FWALL_SOCKS4)\r
2678                 {\r
2679                         /*===== SOCKS4を使う =====*/\r
2680                         DoPrintf("Use SOCKS4 BIND");\r
2681                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2682                         {\r
2683                                 Socks4Cmd.Ver = SOCKS4_VER;\r
2684                                 Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
2685                                 Socks4Cmd.Port = CurSockAddr.sin_port;\r
2686                                 Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2687                                 strcpy(Socks4Cmd.UserID, FwallUser);\r
2688                                 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2689 \r
2690                                 Socks4Reply.Result = -1;\r
2691                                 // 同時接続対応\r
2692 //                              if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2693 //                                 (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || \r
2694 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2695                                 if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2696                                    (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2697                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2698                                 {\r
2699                                         // IPv6対応\r
2700 //                                      SetTaskMsg(MSGJPN028, Socks4Reply.Result);\r
2701                                         SetTaskMsg(MSGJPN028, Socks4Reply.Result, MSGJPN333);\r
2702                                         DoClose(listen_skt);\r
2703                                         listen_skt = INVALID_SOCKET;\r
2704                                 }\r
2705 \r
2706                                 if(Socks4Reply.AdrsInt == 0)\r
2707                                         Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2708 \r
2709                                 a = (char *)&Socks4Reply.AdrsInt;\r
2710                                 p = (char *)&Socks4Reply.Port;\r
2711                         }\r
2712                 }\r
2713                 else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2714                 {\r
2715                         /*===== SOCKS5を使う =====*/\r
2716                         DoPrintf("Use SOCKS5 BIND");\r
2717                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2718                         {\r
2719                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2720                                 {\r
2721                                         DoClose(listen_skt);\r
2722                                         listen_skt = INVALID_SOCKET;\r
2723                                         return(listen_skt);\r
2724                                 }\r
2725 \r
2726                                 Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2727 \r
2728                                 Socks5Reply.Result = -1;\r
2729                                 // 同時接続対応\r
2730 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2731 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2732 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2733                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2734                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2735                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2736                                 {\r
2737                                         // IPv6対応\r
2738 //                                      SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2739                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN333);\r
2740                                         DoClose(listen_skt);\r
2741                                         listen_skt = INVALID_SOCKET;\r
2742                                 }\r
2743 \r
2744                                 // IPv6対応\r
2745 //                              if(Socks5Reply.AdrsInt == 0)\r
2746 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2747 \r
2748                                 // IPv6対応\r
2749 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2750 //                              p = (char *)&Socks5Reply.Port;\r
2751                                 a = (char *)&Socks5Reply._dummy[0];\r
2752                                 p = (char *)&Socks5Reply._dummy[4];\r
2753                         }\r
2754                 }\r
2755                 else\r
2756                 {\r
2757                         /*===== SOCKSを使わない =====*/\r
2758                         DoPrintf("Use normal BIND");\r
2759                         saCtrlAddr.sin_port = htons(0);\r
2760                         saCtrlAddr.sin_family = AF_INET;\r
2761                         saCtrlAddr.sin_addr.s_addr = 0;\r
2762 \r
2763                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr)) != SOCKET_ERROR)\r
2764                         {\r
2765                                 iLength = sizeof(saCtrlAddr);\r
2766                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2767                                 {\r
2768                                         if(do_listen(listen_skt, 1) == 0)\r
2769                                         {\r
2770                                                 iLength = sizeof(saTmpAddr);\r
2771                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2772                                                         ReportWSError("getsockname", WSAGetLastError());\r
2773 \r
2774                                                 a = (char *)&saTmpAddr.sin_addr;\r
2775                                                 p = (char *)&saCtrlAddr.sin_port;\r
2776                                                 // UPnP対応\r
2777                                                 if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
2778                                                 {\r
2779                                                         if(AddPortMapping(AddressToStringIPv4(Adrs, &saTmpAddr.sin_addr), ntohs(saCtrlAddr.sin_port), ExtAdrs) == FFFTP_SUCCESS)\r
2780                                                         {\r
2781                                                                 saTmpAddr.sin_addr.s_addr = inet_addr(ExtAdrs);\r
2782                                                                 SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin_port));\r
2783                                                         }\r
2784                                                 }\r
2785                                         }\r
2786                                         else\r
2787                                         {\r
2788                                                 ReportWSError("listen", WSAGetLastError());\r
2789                                                 do_closesocket(listen_skt);\r
2790                                                 listen_skt = INVALID_SOCKET;\r
2791                                         }\r
2792                                 }\r
2793                                 else\r
2794                                 {\r
2795                                         ReportWSError("getsockname", WSAGetLastError());\r
2796                                         do_closesocket(listen_skt);\r
2797                                         listen_skt = INVALID_SOCKET;\r
2798                                 }\r
2799                         }\r
2800                         else\r
2801                         {\r
2802                                 ReportWSError("bind", WSAGetLastError());\r
2803                                 do_closesocket(listen_skt);\r
2804                                 listen_skt = INVALID_SOCKET;\r
2805                         }\r
2806 \r
2807                         if(listen_skt == INVALID_SOCKET)\r
2808                                 // IPv6対応\r
2809 //                              SetTaskMsg(MSGJPN030);\r
2810                                 SetTaskMsg(MSGJPN030, MSGJPN333);\r
2811                 }\r
2812         }\r
2813         else\r
2814                 ReportWSError("socket create", WSAGetLastError());\r
2815 \r
2816         if(listen_skt != INVALID_SOCKET)\r
2817         {\r
2818 #define  UC(b)  (((int)b)&0xff)\r
2819                 // 同時接続対応\r
2820 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2821 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2822 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2823                 if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d",\r
2824                                 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2825                                 UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2826                 {\r
2827                         // IPv6対応\r
2828 //                      SetTaskMsg(MSGJPN031);\r
2829                         SetTaskMsg(MSGJPN031, MSGJPN333);\r
2830                         // UPnP対応\r
2831                         if(IsUPnPLoaded() == YES)\r
2832                         {\r
2833                                 if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
2834                                         RemovePortMapping(Port);\r
2835                         }\r
2836                         do_closesocket(listen_skt);\r
2837                         listen_skt = INVALID_SOCKET;\r
2838                 }\r
2839 //              else\r
2840 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2841         }\r
2842 \r
2843         return(listen_skt);\r
2844 }\r
2845 \r
2846 \r
2847 SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
2848 {\r
2849         struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
2850         struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
2851         SOCKET listen_skt;\r
2852         int iLength;\r
2853         char *a,*p;\r
2854         struct sockaddr_in6 saCtrlAddr;\r
2855         struct sockaddr_in6 saTmpAddr;\r
2856         SOCKS5REQUEST Socks5Cmd;\r
2857         SOCKS5REPLY Socks5Reply;\r
2858 \r
2859         int Len;\r
2860         int Fwall;\r
2861 \r
2862         char Adrs[40];\r
2863         // UPnP対応\r
2864         int Port;\r
2865         char ExtAdrs[40];\r
2866 \r
2867         // ソケットにデータを付与\r
2868         GetAsyncTableDataIPv6(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
2869 \r
2870         Fwall = FWALL_NONE;\r
2871         if(AskHostFireWall() == YES)\r
2872                 Fwall = FwallType;\r
2873 \r
2874         if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2875         {\r
2876                 if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2877                 {\r
2878                         /*===== SOCKS5を使う =====*/\r
2879                         DoPrintf("Use SOCKS5 BIND");\r
2880                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2881                         {\r
2882                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2883                                 {\r
2884                                         DoClose(listen_skt);\r
2885                                         listen_skt = INVALID_SOCKET;\r
2886                                         return(listen_skt);\r
2887                                 }\r
2888 \r
2889                                 Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
2890 \r
2891                                 Socks5Reply.Result = -1;\r
2892                                 // 同時接続対応\r
2893 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2894 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2895 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2896                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2897                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2898                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2899                                 {\r
2900                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN334);\r
2901                                         DoClose(listen_skt);\r
2902                                         listen_skt = INVALID_SOCKET;\r
2903                                 }\r
2904 \r
2905                                 // IPv6対応\r
2906 //                              if(Socks5Reply.AdrsInt == 0)\r
2907 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2908 \r
2909                                 // IPv6対応\r
2910 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2911 //                              p = (char *)&Socks5Reply.Port;\r
2912                                 a = (char *)&Socks5Reply._dummy[0];\r
2913                                 p = (char *)&Socks5Reply._dummy[16];\r
2914                         }\r
2915                 }\r
2916                 else\r
2917                 {\r
2918                         /*===== SOCKSを使わない =====*/\r
2919                         DoPrintf("Use normal BIND");\r
2920                         saCtrlAddr.sin6_port = htons(0);\r
2921                         saCtrlAddr.sin6_family = AF_INET6;\r
2922                         memset(&saCtrlAddr.sin6_addr, 0, 16);\r
2923                         saCtrlAddr.sin6_flowinfo = 0;\r
2924                         saCtrlAddr.sin6_scope_id = 0;\r
2925 \r
2926                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
2927                         {\r
2928                                 iLength = sizeof(saCtrlAddr);\r
2929                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2930                                 {\r
2931                                         if(do_listen(listen_skt, 1) == 0)\r
2932                                         {\r
2933                                                 iLength = sizeof(saTmpAddr);\r
2934                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2935                                                         ReportWSError("getsockname", WSAGetLastError());\r
2936 \r
2937                                                 a = (char *)&saTmpAddr.sin6_addr;\r
2938                                                 p = (char *)&saCtrlAddr.sin6_port;\r
2939                                                 // UPnP対応\r
2940                                                 if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
2941                                                 {\r
2942                                                         if(AddPortMapping(AddressToStringIPv6(Adrs, &saTmpAddr.sin6_addr), ntohs(saCtrlAddr.sin6_port), ExtAdrs) == FFFTP_SUCCESS)\r
2943                                                         {\r
2944                                                                 saTmpAddr.sin6_addr = inet6_addr(ExtAdrs);\r
2945                                                                 SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin6_port));\r
2946                                                         }\r
2947                                                 }\r
2948                                         }\r
2949                                         else\r
2950                                         {\r
2951                                                 ReportWSError("listen", WSAGetLastError());\r
2952                                                 do_closesocket(listen_skt);\r
2953                                                 listen_skt = INVALID_SOCKET;\r
2954                                         }\r
2955                                 }\r
2956                                 else\r
2957                                 {\r
2958                                         ReportWSError("getsockname", WSAGetLastError());\r
2959                                         do_closesocket(listen_skt);\r
2960                                         listen_skt = INVALID_SOCKET;\r
2961                                 }\r
2962                         }\r
2963                         else\r
2964                         {\r
2965                                 ReportWSError("bind", WSAGetLastError());\r
2966                                 do_closesocket(listen_skt);\r
2967                                 listen_skt = INVALID_SOCKET;\r
2968                         }\r
2969 \r
2970                         if(listen_skt == INVALID_SOCKET)\r
2971                                 SetTaskMsg(MSGJPN030, MSGJPN334);\r
2972                 }\r
2973         }\r
2974         else\r
2975                 ReportWSError("socket create", WSAGetLastError());\r
2976 \r
2977         if(listen_skt != INVALID_SOCKET)\r
2978         {\r
2979 #define  UC(b)  (((int)b)&0xff)\r
2980                 // 同時接続対応\r
2981 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2982 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2983 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2984                 if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
2985                                 AddressToStringIPv6(Adrs, a),\r
2986                                 (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE)\r
2987                 {\r
2988                         SetTaskMsg(MSGJPN031, MSGJPN334);\r
2989                         // UPnP対応\r
2990                         if(IsUPnPLoaded() == YES)\r
2991                         {\r
2992                                 if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
2993                                         RemovePortMapping(Port);\r
2994                         }\r
2995                         do_closesocket(listen_skt);\r
2996                         listen_skt = INVALID_SOCKET;\r
2997                 }\r
2998 //              else\r
2999 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
3000         }\r
3001 \r
3002         return(listen_skt);\r
3003 }\r
3004 \r
3005 \r
3006 /*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
3007 *\r
3008 *       Parameter\r
3009 *               なし\r
3010 *\r
3011 *       Return Value\r
3012 *               int ステータス\r
3013 *                       YES/NO\r
3014 *----------------------------------------------------------------------------*/\r
3015 \r
3016 int AskTryingConnect(void)\r
3017 {\r
3018         return(TryConnect);\r
3019 }\r
3020 \r
3021 \r
3022 #if 0\r
3023 ///*----- ブロッキングコールのフックコールバック --------------------------------\r
3024 //*\r
3025 //*     Parameter\r
3026 //*             なし\r
3027 //*\r
3028 //*     Return Value\r
3029 //*             BOOL FALSE\r
3030 //*----------------------------------------------------------------------------*/\r
3031 //\r
3032 //static BOOL CALLBACK BlkHookFnc(void)\r
3033 //{\r
3034 //      BackgrndMessageProc();\r
3035 //\r
3036 //      if(CancelFlg == YES)\r
3037 //      {\r
3038 //              SetTaskMsg(MSGJPN032);\r
3039 //              WSACancelBlockingCall();\r
3040 //              CancelFlg = NO;\r
3041 //      }\r
3042 //      return(FALSE);\r
3043 //}\r
3044 #endif\r
3045 \r
3046 \r
3047 \r
3048 /*----- SOCKS5のコマンドパケットを作成する ------------------------------------\r
3049 *\r
3050 *       Parameter\r
3051 *               SOCKS5REQUEST *Packet : パケットを作成するワーク\r
3052 *               char Cmd : コマンド\r
3053 *               int ValidIP : IPアドレスを使うかどうか(YES/NO)\r
3054 *               ulong IP : IPアドレス\r
3055 *               char *Host : ホスト名\r
3056 *               ushort Port : ポート\r
3057 *\r
3058 *       Return Value\r
3059 *               int コマンドパケットの長さ\r
3060 *----------------------------------------------------------------------------*/\r
3061 \r
3062 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port)\r
3063 {\r
3064         uchar *Pos;\r
3065         int Len;\r
3066         int TotalLen;\r
3067 \r
3068         Pos = (uchar *)Packet;\r
3069         Pos += SOCKS5REQUEST_SIZE;\r
3070         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
3071 \r
3072         Packet->Ver = SOCKS5_VER;\r
3073         Packet->Cmd = Cmd;\r
3074         Packet->Rsv = 0;\r
3075         if(ValidIP == YES)\r
3076         {\r
3077                 /* IPアドレスを指定 */\r
3078                 Packet->Type = SOCKS5_ADRS_IPV4;\r
3079                 *((ulong *)Pos) = IP;\r
3080                 Pos += 4;\r
3081                 TotalLen += 4;\r
3082         }\r
3083         else\r
3084         {\r
3085                 /* ホスト名を指定 */\r
3086                 Packet->Type = SOCKS5_ADRS_NAME;\r
3087                 Len = strlen(Host);\r
3088                 *Pos++ = Len;\r
3089                 strcpy(Pos, Host);\r
3090                 Pos += Len;\r
3091                 TotalLen += Len + 1;\r
3092         }\r
3093         *((ushort *)Pos) = Port;\r
3094 \r
3095         return(TotalLen);\r
3096 }\r
3097 \r
3098 \r
3099 // IPv6対応\r
3100 static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
3101 {\r
3102         uchar *Pos;\r
3103         int Len;\r
3104         int TotalLen;\r
3105 \r
3106         Pos = (uchar *)Packet;\r
3107         Pos += SOCKS5REQUEST_SIZE;\r
3108         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
3109 \r
3110         Packet->Ver = SOCKS5_VER;\r
3111         Packet->Cmd = Cmd;\r
3112         Packet->Rsv = 0;\r
3113         if(ValidIP == YES)\r
3114         {\r
3115                 /* IPアドレスを指定 */\r
3116                 Packet->Type = SOCKS5_ADRS_IPV6;\r
3117                 memcpy(Pos, IP, 16);\r
3118                 Pos += 16;\r
3119                 TotalLen += 16;\r
3120         }\r
3121         else\r
3122         {\r
3123                 /* ホスト名を指定 */\r
3124                 Packet->Type = SOCKS5_ADRS_NAME;\r
3125                 Len = strlen(Host);\r
3126                 *Pos++ = Len;\r
3127                 strcpy(Pos, Host);\r
3128                 Pos += Len;\r
3129                 TotalLen += Len + 1;\r
3130         }\r
3131         *((ushort *)Pos) = Port;\r
3132 \r
3133         return(TotalLen);\r
3134 }\r
3135 \r
3136 \r
3137 /*----- SOCKSのコマンドを送る -------------------------------------------------\r
3138 *\r
3139 *       Parameter\r
3140 *               SOCKET Socket : ソケット\r
3141 *               void *Data : 送るデータ\r
3142 *               int Size : サイズ\r
3143 *\r
3144 *       Return Value\r
3145 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3146 *----------------------------------------------------------------------------*/\r
3147 \r
3148 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork)\r
3149 {\r
3150         int Ret;\r
3151 \r
3152         Ret = SendData(Socket, (char *)Data, Size, 0, CancelCheckWork);\r
3153 \r
3154         if(Ret != FFFTP_SUCCESS)\r
3155                 SetTaskMsg(MSGJPN033, *((short *)Data));\r
3156 \r
3157         return(Ret);\r
3158 }\r
3159 \r
3160 \r
3161 /*----- SOCKS5のコマンドに対するリプライパケットを受信する --------------------\r
3162 *\r
3163 *       Parameter\r
3164 *               SOCKET Socket : ソケット\r
3165 *               SOCKS5REPLY *Packet : パケット\r
3166 *\r
3167 *       Return Value\r
3168 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3169 *----------------------------------------------------------------------------*/\r
3170 \r
3171 // 同時接続対応\r
3172 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet)\r
3173 static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork)\r
3174 {\r
3175         uchar *Pos;\r
3176         int Len;\r
3177         int Ret;\r
3178 \r
3179         Pos = (uchar *)Packet;\r
3180         Pos += SOCKS5REPLY_SIZE;\r
3181 \r
3182         // 同時接続対応\r
3183 //      if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS)\r
3184         if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, CancelCheckWork)) == FFFTP_SUCCESS)\r
3185         {\r
3186                 if(Packet->Type == SOCKS5_ADRS_IPV4)\r
3187                         Len = 4 + 2;\r
3188                 else if(Packet->Type == SOCKS5_ADRS_IPV6)\r
3189                         Len = 16 + 2;\r
3190                 else\r
3191                 {\r
3192                         // 同時接続対応\r
3193 //                      if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS)\r
3194                         if((Ret = ReadNchar(Socket, (char *)Pos, 1, CancelCheckWork)) == FFFTP_SUCCESS)\r
3195                         {\r
3196                                 Len = *Pos + 2;\r
3197                                 Pos++;\r
3198                         }\r
3199                 }\r
3200 \r
3201                 if(Ret == FFFTP_SUCCESS)\r
3202                         // 同時接続対応\r
3203 //                      Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg);\r
3204                         Ret = ReadNchar(Socket, (char *)Pos, Len, CancelCheckWork);\r
3205         }\r
3206 \r
3207         if(Ret != FFFTP_SUCCESS)\r
3208                 SetTaskMsg(MSGJPN034);\r
3209 \r
3210         return(Ret);\r
3211 }\r
3212 \r
3213 \r
3214 /*----- SOCKS4のコマンドに対するリプライパケットを受信する --------------------\r
3215 *\r
3216 *       Parameter\r
3217 *               SOCKET Socket : ソケット\r
3218 *               SOCKS5REPLY *Packet : パケット\r
3219 *\r
3220 *       Return Value\r
3221 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3222 *----------------------------------------------------------------------------*/\r
3223 \r
3224 // 同時接続対応\r
3225 //static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet)\r
3226 static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork)\r
3227 {\r
3228         int Ret;\r
3229 \r
3230         // 同時接続対応\r
3231 //      Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg);\r
3232         Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, CancelCheckWork);\r
3233 \r
3234         if(Ret != FFFTP_SUCCESS)\r
3235                 DoPrintf(MSGJPN035);\r
3236 \r
3237         return(Ret);\r
3238 }\r
3239 \r
3240 \r
3241 /*----- SOCKS5の認証を行う ----------------------------------------------------\r
3242 *\r
3243 *       Parameter\r
3244 *               SOCKET Socket : ソケット\r
3245 *\r
3246 *       Return Value\r
3247 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3248 *----------------------------------------------------------------------------*/\r
3249 \r
3250 static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork)\r
3251 {\r
3252         int Ret;\r
3253         SOCKS5METHODREQUEST Socks5Method;\r
3254         SOCKS5METHODREPLY Socks5MethodReply;\r
3255         SOCKS5USERPASSSTATUS Socks5Status;\r
3256         char Buf[USER_NAME_LEN + PASSWORD_LEN + 4];\r
3257         int Len;\r
3258         int Len2;\r
3259 \r
3260         Ret = FFFTP_SUCCESS;\r
3261         Socks5Method.Ver = SOCKS5_VER;\r
3262         Socks5Method.Num = 1;\r
3263         if(FwallType == FWALL_SOCKS5_NOAUTH)\r
3264                 Socks5Method.Methods[0] = SOCKS5_AUTH_NONE;\r
3265         else\r
3266                 Socks5Method.Methods[0] = SOCKS5_AUTH_USER;\r
3267 \r
3268         // 同時接続対応\r
3269 //      if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3270 //         (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
3271 //         (Socks5MethodReply.Method == (uchar)0xFF))\r
3272         if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3273            (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3274            (Socks5MethodReply.Method == (uchar)0xFF))\r
3275         {\r
3276                 SetTaskMsg(MSGJPN036);\r
3277                 Ret = FFFTP_FAIL;\r
3278         }\r
3279         else if(Socks5MethodReply.Method == SOCKS5_AUTH_USER)\r
3280         {\r
3281                 DoPrintf("SOCKS5 User/Pass Authentication");\r
3282                 Buf[0] = SOCKS5_USERAUTH_VER;\r
3283                 Len = strlen(FwallUser);\r
3284                 Len2 = strlen(FwallPass);\r
3285                 Buf[1] = Len;\r
3286                 strcpy(Buf+2, FwallUser);\r
3287                 Buf[2 + Len] = Len2;\r
3288                 strcpy(Buf+3+Len, FwallPass);\r
3289 \r
3290                 // 同時接続対応\r
3291 //              if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3292 //                 (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
3293 //                 (Socks5Status.Status != 0))\r
3294                 if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3295                    (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
3296                    (Socks5Status.Status != 0))\r
3297                 {\r
3298                         SetTaskMsg(MSGJPN037);\r
3299                         Ret = FFFTP_FAIL;\r
3300                 }\r
3301         }\r
3302         else\r
3303                 DoPrintf("SOCKS5 No Authentication");\r
3304 \r
3305         return(Ret);\r
3306 }\r
3307 \r
3308 \r
3309 /*----- SOCKSのBINDの第2リプライメッセージを受け取る -------------------------\r
3310 *\r
3311 *       Parameter\r
3312 *               SOCKET Socket : ソケット\r
3313 *               SOCKET *Data : データソケットを返すワーク\r
3314 *\r
3315 *       Return Value\r
3316 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3317 *----------------------------------------------------------------------------*/\r
3318 \r
3319 // 同時接続対応\r
3320 //int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data)\r
3321 int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data, int *CancelCheckWork)\r
3322 {\r
3323         int Ret;\r
3324         char Buf[300];\r
3325 \r
3326         Ret = FFFTP_FAIL;\r
3327         if((AskHostFireWall() == YES) && (FwallType == FWALL_SOCKS4))\r
3328         {\r
3329                 // 同時接続対応\r
3330 //              Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf);\r
3331                 Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf, CancelCheckWork);\r
3332                 *Data = Socket;\r
3333                 Ret = FFFTP_SUCCESS;\r
3334         }\r
3335         else if((AskHostFireWall() == YES) &&\r
3336                         ((FwallType == FWALL_SOCKS5_NOAUTH) || (FwallType == FWALL_SOCKS5_USER)))\r
3337         {\r
3338                 // 同時接続対応\r
3339 //              Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf);\r
3340                 Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf, CancelCheckWork);\r
3341                 *Data = Socket;\r
3342                 Ret = FFFTP_SUCCESS;\r
3343         }\r
3344         return(Ret);\r
3345 }\r
3346 \r
3347 \r
3348 \r
3349 // 暗号化通信対応\r
3350 int AskCryptMode(void)\r
3351 {\r
3352         return(CurHost.CryptMode);\r
3353 }\r
3354 \r
3355 int AskUseNoEncryption(void)\r
3356 {\r
3357         return(CurHost.UseNoEncryption);\r
3358 }\r
3359 \r
3360 int AskUseFTPES(void)\r
3361 {\r
3362         return(CurHost.UseFTPES);\r
3363 }\r
3364 \r
3365 int AskUseFTPIS(void)\r
3366 {\r
3367         return(CurHost.UseFTPIS);\r
3368 }\r
3369 \r
3370 int AskUseSFTP(void)\r
3371 {\r
3372         return(CurHost.UseSFTP);\r
3373 }\r
3374 \r
3375 char *AskPrivateKey(void)\r
3376 {\r
3377         return(CurHost.PrivateKey);\r
3378 }\r
3379 \r
3380 // 同時接続対応\r
3381 int AskMaxThreadCount(void)\r
3382 {\r
3383         return(CurHost.MaxThreadCount);\r
3384 }\r
3385 \r
3386 int AskReuseCmdSkt(void)\r
3387 {\r
3388         return(CurHost.ReuseCmdSkt);\r
3389 }\r
3390 \r
3391 // FEAT対応\r
3392 int AskHostFeature(void)\r
3393 {\r
3394         return(CurHost.Feature);\r
3395 }\r
3396 \r
3397 // MLSD対応\r
3398 int AskUseMLSD(void)\r
3399 {\r
3400         return(CurHost.UseMLSD);\r
3401 }\r
3402 \r
3403 // IPv6対応\r
3404 int AskCurNetType(void)\r
3405 {\r
3406         return(CurHost.CurNetType);\r
3407 }\r
3408 \r
3409 // 自動切断対策\r
3410 int AskNoopInterval(void)\r
3411 {\r
3412         return(CurHost.NoopInterval);\r
3413 }\r
3414 \r
3415 // 再転送対応\r
3416 int AskTransferErrorMode(void)\r
3417 {\r
3418         return(CurHost.TransferErrorMode);\r
3419 }\r
3420 \r
3421 int AskTransferErrorNotify(void)\r
3422 {\r
3423         return(CurHost.TransferErrorNotify);\r
3424 }\r
3425 \r
3426 // セッションあたりの転送量制限対策\r
3427 int AskErrorReconnect(void)\r
3428 {\r
3429         return(CurHost.TransferErrorReconnect);\r
3430 }\r
3431 \r
3432 // ホスト側の設定ミス対策\r
3433 int AskNoPasvAdrs(void)\r
3434 {\r
3435         return(CurHost.NoPasvAdrs);\r
3436 }\r
3437 \r