OSDN Git Service

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