OSDN Git Service

Add support for retrying file transfer.
[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                                                                 // FTPIS対応\r
1544                                                                 // "PBSZ 0"と"PROT P"は黙示的に設定されているはずだが念のため\r
1545                                                                 if(CryptMode == CRYPT_FTPIS)\r
1546                                                                 {\r
1547                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1548                                                                         {\r
1549                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1550                                                                                 {\r
1551                                                                                 }\r
1552                                                                         }\r
1553                                                                 }\r
1554 \r
1555                                                                 ReInPass = NO;\r
1556                                                                 do\r
1557                                                                 {\r
1558                                                                         // FTPES対応\r
1559                                                                         if(Sts == FTP_ERROR)\r
1560                                                                                 break;\r
1561                                                                         Continue = NO;\r
1562                                                                         // 同時接続対応\r
1563 //                                                                      if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1564                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1565                                                                         {\r
1566                                                                                 if((strlen(Pass) != 0) || \r
1567                                                                                    (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1568                                                                                 {\r
1569                                                                                         CheckOneTimePassword(Pass, Reply, Security);\r
1570 \r
1571                                                                                         /* パスワードがスペース1個の時はパスワードの実体なしとする */\r
1572                                                                                         if(strcmp(Reply, " ") == 0)\r
1573                                                                                                 strcpy(Reply, "");\r
1574 \r
1575                                                                                         // 同時接続対応\r
1576 //                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1577                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1578                                                                                         if(Sts == FTP_ERROR)\r
1579                                                                                         {\r
1580                                                                                                 strcpy(Pass, "");\r
1581                                                                                                 if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1582                                                                                                         Continue = YES;\r
1583                                                                                                 else\r
1584                                                                                                         DoPrintf("No password specified.");\r
1585                                                                                                 ReInPass = YES;\r
1586                                                                                         }\r
1587                                                                                         else if(Sts == FTP_CONTINUE)\r
1588                                                                                         {\r
1589                                                                                                 if((strlen(Acct) != 0) || \r
1590                                                                                                    (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1591                                                                                                 {\r
1592                                                                                                         // 同時接続対応\r
1593 //                                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100;\r
1594                                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "ACCT %s", Acct) / 100;\r
1595                                                                                                 }\r
1596                                                                                                 else\r
1597                                                                                                         DoPrintf("No account specified");\r
1598                                                                                         }\r
1599                                                                                 }\r
1600                                                                                 else\r
1601                                                                                 {\r
1602                                                                                         Sts = FTP_ERROR;\r
1603                                                                                         DoPrintf("No password specified.");\r
1604                                                                                 }\r
1605                                                                         }\r
1606                                                                 }\r
1607                                                                 while(Continue == YES);\r
1608                                                         }\r
1609                                                         else\r
1610                                                         {\r
1611                                                                 Sts = FTP_ERROR;\r
1612                                                                 DoPrintf("No user name specified");\r
1613                                                         }\r
1614 \r
1615                                                         if(Sts != FTP_COMPLETE)\r
1616                                                         {\r
1617                                                                 SetTaskMsg(MSGJPN008, Host);\r
1618                                                                 DoClose(ContSock);\r
1619                                                                 ContSock = INVALID_SOCKET;\r
1620                                                         }\r
1621                                                         else if((SavePass == YES) && (ReInPass == YES))\r
1622                                                         {\r
1623                                                                 if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1624                                                                         SetHostPassword(AskCurrentHost(), Pass);\r
1625                                                         }\r
1626                                                 }\r
1627                                         }\r
1628                                 }\r
1629                                 else\r
1630                                 {\r
1631 //#pragma aaa\r
1632                                         SetTaskMsg(MSGJPN009/*"接続できません(1) %x", ContSock*/);\r
1633                                         DoClose(ContSock);\r
1634                                         ContSock = INVALID_SOCKET;\r
1635                                 }\r
1636                         }\r
1637                 }\r
1638                 else\r
1639                 {\r
1640 \r
1641                         if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1642                            (Fwall == FWALL_FU_FP))\r
1643                                 SetTaskMsg(MSGJPN010);\r
1644                         else\r
1645                                 SetTaskMsg(MSGJPN011);\r
1646                 }\r
1647 \r
1648 #if 0\r
1649 //              WSAUnhookBlockingHook();\r
1650 #endif\r
1651                 TryConnect = NO;\r
1652 \r
1653                 // FEAT対応\r
1654                 // ホストの機能を確認\r
1655                 if(ContSock != INVALID_SOCKET)\r
1656                 {\r
1657                         if((Sts = command(ContSock, Reply, CancelCheckWork, "FEAT")) == 211)\r
1658                         {\r
1659                                 // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用\r
1660                                 // UTF-8対応\r
1661                                 if(strstr(Reply, " UTF8 "))\r
1662                                         HostData->Feature |= FEATURE_UTF8;\r
1663                                 // MLST対応\r
1664                                 if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD "))\r
1665                                         HostData->Feature |= FEATURE_MLSD;\r
1666                                 // IPv6対応\r
1667                                 if(strstr(Reply, " EPRT ") || strstr(Reply, " EPSV "))\r
1668                                         HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV;\r
1669                         }\r
1670                         // UTF-8対応\r
1671                         if(HostData->CurNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
1672                         {\r
1673                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200)\r
1674                                         HostData->CurNameKanjiCode = KANJI_UTF8N;\r
1675                         }\r
1676                 }\r
1677         }\r
1678         else if(CryptMode == CRYPT_SFTP)\r
1679         {\r
1680         }\r
1681 \r
1682         return(ContSock);\r
1683 }\r
1684 \r
1685 // 同時接続対応\r
1686 //static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security)\r
1687 static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
1688 {\r
1689         SOCKET ContSock;\r
1690         ContSock = INVALID_SOCKET;\r
1691         *CancelCheckWork = NO;\r
1692         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)\r
1693         {\r
1694                 SetTaskMsg(MSGJPN317);\r
1695                 if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1696                         HostData->CryptMode = CRYPT_SFTP;\r
1697         }\r
1698         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
1699         {\r
1700                 SetTaskMsg(MSGJPN316);\r
1701                 if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1702                         HostData->CryptMode = CRYPT_FTPIS;\r
1703         }\r
1704         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES)\r
1705         {\r
1706                 SetTaskMsg(MSGJPN315);\r
1707                 if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1708                         HostData->CryptMode = CRYPT_FTPES;\r
1709         }\r
1710         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES)\r
1711         {\r
1712                 SetTaskMsg(MSGJPN314);\r
1713                 if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1714                         HostData->CryptMode = CRYPT_NONE;\r
1715         }\r
1716         return ContSock;\r
1717 }\r
1718 \r
1719 \r
1720 /*----- ワンタイムパスワードのチェック ----------------------------------------\r
1721 *\r
1722 *       Parameter\r
1723 *               chat *Pass : パスワード/パスフレーズ\r
1724 *               char *Reply : USERコマンドを送ったあとのリプライ文字列\r
1725 *                                               /PASSコマンドで送るパスワードを返すバッファ\r
1726 *               int Type : タイプ (SECURITY_xxx, MDx)\r
1727 *\r
1728 *       Return Value\r
1729 *               int ステータス\r
1730 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1731 *\r
1732 *       Note\r
1733 *               ワンタイムパスワードでない時はPassをそのままReplyにコピー\r
1734 *----------------------------------------------------------------------------*/\r
1735 \r
1736 static int CheckOneTimePassword(char *Pass, char *Reply, int Type)\r
1737 {\r
1738         int Sts;\r
1739         char *Pos;\r
1740         int Seq;\r
1741         char Seed[MAX_SEED_LEN+1];\r
1742         int i;\r
1743 \r
1744         Sts = FFFTP_SUCCESS;\r
1745         Pos = NULL;\r
1746 \r
1747         if(Type == SECURITY_AUTO)\r
1748         {\r
1749                 if((Pos = stristr(Reply, "otp-md5")) != NULL)\r
1750                 {\r
1751                         Type = MD5;\r
1752                         SetTaskMsg(MSGJPN012);\r
1753                 }\r
1754                 else if((Pos = stristr(Reply, "otp-sha1")) != NULL)\r
1755                 {\r
1756                         Type = SHA1;\r
1757                         SetTaskMsg(MSGJPN013);\r
1758                 }\r
1759                 else if(((Pos = stristr(Reply, "otp-md4")) != NULL) || ((Pos = stristr(Reply, "s/key")) != NULL))\r
1760                 {\r
1761                         Type = MD4;\r
1762                         SetTaskMsg(MSGJPN014);\r
1763                 }\r
1764         }\r
1765         else\r
1766                 Pos = GetNextField(Reply);\r
1767 \r
1768         if((Type == MD4) || (Type == MD5) || (Type == SHA1))\r
1769         {\r
1770                 /* シーケンス番号を見つけるループ */\r
1771                 DoPrintf("Analize OTP");\r
1772                 DoPrintf("%s", Pos);\r
1773                 Sts = FFFTP_FAIL;\r
1774                 while((Pos = GetNextField(Pos)) != NULL)\r
1775                 {\r
1776                         if(IsDigit(*Pos))\r
1777                         {\r
1778                                 Seq = atoi(Pos);\r
1779                                 DoPrintf("Sequence=%d", Seq);\r
1780 \r
1781                                 /* Seed */\r
1782                                 if((Pos = GetNextField(Pos)) != NULL)\r
1783                                 {\r
1784                                         if(GetOneField(Pos, Seed, MAX_SEED_LEN) == FFFTP_SUCCESS)\r
1785                                         {\r
1786                                                 /* Seedは英数字のみ有効とする */\r
1787                                                 for(i = strlen(Seed)-1; i >= 0; i--)\r
1788                                                 {\r
1789                                                         if((IsAlpha(Seed[i]) == 0) && (IsDigit(Seed[i]) == 0))\r
1790                                                                 Seed[i] = NUL;\r
1791                                                 }\r
1792                                                 if(strlen(Seed) > 0)\r
1793                                                 {\r
1794                                                         DoPrintf("Seed=%s", Seed);\r
1795                                                         Make6WordPass(Seq, Seed, Pass, Type, Reply);\r
1796                                                         DoPrintf("Response=%s", Reply);\r
1797 \r
1798                                                         /* シーケンス番号のチェックと警告 */\r
1799                                                         if(Seq <= 10)\r
1800                                                                 DialogBox(GetFtpInst(), MAKEINTRESOURCE(otp_notify_dlg), GetMainHwnd(), ExeEscDialogProc);\r
1801 \r
1802                                                         Sts = FFFTP_SUCCESS;\r
1803                                                 }\r
1804                                         }\r
1805                                 }\r
1806                                 break;\r
1807                         }\r
1808                 }\r
1809 \r
1810                 if(Sts == FFFTP_FAIL)\r
1811                         SetTaskMsg(MSGJPN015);\r
1812         }\r
1813         else\r
1814         {\r
1815                 strcpy(Reply, Pass);\r
1816                 DoPrintf("No OTP used.");\r
1817         }\r
1818         return(Sts);\r
1819 }\r
1820 \r
1821 \r
1822 \r
1823 \r
1824 \r
1825 \r
1826 \r
1827 \r
1828 \r
1829 \r
1830 \r
1831 \r
1832 \r
1833 \r
1834 /*----- ソケットを接続する ----------------------------------------------------\r
1835 *\r
1836 *       Parameter\r
1837 *               char *host : ホスト名\r
1838 *               int port : ポート番号\r
1839 *               char *PreMsg : メッセージの前半部分\r
1840 *\r
1841 *       Return Value\r
1842 *               SOCKET ソケット\r
1843 *----------------------------------------------------------------------------*/\r
1844 \r
1845 // IPv6対応\r
1846 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
1847 {\r
1848         SOCKET Result;\r
1849         Result = INVALID_SOCKET;\r
1850         switch(CurHost.CurNetType)\r
1851         {\r
1852         case NTYPE_AUTO:\r
1853                 if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
1854                         CurHost.CurNetType = NTYPE_IPV4;\r
1855                 else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
1856                         CurHost.CurNetType = NTYPE_IPV6;\r
1857                 break;\r
1858         case NTYPE_IPV4:\r
1859                 Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
1860                 CurHost.CurNetType = NTYPE_IPV4;\r
1861                 break;\r
1862         case NTYPE_IPV6:\r
1863                 Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
1864                 CurHost.CurNetType = NTYPE_IPV6;\r
1865                 break;\r
1866         }\r
1867         return Result;\r
1868 }\r
1869 \r
1870 \r
1871 // IPv6対応\r
1872 //SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
1873 SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
1874 {\r
1875         struct sockaddr_in saSockAddr;\r
1876         char HostEntry[MAXGETHOSTSTRUCT];\r
1877         struct hostent *pHostEntry;\r
1878         SOCKET sSocket;\r
1879         int Len;\r
1880         int Fwall;\r
1881         SOCKS4CMD Socks4Cmd;\r
1882         SOCKS4REPLY Socks4Reply;\r
1883         SOCKS5REQUEST Socks5Cmd;\r
1884         SOCKS5REPLY Socks5Reply;\r
1885 \r
1886         //////////////////////////////\r
1887         // ホスト名解決と接続の準備\r
1888         //////////////////////////////\r
1889 \r
1890         Fwall = FWALL_NONE;\r
1891         if(AskHostFireWall() == YES)\r
1892                 Fwall = FwallType;\r
1893 \r
1894         sSocket = INVALID_SOCKET;\r
1895 \r
1896         UseIPadrs = YES;\r
1897         strcpy(DomainName, host);\r
1898         // IPv6対応\r
1899 //      memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
1900 //      CurSockAddr.sin_port = htons((u_short)port);\r
1901 //      CurSockAddr.sin_family = AF_INET;\r
1902 //      if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
1903         memset(&CurSockAddrIPv4, 0, sizeof(CurSockAddrIPv4));\r
1904         CurSockAddrIPv4.sin_port = htons((u_short)port);\r
1905         CurSockAddrIPv4.sin_family = AF_INET;\r
1906         if((CurSockAddrIPv4.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
1907         {\r
1908                 // ホスト名が指定された\r
1909                 // ホスト名からアドレスを求める\r
1910                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
1911                    (FwallResolv == YES))\r
1912                 {\r
1913                         // ホスト名解決はSOCKSサーバに任せる\r
1914                         pHostEntry = NULL;\r
1915                 }\r
1916                 else\r
1917                 {\r
1918                         // アドレスを取得\r
1919                         SetTaskMsg(MSGJPN016, DomainName);\r
1920                         // IPv6対応\r
1921 //                      pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
1922                         pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
1923                 }\r
1924 \r
1925                 if(pHostEntry != NULL)\r
1926                 {\r
1927                         // IPv6対応\r
1928 //                      memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
1929 //                      SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
1930                         memcpy((char *)&CurSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
1931                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));\r
1932                 }\r
1933                 else\r
1934                 {\r
1935                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
1936                         {\r
1937                                 UseIPadrs = NO;\r
1938                                 // IPv6対応\r
1939 //                              SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
1940                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv4.sin_port));\r
1941                         }\r
1942                         else\r
1943                         {\r
1944                                 SetTaskMsg(MSGJPN019, host);\r
1945                                 return(INVALID_SOCKET);\r
1946                         }\r
1947                 }\r
1948         }\r
1949         else\r
1950                 // IPv6対応\r
1951 //              SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
1952                 SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));\r
1953 \r
1954         if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
1955         {\r
1956                 // SOCKSを使う\r
1957                 // SOCKSに接続する準備\r
1958                 if(Fwall == FWALL_SOCKS4)\r
1959                 {\r
1960                         Socks4Cmd.Ver = SOCKS4_VER;\r
1961                         Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
1962                         // IPv6対応\r
1963 //                      Socks4Cmd.Port = CurSockAddr.sin_port;\r
1964 //                      Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
1965                         Socks4Cmd.Port = CurSockAddrIPv4.sin_port;\r
1966                         Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;\r
1967                         strcpy(Socks4Cmd.UserID, FwallUser);\r
1968                         Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
1969                 }\r
1970                 else\r
1971                 {\r
1972                         // IPv6対応\r
1973 //                      Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
1974                         Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);\r
1975                 }\r
1976 \r
1977                 // IPv6対応\r
1978 //              memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
1979 //              if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
1980                 memset(&SocksSockAddrIPv4, 0, sizeof(SocksSockAddrIPv4));\r
1981                 if((SocksSockAddrIPv4.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
1982                 {\r
1983                         // IPv6対応\r
1984 //                      if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
1985 //                              memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
1986                         if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
1987                                 memcpy((char *)&SocksSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
1988                         else\r
1989                         {\r
1990                                 SetTaskMsg(MSGJPN021, FwallHost);\r
1991                                 return INVALID_SOCKET;\r
1992                         }\r
1993                 }\r
1994                 // IPv6対応\r
1995 //              SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
1996 //              SocksSockAddr.sin_family = AF_INET;\r
1997 //              SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
1998                 SocksSockAddrIPv4.sin_port = htons((u_short)FwallPort);\r
1999                 SocksSockAddrIPv4.sin_family = AF_INET;\r
2000                 SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddrIPv4.sin_addr), ntohs(SocksSockAddrIPv4.sin_port));\r
2001                 // connectで接続する先はSOCKSサーバ\r
2002                 // IPv6対応\r
2003 //              memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2004                 memcpy(&saSockAddr, &SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4));\r
2005         }\r
2006         else\r
2007         {\r
2008                 // connectで接続するのは接続先のホスト\r
2009                 // IPv6対応\r
2010 //              memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2011                 memcpy(&saSockAddr, &CurSockAddrIPv4, sizeof(CurSockAddrIPv4));\r
2012         }\r
2013 \r
2014         /////////////\r
2015         // 接続実行\r
2016         /////////////\r
2017 \r
2018         if((sSocket = do_socket(AF_INET, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2019         {\r
2020                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2021                 {\r
2022                         if(Fwall == FWALL_SOCKS4)\r
2023                         {\r
2024                                 Socks4Reply.Result = -1;\r
2025                                 // 同時接続対応\r
2026 //                              if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2027 //                                 (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || \r
2028 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2029                                 if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2030                                    (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2031                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2032                                 {\r
2033                                         SetTaskMsg(MSGJPN023, Socks4Reply.Result);\r
2034                                         DoClose(sSocket);\r
2035                                         sSocket = INVALID_SOCKET;\r
2036                                 }\r
2037                         }\r
2038                         else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2039                         {\r
2040                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2041                                 {\r
2042                                         DoClose(sSocket);\r
2043                                         sSocket = INVALID_SOCKET;\r
2044                                 }\r
2045 \r
2046                                 Socks5Reply.Result = -1;\r
2047                                 // 同時接続対応\r
2048 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2049 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2050 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2051                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2052                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2053                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2054                                 {\r
2055                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2056                                         DoClose(sSocket);\r
2057                                         sSocket = INVALID_SOCKET;\r
2058                                 }\r
2059 \r
2060                         }\r
2061 \r
2062                         if(sSocket != INVALID_SOCKET)\r
2063                                 SetTaskMsg(MSGJPN025);\r
2064                 }\r
2065                 else\r
2066                 {\r
2067 //#pragma aaa\r
2068                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2069                         DoClose(sSocket);\r
2070                         sSocket = INVALID_SOCKET;\r
2071                 }\r
2072         }\r
2073         else\r
2074                 SetTaskMsg(MSGJPN027);\r
2075 \r
2076         return(sSocket);\r
2077 }\r
2078 \r
2079 \r
2080 SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2081 {\r
2082         struct sockaddr_in6 saSockAddr;\r
2083         char HostEntry[MAXGETHOSTSTRUCT];\r
2084         struct hostent *pHostEntry;\r
2085         SOCKET sSocket;\r
2086         int Len;\r
2087         int Fwall;\r
2088         SOCKS5REQUEST Socks5Cmd;\r
2089         SOCKS5REPLY Socks5Reply;\r
2090 \r
2091         //////////////////////////////\r
2092         // ホスト名解決と接続の準備\r
2093         //////////////////////////////\r
2094 \r
2095         Fwall = FWALL_NONE;\r
2096         if(AskHostFireWall() == YES)\r
2097                 Fwall = FwallType;\r
2098 \r
2099         sSocket = INVALID_SOCKET;\r
2100 \r
2101         UseIPadrs = YES;\r
2102         strcpy(DomainName, host);\r
2103         memset(&CurSockAddrIPv6, 0, sizeof(CurSockAddrIPv6));\r
2104         CurSockAddrIPv6.sin6_port = htons((u_short)port);\r
2105         CurSockAddrIPv6.sin6_family = AF_INET6;\r
2106         CurSockAddrIPv6.sin6_addr = inet6_addr(host);\r
2107         if(memcmp(&CurSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2108         {\r
2109                 // ホスト名が指定された\r
2110                 // ホスト名からアドレスを求める\r
2111                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2112                    (FwallResolv == YES))\r
2113                 {\r
2114                         // ホスト名解決はSOCKSサーバに任せる\r
2115                         pHostEntry = NULL;\r
2116                 }\r
2117                 else\r
2118                 {\r
2119                         // アドレスを取得\r
2120                         SetTaskMsg(MSGJPN016, DomainName);\r
2121                         pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2122                 }\r
2123 \r
2124                 if(pHostEntry != NULL)\r
2125                 {\r
2126                         memcpy((char *)&CurSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2127                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));\r
2128                 }\r
2129                 else\r
2130                 {\r
2131                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2132                         {\r
2133                                 UseIPadrs = NO;\r
2134                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv6.sin6_port));\r
2135                         }\r
2136                         else\r
2137                         {\r
2138                                 SetTaskMsg(MSGJPN019, host);\r
2139                                 return(INVALID_SOCKET);\r
2140                         }\r
2141                 }\r
2142         }\r
2143         else\r
2144                 SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));\r
2145 \r
2146         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2147         {\r
2148                 // SOCKSを使う\r
2149                 // SOCKSに接続する準備\r
2150                 {\r
2151                         Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);\r
2152                 }\r
2153 \r
2154                 memset(&SocksSockAddrIPv6, 0, sizeof(SocksSockAddrIPv6));\r
2155                 SocksSockAddrIPv6.sin6_addr = inet6_addr(FwallHost);\r
2156                 if(memcmp(&SocksSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2157                 {\r
2158                         if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2159                                 memcpy((char *)&SocksSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2160                         else\r
2161                         {\r
2162                                 SetTaskMsg(MSGJPN021, FwallHost);\r
2163                                 return INVALID_SOCKET;\r
2164                         }\r
2165                 }\r
2166                 SocksSockAddrIPv6.sin6_port = htons((u_short)FwallPort);\r
2167                 SocksSockAddrIPv6.sin6_family = AF_INET6;\r
2168                 SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddrIPv6.sin6_addr), ntohs(SocksSockAddrIPv6.sin6_port));\r
2169                 // connectで接続する先はSOCKSサーバ\r
2170                 memcpy(&saSockAddr, &SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6));\r
2171         }\r
2172         else\r
2173         {\r
2174                 // connectで接続するのは接続先のホスト\r
2175                 memcpy(&saSockAddr, &CurSockAddrIPv6, sizeof(CurSockAddrIPv6));\r
2176         }\r
2177 \r
2178         /////////////\r
2179         // 接続実行\r
2180         /////////////\r
2181 \r
2182         inet6_ntoa(saSockAddr.sin6_addr);\r
2183         if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2184         {\r
2185                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2186                 {\r
2187                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2188                         {\r
2189                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2190                                 {\r
2191                                         DoClose(sSocket);\r
2192                                         sSocket = INVALID_SOCKET;\r
2193                                 }\r
2194 \r
2195                                 Socks5Reply.Result = -1;\r
2196                                 // 同時接続対応\r
2197 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2198 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2199 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2200                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2201                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2202                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2203                                 {\r
2204                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2205                                         DoClose(sSocket);\r
2206                                         sSocket = INVALID_SOCKET;\r
2207                                 }\r
2208 \r
2209                         }\r
2210 \r
2211                         if(sSocket != INVALID_SOCKET)\r
2212                                 SetTaskMsg(MSGJPN025);\r
2213                 }\r
2214                 else\r
2215                 {\r
2216 //#pragma aaa\r
2217                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2218                         DoClose(sSocket);\r
2219                         sSocket = INVALID_SOCKET;\r
2220                 }\r
2221         }\r
2222         else\r
2223                 SetTaskMsg(MSGJPN027);\r
2224 \r
2225         return(sSocket);\r
2226 }\r
2227 \r
2228 \r
2229 /*----- リッスンソケットを取得 ------------------------------------------------\r
2230 *\r
2231 *       Parameter\r
2232 *               SOCKET ctrl_skt : コントロールソケット\r
2233 *\r
2234 *       Return Value\r
2235 *               SOCKET リッスンソケット\r
2236 *----------------------------------------------------------------------------*/\r
2237 \r
2238 // IPv6対応\r
2239 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2240 {\r
2241         SOCKET Result;\r
2242         Result = INVALID_SOCKET;\r
2243         switch(CurHost.CurNetType)\r
2244         {\r
2245         case NTYPE_IPV4:\r
2246                 Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
2247                 break;\r
2248         case NTYPE_IPV6:\r
2249                 Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
2250                 break;\r
2251         }\r
2252         return Result;\r
2253 }\r
2254 \r
2255 \r
2256 // IPv6対応\r
2257 //SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2258 SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
2259 {\r
2260     SOCKET listen_skt;\r
2261     int iLength;\r
2262     char *a,*p;\r
2263         struct sockaddr_in saCtrlAddr;\r
2264         struct sockaddr_in saTmpAddr;\r
2265         SOCKS4CMD Socks4Cmd;\r
2266         SOCKS4REPLY Socks4Reply;\r
2267         SOCKS5REQUEST Socks5Cmd;\r
2268         SOCKS5REPLY Socks5Reply;\r
2269 \r
2270         int Len;\r
2271         int Fwall;\r
2272 \r
2273         Fwall = FWALL_NONE;\r
2274         if(AskHostFireWall() == YES)\r
2275                 Fwall = FwallType;\r
2276 \r
2277         if((listen_skt = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2278         {\r
2279                 if(Fwall == FWALL_SOCKS4)\r
2280                 {\r
2281                         /*===== SOCKS4を使う =====*/\r
2282                         DoPrintf("Use SOCKS4 BIND");\r
2283                         // IPv6対応\r
2284 //                      if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2285                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)\r
2286                         {\r
2287                                 Socks4Cmd.Ver = SOCKS4_VER;\r
2288                                 Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
2289                                 // IPv6対応\r
2290 //                              Socks4Cmd.Port = CurSockAddr.sin_port;\r
2291 //                              Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2292                                 Socks4Cmd.Port = CurSockAddrIPv4.sin_port;\r
2293                                 Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;\r
2294                                 strcpy(Socks4Cmd.UserID, FwallUser);\r
2295                                 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2296 \r
2297                                 Socks4Reply.Result = -1;\r
2298                                 // 同時接続対応\r
2299 //                              if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2300 //                                 (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || \r
2301 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2302                                 if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2303                                    (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2304                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2305                                 {\r
2306                                         SetTaskMsg(MSGJPN028, Socks4Reply.Result);\r
2307                                         DoClose(listen_skt);\r
2308                                         listen_skt = INVALID_SOCKET;\r
2309                                 }\r
2310 \r
2311                                 if(Socks4Reply.AdrsInt == 0)\r
2312                                         // IPv6対応\r
2313 //                                      Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2314                                         Socks4Reply.AdrsInt = SocksSockAddrIPv4.sin_addr.s_addr;\r
2315 \r
2316                                 a = (char *)&Socks4Reply.AdrsInt;\r
2317                                 p = (char *)&Socks4Reply.Port;\r
2318                         }\r
2319                 }\r
2320                 else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2321                 {\r
2322                         /*===== SOCKS5を使う =====*/\r
2323                         DoPrintf("Use SOCKS5 BIND");\r
2324                         // IPv6対応\r
2325 //                      if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2326                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)\r
2327                         {\r
2328                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2329                                 {\r
2330                                         DoClose(listen_skt);\r
2331                                         listen_skt = INVALID_SOCKET;\r
2332                                         return(listen_skt);\r
2333                                 }\r
2334 \r
2335                                 // IPv6対応\r
2336 //                              Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2337                                 Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);\r
2338 \r
2339                                 Socks5Reply.Result = -1;\r
2340                                 // 同時接続対応\r
2341 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2342 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2343 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2344                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2345                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2346                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2347                                 {\r
2348                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2349                                         DoClose(listen_skt);\r
2350                                         listen_skt = INVALID_SOCKET;\r
2351                                 }\r
2352 \r
2353                                 // IPv6対応\r
2354 //                              if(Socks5Reply.AdrsInt == 0)\r
2355 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2356 \r
2357                                 // IPv6対応\r
2358 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2359 //                              p = (char *)&Socks5Reply.Port;\r
2360                                 a = (char *)&Socks5Reply._dummy[0];\r
2361                                 p = (char *)&Socks5Reply._dummy[4];\r
2362                         }\r
2363                 }\r
2364                 else\r
2365                 {\r
2366                         /*===== SOCKSを使わない =====*/\r
2367                         DoPrintf("Use normal BIND");\r
2368                         saCtrlAddr.sin_port = htons(0);\r
2369                         saCtrlAddr.sin_family = AF_INET;\r
2370                         saCtrlAddr.sin_addr.s_addr = 0;\r
2371 \r
2372                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr)) != SOCKET_ERROR)\r
2373                         {\r
2374                                 iLength = sizeof(saCtrlAddr);\r
2375                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2376                                 {\r
2377                                         if(do_listen(listen_skt, 1) == 0)\r
2378                                         {\r
2379                                                 iLength = sizeof(saTmpAddr);\r
2380                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2381                                                         ReportWSError("getsockname", WSAGetLastError());\r
2382 \r
2383                                                 a = (char *)&saTmpAddr.sin_addr;\r
2384                                                 p = (char *)&saCtrlAddr.sin_port;\r
2385                                         }\r
2386                                         else\r
2387                                         {\r
2388                                                 ReportWSError("listen", WSAGetLastError());\r
2389                                                 do_closesocket(listen_skt);\r
2390                                                 listen_skt = INVALID_SOCKET;\r
2391                                         }\r
2392                                 }\r
2393                                 else\r
2394                                 {\r
2395                                         ReportWSError("getsockname", WSAGetLastError());\r
2396                                         do_closesocket(listen_skt);\r
2397                                         listen_skt = INVALID_SOCKET;\r
2398                                 }\r
2399                         }\r
2400                         else\r
2401                         {\r
2402                                 ReportWSError("bind", WSAGetLastError());\r
2403                                 do_closesocket(listen_skt);\r
2404                                 listen_skt = INVALID_SOCKET;\r
2405                         }\r
2406 \r
2407                         if(listen_skt == INVALID_SOCKET)\r
2408                                 SetTaskMsg(MSGJPN030);\r
2409                 }\r
2410         }\r
2411         else\r
2412                 ReportWSError("socket create", WSAGetLastError());\r
2413 \r
2414         if(listen_skt != INVALID_SOCKET)\r
2415         {\r
2416 #define  UC(b)  (((int)b)&0xff)\r
2417                 // 同時接続対応\r
2418 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2419 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2420 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2421                 if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d",\r
2422                                 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2423                                 UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2424                 {\r
2425                         SetTaskMsg(MSGJPN031);\r
2426                         do_closesocket(listen_skt);\r
2427                         listen_skt = INVALID_SOCKET;\r
2428                 }\r
2429 //              else\r
2430 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2431         }\r
2432 \r
2433         return(listen_skt);\r
2434 }\r
2435 \r
2436 \r
2437 SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
2438 {\r
2439     SOCKET listen_skt;\r
2440     int iLength;\r
2441     char *a,*p;\r
2442         struct sockaddr_in6 saCtrlAddr;\r
2443         struct sockaddr_in6 saTmpAddr;\r
2444         SOCKS5REQUEST Socks5Cmd;\r
2445         SOCKS5REPLY Socks5Reply;\r
2446 \r
2447         int Len;\r
2448         int Fwall;\r
2449 \r
2450         char Adrs[40];\r
2451 \r
2452         Fwall = FWALL_NONE;\r
2453         if(AskHostFireWall() == YES)\r
2454                 Fwall = FwallType;\r
2455 \r
2456         if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2457         {\r
2458                 if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2459                 {\r
2460                         /*===== SOCKS5を使う =====*/\r
2461                         DoPrintf("Use SOCKS5 BIND");\r
2462                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6), CancelCheckWork) != SOCKET_ERROR)\r
2463                         {\r
2464                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2465                                 {\r
2466                                         DoClose(listen_skt);\r
2467                                         listen_skt = INVALID_SOCKET;\r
2468                                         return(listen_skt);\r
2469                                 }\r
2470 \r
2471                                 Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);\r
2472 \r
2473                                 Socks5Reply.Result = -1;\r
2474                                 // 同時接続対応\r
2475 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2476 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2477 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2478                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2479                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2480                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2481                                 {\r
2482                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2483                                         DoClose(listen_skt);\r
2484                                         listen_skt = INVALID_SOCKET;\r
2485                                 }\r
2486 \r
2487                                 // IPv6対応\r
2488 //                              if(Socks5Reply.AdrsInt == 0)\r
2489 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2490 \r
2491                                 // IPv6対応\r
2492 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2493 //                              p = (char *)&Socks5Reply.Port;\r
2494                                 a = (char *)&Socks5Reply._dummy[0];\r
2495                                 p = (char *)&Socks5Reply._dummy[16];\r
2496                         }\r
2497                 }\r
2498                 else\r
2499                 {\r
2500                         /*===== SOCKSを使わない =====*/\r
2501                         DoPrintf("Use normal BIND");\r
2502                         saCtrlAddr.sin6_port = htons(0);\r
2503                         saCtrlAddr.sin6_family = AF_INET6;\r
2504                         memset(&saCtrlAddr.sin6_addr, 0, 16);\r
2505 \r
2506                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
2507                         {\r
2508                                 iLength = sizeof(saCtrlAddr);\r
2509                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2510                                 {\r
2511                                         if(do_listen(listen_skt, 1) == 0)\r
2512                                         {\r
2513                                                 iLength = sizeof(saTmpAddr);\r
2514                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2515                                                         ReportWSError("getsockname", WSAGetLastError());\r
2516 \r
2517                                                 a = (char *)&saTmpAddr.sin6_addr;\r
2518                                                 p = (char *)&saCtrlAddr.sin6_port;\r
2519                                         }\r
2520                                         else\r
2521                                         {\r
2522                                                 ReportWSError("listen", WSAGetLastError());\r
2523                                                 do_closesocket(listen_skt);\r
2524                                                 listen_skt = INVALID_SOCKET;\r
2525                                         }\r
2526                                 }\r
2527                                 else\r
2528                                 {\r
2529                                         ReportWSError("getsockname", WSAGetLastError());\r
2530                                         do_closesocket(listen_skt);\r
2531                                         listen_skt = INVALID_SOCKET;\r
2532                                 }\r
2533                         }\r
2534                         else\r
2535                         {\r
2536                                 ReportWSError("bind", WSAGetLastError());\r
2537                                 do_closesocket(listen_skt);\r
2538                                 listen_skt = INVALID_SOCKET;\r
2539                         }\r
2540 \r
2541                         if(listen_skt == INVALID_SOCKET)\r
2542                                 SetTaskMsg(MSGJPN030);\r
2543                 }\r
2544         }\r
2545         else\r
2546                 ReportWSError("socket create", WSAGetLastError());\r
2547 \r
2548         if(listen_skt != INVALID_SOCKET)\r
2549         {\r
2550 #define  UC(b)  (((int)b)&0xff)\r
2551                 // 同時接続対応\r
2552 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2553 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2554 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2555                 if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
2556                                 AddressToStringIPv6(Adrs, a),\r
2557                                 (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE)\r
2558                 {\r
2559                         SetTaskMsg(MSGJPN031);\r
2560                         do_closesocket(listen_skt);\r
2561                         listen_skt = INVALID_SOCKET;\r
2562                 }\r
2563 //              else\r
2564 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2565         }\r
2566 \r
2567         return(listen_skt);\r
2568 }\r
2569 \r
2570 \r
2571 /*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
2572 *\r
2573 *       Parameter\r
2574 *               なし\r
2575 *\r
2576 *       Return Value\r
2577 *               int ステータス\r
2578 *                       YES/NO\r
2579 *----------------------------------------------------------------------------*/\r
2580 \r
2581 int AskTryingConnect(void)\r
2582 {\r
2583         return(TryConnect);\r
2584 }\r
2585 \r
2586 \r
2587 #if 0\r
2588 ///*----- ブロッキングコールのフックコールバック --------------------------------\r
2589 //*\r
2590 //*     Parameter\r
2591 //*             なし\r
2592 //*\r
2593 //*     Return Value\r
2594 //*             BOOL FALSE\r
2595 //*----------------------------------------------------------------------------*/\r
2596 //\r
2597 //static BOOL CALLBACK BlkHookFnc(void)\r
2598 //{\r
2599 //      BackgrndMessageProc();\r
2600 //\r
2601 //      if(CancelFlg == YES)\r
2602 //      {\r
2603 //              SetTaskMsg(MSGJPN032);\r
2604 //              WSACancelBlockingCall();\r
2605 //              CancelFlg = NO;\r
2606 //      }\r
2607 //      return(FALSE);\r
2608 //}\r
2609 #endif\r
2610 \r
2611 \r
2612 \r
2613 /*----- SOCKS5のコマンドパケットを作成する ------------------------------------\r
2614 *\r
2615 *       Parameter\r
2616 *               SOCKS5REQUEST *Packet : パケットを作成するワーク\r
2617 *               char Cmd : コマンド\r
2618 *               int ValidIP : IPアドレスを使うかどうか(YES/NO)\r
2619 *               ulong IP : IPアドレス\r
2620 *               char *Host : ホスト名\r
2621 *               ushort Port : ポート\r
2622 *\r
2623 *       Return Value\r
2624 *               int コマンドパケットの長さ\r
2625 *----------------------------------------------------------------------------*/\r
2626 \r
2627 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port)\r
2628 {\r
2629         uchar *Pos;\r
2630         int Len;\r
2631         int TotalLen;\r
2632 \r
2633         Pos = (uchar *)Packet;\r
2634         Pos += SOCKS5REQUEST_SIZE;\r
2635         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
2636 \r
2637         Packet->Ver = SOCKS5_VER;\r
2638         Packet->Cmd = Cmd;\r
2639         Packet->Rsv = 0;\r
2640         if(ValidIP == YES)\r
2641         {\r
2642                 /* IPアドレスを指定 */\r
2643                 Packet->Type = SOCKS5_ADRS_IPV4;\r
2644                 *((ulong *)Pos) = IP;\r
2645                 Pos += 4;\r
2646                 TotalLen += 4;\r
2647         }\r
2648         else\r
2649         {\r
2650                 /* ホスト名を指定 */\r
2651                 Packet->Type = SOCKS5_ADRS_NAME;\r
2652                 Len = strlen(Host);\r
2653                 *Pos++ = Len;\r
2654                 strcpy(Pos, Host);\r
2655                 Pos += Len;\r
2656                 TotalLen += Len + 1;\r
2657         }\r
2658         *((ushort *)Pos) = Port;\r
2659 \r
2660         return(TotalLen);\r
2661 }\r
2662 \r
2663 \r
2664 // IPv6対応\r
2665 static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
2666 {\r
2667         uchar *Pos;\r
2668         int Len;\r
2669         int TotalLen;\r
2670 \r
2671         Pos = (uchar *)Packet;\r
2672         Pos += SOCKS5REQUEST_SIZE;\r
2673         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
2674 \r
2675         Packet->Ver = SOCKS5_VER;\r
2676         Packet->Cmd = Cmd;\r
2677         Packet->Rsv = 0;\r
2678         if(ValidIP == YES)\r
2679         {\r
2680                 /* IPアドレスを指定 */\r
2681                 Packet->Type = SOCKS5_ADRS_IPV6;\r
2682                 memcpy(Pos, IP, 16);\r
2683                 Pos += 16;\r
2684                 TotalLen += 16;\r
2685         }\r
2686         else\r
2687         {\r
2688                 /* ホスト名を指定 */\r
2689                 Packet->Type = SOCKS5_ADRS_NAME;\r
2690                 Len = strlen(Host);\r
2691                 *Pos++ = Len;\r
2692                 strcpy(Pos, Host);\r
2693                 Pos += Len;\r
2694                 TotalLen += Len + 1;\r
2695         }\r
2696         *((ushort *)Pos) = Port;\r
2697 \r
2698         return(TotalLen);\r
2699 }\r
2700 \r
2701 \r
2702 /*----- SOCKSのコマンドを送る -------------------------------------------------\r
2703 *\r
2704 *       Parameter\r
2705 *               SOCKET Socket : ソケット\r
2706 *               void *Data : 送るデータ\r
2707 *               int Size : サイズ\r
2708 *\r
2709 *       Return Value\r
2710 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2711 *----------------------------------------------------------------------------*/\r
2712 \r
2713 static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork)\r
2714 {\r
2715         int Ret;\r
2716 \r
2717         Ret = SendData(Socket, (char *)Data, Size, 0, CancelCheckWork);\r
2718 \r
2719         if(Ret != FFFTP_SUCCESS)\r
2720                 SetTaskMsg(MSGJPN033, *((short *)Data));\r
2721 \r
2722         return(Ret);\r
2723 }\r
2724 \r
2725 \r
2726 /*----- SOCKS5のコマンドに対するリプライパケットを受信する --------------------\r
2727 *\r
2728 *       Parameter\r
2729 *               SOCKET Socket : ソケット\r
2730 *               SOCKS5REPLY *Packet : パケット\r
2731 *\r
2732 *       Return Value\r
2733 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2734 *----------------------------------------------------------------------------*/\r
2735 \r
2736 // 同時接続対応\r
2737 //static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet)\r
2738 static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork)\r
2739 {\r
2740         uchar *Pos;\r
2741         int Len;\r
2742         int Ret;\r
2743 \r
2744         Pos = (uchar *)Packet;\r
2745         Pos += SOCKS5REPLY_SIZE;\r
2746 \r
2747         // 同時接続対応\r
2748 //      if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS)\r
2749         if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, CancelCheckWork)) == FFFTP_SUCCESS)\r
2750         {\r
2751                 if(Packet->Type == SOCKS5_ADRS_IPV4)\r
2752                         Len = 4 + 2;\r
2753                 else if(Packet->Type == SOCKS5_ADRS_IPV6)\r
2754                         Len = 16 + 2;\r
2755                 else\r
2756                 {\r
2757                         // 同時接続対応\r
2758 //                      if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS)\r
2759                         if((Ret = ReadNchar(Socket, (char *)Pos, 1, CancelCheckWork)) == FFFTP_SUCCESS)\r
2760                         {\r
2761                                 Len = *Pos + 2;\r
2762                                 Pos++;\r
2763                         }\r
2764                 }\r
2765 \r
2766                 if(Ret == FFFTP_SUCCESS)\r
2767                         // 同時接続対応\r
2768 //                      Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg);\r
2769                         Ret = ReadNchar(Socket, (char *)Pos, Len, CancelCheckWork);\r
2770         }\r
2771 \r
2772         if(Ret != FFFTP_SUCCESS)\r
2773                 SetTaskMsg(MSGJPN034);\r
2774 \r
2775         return(Ret);\r
2776 }\r
2777 \r
2778 \r
2779 /*----- SOCKS4のコマンドに対するリプライパケットを受信する --------------------\r
2780 *\r
2781 *       Parameter\r
2782 *               SOCKET Socket : ソケット\r
2783 *               SOCKS5REPLY *Packet : パケット\r
2784 *\r
2785 *       Return Value\r
2786 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2787 *----------------------------------------------------------------------------*/\r
2788 \r
2789 // 同時接続対応\r
2790 //static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet)\r
2791 static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork)\r
2792 {\r
2793         int Ret;\r
2794 \r
2795         // 同時接続対応\r
2796 //      Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg);\r
2797         Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, CancelCheckWork);\r
2798 \r
2799         if(Ret != FFFTP_SUCCESS)\r
2800                 DoPrintf(MSGJPN035);\r
2801 \r
2802         return(Ret);\r
2803 }\r
2804 \r
2805 \r
2806 /*----- SOCKS5の認証を行う ----------------------------------------------------\r
2807 *\r
2808 *       Parameter\r
2809 *               SOCKET Socket : ソケット\r
2810 *\r
2811 *       Return Value\r
2812 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2813 *----------------------------------------------------------------------------*/\r
2814 \r
2815 static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork)\r
2816 {\r
2817         int Ret;\r
2818         SOCKS5METHODREQUEST Socks5Method;\r
2819         SOCKS5METHODREPLY Socks5MethodReply;\r
2820         SOCKS5USERPASSSTATUS Socks5Status;\r
2821         char Buf[USER_NAME_LEN + PASSWORD_LEN + 4];\r
2822         int Len;\r
2823         int Len2;\r
2824 \r
2825         Ret = FFFTP_SUCCESS;\r
2826         Socks5Method.Ver = SOCKS5_VER;\r
2827         Socks5Method.Num = 1;\r
2828         if(FwallType == FWALL_SOCKS5_NOAUTH)\r
2829                 Socks5Method.Methods[0] = SOCKS5_AUTH_NONE;\r
2830         else\r
2831                 Socks5Method.Methods[0] = SOCKS5_AUTH_USER;\r
2832 \r
2833         // 同時接続対応\r
2834 //      if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2835 //         (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
2836 //         (Socks5MethodReply.Method == (uchar)0xFF))\r
2837         if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2838            (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2839            (Socks5MethodReply.Method == (uchar)0xFF))\r
2840         {\r
2841                 SetTaskMsg(MSGJPN036);\r
2842                 Ret = FFFTP_FAIL;\r
2843         }\r