OSDN Git Service

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