OSDN Git Service

Compile executable files.
[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 //              AskRemoteCurDir(Path, FMAX_PATH);\r
1110 //              DoCWD(Path, YES, YES, YES);\r
1111                 Sts = FFFTP_SUCCESS;\r
1112         }\r
1113         else\r
1114                 SoundPlay(SND_ERROR);\r
1115 \r
1116 //      EnableUserOpe();\r
1117         return(Sts);\r
1118 }\r
1119 \r
1120 \r
1121 /*----- 回線の再接続 ----------------------------------------------------------\r
1122 *\r
1123 *       Parameter\r
1124 *               SOCKET *Skt : 接続したソケットを返すワーク\r
1125 *\r
1126 *       Return Value\r
1127 *               int ステータス\r
1128 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1129 *----------------------------------------------------------------------------*/\r
1130 \r
1131 static int ReConnectSkt(SOCKET *Skt)\r
1132 {\r
1133         char Path[FMAX_PATH+1];\r
1134         int Sts;\r
1135 \r
1136         Sts = FFFTP_FAIL;\r
1137 \r
1138         SetTaskMsg(MSGJPN003);\r
1139 \r
1140         DisableUserOpe();\r
1141         /* 現在のソケットは切断 */\r
1142         if(*Skt != INVALID_SOCKET)\r
1143                 do_closesocket(*Skt);\r
1144         /* 再接続 */\r
1145         // 暗号化通信対応\r
1146         // 同時接続対応\r
1147 //      if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
1148         if((*Skt = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg)) != INVALID_SOCKET)\r
1149         {\r
1150                 AskRemoteCurDir(Path, FMAX_PATH);\r
1151                 DoCWD(Path, YES, YES, YES);\r
1152                 Sts = FFFTP_SUCCESS;\r
1153         }\r
1154         else\r
1155                 SoundPlay(SND_ERROR);\r
1156 \r
1157         EnableUserOpe();\r
1158         return(Sts);\r
1159 }\r
1160 \r
1161 \r
1162 /*----- コマンドコントロールソケットを返す ------------------------------------\r
1163 *\r
1164 *       Parameter\r
1165 *               なし\r
1166 *\r
1167 *       Return Value\r
1168 *               SOCKET コマンドコントロールソケット\r
1169 *----------------------------------------------------------------------------*/\r
1170 \r
1171 SOCKET AskCmdCtrlSkt(void)\r
1172 {\r
1173         return(CmdCtrlSocket);\r
1174 }\r
1175 \r
1176 \r
1177 /*----- 転送コントロールソケットを返す ----------------------------------------\r
1178 *\r
1179 *       Parameter\r
1180 *               なし\r
1181 *\r
1182 *       Return Value\r
1183 *               SOCKET 転送コントロールソケット\r
1184 *----------------------------------------------------------------------------*/\r
1185 \r
1186 SOCKET AskTrnCtrlSkt(void)\r
1187 {\r
1188         return(TrnCtrlSocket);\r
1189 }\r
1190 \r
1191 \r
1192 /*----- コマンド/転送コントロールソケットの共有を解除 ------------------------\r
1193 *\r
1194 *       Parameter\r
1195 *               なし\r
1196 *\r
1197 *       Return Value\r
1198 *               なし\r
1199 *----------------------------------------------------------------------------*/\r
1200 \r
1201 void SktShareProh(void)\r
1202 {\r
1203         if(CmdCtrlSocket == TrnCtrlSocket)\r
1204         {\r
1205 \r
1206 //SetTaskMsg("############### SktShareProh");\r
1207 \r
1208                 // 同時接続対応\r
1209 //              CmdCtrlSocket = INVALID_SOCKET;\r
1210 //              ReConnectSkt(&CmdCtrlSocket);\r
1211                 if(CurHost.ReuseCmdSkt == YES)\r
1212                 {\r
1213                         CmdCtrlSocket = INVALID_SOCKET;\r
1214                         ReConnectSkt(&CmdCtrlSocket);\r
1215                 }\r
1216         }\r
1217         return;\r
1218 }\r
1219 \r
1220 \r
1221 /*----- コマンド/転送コントロールソケットの共有が解除されているかチェック ----\r
1222 *\r
1223 *       Parameter\r
1224 *               なし\r
1225 *\r
1226 *       Return Value\r
1227 *               int ステータス\r
1228 *                       YES=共有解除/NO=共有\r
1229 *----------------------------------------------------------------------------*/\r
1230 \r
1231 int AskShareProh(void)\r
1232 {\r
1233         int Sts;\r
1234 \r
1235         Sts = YES;\r
1236         // 同時接続対応\r
1237 //      if(CmdCtrlSocket == TrnCtrlSocket)\r
1238         if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET)\r
1239                 Sts = NO;\r
1240 \r
1241         return(Sts);\r
1242 }\r
1243 \r
1244 \r
1245 /*----- ホストから切断 --------------------------------------------------------\r
1246 *\r
1247 *       Parameter\r
1248 *               なし\r
1249 *\r
1250 *       Return Value\r
1251 *               なし\r
1252 *----------------------------------------------------------------------------*/\r
1253 \r
1254 void DisconnectProc(void)\r
1255 {\r
1256 \r
1257 //SetTaskMsg("############### Disconnect Cmd=%x, Trn=%x", CmdCtrlSocket,TrnCtrlSocket);\r
1258 \r
1259         if((CmdCtrlSocket != INVALID_SOCKET) && (CmdCtrlSocket != TrnCtrlSocket))\r
1260         {\r
1261                 DoQUIT(CmdCtrlSocket);\r
1262                 DoClose(CmdCtrlSocket);\r
1263         }\r
1264 \r
1265         if(TrnCtrlSocket != INVALID_SOCKET)\r
1266         {\r
1267                 DoQUIT(TrnCtrlSocket);\r
1268                 DoClose(TrnCtrlSocket);\r
1269 \r
1270                 SaveCurrentSetToHistory();\r
1271 \r
1272                 EraseRemoteDirForWnd();\r
1273                 SetTaskMsg(MSGJPN004);\r
1274         }\r
1275 \r
1276         TrnCtrlSocket = INVALID_SOCKET;\r
1277         CmdCtrlSocket = INVALID_SOCKET;\r
1278 \r
1279         DispWindowTitle();\r
1280         MakeButtonsFocus();\r
1281         ClearBookMark();\r
1282 \r
1283         return;\r
1284 }\r
1285 \r
1286 \r
1287 /*----- ソケットが強制切断されたときの処理 ------------------------------------\r
1288 *\r
1289 *       Parameter\r
1290 *               なし\r
1291 *\r
1292 *       Return Value\r
1293 *               なし\r
1294 *----------------------------------------------------------------------------*/\r
1295 \r
1296 void DisconnectSet(void)\r
1297 {\r
1298         CmdCtrlSocket = INVALID_SOCKET;\r
1299         TrnCtrlSocket = INVALID_SOCKET;\r
1300 \r
1301         EraseRemoteDirForWnd();\r
1302         DispWindowTitle();\r
1303         MakeButtonsFocus();\r
1304         SetTaskMsg(MSGJPN005);\r
1305         return;\r
1306 }\r
1307 \r
1308 \r
1309 /*----- ホストに接続中かどうかを返す ------------------------------------------\r
1310 *\r
1311 *       Parameter\r
1312 *               なし\r
1313 *\r
1314 *       Return Value\r
1315 *               int ステータス (YES/NO)\r
1316 *----------------------------------------------------------------------------*/\r
1317 \r
1318 int AskConnecting(void)\r
1319 {\r
1320         int Sts;\r
1321 \r
1322         Sts = NO;\r
1323         if(TrnCtrlSocket != INVALID_SOCKET)\r
1324                 Sts = YES;\r
1325 \r
1326         return(Sts);\r
1327 }\r
1328 \r
1329 \r
1330 #if defined(HAVE_TANDEM)\r
1331 /*----- 接続している本当のホストのホストタイプを返す --------------------------\r
1332 *\r
1333 *       Parameter\r
1334 *               なし\r
1335 *\r
1336 *       Return Value\r
1337 *               char *ファイル名/オプション\r
1338 *----------------------------------------------------------------------------*/\r
1339 \r
1340 int AskRealHostType(void)\r
1341 {\r
1342         if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
1343                 CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
1344 \r
1345         return(CurHost.HostType);\r
1346 }\r
1347 \r
1348 /*----- OSS ファイルシステムにアクセスしているかどうかのフラグを変更する ------\r
1349 *\r
1350 *       Parameter\r
1351 *               int ステータス (YES/NO)\r
1352 *\r
1353 *       Return Value\r
1354 *               int ステータス (YES/NO)\r
1355 *----------------------------------------------------------------------------*/\r
1356 \r
1357 int SetOSS(int wkOss)\r
1358 {\r
1359         Oss = wkOss;\r
1360         return(Oss);\r
1361 }\r
1362 \r
1363 /*----- OSS ファイルシステムにアクセスしているかどうかを返す ------------------\r
1364 *\r
1365 *       Parameter\r
1366 *               なし\r
1367 *\r
1368 *       Return Value\r
1369 *               int ステータス (YES/NO)\r
1370 *----------------------------------------------------------------------------*/\r
1371 \r
1372 int AskOSS(void)\r
1373 {\r
1374         return(Oss);\r
1375 }\r
1376 #endif /* HAVE_TANDEM */\r
1377 \r
1378 \r
1379 /*----- ホストへ接続する ------------------------------------------------------\r
1380 *\r
1381 *       Parameter\r
1382 *               char *Host : ホスト名\r
1383 *               char *User : ユーザ名\r
1384 *               char *Pass : パスワード\r
1385 *               char *Acct : アカウント\r
1386 *               int Port : ポート\r
1387 *               int Fwall : FireWallを使うかどうか (YES/NO)\r
1388 *               int SavePass : パスワードを再入力した時に保存するかどうか (YES/NO)\r
1389 *               int Security : セキュリティ (SECURITY_xxx, MDx)\r
1390 *\r
1391 *       Return Value\r
1392 *               SOCKET ソケット\r
1393 *\r
1394 *       Note\r
1395 *               ホスト名、ユーザ名、パスワードが指定されていなかったときは、接続に使用\r
1396 *               したものをコピーしてかえす\r
1397 *                       char *Host : ホスト名\r
1398 *                       char *User : ユーザ名\r
1399 *                       char *Pass : パスワード\r
1400 *                       char *Acct : アカウント\r
1401 *\r
1402 *               FireWallは次のように動作する\r
1403 *                       TYPE1   Connect fire → USER user(f) → PASS pass(f) → SITE host → USER user(h) →      PASS pass(h) → ACCT acct\r
1404 *                       TYPE2   Connect fire → USER user(f) → PASS pass(f) →              USER user(h)@host → PASS pass(h) → ACCT acct\r
1405 *                       TYPE3   Connect fire →                                              USER user(h)@host → PASS pass(h) → ACCT acct\r
1406 *                       TYPE4   Connect fire →                                 OPEN host → USER user(h) →      PASS pass(h) → ACCT acct\r
1407 *                       TYPE5   SOCKS4\r
1408 *                       none    Connect host →                                              USER user(h) →      PASS pass(h) → ACCT acct\r
1409 *----------------------------------------------------------------------------*/\r
1410 \r
1411 // 暗号化通信対応\r
1412 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
1413 {\r
1414         int Sts;\r
1415         int Flg;\r
1416         int Anony;\r
1417         SOCKET ContSock;\r
1418         char Buf[1024];\r
1419         char Reply[1024];\r
1420         int Continue;\r
1421         int ReInPass;\r
1422         char *Tmp;\r
1423         int HostPort;\r
1424         static const char *SiteTbl[4] = { "SITE", "site", "OPEN", "open" };\r
1425         char TmpBuf[ONELINE_BUF_SIZE];\r
1426         struct linger LingerOpt;\r
1427 \r
1428         // 暗号化通信対応\r
1429         ContSock = INVALID_SOCKET;\r
1430 \r
1431         if(CryptMode == CRYPT_NONE || CryptMode == CRYPT_FTPES || CryptMode == CRYPT_FTPIS)\r
1432         {\r
1433                 if(Fwall == YES)\r
1434                         Fwall = FwallType;\r
1435                 else\r
1436                         Fwall = FWALL_NONE;\r
1437 \r
1438                 TryConnect = YES;\r
1439                 // 暗号化通信対応\r
1440 //              CancelFlg = NO;\r
1441 #if 0\r
1442 //              WSASetBlockingHook(BlkHookFnc);\r
1443 #endif\r
1444 \r
1445                 ContSock = INVALID_SOCKET;\r
1446 \r
1447                 HostPort = Port;\r
1448                 Tmp = Host;\r
1449                 if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1450                    (Fwall == FWALL_SIDEWINDER) ||\r
1451                    (Fwall == FWALL_FU_FP))\r
1452                 {\r
1453                         Tmp = FwallHost;\r
1454                         Port = FwallPort;\r
1455                 }\r
1456 \r
1457                 if(strlen(Tmp) != 0)\r
1458                 {\r
1459                         // 同時接続対応\r
1460 //                      if((ContSock = connectsock(Tmp, Port, "", &CancelFlg)) != INVALID_SOCKET)\r
1461                         if((ContSock = connectsock(Tmp, Port, "", CancelCheckWork)) != INVALID_SOCKET)\r
1462                         {\r
1463                                 // バッファを無効\r
1464 #ifdef DISABLE_CONTROL_NETWORK_BUFFERS\r
1465                                 int BufferSize = 0;\r
1466                                 setsockopt(ContSock, SOL_SOCKET, SO_SNDBUF, (char*)&BufferSize, sizeof(int));\r
1467                                 setsockopt(ContSock, SOL_SOCKET, SO_RCVBUF, (char*)&BufferSize, sizeof(int));\r
1468 #endif\r
1469                                 // FTPIS対応\r
1470 //                              while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM)\r
1471 //                                      ;\r
1472                                 if(CryptMode == CRYPT_FTPIS)\r
1473                                 {\r
1474                                         if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork))\r
1475                                         {\r
1476                                                 while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
1477                                                         ;\r
1478                                         }\r
1479                                         else\r
1480                                                 Sts = FTP_ERROR;\r
1481                                 }\r
1482                                 else\r
1483                                 {\r
1484                                         while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
1485                                                 ;\r
1486                                 }\r
1487 \r
1488                                 if(Sts == FTP_COMPLETE)\r
1489                                 {\r
1490                                         Flg = 1;\r
1491                                         if(setsockopt(ContSock, SOL_SOCKET, SO_OOBINLINE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1492                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1493                                         // データ転送用ソケットのTCP遅延転送が無効されているので念のため\r
1494                                         if(setsockopt(ContSock, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1495                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1496 //#pragma aaa\r
1497                                         Flg = 1;\r
1498                                         if(setsockopt(ContSock, SOL_SOCKET, SO_KEEPALIVE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1499                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1500                                         LingerOpt.l_onoff = 1;\r
1501                                         LingerOpt.l_linger = 90;\r
1502                                         if(setsockopt(ContSock, SOL_SOCKET, SO_LINGER, (LPSTR)&LingerOpt, sizeof(LingerOpt)) == SOCKET_ERROR)\r
1503                                                 ReportWSError("setsockopt", WSAGetLastError());\r
1504 ///////\r
1505 \r
1506 \r
1507                                         /*===== 認証を行なう =====*/\r
1508 \r
1509                                         Sts = FTP_COMPLETE;\r
1510                                         if((Fwall == FWALL_FU_FP_SITE) ||\r
1511                                            (Fwall == FWALL_FU_FP_USER) ||\r
1512                                            (Fwall == FWALL_FU_FP))\r
1513                                         {\r
1514                                                 // 同時接続対応\r
1515 //                                              if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
1516                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
1517                                                 {\r
1518                                                         CheckOneTimePassword(FwallPass, Reply, FwallSecurity);\r
1519                                                         // 同時接続対応\r
1520 //                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1521                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1522                                                 }\r
1523                                         }\r
1524                                         else if(Fwall == FWALL_SIDEWINDER)\r
1525                                         {\r
1526                                                 // 同時接続対応\r
1527 //                                              Sts = command(ContSock, Reply, &CancelFlg, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
1528                                                 Sts = command(ContSock, Reply, CancelCheckWork, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
1529                                         }\r
1530                                         if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
1531                                         {\r
1532                                                 SetTaskMsg(MSGJPN006);\r
1533                                                 DoClose(ContSock);\r
1534                                                 ContSock = INVALID_SOCKET;\r
1535                                         }\r
1536                                         else\r
1537                                         {\r
1538                                                 if((Fwall == FWALL_FU_FP_SITE) || (Fwall == FWALL_OPEN))\r
1539                                                 {\r
1540                                                         Flg = 0;\r
1541                                                         if(Fwall == FWALL_OPEN)\r
1542                                                                 Flg = 2;\r
1543                                                         if(FwallLower == YES)\r
1544                                                                 Flg++;\r
1545 \r
1546                                                         if(HostPort == PORT_NOR)\r
1547                                                                 // 同時接続対応\r
1548 //                                                              Sts = command(ContSock, NULL, &CancelFlg, "%s %s", SiteTbl[Flg], Host) / 100;\r
1549                                                                 Sts = command(ContSock, NULL, CancelCheckWork, "%s %s", SiteTbl[Flg], Host) / 100;\r
1550                                                         else\r
1551                                                                 // 同時接続対応\r
1552 //                                                              Sts = command(ContSock, NULL, &CancelFlg, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
1553                                                                 Sts = command(ContSock, NULL, CancelCheckWork, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
1554                                                 }\r
1555 \r
1556                                                 if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
1557                                                 {\r
1558                                                         SetTaskMsg(MSGJPN007, Host);\r
1559                                                         DoClose(ContSock);\r
1560                                                         ContSock = INVALID_SOCKET;\r
1561                                                 }\r
1562                                                 else\r
1563                                                 {\r
1564                                                         Anony = NO;\r
1565                                                         // 同時接続対応\r
1566 //                                                      if((strlen(User) != 0) || \r
1567 //                                                         (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1568                                                         if((strlen(User) != 0) || \r
1569                                                            ((HostData->NoDisplayUI == NO) && (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1570                                                         {\r
1571                                                                 if(Anony == YES)\r
1572                                                                 {\r
1573                                                                         strcpy(User, "anonymous");\r
1574                                                                         strcpy(Pass, UserMailAdrs);\r
1575                                                                 }\r
1576 \r
1577                                                                 if((Fwall == FWALL_FU_FP_USER) || (Fwall == FWALL_USER))\r
1578                                                                 {\r
1579                                                                         if(HostPort == PORT_NOR)\r
1580                                                                                 sprintf(Buf, "%s%c%s", User, FwallDelimiter, Host);\r
1581                                                                         else\r
1582                                                                                 sprintf(Buf, "%s%c%s %d", User, FwallDelimiter, Host, HostPort);\r
1583                                                                 }\r
1584                                                                 else\r
1585                                                                         strcpy(Buf, User);\r
1586 \r
1587                                                                 // FTPES対応\r
1588                                                                 if(CryptMode == CRYPT_FTPES)\r
1589                                                                 {\r
1590                                                                         if(IsOpenSSLLoaded() && (Sts = command(ContSock, Reply, CancelCheckWork, "AUTH TLS")) == 234)\r
1591                                                                         {\r
1592                                                                                 if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork))\r
1593                                                                                 {\r
1594                                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1595                                                                                         {\r
1596                                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1597                                                                                                 {\r
1598                                                                                                 }\r
1599                                                                                                 else\r
1600                                                                                                         Sts = FTP_ERROR;\r
1601                                                                                         }\r
1602                                                                                         else\r
1603                                                                                                 Sts = FTP_ERROR;\r
1604                                                                                 }\r
1605                                                                                 else\r
1606                                                                                         Sts = FTP_ERROR;\r
1607                                                                         }\r
1608                                                                         else\r
1609                                                                                 Sts = FTP_ERROR;\r
1610                                                                 }\r
1611 \r
1612                                                                 // FTPIS対応\r
1613                                                                 // "PBSZ 0"と"PROT P"は黙示的に設定されているはずだが念のため\r
1614                                                                 if(CryptMode == CRYPT_FTPIS)\r
1615                                                                 {\r
1616                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
1617                                                                         {\r
1618                                                                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
1619                                                                                 {\r
1620                                                                                 }\r
1621                                                                         }\r
1622                                                                 }\r
1623 \r
1624                                                                 ReInPass = NO;\r
1625                                                                 do\r
1626                                                                 {\r
1627                                                                         // FTPES対応\r
1628                                                                         if(Sts == FTP_ERROR)\r
1629                                                                                 break;\r
1630                                                                         Continue = NO;\r
1631                                                                         // 同時接続対応\r
1632 //                                                                      if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1633                                                                         if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
1634                                                                         {\r
1635                                                                                 // 同時接続対応\r
1636 //                                                                              if((strlen(Pass) != 0) || \r
1637 //                                                                                 (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1638                                                                                 if((strlen(Pass) != 0) || \r
1639                                                                                    ((HostData->NoDisplayUI == NO) && (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1640                                                                                 {\r
1641                                                                                         CheckOneTimePassword(Pass, Reply, Security);\r
1642 \r
1643                                                                                         /* パスワードがスペース1個の時はパスワードの実体なしとする */\r
1644                                                                                         if(strcmp(Reply, " ") == 0)\r
1645                                                                                                 strcpy(Reply, "");\r
1646 \r
1647                                                                                         // 同時接続対応\r
1648 //                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
1649                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
1650                                                                                         if(Sts == FTP_ERROR)\r
1651                                                                                         {\r
1652                                                                                                 strcpy(Pass, "");\r
1653                                                                                                 // 同時接続対応\r
1654 //                                                                                              if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1655                                                                                                 if(HostData->NoDisplayUI == NO && InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
1656                                                                                                         Continue = YES;\r
1657                                                                                                 else\r
1658                                                                                                         DoPrintf("No password specified.");\r
1659                                                                                                 ReInPass = YES;\r
1660                                                                                         }\r
1661                                                                                         else if(Sts == FTP_CONTINUE)\r
1662                                                                                         {\r
1663                                                                                                 // 同時接続対応\r
1664 //                                                                                              if((strlen(Acct) != 0) || \r
1665 //                                                                                                 (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
1666                                                                                                 if((strlen(Acct) != 0) || \r
1667                                                                                                    ((HostData->NoDisplayUI == NO) && (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
1668                                                                                                 {\r
1669                                                                                                         // 同時接続対応\r
1670 //                                                                                                      Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100;\r
1671                                                                                                         Sts = command(ContSock, NULL, CancelCheckWork, "ACCT %s", Acct) / 100;\r
1672                                                                                                 }\r
1673                                                                                                 else\r
1674                                                                                                         DoPrintf("No account specified");\r
1675                                                                                         }\r
1676                                                                                 }\r
1677                                                                                 else\r
1678                                                                                 {\r
1679                                                                                         Sts = FTP_ERROR;\r
1680                                                                                         DoPrintf("No password specified.");\r
1681                                                                                 }\r
1682                                                                         }\r
1683                                                                         // FTPES対応\r
1684                                                                         if(Continue == YES)\r
1685                                                                                 Sts = FTP_COMPLETE;\r
1686                                                                 }\r
1687                                                                 while(Continue == YES);\r
1688                                                         }\r
1689                                                         else\r
1690                                                         {\r
1691                                                                 Sts = FTP_ERROR;\r
1692                                                                 DoPrintf("No user name specified");\r
1693                                                         }\r
1694 \r
1695                                                         if(Sts != FTP_COMPLETE)\r
1696                                                         {\r
1697                                                                 SetTaskMsg(MSGJPN008, Host);\r
1698                                                                 DoClose(ContSock);\r
1699                                                                 ContSock = INVALID_SOCKET;\r
1700                                                         }\r
1701                                                         else if((SavePass == YES) && (ReInPass == YES))\r
1702                                                         {\r
1703                                                                 // 同時接続対応\r
1704 //                                                              if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1705                                                                 if(HostData->NoDisplayUI == NO && DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
1706                                                                         SetHostPassword(AskCurrentHost(), Pass);\r
1707                                                         }\r
1708                                                 }\r
1709                                         }\r
1710                                 }\r
1711                                 else\r
1712                                 {\r
1713 //#pragma aaa\r
1714                                         SetTaskMsg(MSGJPN009/*"接続できません(1) %x", ContSock*/);\r
1715                                         DoClose(ContSock);\r
1716                                         ContSock = INVALID_SOCKET;\r
1717                                 }\r
1718                         }\r
1719                 }\r
1720                 else\r
1721                 {\r
1722 \r
1723                         if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
1724                            (Fwall == FWALL_FU_FP))\r
1725                                 SetTaskMsg(MSGJPN010);\r
1726                         else\r
1727                                 SetTaskMsg(MSGJPN011);\r
1728                 }\r
1729 \r
1730 #if 0\r
1731 //              WSAUnhookBlockingHook();\r
1732 #endif\r
1733                 TryConnect = NO;\r
1734 \r
1735                 // FEAT対応\r
1736                 // ホストの機能を確認\r
1737                 if(ContSock != INVALID_SOCKET)\r
1738                 {\r
1739                         if((Sts = command(ContSock, Reply, CancelCheckWork, "FEAT")) == 211)\r
1740                         {\r
1741                                 // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用\r
1742                                 // UTF-8対応\r
1743                                 if(strstr(Reply, " UTF8 "))\r
1744                                         HostData->Feature |= FEATURE_UTF8;\r
1745                                 // MLST対応\r
1746                                 if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD "))\r
1747                                         HostData->Feature |= FEATURE_MLSD;\r
1748                                 // IPv6対応\r
1749                                 if(strstr(Reply, " EPRT ") || strstr(Reply, " EPSV "))\r
1750                                         HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV;\r
1751                         }\r
1752                         // UTF-8対応\r
1753                         if(HostData->CurNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
1754                         {\r
1755                                 if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200)\r
1756                                         HostData->CurNameKanjiCode = KANJI_UTF8N;\r
1757                         }\r
1758                 }\r
1759         }\r
1760         else if(CryptMode == CRYPT_SFTP)\r
1761         {\r
1762                 // TODO:\r
1763                 // テストコード\r
1764                 // ログイン成功を確認\r
1765 #define strrcmp(_Str1, _Str2) (strcmp(strstr(_Str1, _Str2) ? strstr(_Str1, _Str2) : "", _Str2))\r
1766                 size_t r;\r
1767                 ContSock = SFTP_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
1768                 SFTP_SetTimeoutCallback(ContSock, SSLTimeoutCallback);\r
1769                 while(1)\r
1770                 {\r
1771                         r = SFTP_recv(ContSock, Reply, 1024, 0);\r
1772                         if(r == SOCKET_ERROR)\r
1773                                 break;\r
1774                         if(r <= 0)\r
1775                                 continue;\r
1776                         Reply[r] = '\0';\r
1777                         SetTaskMsg("%s", Reply);\r
1778                         if(strrcmp(Reply, "psftp> ") == 0)\r
1779                                 break;\r
1780                 }\r
1781                 r = SFTP_send(ContSock, "open \"", strlen("open \""), 0);\r
1782                 r = SFTP_send(ContSock, Host, strlen(Host), 0);\r
1783                 r = SFTP_send(ContSock, "\"\r\n", strlen("\"\r\n"), 0);\r
1784                 while(1)\r
1785                 {\r
1786                         r = SFTP_recv(ContSock, Reply, 1024, 0);\r
1787                         if(r == SOCKET_ERROR)\r
1788                                 break;\r
1789                         if(r <= 0)\r
1790                                 continue;\r
1791                         Reply[r] = '\0';\r
1792                         SetTaskMsg("%s", Reply);\r
1793                         if(strrcmp(Reply, "Store key in cache? (y/n) ") == 0)\r
1794                         {\r
1795                                 r = SFTP_send(ContSock, "n\r\n", strlen("n\r\n"), 0);\r
1796                         }\r
1797                         if(strrcmp(Reply, "Update cached key? (y/n, Return cancels connection) ") == 0)\r
1798                         {\r
1799                                 r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
1800                         }\r
1801                         if(strrcmp(Reply, "login as: ") == 0)\r
1802                         {\r
1803                                 r = SFTP_send(ContSock, User, strlen(User), 0);\r
1804                                 r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
1805                         }\r
1806                         if(strrcmp(Reply, "password: ") == 0)\r
1807                         {\r
1808                                 r = SFTP_send(ContSock, Pass, strlen(Pass), 0);\r
1809                                 r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
1810                         }\r
1811                         if(strrcmp(Reply, "psftp> ") == 0)\r
1812                                 break;\r
1813                         Sleep(1);\r
1814                 }\r
1815                 SFTP_closesocket(ContSock);\r
1816                 ContSock = INVALID_SOCKET;\r
1817         }\r
1818 \r
1819         return(ContSock);\r
1820 }\r
1821 \r
1822 // 同時接続対応\r
1823 //static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security)\r
1824 static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
1825 {\r
1826         SOCKET ContSock;\r
1827         ContSock = INVALID_SOCKET;\r
1828         *CancelCheckWork = NO;\r
1829         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)\r
1830         {\r
1831                 SetTaskMsg(MSGJPN317);\r
1832                 if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1833                         HostData->CryptMode = CRYPT_SFTP;\r
1834         }\r
1835         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
1836         {\r
1837                 SetTaskMsg(MSGJPN316);\r
1838                 if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1839                         HostData->CryptMode = CRYPT_FTPIS;\r
1840         }\r
1841         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES)\r
1842         {\r
1843                 SetTaskMsg(MSGJPN315);\r
1844                 if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1845                         HostData->CryptMode = CRYPT_FTPES;\r
1846         }\r
1847         if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES)\r
1848         {\r
1849                 SetTaskMsg(MSGJPN314);\r
1850                 if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
1851                         HostData->CryptMode = CRYPT_NONE;\r
1852         }\r
1853         return ContSock;\r
1854 }\r
1855 \r
1856 \r
1857 /*----- ワンタイムパスワードのチェック ----------------------------------------\r
1858 *\r
1859 *       Parameter\r
1860 *               chat *Pass : パスワード/パスフレーズ\r
1861 *               char *Reply : USERコマンドを送ったあとのリプライ文字列\r
1862 *                                               /PASSコマンドで送るパスワードを返すバッファ\r
1863 *               int Type : タイプ (SECURITY_xxx, MDx)\r
1864 *\r
1865 *       Return Value\r
1866 *               int ステータス\r
1867 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1868 *\r
1869 *       Note\r
1870 *               ワンタイムパスワードでない時はPassをそのままReplyにコピー\r
1871 *----------------------------------------------------------------------------*/\r
1872 \r
1873 static int CheckOneTimePassword(char *Pass, char *Reply, int Type)\r
1874 {\r
1875         int Sts;\r
1876         char *Pos;\r
1877         int Seq;\r
1878         char Seed[MAX_SEED_LEN+1];\r
1879         int i;\r
1880 \r
1881         Sts = FFFTP_SUCCESS;\r
1882         Pos = NULL;\r
1883 \r
1884         if(Type == SECURITY_AUTO)\r
1885         {\r
1886                 if((Pos = stristr(Reply, "otp-md5")) != NULL)\r
1887                 {\r
1888                         Type = MD5;\r
1889                         SetTaskMsg(MSGJPN012);\r
1890                 }\r
1891                 else if((Pos = stristr(Reply, "otp-sha1")) != NULL)\r
1892                 {\r
1893                         Type = SHA1;\r
1894                         SetTaskMsg(MSGJPN013);\r
1895                 }\r
1896                 else if(((Pos = stristr(Reply, "otp-md4")) != NULL) || ((Pos = stristr(Reply, "s/key")) != NULL))\r
1897                 {\r
1898                         Type = MD4;\r
1899                         SetTaskMsg(MSGJPN014);\r
1900                 }\r
1901         }\r
1902         else\r
1903                 Pos = GetNextField(Reply);\r
1904 \r
1905         if((Type == MD4) || (Type == MD5) || (Type == SHA1))\r
1906         {\r
1907                 /* シーケンス番号を見つけるループ */\r
1908                 DoPrintf("Analize OTP");\r
1909                 DoPrintf("%s", Pos);\r
1910                 Sts = FFFTP_FAIL;\r
1911                 while((Pos = GetNextField(Pos)) != NULL)\r
1912                 {\r
1913                         if(IsDigit(*Pos))\r
1914                         {\r
1915                                 Seq = atoi(Pos);\r
1916                                 DoPrintf("Sequence=%d", Seq);\r
1917 \r
1918                                 /* Seed */\r
1919                                 if((Pos = GetNextField(Pos)) != NULL)\r
1920                                 {\r
1921                                         if(GetOneField(Pos, Seed, MAX_SEED_LEN) == FFFTP_SUCCESS)\r
1922                                         {\r
1923                                                 /* Seedは英数字のみ有効とする */\r
1924                                                 for(i = strlen(Seed)-1; i >= 0; i--)\r
1925                                                 {\r
1926                                                         if((IsAlpha(Seed[i]) == 0) && (IsDigit(Seed[i]) == 0))\r
1927                                                                 Seed[i] = NUL;\r
1928                                                 }\r
1929                                                 if(strlen(Seed) > 0)\r
1930                                                 {\r
1931                                                         DoPrintf("Seed=%s", Seed);\r
1932                                                         Make6WordPass(Seq, Seed, Pass, Type, Reply);\r
1933                                                         DoPrintf("Response=%s", Reply);\r
1934 \r
1935                                                         /* シーケンス番号のチェックと警告 */\r
1936                                                         if(Seq <= 10)\r
1937                                                                 DialogBox(GetFtpInst(), MAKEINTRESOURCE(otp_notify_dlg), GetMainHwnd(), ExeEscDialogProc);\r
1938 \r
1939                                                         Sts = FFFTP_SUCCESS;\r
1940                                                 }\r
1941                                         }\r
1942                                 }\r
1943                                 break;\r
1944                         }\r
1945                 }\r
1946 \r
1947                 if(Sts == FFFTP_FAIL)\r
1948                         SetTaskMsg(MSGJPN015);\r
1949         }\r
1950         else\r
1951         {\r
1952                 strcpy(Reply, Pass);\r
1953                 DoPrintf("No OTP used.");\r
1954         }\r
1955         return(Sts);\r
1956 }\r
1957 \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 *       Parameter\r
1974 *               char *host : ホスト名\r
1975 *               int port : ポート番号\r
1976 *               char *PreMsg : メッセージの前半部分\r
1977 *\r
1978 *       Return Value\r
1979 *               SOCKET ソケット\r
1980 *----------------------------------------------------------------------------*/\r
1981 \r
1982 // IPv6対応\r
1983 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
1984 {\r
1985         SOCKET Result;\r
1986         Result = INVALID_SOCKET;\r
1987         switch(CurHost.CurNetType)\r
1988         {\r
1989         case NTYPE_AUTO:\r
1990                 if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
1991                         CurHost.CurNetType = NTYPE_IPV4;\r
1992                 else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
1993                         CurHost.CurNetType = NTYPE_IPV6;\r
1994                 break;\r
1995         case NTYPE_IPV4:\r
1996                 Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
1997                 CurHost.CurNetType = NTYPE_IPV4;\r
1998                 break;\r
1999         case NTYPE_IPV6:\r
2000                 Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
2001                 CurHost.CurNetType = NTYPE_IPV6;\r
2002                 break;\r
2003         }\r
2004         return Result;\r
2005 }\r
2006 \r
2007 \r
2008 // IPv6対応\r
2009 //SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2010 SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2011 {\r
2012         struct sockaddr_in saSockAddr;\r
2013         char HostEntry[MAXGETHOSTSTRUCT];\r
2014         struct hostent *pHostEntry;\r
2015         SOCKET sSocket;\r
2016         int Len;\r
2017         int Fwall;\r
2018         SOCKS4CMD Socks4Cmd;\r
2019         SOCKS4REPLY Socks4Reply;\r
2020         SOCKS5REQUEST Socks5Cmd;\r
2021         SOCKS5REPLY Socks5Reply;\r
2022 \r
2023         //////////////////////////////\r
2024         // ホスト名解決と接続の準備\r
2025         //////////////////////////////\r
2026 \r
2027         Fwall = FWALL_NONE;\r
2028         if(AskHostFireWall() == YES)\r
2029                 Fwall = FwallType;\r
2030 \r
2031         sSocket = INVALID_SOCKET;\r
2032 \r
2033         UseIPadrs = YES;\r
2034         strcpy(DomainName, host);\r
2035         // IPv6対応\r
2036 //      memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
2037 //      CurSockAddr.sin_port = htons((u_short)port);\r
2038 //      CurSockAddr.sin_family = AF_INET;\r
2039 //      if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
2040         memset(&CurSockAddrIPv4, 0, sizeof(CurSockAddrIPv4));\r
2041         CurSockAddrIPv4.sin_port = htons((u_short)port);\r
2042         CurSockAddrIPv4.sin_family = AF_INET;\r
2043         if((CurSockAddrIPv4.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
2044         {\r
2045                 // ホスト名が指定された\r
2046                 // ホスト名からアドレスを求める\r
2047                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2048                    (FwallResolv == YES))\r
2049                 {\r
2050                         // ホスト名解決はSOCKSサーバに任せる\r
2051                         pHostEntry = NULL;\r
2052                 }\r
2053                 else\r
2054                 {\r
2055                         // アドレスを取得\r
2056                         SetTaskMsg(MSGJPN016, DomainName);\r
2057                         // IPv6対応\r
2058 //                      pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2059                         pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2060                 }\r
2061 \r
2062                 if(pHostEntry != NULL)\r
2063                 {\r
2064                         // IPv6対応\r
2065 //                      memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2066 //                      SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2067                         memcpy((char *)&CurSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2068                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));\r
2069                 }\r
2070                 else\r
2071                 {\r
2072                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2073                         {\r
2074                                 UseIPadrs = NO;\r
2075                                 // IPv6対応\r
2076 //                              SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
2077                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv4.sin_port));\r
2078                         }\r
2079                         else\r
2080                         {\r
2081                                 SetTaskMsg(MSGJPN019, host);\r
2082                                 return(INVALID_SOCKET);\r
2083                         }\r
2084                 }\r
2085         }\r
2086         else\r
2087                 // IPv6対応\r
2088 //              SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
2089                 SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port));\r
2090 \r
2091         if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2092         {\r
2093                 // SOCKSを使う\r
2094                 // SOCKSに接続する準備\r
2095                 if(Fwall == FWALL_SOCKS4)\r
2096                 {\r
2097                         Socks4Cmd.Ver = SOCKS4_VER;\r
2098                         Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
2099                         // IPv6対応\r
2100 //                      Socks4Cmd.Port = CurSockAddr.sin_port;\r
2101 //                      Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2102                         Socks4Cmd.Port = CurSockAddrIPv4.sin_port;\r
2103                         Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;\r
2104                         strcpy(Socks4Cmd.UserID, FwallUser);\r
2105                         Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2106                 }\r
2107                 else\r
2108                 {\r
2109                         // IPv6対応\r
2110 //                      Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2111                         Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);\r
2112                 }\r
2113 \r
2114                 // IPv6対応\r
2115 //              memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
2116 //              if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
2117                 memset(&SocksSockAddrIPv4, 0, sizeof(SocksSockAddrIPv4));\r
2118                 if((SocksSockAddrIPv4.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
2119                 {\r
2120                         // IPv6対応\r
2121 //                      if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2122 //                              memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2123                         if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2124                                 memcpy((char *)&SocksSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2125                         else\r
2126                         {\r
2127                                 SetTaskMsg(MSGJPN021, FwallHost);\r
2128                                 return INVALID_SOCKET;\r
2129                         }\r
2130                 }\r
2131                 // IPv6対応\r
2132 //              SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
2133 //              SocksSockAddr.sin_family = AF_INET;\r
2134 //              SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
2135                 SocksSockAddrIPv4.sin_port = htons((u_short)FwallPort);\r
2136                 SocksSockAddrIPv4.sin_family = AF_INET;\r
2137                 SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddrIPv4.sin_addr), ntohs(SocksSockAddrIPv4.sin_port));\r
2138                 // connectで接続する先はSOCKSサーバ\r
2139                 // IPv6対応\r
2140 //              memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
2141                 memcpy(&saSockAddr, &SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4));\r
2142         }\r
2143         else\r
2144         {\r
2145                 // connectで接続するのは接続先のホスト\r
2146                 // IPv6対応\r
2147 //              memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
2148                 memcpy(&saSockAddr, &CurSockAddrIPv4, sizeof(CurSockAddrIPv4));\r
2149         }\r
2150 \r
2151         /////////////\r
2152         // 接続実行\r
2153         /////////////\r
2154 \r
2155         if((sSocket = do_socket(AF_INET, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2156         {\r
2157                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2158                 {\r
2159                         if(Fwall == FWALL_SOCKS4)\r
2160                         {\r
2161                                 Socks4Reply.Result = -1;\r
2162                                 // 同時接続対応\r
2163 //                              if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2164 //                                 (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || \r
2165 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2166                                 if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2167                                    (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2168                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2169                                 {\r
2170                                         SetTaskMsg(MSGJPN023, Socks4Reply.Result);\r
2171                                         DoClose(sSocket);\r
2172                                         sSocket = INVALID_SOCKET;\r
2173                                 }\r
2174                         }\r
2175                         else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2176                         {\r
2177                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2178                                 {\r
2179                                         DoClose(sSocket);\r
2180                                         sSocket = INVALID_SOCKET;\r
2181                                 }\r
2182 \r
2183                                 Socks5Reply.Result = -1;\r
2184                                 // 同時接続対応\r
2185 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2186 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2187 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2188                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2189                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2190                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2191                                 {\r
2192                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2193                                         DoClose(sSocket);\r
2194                                         sSocket = INVALID_SOCKET;\r
2195                                 }\r
2196 \r
2197                         }\r
2198 \r
2199                         if(sSocket != INVALID_SOCKET)\r
2200                                 SetTaskMsg(MSGJPN025);\r
2201                 }\r
2202                 else\r
2203                 {\r
2204 //#pragma aaa\r
2205                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2206                         DoClose(sSocket);\r
2207                         sSocket = INVALID_SOCKET;\r
2208                 }\r
2209         }\r
2210         else\r
2211                 SetTaskMsg(MSGJPN027);\r
2212 \r
2213         return(sSocket);\r
2214 }\r
2215 \r
2216 \r
2217 SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
2218 {\r
2219         struct sockaddr_in6 saSockAddr;\r
2220         char HostEntry[MAXGETHOSTSTRUCT];\r
2221         struct hostent *pHostEntry;\r
2222         SOCKET sSocket;\r
2223         int Len;\r
2224         int Fwall;\r
2225         SOCKS5REQUEST Socks5Cmd;\r
2226         SOCKS5REPLY Socks5Reply;\r
2227 \r
2228         //////////////////////////////\r
2229         // ホスト名解決と接続の準備\r
2230         //////////////////////////////\r
2231 \r
2232         Fwall = FWALL_NONE;\r
2233         if(AskHostFireWall() == YES)\r
2234                 Fwall = FwallType;\r
2235 \r
2236         sSocket = INVALID_SOCKET;\r
2237 \r
2238         UseIPadrs = YES;\r
2239         strcpy(DomainName, host);\r
2240         memset(&CurSockAddrIPv6, 0, sizeof(CurSockAddrIPv6));\r
2241         CurSockAddrIPv6.sin6_port = htons((u_short)port);\r
2242         CurSockAddrIPv6.sin6_family = AF_INET6;\r
2243         CurSockAddrIPv6.sin6_addr = inet6_addr(host);\r
2244         if(memcmp(&CurSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2245         {\r
2246                 // ホスト名が指定された\r
2247                 // ホスト名からアドレスを求める\r
2248                 if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
2249                    (FwallResolv == YES))\r
2250                 {\r
2251                         // ホスト名解決はSOCKSサーバに任せる\r
2252                         pHostEntry = NULL;\r
2253                 }\r
2254                 else\r
2255                 {\r
2256                         // アドレスを取得\r
2257                         SetTaskMsg(MSGJPN016, DomainName);\r
2258                         pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
2259                 }\r
2260 \r
2261                 if(pHostEntry != NULL)\r
2262                 {\r
2263                         memcpy((char *)&CurSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2264                         SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));\r
2265                 }\r
2266                 else\r
2267                 {\r
2268                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2269                         {\r
2270                                 UseIPadrs = NO;\r
2271                                 SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv6.sin6_port));\r
2272                         }\r
2273                         else\r
2274                         {\r
2275                                 SetTaskMsg(MSGJPN019, host);\r
2276                                 return(INVALID_SOCKET);\r
2277                         }\r
2278                 }\r
2279         }\r
2280         else\r
2281                 SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port));\r
2282 \r
2283         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2284         {\r
2285                 // SOCKSを使う\r
2286                 // SOCKSに接続する準備\r
2287                 {\r
2288                         Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);\r
2289                 }\r
2290 \r
2291                 memset(&SocksSockAddrIPv6, 0, sizeof(SocksSockAddrIPv6));\r
2292                 SocksSockAddrIPv6.sin6_addr = inet6_addr(FwallHost);\r
2293                 if(memcmp(&SocksSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
2294                 {\r
2295                         if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
2296                                 memcpy((char *)&SocksSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
2297                         else\r
2298                         {\r
2299                                 SetTaskMsg(MSGJPN021, FwallHost);\r
2300                                 return INVALID_SOCKET;\r
2301                         }\r
2302                 }\r
2303                 SocksSockAddrIPv6.sin6_port = htons((u_short)FwallPort);\r
2304                 SocksSockAddrIPv6.sin6_family = AF_INET6;\r
2305                 SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddrIPv6.sin6_addr), ntohs(SocksSockAddrIPv6.sin6_port));\r
2306                 // connectで接続する先はSOCKSサーバ\r
2307                 memcpy(&saSockAddr, &SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6));\r
2308         }\r
2309         else\r
2310         {\r
2311                 // connectで接続するのは接続先のホスト\r
2312                 memcpy(&saSockAddr, &CurSockAddrIPv6, sizeof(CurSockAddrIPv6));\r
2313         }\r
2314 \r
2315         /////////////\r
2316         // 接続実行\r
2317         /////////////\r
2318 \r
2319         inet6_ntoa(saSockAddr.sin6_addr);\r
2320         if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
2321         {\r
2322                 if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2323                 {\r
2324                         if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2325                         {\r
2326                                 if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
2327                                 {\r
2328                                         DoClose(sSocket);\r
2329                                         sSocket = INVALID_SOCKET;\r
2330                                 }\r
2331 \r
2332                                 Socks5Reply.Result = -1;\r
2333                                 // 同時接続対応\r
2334 //                              if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2335 //                                 (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
2336 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2337                                 if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2338                                    (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2339                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2340                                 {\r
2341                                         SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
2342                                         DoClose(sSocket);\r
2343                                         sSocket = INVALID_SOCKET;\r
2344                                 }\r
2345 \r
2346                         }\r
2347 \r
2348                         if(sSocket != INVALID_SOCKET)\r
2349                                 SetTaskMsg(MSGJPN025);\r
2350                 }\r
2351                 else\r
2352                 {\r
2353 //#pragma aaa\r
2354                         SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
2355                         DoClose(sSocket);\r
2356                         sSocket = INVALID_SOCKET;\r
2357                 }\r
2358         }\r
2359         else\r
2360                 SetTaskMsg(MSGJPN027);\r
2361 \r
2362         return(sSocket);\r
2363 }\r
2364 \r
2365 \r
2366 /*----- リッスンソケットを取得 ------------------------------------------------\r
2367 *\r
2368 *       Parameter\r
2369 *               SOCKET ctrl_skt : コントロールソケット\r
2370 *\r
2371 *       Return Value\r
2372 *               SOCKET リッスンソケット\r
2373 *----------------------------------------------------------------------------*/\r
2374 \r
2375 // IPv6対応\r
2376 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2377 {\r
2378         SOCKET Result;\r
2379         Result = INVALID_SOCKET;\r
2380         switch(CurHost.CurNetType)\r
2381         {\r
2382         case NTYPE_IPV4:\r
2383                 Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
2384                 break;\r
2385         case NTYPE_IPV6:\r
2386                 Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
2387                 break;\r
2388         }\r
2389         return Result;\r
2390 }\r
2391 \r
2392 \r
2393 // IPv6対応\r
2394 //SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
2395 SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
2396 {\r
2397     SOCKET listen_skt;\r
2398     int iLength;\r
2399     char *a,*p;\r
2400         struct sockaddr_in saCtrlAddr;\r
2401         struct sockaddr_in saTmpAddr;\r
2402         SOCKS4CMD Socks4Cmd;\r
2403         SOCKS4REPLY Socks4Reply;\r
2404         SOCKS5REQUEST Socks5Cmd;\r
2405         SOCKS5REPLY Socks5Reply;\r
2406 \r
2407         int Len;\r
2408         int Fwall;\r
2409 \r
2410         Fwall = FWALL_NONE;\r
2411         if(AskHostFireWall() == YES)\r
2412                 Fwall = FwallType;\r
2413 \r
2414         if((listen_skt = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2415         {\r
2416                 if(Fwall == FWALL_SOCKS4)\r
2417                 {\r
2418                         /*===== SOCKS4を使う =====*/\r
2419                         DoPrintf("Use SOCKS4 BIND");\r
2420                         // IPv6対応\r
2421 //                      if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2422                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)\r
2423                         {\r
2424                                 Socks4Cmd.Ver = SOCKS4_VER;\r
2425                                 Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
2426                                 // IPv6対応\r
2427 //                              Socks4Cmd.Port = CurSockAddr.sin_port;\r
2428 //                              Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
2429                                 Socks4Cmd.Port = CurSockAddrIPv4.sin_port;\r
2430                                 Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr;\r
2431                                 strcpy(Socks4Cmd.UserID, FwallUser);\r
2432                                 Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
2433 \r
2434                                 Socks4Reply.Result = -1;\r
2435                                 // 同時接続対応\r
2436 //                              if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2437 //                                 (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || \r
2438 //                                 (Socks4Reply.Result != SOCKS4_RES_OK))\r
2439                                 if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2440                                    (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2441                                    (Socks4Reply.Result != SOCKS4_RES_OK))\r
2442                                 {\r
2443                                         SetTaskMsg(MSGJPN028, Socks4Reply.Result);\r
2444                                         DoClose(listen_skt);\r
2445                                         listen_skt = INVALID_SOCKET;\r
2446                                 }\r
2447 \r
2448                                 if(Socks4Reply.AdrsInt == 0)\r
2449                                         // IPv6対応\r
2450 //                                      Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2451                                         Socks4Reply.AdrsInt = SocksSockAddrIPv4.sin_addr.s_addr;\r
2452 \r
2453                                 a = (char *)&Socks4Reply.AdrsInt;\r
2454                                 p = (char *)&Socks4Reply.Port;\r
2455                         }\r
2456                 }\r
2457                 else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2458                 {\r
2459                         /*===== SOCKS5を使う =====*/\r
2460                         DoPrintf("Use SOCKS5 BIND");\r
2461                         // IPv6対応\r
2462 //                      if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
2463                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR)\r
2464                         {\r
2465                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2466                                 {\r
2467                                         DoClose(listen_skt);\r
2468                                         listen_skt = INVALID_SOCKET;\r
2469                                         return(listen_skt);\r
2470                                 }\r
2471 \r
2472                                 // IPv6対応\r
2473 //                              Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
2474                                 Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port);\r
2475 \r
2476                                 Socks5Reply.Result = -1;\r
2477                                 // 同時接続対応\r
2478 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2479 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2480 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2481                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2482                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2483                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2484                                 {\r
2485                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2486                                         DoClose(listen_skt);\r
2487                                         listen_skt = INVALID_SOCKET;\r
2488                                 }\r
2489 \r
2490                                 // IPv6対応\r
2491 //                              if(Socks5Reply.AdrsInt == 0)\r
2492 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2493 \r
2494                                 // IPv6対応\r
2495 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2496 //                              p = (char *)&Socks5Reply.Port;\r
2497                                 a = (char *)&Socks5Reply._dummy[0];\r
2498                                 p = (char *)&Socks5Reply._dummy[4];\r
2499                         }\r
2500                 }\r
2501                 else\r
2502                 {\r
2503                         /*===== SOCKSを使わない =====*/\r
2504                         DoPrintf("Use normal BIND");\r
2505                         saCtrlAddr.sin_port = htons(0);\r
2506                         saCtrlAddr.sin_family = AF_INET;\r
2507                         saCtrlAddr.sin_addr.s_addr = 0;\r
2508 \r
2509                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr)) != SOCKET_ERROR)\r
2510                         {\r
2511                                 iLength = sizeof(saCtrlAddr);\r
2512                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2513                                 {\r
2514                                         if(do_listen(listen_skt, 1) == 0)\r
2515                                         {\r
2516                                                 iLength = sizeof(saTmpAddr);\r
2517                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2518                                                         ReportWSError("getsockname", WSAGetLastError());\r
2519 \r
2520                                                 a = (char *)&saTmpAddr.sin_addr;\r
2521                                                 p = (char *)&saCtrlAddr.sin_port;\r
2522                                         }\r
2523                                         else\r
2524                                         {\r
2525                                                 ReportWSError("listen", WSAGetLastError());\r
2526                                                 do_closesocket(listen_skt);\r
2527                                                 listen_skt = INVALID_SOCKET;\r
2528                                         }\r
2529                                 }\r
2530                                 else\r
2531                                 {\r
2532                                         ReportWSError("getsockname", WSAGetLastError());\r
2533                                         do_closesocket(listen_skt);\r
2534                                         listen_skt = INVALID_SOCKET;\r
2535                                 }\r
2536                         }\r
2537                         else\r
2538                         {\r
2539                                 ReportWSError("bind", WSAGetLastError());\r
2540                                 do_closesocket(listen_skt);\r
2541                                 listen_skt = INVALID_SOCKET;\r
2542                         }\r
2543 \r
2544                         if(listen_skt == INVALID_SOCKET)\r
2545                                 SetTaskMsg(MSGJPN030);\r
2546                 }\r
2547         }\r
2548         else\r
2549                 ReportWSError("socket create", WSAGetLastError());\r
2550 \r
2551         if(listen_skt != INVALID_SOCKET)\r
2552         {\r
2553 #define  UC(b)  (((int)b)&0xff)\r
2554                 // 同時接続対応\r
2555 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2556 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2557 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2558                 if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d",\r
2559                                 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2560                                 UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2561                 {\r
2562                         SetTaskMsg(MSGJPN031);\r
2563                         do_closesocket(listen_skt);\r
2564                         listen_skt = INVALID_SOCKET;\r
2565                 }\r
2566 //              else\r
2567 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2568         }\r
2569 \r
2570         return(listen_skt);\r
2571 }\r
2572 \r
2573 \r
2574 SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
2575 {\r
2576     SOCKET listen_skt;\r
2577     int iLength;\r
2578     char *a,*p;\r
2579         struct sockaddr_in6 saCtrlAddr;\r
2580         struct sockaddr_in6 saTmpAddr;\r
2581         SOCKS5REQUEST Socks5Cmd;\r
2582         SOCKS5REPLY Socks5Reply;\r
2583 \r
2584         int Len;\r
2585         int Fwall;\r
2586 \r
2587         char Adrs[40];\r
2588 \r
2589         Fwall = FWALL_NONE;\r
2590         if(AskHostFireWall() == YES)\r
2591                 Fwall = FwallType;\r
2592 \r
2593         if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
2594         {\r
2595                 if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
2596                 {\r
2597                         /*===== SOCKS5を使う =====*/\r
2598                         DoPrintf("Use SOCKS5 BIND");\r
2599                         if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6), CancelCheckWork) != SOCKET_ERROR)\r
2600                         {\r
2601                                 if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
2602                                 {\r
2603                                         DoClose(listen_skt);\r
2604                                         listen_skt = INVALID_SOCKET;\r
2605                                         return(listen_skt);\r
2606                                 }\r
2607 \r
2608                                 Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port);\r
2609 \r
2610                                 Socks5Reply.Result = -1;\r
2611                                 // 同時接続対応\r
2612 //                              if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2613 //                                 (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
2614 //                                 (Socks5Reply.Result != SOCKS5_RES_OK))\r
2615                                 if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
2616                                    (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
2617                                    (Socks5Reply.Result != SOCKS5_RES_OK))\r
2618                                 {\r
2619                                         SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
2620                                         DoClose(listen_skt);\r
2621                                         listen_skt = INVALID_SOCKET;\r
2622                                 }\r
2623 \r
2624                                 // IPv6対応\r
2625 //                              if(Socks5Reply.AdrsInt == 0)\r
2626 //                                      Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
2627 \r
2628                                 // IPv6対応\r
2629 //                              a = (char *)&Socks5Reply.AdrsInt;\r
2630 //                              p = (char *)&Socks5Reply.Port;\r
2631                                 a = (char *)&Socks5Reply._dummy[0];\r
2632                                 p = (char *)&Socks5Reply._dummy[16];\r
2633                         }\r
2634                 }\r
2635                 else\r
2636                 {\r
2637                         /*===== SOCKSを使わない =====*/\r
2638                         DoPrintf("Use normal BIND");\r
2639                         saCtrlAddr.sin6_port = htons(0);\r
2640                         saCtrlAddr.sin6_family = AF_INET6;\r
2641                         memset(&saCtrlAddr.sin6_addr, 0, 16);\r
2642 \r
2643                         if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
2644                         {\r
2645                                 iLength = sizeof(saCtrlAddr);\r
2646                                 if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
2647                                 {\r
2648                                         if(do_listen(listen_skt, 1) == 0)\r
2649                                         {\r
2650                                                 iLength = sizeof(saTmpAddr);\r
2651                                                 if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
2652                                                         ReportWSError("getsockname", WSAGetLastError());\r
2653 \r
2654                                                 a = (char *)&saTmpAddr.sin6_addr;\r
2655                                                 p = (char *)&saCtrlAddr.sin6_port;\r
2656                                         }\r
2657                                         else\r
2658                                         {\r
2659                                                 ReportWSError("listen", WSAGetLastError());\r
2660                                                 do_closesocket(listen_skt);\r
2661                                                 listen_skt = INVALID_SOCKET;\r
2662                                         }\r
2663                                 }\r
2664                                 else\r
2665                                 {\r
2666                                         ReportWSError("getsockname", WSAGetLastError());\r
2667                                         do_closesocket(listen_skt);\r
2668                                         listen_skt = INVALID_SOCKET;\r
2669                                 }\r
2670                         }\r
2671                         else\r
2672                         {\r
2673                                 ReportWSError("bind", WSAGetLastError());\r
2674                                 do_closesocket(listen_skt);\r
2675                                 listen_skt = INVALID_SOCKET;\r
2676                         }\r
2677 \r
2678                         if(listen_skt == INVALID_SOCKET)\r
2679                                 SetTaskMsg(MSGJPN030);\r
2680                 }\r
2681         }\r
2682         else\r
2683                 ReportWSError("socket create", WSAGetLastError());\r
2684 \r
2685         if(listen_skt != INVALID_SOCKET)\r
2686         {\r
2687 #define  UC(b)  (((int)b)&0xff)\r
2688                 // 同時接続対応\r
2689 //              if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
2690 //                              UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
2691 //                              UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
2692                 if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
2693                                 AddressToStringIPv6(Adrs, a),\r
2694                                 (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE)\r
2695                 {\r
2696                         SetTaskMsg(MSGJPN031);\r
2697                         do_closesocket(listen_skt);\r
2698                         listen_skt = INVALID_SOCKET;\r
2699                 }\r
2700 //              else\r
2701 //                      DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
2702         }\r
2703 \r
2704         return(listen_skt);\r
2705 }\r
2706 \r
2707 \r
2708 /*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
2709 *\r
2710 *       Parameter\r
2711 *               なし\r
2712 *\r
2713 *       Return Value\r
2714 *               int ステータス\r
2715 *                       YES/NO\r
2716 *----------------------------------------------------------------------------*/\r
2717 \r
2718 int AskTryingConnect(void)\r
2719 {\r
2720         return(TryConnect);\r
2721 }\r
2722 \r
2723 \r
2724 #if 0\r
2725 ///*----- ブロッキングコールのフックコールバック --------------------------------\r
2726 //*\r
2727 //*     Parameter\r
2728 //*             なし\r
2729 //*\r
2730 //*     Return Value\r
2731 //*             BOOL FALSE\r
2732 //*----------------------------------------------------------------------------*/\r
2733 //\r
2734 //static BOOL CALLBACK BlkHookFnc(void)\r
2735 //{\r
2736 //      BackgrndMessageProc();\r
2737 //\r
2738 //      if(CancelFlg == YES)\r
2739 //      {\r
2740 //              SetTaskMsg(MSGJPN032);\r
2741 //              WSACancelBlockingCall();\r
2742 //              CancelFlg = NO;\r
2743 //      }\r
2744 //      return(FALSE);\r
2745 //}\r
2746 #endif\r
2747 \r
2748 \r
2749 \r
2750 /*----- SOCKS5のコマンドパケットを作成する ------------------------------------\r
2751 *\r
2752 *       Parameter\r
2753 *               SOCKS5REQUEST *Packet : パケットを作成するワーク\r
2754 *               char Cmd : コマンド\r
2755 *               int ValidIP : IPアドレスを使うかどうか(YES/NO)\r
2756 *               ulong IP : IPアドレス\r
2757 *               char *Host : ホスト名\r
2758 *               ushort Port : ポート\r
2759 *\r
2760 *       Return Value\r
2761 *               int コマンドパケットの長さ\r
2762 *----------------------------------------------------------------------------*/\r
2763 \r
2764 static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port)\r
2765 {\r
2766         uchar *Pos;\r
2767         int Len;\r
2768         int TotalLen;\r
2769 \r
2770         Pos = (uchar *)Packet;\r
2771         Pos += SOCKS5REQUEST_SIZE;\r
2772         TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
2773 \r
2774         Packet->Ver = SOCKS5_VER;\r
2775         Packet->Cmd = Cmd;\r
2776         Packet->Rsv = 0;\r
2777         if(ValidIP == YES)\r
2778         {\r
2779                 /* IPアドレスを指定 */\r
2780                 Packet->Type = SOCKS5_ADRS_IPV4;\r
2781                 *((ulong *)Pos) = IP;\r
2782                 Pos += 4;\r
2783                 TotalLen += 4;\r
2784         }\r
2785         else\r
2786         {\r
2787                 /* ホスト名を指定 */\r
2788                 Packet->Type = SOCKS5_ADRS_NAME;\r
2789                 Len = strlen(Host);\r
2790                 *Pos++ = Len;\r
2791                 strcpy(Pos, Host);\r
2792                 Pos += Len;\r
2793                 TotalLen += Len + 1;\r
2794         }\r
2795         *((ushort *)Pos) = Port;\r
2796 \r
2797         return(TotalLen);\r
2798 }\r
2799 \r
2800 \r
2801 // IPv6対応\r
2802 static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
2803 {\r
2804         uchar *Pos;\r
2805         int Len;\r
2806         int TotalLen;\r
2807 \r
2808         Pos = (uchar *)Packet;\r