OSDN Git Service

Enhanced routine for simultaneous connection and canceling or aborting.
[ffftp/ffftp.git] / remote.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 /* このソースは一部、WS_FTP Version 93.12.05 のソースを参考にしました。 */\r
31 \r
32 #define STRICT\r
33 #include <stdio.h>\r
34 #include <stdlib.h>\r
35 #include <stdarg.h>\r
36 #include <string.h>\r
37 #include <mbstring.h>\r
38 #include <time.h>\r
39 #include <winsock.h>\r
40 #include <windowsx.h>\r
41 #include <commctrl.h>\r
42 \r
43 #include "common.h"\r
44 #include "resource.h"\r
45 \r
46 #define PWD_XPWD                0\r
47 #define PWD_PWD                 1\r
48 \r
49 /*===== プロトタイプ =====*/\r
50 \r
51 static int DoPWD(char *Buf);\r
52 static int ReadOneLine(SOCKET cSkt, char *Buf, int Max, int *CancelCheckWork);\r
53 static int DoDirList(HWND hWnd, SOCKET cSkt, char *AddOpt, char *Path, int Num, int *CancelCheckWork);\r
54 static void ChangeSepaLocal2Remote(char *Fname);\r
55 static void ChangeSepaRemote2Local(char *Fname);\r
56 \r
57 /*===== 外部参照 =====*/\r
58 \r
59 extern TRANSPACKET MainTransPkt;\r
60 \r
61 /* 設定値 */\r
62 extern int TimeOut;\r
63 extern int SendQuit;\r
64 \r
65 // 同時接続対応\r
66 extern int CancelFlg;\r
67 \r
68 /*===== ローカルなワーク =====*/\r
69 \r
70 static int PwdCommandType;\r
71 \r
72 // 同時接続対応\r
73 //static int CheckCancelFlg = NO;\r
74 \r
75 \r
76 \r
77 /*----- リモート側のカレントディレクトリ変更 ----------------------------------\r
78 *\r
79 *       Parameter\r
80 *               char *Path : パス名\r
81 *               int Disp : ディレクトリリストにパス名を表示するかどうか(YES/NO)\r
82 *               int ForceGet : 失敗してもカレントディレクトリを取得する\r
83 *               int ErrorBell : エラー事の音を鳴らすかどうか(YES/NO)\r
84 *\r
85 *       Return Value\r
86 *               int 応答コードの1桁目\r
87 *----------------------------------------------------------------------------*/\r
88 \r
89 int DoCWD(char *Path, int Disp, int ForceGet, int ErrorBell)\r
90 {\r
91         int Sts;\r
92         char Buf[FMAX_PATH+1];\r
93 \r
94         Sts = FTP_COMPLETE * 100;\r
95 \r
96         if(strcmp(Path, "..") == 0)\r
97                 Sts = CommandProcCmd(NULL, "CDUP");\r
98         else if(strcmp(Path, "") != 0)\r
99         {\r
100                 if((AskHostType() != HTYPE_VMS) || (strchr(Path, '[') != NULL))\r
101                         Sts = CommandProcCmd(NULL, "CWD %s", Path);\r
102                 else\r
103                         Sts = CommandProcCmd(NULL, "CWD [.%s]", Path);  /* VMS用 */\r
104         }\r
105 \r
106         if((Sts/100 >= FTP_CONTINUE) && (ErrorBell == YES))\r
107                 SoundPlay(SND_ERROR);\r
108 \r
109         if((Sts/100 == FTP_COMPLETE) ||\r
110            (ForceGet == YES))\r
111         {\r
112                 if(Disp == YES)\r
113                 {\r
114                         if(DoPWD(Buf) != FTP_COMPLETE)\r
115                         {\r
116                                 /*===== PWDが使えなかった場合 =====*/\r
117 \r
118                                 if(*Path == '/')\r
119                                         strcpy(Buf, Path);\r
120                                 else\r
121                                 {\r
122                                         AskRemoteCurDir(Buf, FMAX_PATH);\r
123                                         if(strlen(Buf) == 0)\r
124                                                 strcpy(Buf, "/");\r
125 \r
126                                         while(*Path != NUL)\r
127                                         {\r
128                                                 if(strcmp(Path, ".") == 0)\r
129                                                         Path++;\r
130                                                 else if(strncmp(Path, "./", 2) == 0)\r
131                                                         Path += 2;\r
132                                                 else if(strcmp(Path, "..") == 0)\r
133                                                 {\r
134                                                         GetUpperDir(Buf);\r
135                                                         Path += 2;\r
136                                                 }\r
137                                                 else if(strncmp(Path, "../", 2) == 0)\r
138                                                 {\r
139                                                         GetUpperDir(Buf);\r
140                                                         Path += 3;\r
141                                                 }\r
142                                                 else\r
143                                                 {\r
144                                                         SetSlashTail(Buf);\r
145                                                         strcat(Buf, Path);\r
146                                                         break;\r
147                                                 }\r
148                                         }\r
149                                 }\r
150                         }\r
151                         SetRemoteDirHist(Buf);\r
152                 }\r
153         }\r
154         return(Sts/100);\r
155 }\r
156 \r
157 \r
158 \r
159 \r
160 /*----- リモート側のカレントディレクトリ変更(その2)-------------------------\r
161 *\r
162 *       Parameter\r
163 *               char *Path : パス名\r
164 *               char *Cur : カレントディレクトリ\r
165 *\r
166 *       Return Value\r
167 *               int 応答コードの1桁目\r
168 *\r
169 *       Note\r
170 *               パス名は "xxx/yyy/zzz" の形式\r
171 *               ディレクトリ変更が失敗したら、カレントディレクトリに戻しておく\r
172 *----------------------------------------------------------------------------*/\r
173 \r
174 int DoCWDStepByStep(char *Path, char *Cur)\r
175 {\r
176         int Sts;\r
177         char *Set;\r
178         char *Set2;\r
179         char Tmp[FMAX_PATH+2];\r
180 \r
181         Sts = FTP_COMPLETE;\r
182 \r
183         memset(Tmp, NUL, FMAX_PATH+2);\r
184         strcpy(Tmp, Path);\r
185         Set = Tmp;\r
186         while(*Set != NUL)\r
187         {\r
188                 if((Set2 = strchr(Set, '/')) != NULL)\r
189                         *Set2 = NUL;\r
190                 if((Sts = DoCWD(Set, NO, NO, NO)) != FTP_COMPLETE)\r
191                         break;\r
192                 if(Set2 == NULL)\r
193                         break;\r
194                 Set = Set2 + 1;\r
195         }\r
196 \r
197         if(Sts != FTP_COMPLETE)\r
198                 DoCWD(Cur, NO, NO, NO);\r
199 \r
200         return(Sts);\r
201 }\r
202 \r
203 \r
204 /*----- リモート側のカレントディレクトリ取得 ----------------------------------\r
205 *\r
206 *       Parameter\r
207 *               char *Buf : パス名を返すバッファ\r
208 *\r
209 *       Return Value\r
210 *               int 応答コードの1桁目\r
211 *----------------------------------------------------------------------------*/\r
212 \r
213 static int DoPWD(char *Buf)\r
214 {\r
215         char *Pos;\r
216         char Tmp[1024];\r
217         int Sts;\r
218 \r
219         if(PwdCommandType == PWD_XPWD)\r
220         {\r
221                 Sts = CommandProcCmd(Tmp, "XPWD");\r
222                 if(Sts/100 != FTP_COMPLETE)\r
223                         PwdCommandType = PWD_PWD;\r
224         }\r
225         if(PwdCommandType == PWD_PWD)\r
226                 Sts = CommandProcCmd(Tmp, "PWD");\r
227 \r
228         if(Sts/100 == FTP_COMPLETE)\r
229         {\r
230                 if((Pos = strchr(Tmp, '"')) != NULL)\r
231                 {\r
232                         memmove(Tmp, Pos+1, strlen(Pos+1)+1);\r
233                         if((Pos = strchr(Tmp, '"')) != NULL)\r
234                                 *Pos = NUL;\r
235                 }\r
236                 else\r
237                         memmove(Tmp, Tmp+4, strlen(Tmp+4)+1);\r
238 \r
239                 if(strlen(Tmp) < FMAX_PATH)\r
240                 {\r
241                         strcpy(Buf, Tmp);\r
242                         ReplaceAll(Buf, '\\', '/');\r
243                         ChangeSepaRemote2Local(Buf);\r
244                         ChangeFnameRemote2Local(Buf, FMAX_PATH);\r
245                 }\r
246                 else\r
247                         Sts = FTP_ERROR*100;\r
248         }\r
249         return(Sts/100);\r
250 }\r
251 \r
252 \r
253 /*----- PWDコマンドのタイプを初期化する ---------------------------------------\r
254 *\r
255 *       Parameter\r
256 *               なし\r
257 *\r
258 *       Return Value\r
259 *               なし\r
260 *----------------------------------------------------------------------------*/\r
261 \r
262 void InitPWDcommand()\r
263 {\r
264         PwdCommandType = PWD_XPWD;\r
265 }\r
266 \r
267 \r
268 /*----- リモート側のディレクトリ作成 ----------------------------------------\r
269 *\r
270 *       Parameter\r
271 *               char *Path : パス名\r
272 *\r
273 *       Return Value\r
274 *               int 応答コードの1桁目\r
275 *----------------------------------------------------------------------------*/\r
276 \r
277 int DoMKD(char *Path)\r
278 {\r
279         int Sts;\r
280 \r
281         Sts = CommandProcCmd(NULL, "MKD %s", Path);\r
282 \r
283         if(Sts/100 >= FTP_CONTINUE)\r
284                 SoundPlay(SND_ERROR);\r
285 \r
286         return(Sts/100);\r
287 }\r
288 \r
289 \r
290 /*----- リモート側のディレクトリ削除 ------------------------------------------\r
291 *\r
292 *       Parameter\r
293 *               char *Path : パス名\r
294 *\r
295 *       Return Value\r
296 *               int 応答コードの1桁目\r
297 *----------------------------------------------------------------------------*/\r
298 \r
299 int DoRMD(char *Path)\r
300 {\r
301         int Sts;\r
302 \r
303         Sts = CommandProcCmd(NULL, "RMD %s", Path);\r
304 \r
305         if(Sts/100 >= FTP_CONTINUE)\r
306                 SoundPlay(SND_ERROR);\r
307 \r
308         return(Sts/100);\r
309 }\r
310 \r
311 \r
312 /*----- リモート側のファイル削除 ----------------------------------------------\r
313 *\r
314 *       Parameter\r
315 *               char *Path : パス名\r
316 *\r
317 *       Return Value\r
318 *               int 応答コードの1桁目\r
319 *----------------------------------------------------------------------------*/\r
320 \r
321 int DoDELE(char *Path)\r
322 {\r
323         int Sts;\r
324 \r
325         Sts = CommandProcCmd(NULL, "DELE %s", Path);\r
326 \r
327         if(Sts/100 >= FTP_CONTINUE)\r
328                 SoundPlay(SND_ERROR);\r
329 \r
330         return(Sts/100);\r
331 }\r
332 \r
333 \r
334 /*----- リモート側のファイル名変更 --------------------------------------------\r
335 *\r
336 *       Parameter\r
337 *               char *Src : 元ファイル名\r
338 *               char *Dst : 変更後のファイル名\r
339 *\r
340 *       Return Value\r
341 *               int 応答コードの1桁目\r
342 *----------------------------------------------------------------------------*/\r
343 \r
344 int DoRENAME(char *Src, char *Dst)\r
345 {\r
346         int Sts;\r
347 \r
348         Sts = CommandProcCmd(NULL, "RNFR %s", Src);\r
349         if(Sts == 350)\r
350                 // 同時接続対応\r
351 //              Sts = command(AskCmdCtrlSkt(), NULL, &CheckCancelFlg, "RNTO %s", Dst);\r
352                 Sts = command(AskCmdCtrlSkt(), NULL, &CancelFlg, "RNTO %s", Dst);\r
353 \r
354         if(Sts/100 >= FTP_CONTINUE)\r
355                 SoundPlay(SND_ERROR);\r
356 \r
357         return(Sts/100);\r
358 }\r
359 \r
360 \r
361 /*----- リモート側のファイルの属性変更 ----------------------------------------\r
362 *\r
363 *       Parameter\r
364 *               char *Path : パス名\r
365 *               char *Mode : モード文字列\r
366 *\r
367 *       Return Value\r
368 *               int 応答コードの1桁目\r
369 *----------------------------------------------------------------------------*/\r
370 \r
371 int DoCHMOD(char *Path, char *Mode)\r
372 {\r
373         int Sts;\r
374 \r
375         Sts = CommandProcCmd(NULL, "%s %s %s", AskHostChmodCmd(), Mode, Path);\r
376 \r
377         if(Sts/100 >= FTP_CONTINUE)\r
378                 SoundPlay(SND_ERROR);\r
379 \r
380         return(Sts/100);\r
381 }\r
382 \r
383 \r
384 /*----- リモート側のファイルのサイズを取得(転送ソケット使用)-----------------\r
385 *\r
386 *       Parameter\r
387 *               char *Path : パス名\r
388 *               LONGLONG *Size : ファイルのサイズを返すワーク\r
389 *\r
390 *       Return Value\r
391 *               int 応答コードの1桁目\r
392 *\r
393 *       Note\r
394 *               ★★転送ソケットを使用する★★\r
395 *               サイズが選られない時は Size = -1 を返す\r
396 *----------------------------------------------------------------------------*/\r
397 \r
398 // 同時接続対応\r
399 //int DoSIZE(char *Path, LONGLONG *Size)\r
400 int DoSIZE(SOCKET cSkt, char *Path, LONGLONG *Size, int *CancelCheckWork)\r
401 {\r
402         int Sts;\r
403         char Tmp[1024];\r
404 \r
405         // 同時接続対応\r
406 //      Sts = CommandProcTrn(Tmp, "SIZE %s", Path);\r
407         Sts = CommandProcTrn(cSkt, Tmp, CancelCheckWork, "SIZE %s", Path);\r
408 \r
409         *Size = -1;\r
410         if((Sts/100 == FTP_COMPLETE) && (strlen(Tmp) > 4) && IsDigit(Tmp[4]))\r
411                 *Size = _atoi64(&Tmp[4]);\r
412 \r
413         return(Sts/100);\r
414 }\r
415 \r
416 \r
417 /*----- リモート側のファイルの日付を取得(転送ソケット使用)-------------------\r
418 *\r
419 *       Parameter\r
420 *               char *Path : パス名\r
421 *               FILETIME *Time : 日付を返すワーク\r
422 *\r
423 *       Return Value\r
424 *               int 応答コードの1桁目\r
425 *\r
426 *       Note\r
427 *               ★★転送ソケットを使用する★★\r
428 *               日付が選られない時は Time = 0 を返す\r
429 *----------------------------------------------------------------------------*/\r
430 \r
431 // 同時接続対応\r
432 //int DoMDTM(char *Path, FILETIME *Time)\r
433 int DoMDTM(SOCKET cSkt, char *Path, FILETIME *Time, int *CancelCheckWork)\r
434 {\r
435         int Sts;\r
436         char Tmp[1024];\r
437         SYSTEMTIME sTime;\r
438 \r
439     Time->dwLowDateTime = 0;\r
440     Time->dwHighDateTime = 0;\r
441 \r
442         // 同時接続対応\r
443 //      Sts = CommandProcTrn(Tmp, "MDTM %s", Path);\r
444         Sts = CommandProcTrn(cSkt, Tmp, CancelCheckWork, "MDTM %s", Path);\r
445         if(Sts/100 == FTP_COMPLETE)\r
446         {\r
447                 sTime.wMilliseconds = 0;\r
448                 if(sscanf(Tmp+4, "%04d%02d%02d%02d%02d%02d",\r
449                         &sTime.wYear, &sTime.wMonth, &sTime.wDay,\r
450                         &sTime.wHour, &sTime.wMinute, &sTime.wSecond) == 6)\r
451                 {\r
452                         SystemTimeToFileTime(&sTime, Time);\r
453                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
454 \r
455                 }\r
456         }\r
457         return(Sts/100);\r
458 }\r
459 \r
460 \r
461 /*----- リモート側のコマンドを実行 --------------------------------------------\r
462 *\r
463 *       Parameter\r
464 *               char *CmdStr : コマンド文字列\r
465 *\r
466 *       Return Value\r
467 *               int 応答コードの1桁目\r
468 *----------------------------------------------------------------------------*/\r
469 \r
470 int DoQUOTE(char *CmdStr)\r
471 {\r
472         int Sts;\r
473 \r
474         Sts = CommandProcCmd(NULL, "%s", CmdStr);\r
475 \r
476         if(Sts/100 >= FTP_CONTINUE)\r
477                 SoundPlay(SND_ERROR);\r
478 \r
479         return(Sts/100);\r
480 }\r
481 \r
482 \r
483 /*----- ソケットを閉じる ------------------------------------------------------\r
484 *\r
485 *       Parameter\r
486 *               なし\r
487 *\r
488 *       Return Value\r
489 *               SOCKET 閉じた後のソケット\r
490 *----------------------------------------------------------------------------*/\r
491 \r
492 SOCKET DoClose(SOCKET Sock)\r
493 {\r
494         if(Sock != INVALID_SOCKET)\r
495         {\r
496 //              if(WSAIsBlocking())\r
497 //              {\r
498 //                      DoPrintf("Skt=%u : Cancelled blocking call", Sock);\r
499 //                      WSACancelBlockingCall();\r
500 //              }\r
501                 do_closesocket(Sock);\r
502                 DoPrintf("Skt=%u : Socket closed.", Sock);\r
503                 Sock = INVALID_SOCKET;\r
504         }\r
505         if(Sock != INVALID_SOCKET)\r
506                 DoPrintf("Skt=%u : Failed to close socket.", Sock);\r
507 \r
508         return(Sock);\r
509 }\r
510 \r
511 \r
512 /*----- ホストからログアウトする ----------------------------------------------\r
513 *\r
514 *       Parameter\r
515 *               kSOCKET ctrl_skt : ソケット\r
516 *\r
517 *       Return Value\r
518 *               int 応答コードの1桁目\r
519 *----------------------------------------------------------------------------*/\r
520 \r
521 int DoQUIT(SOCKET ctrl_skt)\r
522 {\r
523         int Ret;\r
524 \r
525         Ret = FTP_COMPLETE;\r
526         if(SendQuit == YES)\r
527                 // 同時接続対応\r
528 //              Ret = command(ctrl_skt, NULL, &CheckCancelFlg, "QUIT") / 100;\r
529                 Ret = command(ctrl_skt, NULL, &CancelFlg, "QUIT") / 100;\r
530 \r
531         return(Ret);\r
532 }\r
533 \r
534 \r
535 /*----- リモート側のディレクトリリストを取得(コマンドコントロールソケットを使用)\r
536 *\r
537 *       Parameter\r
538 *               char *AddOpt : 追加のオプション\r
539 *               char *Path : パス名\r
540 *               int Num : ファイル名番号\r
541 *\r
542 *       Return Value\r
543 *               int 応答コードの1桁目\r
544 *----------------------------------------------------------------------------*/\r
545 \r
546 int DoDirListCmdSkt(char *AddOpt, char *Path, int Num, int *CancelCheckWork)\r
547 {\r
548         int Sts;\r
549 \r
550         if(AskTransferNow() == YES)\r
551                 SktShareProh();\r
552 \r
553 //      if((Sts = DoDirList(NULL, AskCmdCtrlSkt(), AddOpt, Path, Num)) == 429)\r
554 //      {\r
555 //              ReConnectCmdSkt();\r
556                 Sts = DoDirList(NULL, AskCmdCtrlSkt(), AddOpt, Path, Num, CancelCheckWork);\r
557 \r
558                 if(Sts/100 >= FTP_CONTINUE)\r
559                         SoundPlay(SND_ERROR);\r
560 //      }\r
561         return(Sts/100);\r
562 }\r
563 \r
564 \r
565 /*----- リモート側のディレクトリリストを取得 ----------------------------------\r
566 *\r
567 *       Parameter\r
568 *               HWND hWnd : 転送中ダイアログのウインドウハンドル\r
569 *               SOCKET cSkt : コントロールソケット\r
570 *               char *AddOpt : 追加のオプション\r
571 *               char *Path : パス名 (""=カレントディレクトリ)\r
572 *               int Num : ファイル名番号\r
573 *\r
574 *       Return Value\r
575 *               int 応答コード\r
576 *----------------------------------------------------------------------------*/\r
577 \r
578 static int DoDirList(HWND hWnd, SOCKET cSkt, char *AddOpt, char *Path, int Num, int *CancelCheckWork)\r
579 {\r
580         char Tmp[FMAX_PATH];\r
581         int Sts;\r
582 \r
583 //#pragma aaa\r
584 //DoPrintf("===== DoDirList %d = %s", Num, Path);\r
585 \r
586         MakeCacheFileName(Num, Tmp);\r
587 //      MainTransPkt.ctrl_skt = cSkt;\r
588 \r
589         if(AskListCmdMode() == NO)\r
590         {\r
591                 strcpy(MainTransPkt.Cmd, "NLST");\r
592                 if(strlen(AskHostLsName()) > 0)\r
593                 {\r
594                         strcat(MainTransPkt.Cmd, " ");\r
595                         if((AskHostType() == HTYPE_ACOS) || (AskHostType() == HTYPE_ACOS_4))\r
596                                 strcat(MainTransPkt.Cmd, "'");\r
597                         strcat(MainTransPkt.Cmd, AskHostLsName());\r
598                         if((AskHostType() == HTYPE_ACOS) || (AskHostType() == HTYPE_ACOS_4))\r
599                                 strcat(MainTransPkt.Cmd, "'");\r
600                 }\r
601                 if(strlen(AddOpt) > 0)\r
602                         strcat(MainTransPkt.Cmd, AddOpt);\r
603         }\r
604         else\r
605         {\r
606                 // MLSD対応\r
607 //              strcpy(MainTransPkt.Cmd, "LIST");\r
608                 if(AskUseMLSD() && (AskHostFeature() & FEATURE_MLSD))\r
609                         strcpy(MainTransPkt.Cmd, "MLSD");\r
610                 else\r
611                         strcpy(MainTransPkt.Cmd, "LIST");\r
612                 if(strlen(AddOpt) > 0)\r
613                 {\r
614                         strcat(MainTransPkt.Cmd, " -");\r
615                         strcat(MainTransPkt.Cmd, AddOpt);\r
616                 }\r
617         }\r
618 \r
619         if(strlen(Path) > 0)\r
620                 strcat(MainTransPkt.Cmd, " ");\r
621 \r
622         strcpy(MainTransPkt.RemoteFile, Path);\r
623         strcpy(MainTransPkt.LocalFile, Tmp);\r
624         MainTransPkt.Type = TYPE_A;\r
625         MainTransPkt.Size = -1;\r
626         /* ファイルリストの中の漢字のファイル名は、別途   */\r
627         /* ChangeFnameRemote2Local で変換する                      */\r
628         MainTransPkt.KanjiCode = KANJI_NOCNV;\r
629         MainTransPkt.KanaCnv = YES;\r
630         MainTransPkt.Mode = EXIST_OVW;\r
631         MainTransPkt.ExistSize = 0;\r
632         MainTransPkt.hWndTrans = hWnd;\r
633         MainTransPkt.Next = NULL;\r
634 \r
635         Sts = DoDownLoad(cSkt, &MainTransPkt, YES, CancelCheckWork);\r
636 \r
637 //#pragma aaa\r
638 //DoPrintf("===== DoDirList Done.");\r
639 \r
640         return(Sts);\r
641 }\r
642 \r
643 \r
644 /*----- リモート側へコマンドを送りリプライを待つ(コマンドソケット)-----------\r
645 *\r
646 *       Parameter\r
647 *               char *Reply : リプライのコピー先 (NULL=コピーしない)\r
648 *               char *fmt : フォーマット文字列\r
649 *               ... : パラメータ\r
650 *\r
651 *       Return Value\r
652 *               int 応答コード\r
653 *\r
654 *       Note\r
655 *               コマンドコントロールソケットを使う\r
656 *----------------------------------------------------------------------------*/\r
657 \r
658 int CommandProcCmd(char *Reply, char *fmt, ...)\r
659 {\r
660         va_list Args;\r
661         char Cmd[1024];\r
662         int Sts;\r
663 \r
664         va_start(Args, fmt);\r
665         wvsprintf(Cmd, fmt, Args);\r
666         va_end(Args);\r
667 \r
668         if(AskTransferNow() == YES)\r
669                 SktShareProh();\r
670 \r
671 //#pragma aaa\r
672 //DoPrintf("**CommandProcCmd : %s", Cmd);\r
673 \r
674 //      if((Sts = command(AskCmdCtrlSkt(), Reply, "%s", Cmd)) == 429)\r
675 //      {\r
676 //              if(ReConnectCmdSkt() == FFFTP_SUCCESS)\r
677 //              {\r
678                         // 同時接続対応\r
679 //                      Sts = command(AskCmdCtrlSkt(), Reply, &CheckCancelFlg, "%s", Cmd);\r
680                         Sts = command(AskCmdCtrlSkt(), Reply, &CancelFlg, "%s", Cmd);\r
681 //              }\r
682 //      }\r
683         return(Sts);\r
684 }\r
685 \r
686 \r
687 /*----- リモート側へコマンドを送りリプライを待つ(転送ソケット)---------------\r
688 *\r
689 *       Parameter\r
690 *               char *Reply : リプライのコピー先 (NULL=コピーしない)\r
691 *               char *fmt : フォーマット文字列\r
692 *               ... : パラメータ\r
693 *\r
694 *       Return Value\r
695 *               int 応答コード\r
696 *\r
697 *       Note\r
698 *               転送コントロールソケットを使う\r
699 *----------------------------------------------------------------------------*/\r
700 \r
701 // 同時接続対応\r
702 //int CommandProcTrn(char *Reply, char *fmt, ...)\r
703 int CommandProcTrn(SOCKET cSkt, char *Reply, int* CancelCheckWork, char *fmt, ...)\r
704 {\r
705         va_list Args;\r
706         char Cmd[1024];\r
707         int Sts;\r
708 \r
709         va_start(Args, fmt);\r
710         wvsprintf(Cmd, fmt, Args);\r
711         va_end(Args);\r
712 \r
713 //#pragma aaa\r
714 //DoPrintf("**CommandProcTrn : %s", Cmd);\r
715 \r
716 //      if((Sts = command(AskTrnCtrlSkt(), Reply, "%s", Cmd)) == 429)\r
717 //      {\r
718 //              if(ReConnectTrnSkt() == FFFTP_SUCCESS)\r
719 //                      Sts = command(AskTrnCtrlSkt(), Reply, &CheckCancelFlg, "%s", Cmd);\r
720                         Sts = command(cSkt, Reply, CancelCheckWork, "%s", Cmd);\r
721 //      }\r
722         return(Sts);\r
723 }\r
724 \r
725 \r
726 /*----- コマンドを送りリプライを待つ ------------------------------------------\r
727 *\r
728 *       Parameter\r
729 *               SOCKET cSkt : コントロールソケット\r
730 *               char *Reply : リプライのコピー先 (NULL=コピーしない)\r
731 *               char *fmt : フォーマット文字列\r
732 *               ... : パラメータ\r
733 *\r
734 *       Return Value\r
735 *               int 応答コード\r
736 *\r
737 *       Note\r
738 *               ホストのファイル名の漢字コードに応じて、ここで漢字コードの変換を行なう\r
739 *----------------------------------------------------------------------------*/\r
740 \r
741 //#pragma aaa\r
742 //static int cntcnt = 0;\r
743 \r
744 int command(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *fmt, ...)\r
745 {\r
746         va_list Args;\r
747         char Cmd[FMAX_PATH*2];\r
748         int Sts;\r
749         char TmpBuf[ONELINE_BUF_SIZE];\r
750 \r
751         if(cSkt != INVALID_SOCKET)\r
752         {\r
753                 va_start(Args, fmt);\r
754                 wvsprintf(Cmd, fmt, Args);\r
755                 va_end(Args);\r
756 \r
757                 if(strncmp(Cmd, "PASS ", 5) == 0)\r
758                         SetTaskMsg(">PASS [xxxxxx]");\r
759                 else if((strncmp(Cmd, "USER ", 5) == 0) ||\r
760                                 (strncmp(Cmd, "OPEN ", 5) == 0))\r
761                 {\r
762                         SetTaskMsg(">%s", Cmd);\r
763                 }\r
764                 else\r
765                 {\r
766                         ChangeSepaLocal2Remote(Cmd);\r
767                         SetTaskMsg(">%s", Cmd);\r
768                         ChangeFnameLocal2Remote(Cmd, FMAX_PATH*2);\r
769                 }\r
770 \r
771 //              DoPrintf("SEND : %s", Cmd);\r
772                 strcat(Cmd, "\x0D\x0A");\r
773 \r
774                 if(Reply != NULL)\r
775                         strcpy(Reply, "");\r
776 \r
777                 Sts = 429;\r
778                 if(SendData(cSkt, Cmd, strlen(Cmd), 0, CancelCheckWork) == FFFTP_SUCCESS)\r
779                 {\r
780                         Sts = ReadReplyMessage(cSkt, Reply, 1024, CancelCheckWork, TmpBuf);\r
781                 }\r
782 \r
783 //#pragma aaa\r
784 //if(Reply != NULL)\r
785 //      DoPrintf("%x : %x : %s : %s", cSkt, &TmpBuf, Cmd, Reply);\r
786 //else\r
787 //      DoPrintf("%x : %x : %s : NULL", cSkt, &TmpBuf, Cmd);\r
788 \r
789 //              DoPrintf("command() RET=%d", Sts);\r
790         }\r
791         else\r
792                 Sts = 429;\r
793 \r
794         return(Sts);\r
795 }\r
796 \r
797 \r
798 /*----- データを送る ----------------------------------------------------------\r
799 *\r
800 *       Parameter\r
801 *               SOCKET Skt : ソケット\r
802 *               char *Data : データ\r
803 *               int Size : 送るデータのサイズ\r
804 *               int Mode : コールモード\r
805 *\r
806 *       Return Value\r
807 *               int ステータス\r
808 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
809 *----------------------------------------------------------------------------*/\r
810 \r
811 int SendData(SOCKET Skt, char *Data, int Size, int Mode, int *CancelCheckWork)\r
812 {\r
813         int Sts;\r
814         int Tmp;\r
815 //      fd_set SendFds;\r
816 //      struct timeval Tout;\r
817 //      struct timeval *ToutPtr;\r
818         int TimeOutErr;\r
819 \r
820         Sts = FFFTP_FAIL;\r
821         if(Skt != INVALID_SOCKET)\r
822         {\r
823                 Sts = FFFTP_SUCCESS;\r
824                 while(Size > 0)\r
825                 {\r
826 //                      FD_ZERO(&SendFds);\r
827 //                      FD_SET(Skt, &SendFds);\r
828 //                      ToutPtr = NULL;\r
829 //                      if(TimeOut != 0)\r
830 //                      {\r
831 //                              Tout.tv_sec = TimeOut;\r
832 //                              Tout.tv_usec = 0;\r
833 //                              ToutPtr = &Tout;\r
834 //                      }\r
835 //                      Tmp = select(0, NULL, &SendFds, NULL, ToutPtr);\r
836 //                      if(Tmp == SOCKET_ERROR)\r
837 //                      {\r
838 //                              Sts = FFFTP_FAIL;\r
839 //                              ReportWSError("select", WSAGetLastError());\r
840 //                              break;\r
841 //                      }\r
842 //                      else if(Tmp == 0)\r
843 //                      {\r
844 //                              Sts = FFFTP_FAIL;\r
845 //                              SetTaskMsg(MSGJPN241);\r
846 //                              break;\r
847 //                      }\r
848 \r
849                         Tmp = do_send(Skt, Data, Size, Mode, &TimeOutErr, CancelCheckWork);\r
850                         if(TimeOutErr == YES)\r
851                         {\r
852                                 Sts = FFFTP_FAIL;\r
853                                 SetTaskMsg(MSGJPN241);\r
854                                 break;\r
855                         }\r
856                         else if(Tmp == SOCKET_ERROR)\r
857                         {\r
858                                 Sts = FFFTP_FAIL;\r
859                                 ReportWSError("send", WSAGetLastError());\r
860                                 break;\r
861                         }\r
862 \r
863                         Size -= Tmp;\r
864                         Data += Tmp;\r
865                 }\r
866         }\r
867         return(Sts);\r
868 }\r
869 \r
870 \r
871 /*----- 応答メッセージを受け取る ----------------------------------------------\r
872 *\r
873 *       Parameter\r
874 *               SOCKET cSkt : コントロールソケット\r
875 *               char *Buf : メッセージを受け取るバッファ (NULL=コピーしない)\r
876 *               int Max : バッファのサイズ\r
877 *               int *CancelCheckWork :\r
878 *               char *Tmp : テンポラリワーク\r
879 *\r
880 *       Return Value\r
881 *               int 応答コード\r
882 *----------------------------------------------------------------------------*/\r
883 \r
884 int ReadReplyMessage(SOCKET cSkt, char *Buf, int Max, int *CancelCheckWork, char *Tmp)\r
885 {\r
886         int iRetCode;\r
887         int iContinue;\r
888         int FirstCode;\r
889         int Lines;\r
890         int i;\r
891 \r
892         if(Buf != NULL)\r
893                 memset(Buf, NUL, Max);\r
894         Max--;\r
895 \r
896         FirstCode = 0;\r
897         if(cSkt != INVALID_SOCKET)\r
898         {\r
899                 Lines = 0;\r
900                 do\r
901                 {\r
902                         iContinue = NO;\r
903                         iRetCode = ReadOneLine(cSkt, Tmp, ONELINE_BUF_SIZE, CancelCheckWork);\r
904 \r
905                         SetTaskMsg("%s", Tmp);\r
906 \r
907                         if(Buf != NULL)\r
908                         {\r
909                                 // 2行目以降の応答コードは消す\r
910                                 if(Lines > 0)\r
911                                 {\r
912                                         for(i = 0; ; i++)\r
913                                         {\r
914                                                 if(IsDigit(Tmp[i]) == 0)\r
915                                                         break;\r
916                                                 Tmp[i] = ' ';\r
917                                         }\r
918                                 }\r
919                                 strncat(Buf, Tmp, Max);\r
920                                 Max = max1(0, Max-strlen(Tmp));\r
921 \r
922 //                              strncpy(Buf, Tmp, Max);\r
923                         }\r
924 \r
925                         if((iRetCode != 421) && (iRetCode != 429))\r
926                         {\r
927                                 if((FirstCode == 0) &&\r
928                                    (iRetCode >= 100) && (iRetCode <= 599))\r
929                                 {\r
930                                         FirstCode = iRetCode;\r
931                                 }\r
932 \r
933                                 if((iRetCode < 100) || (iRetCode > 599) ||\r
934                                    (*(Tmp + 3) == '-') ||\r
935                                    ((FirstCode > 0) && (iRetCode != FirstCode)))\r
936                                 {\r
937                                         iContinue = YES;\r
938                                 }\r
939                         }\r
940                         else\r
941                                 FirstCode = iRetCode;\r
942 \r
943                         Lines++;\r
944                 }\r
945                 while(iContinue == YES);\r
946         }\r
947         return(FirstCode);\r
948 }\r
949 \r
950 \r
951 /*----- 1行分のデータを受け取る ----------------------------------------------\r
952 *\r
953 *       Parameter\r
954 *               SOCKET cSkt : コントロールソケット\r
955 *               char *Buf : メッセージを受け取るバッファ\r
956 *               int Max : バッファのサイズ\r
957 *               int *CancelCheckWork : \r
958 *\r
959 *       Return Value\r
960 *               int 応答コード\r
961 *----------------------------------------------------------------------------*/\r
962 \r
963 static int ReadOneLine(SOCKET cSkt, char *Buf, int Max, int *CancelCheckWork)\r
964 {\r
965         char *Pos;\r
966         int SizeOnce;\r
967         int CopySize;\r
968         int ResCode;\r
969         int i;\r
970 //      fd_set ReadFds;\r
971 //      struct timeval Tout;\r
972 //      struct timeval *ToutPtr;\r
973         char Tmp[1024];\r
974         int TimeOutErr;\r
975 \r
976         ResCode = 0;\r
977         if(cSkt != INVALID_SOCKET)\r
978         {\r
979                 memset(Buf, NUL, Max);\r
980                 Max--;                                  /* 末尾のNULLのぶん */\r
981                 Pos = Buf;\r
982 \r
983                 for(;;)\r
984                 {\r
985 //                      FD_ZERO(&ReadFds);\r
986 //                      FD_SET(cSkt, &ReadFds);\r
987 //                      ToutPtr = NULL;\r
988 //                      if(TimeOut != 0)\r
989 //                      {\r
990 //                              Tout.tv_sec = TimeOut;\r
991 //                              Tout.tv_usec = 0;\r
992 //                              ToutPtr = &Tout;\r
993 //                      }\r
994 //                      i = select(0, &ReadFds, NULL, NULL, ToutPtr);\r
995 //                      if(i == SOCKET_ERROR)\r
996 //                      {\r
997 //                              ReportWSError("select", WSAGetLastError());\r
998 //                              SizeOnce = -1;\r
999 //                              break;\r
1000 //                      }\r
1001 //                      else if(i == 0)\r
1002 //                      {\r
1003 //                              SetTaskMsg(MSGJPN242);\r
1004 //                              SizeOnce = -2;\r
1005 //                              break;\r
1006 //                      }\r
1007 \r
1008                         /* LFまでを受信するために、最初はPEEKで受信 */\r
1009                         if((SizeOnce = do_recv(cSkt, (LPSTR)Tmp, 1024, MSG_PEEK, &TimeOutErr, CancelCheckWork)) <= 0)\r
1010                         {\r
1011                                 if(TimeOutErr == YES)\r
1012                                 {\r
1013                                         SetTaskMsg(MSGJPN242);\r
1014                                         SizeOnce = -2;\r
1015                                 }\r
1016                                 else if(SizeOnce == SOCKET_ERROR)\r
1017                                 {\r
1018                                         SizeOnce = -1;\r
1019                                 }\r
1020                                 break;\r
1021                         }\r
1022 \r
1023                         /* LFを探して、あったらそこまでの長さをセット */\r
1024                         for(i = 0; i < SizeOnce ; i++)\r
1025                         {\r
1026                                 if(*(Tmp + i) == NUL || *(Tmp + i) == 0x0A)\r
1027                                 {\r
1028                                         SizeOnce = i + 1;\r
1029                                         break;\r
1030                                 }\r
1031                         }\r
1032 \r
1033                         /* 本受信 */\r
1034                         if((SizeOnce = do_recv(cSkt, Tmp, SizeOnce, 0, &TimeOutErr, CancelCheckWork)) <= 0)\r
1035                                 break;\r
1036 \r
1037                         CopySize = min1(Max, SizeOnce);\r
1038                         memcpy(Pos, Tmp, CopySize);\r
1039                         Pos += CopySize;\r
1040                         Max -= CopySize;\r
1041 \r
1042                         /* データがLFで終わっていたら1行終わり */\r
1043                         if(*(Tmp + SizeOnce - 1) == 0x0A)\r
1044                                 break;\r
1045                 }\r
1046                 *Pos = NUL;\r
1047 \r
1048                 if(SizeOnce <= 0)\r
1049                 {\r
1050                         ResCode = 429;\r
1051                         memset(Buf, 0, Max);\r
1052 \r
1053                         if((SizeOnce == -2) || (AskTransferNow() == YES))\r
1054                         // 転送中に全て中止を行うと不正なデータが得られる場合のバグ修正\r
1055 //                              DisconnectSet();\r
1056                                 cSkt = DoClose(cSkt);\r
1057                 }\r
1058                 else\r
1059                 {\r
1060                         if(IsDigit(*Buf) && IsDigit(*(Buf+1)) && IsDigit(*(Buf+2)))\r
1061                         {\r
1062                                 memset(Tmp, NUL, 4);\r
1063                                 strncpy(Tmp, Buf, 3);\r
1064                                 ResCode = atoi(Tmp);\r
1065                         }\r
1066 \r
1067                         /* 末尾の CR,LF,スペースを取り除く */\r
1068                         while((i=strlen(Buf))>2 &&\r
1069                                   (Buf[i-1]==0x0a || Buf[i-1]==0x0d || Buf[i-1]==' '))\r
1070                                 Buf[i-1]=0;\r
1071                 }\r
1072         }\r
1073         return(ResCode);\r
1074 }\r
1075 \r
1076 \r
1077 /*----- 固定長データを受け取る ------------------------------------------------\r
1078 *\r
1079 *       Parameter\r
1080 *               SOCKET cSkt : コントロールソケット\r
1081 *               char *Buf : メッセージを受け取るバッファ\r
1082 *               int Size : バイト数\r
1083 *               int *CancelCheckWork : \r
1084 *\r
1085 *       Return Value\r
1086 *               int ステータス\r
1087 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1088 *----------------------------------------------------------------------------*/\r
1089 \r
1090 int ReadNchar(SOCKET cSkt, char *Buf, int Size, int *CancelCheckWork)\r
1091 {\r
1092 //      struct timeval Tout;\r
1093 //      struct timeval *ToutPtr;\r
1094 //      fd_set ReadFds;\r
1095 //      int i;\r
1096         int SizeOnce;\r
1097         int Sts;\r
1098         int TimeOutErr;\r
1099 \r
1100         Sts = FFFTP_FAIL;\r
1101         if(cSkt != INVALID_SOCKET)\r
1102         {\r
1103                 Sts = FFFTP_SUCCESS;\r
1104                 while(Size > 0)\r
1105                 {\r
1106 //                      FD_ZERO(&ReadFds);\r
1107 //                      FD_SET(cSkt, &ReadFds);\r
1108 //                      ToutPtr = NULL;\r
1109 //                      if(TimeOut != 0)\r
1110 //                      {\r
1111 //                              Tout.tv_sec = TimeOut;\r
1112 //                              Tout.tv_usec = 0;\r
1113 //                              ToutPtr = &Tout;\r
1114 //                      }\r
1115 //                      i = select(0, &ReadFds, NULL, NULL, ToutPtr);\r
1116 //                      if(i == SOCKET_ERROR)\r
1117 //                      {\r
1118 //                              ReportWSError("select", WSAGetLastError());\r
1119 //                              Sts = FFFTP_FAIL;\r
1120 //                              break;\r
1121 //                      }\r
1122 //                      else if(i == 0)\r
1123 //                      {\r
1124 //                              SetTaskMsg(MSGJPN243);\r
1125 //                              Sts = FFFTP_FAIL;\r
1126 //                              break;\r
1127 //                      }\r
1128 \r
1129                         if((SizeOnce = do_recv(cSkt, Buf, Size, 0, &TimeOutErr, CancelCheckWork)) <= 0)\r
1130                         {\r
1131                                 if(TimeOutErr == YES)\r
1132                                         SetTaskMsg(MSGJPN243);\r
1133                                 Sts = FFFTP_FAIL;\r
1134                                 break;\r
1135                         }\r
1136 \r
1137                         Buf += SizeOnce;\r
1138                         Size -= SizeOnce;\r
1139                 }\r
1140         }\r
1141 \r
1142         if(Sts == FFFTP_FAIL)\r
1143                 SetTaskMsg(MSGJPN244);\r
1144 \r
1145         return(Sts);\r
1146 }\r
1147 \r
1148 \r
1149 /*----- エラー文字列を取得 ----------------------------------------------------\r
1150 *\r
1151 *       Parameter\r
1152 *               UINT Error : エラー番号\r
1153 *\r
1154 *       Return Value\r
1155 *               char *エラー文字列\r
1156 *----------------------------------------------------------------------------*/\r
1157 \r
1158 char *ReturnWSError(UINT Error)\r
1159 {\r
1160         static char Msg[128];\r
1161         char *Str;\r
1162 \r
1163         switch(Error)\r
1164         {\r
1165                 case WSAVERNOTSUPPORTED:\r
1166                         Str = "version of WinSock not supported";\r
1167                         break;\r
1168 \r
1169                 case WSASYSNOTREADY:\r
1170                         Str = "WinSock not present or not responding";\r
1171                         break;\r
1172 \r
1173                 case WSAEINVAL:\r
1174                         Str = "app version not supported by DLL";\r
1175                         break;\r
1176 \r
1177                 case WSAHOST_NOT_FOUND:\r
1178                         Str = "Authoritive: Host not found";\r
1179                         break;\r
1180 \r
1181                 case WSATRY_AGAIN:\r
1182                         Str = "Non-authoritive: host not found or server failure";\r
1183                         break;\r
1184 \r
1185                 case WSANO_RECOVERY:\r
1186                         Str = "Non-recoverable: refused or not implemented";\r
1187                         break;\r
1188 \r
1189                 case WSANO_DATA:\r
1190                         Str = "Valid name, no data record for type";\r
1191                         break;\r
1192 \r
1193 #if 0\r
1194                 case WSANO_ADDRESS:\r
1195                         Str = "Valid name, no MX record";\r
1196                         break;\r
1197 #endif\r
1198 \r
1199                 case WSANOTINITIALISED:\r
1200                         Str = "WSA Startup not initialized";\r
1201                         break;\r
1202 \r
1203                 case WSAENETDOWN:\r
1204                         Str = "Network subsystem failed";\r
1205                         break;\r
1206 \r
1207                 case WSAEINPROGRESS:\r
1208                         Str = "Blocking operation in progress";\r
1209                         break;\r
1210 \r
1211                 case WSAEINTR:\r
1212                         Str = "Blocking call cancelled";\r
1213                         break;\r
1214 \r
1215                 case WSAEAFNOSUPPORT:\r
1216                         Str = "address family not supported";\r
1217                         break;\r
1218 \r
1219                 case WSAEMFILE:\r
1220                         Str = "no file descriptors available";\r
1221                         break;\r
1222 \r
1223                 case WSAENOBUFS:\r
1224                         Str = "no buffer space available";\r
1225                         break;\r
1226 \r
1227                 case WSAEPROTONOSUPPORT:\r
1228                         Str = "specified protocol not supported";\r
1229                         break;\r
1230 \r
1231                 case WSAEPROTOTYPE:\r
1232                         Str = "protocol wrong type for this socket";\r
1233                         break;\r
1234 \r
1235                 case WSAESOCKTNOSUPPORT:\r
1236                         Str = "socket type not supported for address family";\r
1237                         break;\r
1238 \r
1239                 case WSAENOTSOCK:\r
1240                         Str = "descriptor is not a socket";\r
1241                         break;\r
1242 \r
1243                 case WSAEWOULDBLOCK:\r
1244                         Str = "socket marked as non-blocking and SO_LINGER set not 0";\r
1245                         break;\r
1246 \r
1247                 case WSAEADDRINUSE:\r
1248                         Str = "address already in use";\r
1249                         break;\r
1250 \r
1251                 case WSAECONNABORTED:\r
1252                         Str = "connection aborted";\r
1253                         break;\r
1254 \r
1255                 case WSAECONNRESET:\r
1256                         Str = "connection reset";\r
1257                         break;\r
1258 \r
1259                 case WSAENOTCONN:\r
1260                         Str = "not connected";\r
1261                         break;\r
1262 \r
1263                 case WSAETIMEDOUT:\r
1264                         Str = "connection timed out";\r
1265                         break;\r
1266 \r
1267                 case WSAECONNREFUSED:\r
1268                         Str = "connection refused";\r
1269                         break;\r
1270 \r
1271                 case WSAEHOSTDOWN:\r
1272                         Str = "host down";\r
1273                         break;\r
1274 \r
1275                 case WSAEHOSTUNREACH:\r
1276                         Str = "host unreachable";\r
1277                         break;\r
1278 \r
1279                 case WSAEADDRNOTAVAIL:\r
1280                         Str = "address not available";\r
1281                         break;\r
1282 \r
1283                 default:\r
1284                         sprintf(Msg, "error %u", Error);\r
1285                         return(Msg);\r
1286         }\r
1287         return(Str);\r
1288 }\r
1289 \r
1290 \r
1291 /*----- デバッグコンソールにエラーを表示 --------------------------------------\r
1292 *\r
1293 *       Parameter\r
1294 *               char *Msg : エラーの前に表示するメッセージ\r
1295 *               UINT Error : エラー番号\r
1296 *\r
1297 *       Return Value\r
1298 *               なし\r
1299 *----------------------------------------------------------------------------*/\r
1300 \r
1301 void ReportWSError(char *Msg, UINT Error)\r
1302 {\r
1303         if(Msg != NULL)\r
1304                 DoPrintf("[[%s : %s]]", Msg, ReturnWSError(Error));\r
1305         else\r
1306                 DoPrintf("[[%s]]", ReturnWSError(Error));\r
1307 }\r
1308 \r
1309 \r
1310 /*----- ファイル名をローカル側で扱えるように変換する --------------------------\r
1311 *\r
1312 *       Parameter\r
1313 *               char *Fname : ファイル名\r
1314 *               int Max : 最大長\r
1315 *\r
1316 *       Return Value\r
1317 *               int ステータス\r
1318 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1319 *----------------------------------------------------------------------------*/\r
1320 \r
1321 int ChangeFnameRemote2Local(char *Fname, int Max)\r
1322 {\r
1323         int Sts;\r
1324         char *Buf;\r
1325         char *Pos;\r
1326         CODECONVINFO cInfo;\r
1327 \r
1328         Sts = FFFTP_FAIL;\r
1329         if((Buf = malloc(Max)) != NULL)\r
1330         {\r
1331                 InitCodeConvInfo(&cInfo);\r
1332                 cInfo.KanaCnv = NO;                     //AskHostNameKana();\r
1333                 cInfo.Str = Fname;\r
1334                 cInfo.StrLen = strlen(Fname);\r
1335                 cInfo.Buf = Buf;\r
1336                 cInfo.BufSize = Max - 1;\r
1337 \r
1338                 // ここで全てUTF-8へ変換する\r
1339                 // TODO: SJIS以外も直接UTF-8へ変換\r
1340                 switch(AskHostNameKanji())\r
1341                 {\r
1342                         case KANJI_SJIS :\r
1343                                 ConvSJIStoUTF8N(&cInfo);\r
1344                                 *(Buf + cInfo.OutLen) = NUL;\r
1345                                 strcpy(Fname, Buf);\r
1346                                 Pos = strchr(Fname, NUL);\r
1347                                 FlushRestData(&cInfo);\r
1348                                 *(Buf + cInfo.OutLen) = NUL;\r
1349                                 strcpy(Pos, Buf);\r
1350                                 break;\r
1351 \r
1352                         case KANJI_JIS :\r
1353                                 ConvJIStoSJIS(&cInfo);\r
1354                                 *(Buf + cInfo.OutLen) = NUL;\r
1355                                 strcpy(Fname, Buf);\r
1356                                 Pos = strchr(Fname, NUL);\r
1357                                 FlushRestData(&cInfo);\r
1358                                 *(Buf + cInfo.OutLen) = NUL;\r
1359                                 strcpy(Pos, Buf);\r
1360                                 // TODO\r
1361                                 InitCodeConvInfo(&cInfo);\r
1362                                 cInfo.KanaCnv = NO;\r
1363                                 cInfo.Str = Fname;\r
1364                                 cInfo.StrLen = strlen(Fname);\r
1365                                 cInfo.Buf = Buf;\r
1366                                 cInfo.BufSize = Max - 1;\r
1367                                 ConvSJIStoUTF8N(&cInfo);\r
1368                                 *(Buf + cInfo.OutLen) = NUL;\r
1369                                 strcpy(Fname, Buf);\r
1370                                 Pos = strchr(Fname, NUL);\r
1371                                 FlushRestData(&cInfo);\r
1372                                 *(Buf + cInfo.OutLen) = NUL;\r
1373                                 strcpy(Pos, Buf);\r
1374                                 break;\r
1375 \r
1376                         case KANJI_EUC :\r
1377                                 ConvEUCtoSJIS(&cInfo);\r
1378                                 *(Buf + cInfo.OutLen) = NUL;\r
1379                                 strcpy(Fname, Buf);\r
1380                                 Pos = strchr(Fname, NUL);\r
1381                                 FlushRestData(&cInfo);\r
1382                                 *(Buf + cInfo.OutLen) = NUL;\r
1383                                 strcpy(Pos, Buf);\r
1384                                 // TODO\r
1385                                 InitCodeConvInfo(&cInfo);\r
1386                                 cInfo.KanaCnv = NO;\r
1387                                 cInfo.Str = Fname;\r
1388                                 cInfo.StrLen = strlen(Fname);\r
1389                                 cInfo.Buf = Buf;\r
1390                                 cInfo.BufSize = Max - 1;\r
1391                                 ConvSJIStoUTF8N(&cInfo);\r
1392                                 *(Buf + cInfo.OutLen) = NUL;\r
1393                                 strcpy(Fname, Buf);\r
1394                                 Pos = strchr(Fname, NUL);\r
1395                                 FlushRestData(&cInfo);\r
1396                                 *(Buf + cInfo.OutLen) = NUL;\r
1397                                 strcpy(Pos, Buf);\r
1398                                 break;\r
1399 \r
1400                         case KANJI_SMB_HEX :\r
1401                         case KANJI_SMB_CAP :\r
1402                                 ConvSMBtoSJIS(&cInfo);\r
1403                                 *(Buf + cInfo.OutLen) = NUL;\r
1404                                 strcpy(Fname, Buf);\r
1405                                 Pos = strchr(Fname, NUL);\r
1406                                 FlushRestData(&cInfo);\r
1407                                 *(Buf + cInfo.OutLen) = NUL;\r
1408                                 strcpy(Pos, Buf);\r
1409                                 // TODO\r
1410                                 InitCodeConvInfo(&cInfo);\r
1411                                 cInfo.KanaCnv = NO;\r
1412                                 cInfo.Str = Fname;\r
1413                                 cInfo.StrLen = strlen(Fname);\r
1414                                 cInfo.Buf = Buf;\r
1415                                 cInfo.BufSize = Max - 1;\r
1416                                 ConvSJIStoUTF8N(&cInfo);\r
1417                                 *(Buf + cInfo.OutLen) = NUL;\r
1418                                 strcpy(Fname, Buf);\r
1419                                 Pos = strchr(Fname, NUL);\r
1420                                 FlushRestData(&cInfo);\r
1421                                 *(Buf + cInfo.OutLen) = NUL;\r
1422                                 strcpy(Pos, Buf);\r
1423                                 break;\r
1424 \r
1425 //                      case KANJI_UTF8N :\r
1426 //                              ConvUTF8NtoSJIS(&cInfo);\r
1427 //                              *(Buf + cInfo.OutLen) = NUL;\r
1428 //                              strcpy(Fname, Buf);\r
1429 //                              Pos = strchr(Fname, NUL);\r
1430 //                              FlushRestData(&cInfo);\r
1431 //                              *(Buf + cInfo.OutLen) = NUL;\r
1432 //                              strcpy(Pos, Buf);\r
1433 //                              break;\r
1434                 }\r
1435                 free(Buf);\r
1436                 Sts = FFFTP_SUCCESS;\r
1437         }\r
1438         return(Sts);\r
1439 }\r
1440 \r
1441 \r
1442 /*----- ファイル名をリモート側で扱えるように変換する --------------------------\r
1443 *\r
1444 *       Parameter\r
1445 *               char *Fname : ファイル名\r
1446 *               int Max : 最大長\r
1447 *\r
1448 *       Return Value\r
1449 *               int ステータス\r
1450 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1451 *----------------------------------------------------------------------------*/\r
1452 \r
1453 int ChangeFnameLocal2Remote(char *Fname, int Max)\r
1454 {\r
1455         int Sts;\r
1456         char *Buf;\r
1457         char *Pos;\r
1458         CODECONVINFO cInfo;\r
1459 \r
1460         Sts = FFFTP_FAIL;\r
1461         if((Buf = malloc(Max)) != NULL)\r
1462         {\r
1463                 InitCodeConvInfo(&cInfo);\r
1464                 cInfo.KanaCnv = AskHostNameKana();\r
1465                 cInfo.Str = Fname;\r
1466                 cInfo.StrLen = strlen(Fname);\r
1467                 cInfo.Buf = Buf;\r
1468                 cInfo.BufSize = Max - 1;\r
1469 \r
1470                 // ここで全てUTF-8から変換する\r
1471                 // TODO: SJIS以外も直接UTF-8から変換\r
1472                 switch(AskHostNameKanji())\r
1473                 {\r
1474                         case KANJI_SJIS :\r
1475                                 ConvUTF8NtoSJIS(&cInfo);\r
1476                                 *(Buf + cInfo.OutLen) = NUL;\r
1477                                 strcpy(Fname, Buf);\r
1478                                 Pos = strchr(Fname, NUL);\r
1479                                 FlushRestData(&cInfo);\r
1480                                 *(Buf + cInfo.OutLen) = NUL;\r
1481                                 strcpy(Pos, Buf);\r
1482                                 break;\r
1483 \r
1484                         case KANJI_JIS :\r
1485                                 ConvUTF8NtoSJIS(&cInfo);\r
1486                                 *(Buf + cInfo.OutLen) = NUL;\r
1487                                 strcpy(Fname, Buf);\r
1488                                 Pos = strchr(Fname, NUL);\r
1489                                 FlushRestData(&cInfo);\r
1490                                 *(Buf + cInfo.OutLen) = NUL;\r
1491                                 strcpy(Pos, Buf);\r
1492                                 // TODO\r
1493                                 InitCodeConvInfo(&cInfo);\r
1494                                 cInfo.KanaCnv = NO;\r
1495                                 cInfo.Str = Fname;\r
1496                                 cInfo.StrLen = strlen(Fname);\r
1497                                 cInfo.Buf = Buf;\r
1498                                 cInfo.BufSize = Max - 1;\r
1499                                 ConvSJIStoJIS(&cInfo);\r
1500                                 *(Buf + cInfo.OutLen) = NUL;\r
1501                                 strcpy(Fname, Buf);\r
1502                                 Pos = strchr(Fname, NUL);\r
1503                                 FlushRestData(&cInfo);\r
1504                                 *(Buf + cInfo.OutLen) = NUL;\r
1505                                 strcpy(Pos, Buf);\r
1506                                 break;\r
1507 \r
1508                         case KANJI_EUC :\r
1509                                 ConvUTF8NtoSJIS(&cInfo);\r
1510                                 *(Buf + cInfo.OutLen) = NUL;\r
1511                                 strcpy(Fname, Buf);\r
1512                                 Pos = strchr(Fname, NUL);\r
1513                                 FlushRestData(&cInfo);\r
1514                                 *(Buf + cInfo.OutLen) = NUL;\r
1515                                 strcpy(Pos, Buf);\r
1516                                 // TODO\r
1517                                 InitCodeConvInfo(&cInfo);\r
1518                                 cInfo.KanaCnv = NO;\r
1519                                 cInfo.Str = Fname;\r
1520                                 cInfo.StrLen = strlen(Fname);\r
1521                                 cInfo.Buf = Buf;\r
1522                                 cInfo.BufSize = Max - 1;\r
1523                                 ConvSJIStoEUC(&cInfo);\r
1524                                 *(Buf + cInfo.OutLen) = NUL;\r
1525                                 strcpy(Fname, Buf);\r
1526                                 Pos = strchr(Fname, NUL);\r
1527                                 FlushRestData(&cInfo);\r
1528                                 *(Buf + cInfo.OutLen) = NUL;\r
1529                                 strcpy(Pos, Buf);\r
1530                                 break;\r
1531 \r
1532                         case KANJI_SMB_HEX :\r
1533                                 ConvUTF8NtoSJIS(&cInfo);\r
1534                                 *(Buf + cInfo.OutLen) = NUL;\r
1535                                 strcpy(Fname, Buf);\r
1536                                 Pos = strchr(Fname, NUL);\r
1537                                 FlushRestData(&cInfo);\r
1538                                 *(Buf + cInfo.OutLen) = NUL;\r
1539                                 strcpy(Pos, Buf);\r
1540                                 // TODO\r
1541                                 InitCodeConvInfo(&cInfo);\r
1542                                 cInfo.KanaCnv = NO;\r
1543                                 cInfo.Str = Fname;\r
1544                                 cInfo.StrLen = strlen(Fname);\r
1545                                 cInfo.Buf = Buf;\r
1546                                 cInfo.BufSize = Max - 1;\r
1547                                 ConvSJIStoSMB_HEX(&cInfo);\r
1548                                 *(Buf + cInfo.OutLen) = NUL;\r
1549                                 strcpy(Fname, Buf);\r
1550                                 Pos = strchr(Fname, NUL);\r
1551                                 FlushRestData(&cInfo);\r
1552                                 *(Buf + cInfo.OutLen) = NUL;\r
1553                                 strcpy(Pos, Buf);\r
1554                                 break;\r
1555 \r
1556                         case KANJI_SMB_CAP :\r
1557                                 ConvUTF8NtoSJIS(&cInfo);\r
1558                                 *(Buf + cInfo.OutLen) = NUL;\r
1559                                 strcpy(Fname, Buf);\r
1560                                 Pos = strchr(Fname, NUL);\r
1561                                 FlushRestData(&cInfo);\r
1562                                 *(Buf + cInfo.OutLen) = NUL;\r
1563                                 strcpy(Pos, Buf);\r
1564                                 // TODO\r
1565                                 InitCodeConvInfo(&cInfo);\r
1566                                 cInfo.KanaCnv = NO;\r
1567                                 cInfo.Str = Fname;\r
1568                                 cInfo.StrLen = strlen(Fname);\r
1569                                 cInfo.Buf = Buf;\r
1570                                 cInfo.BufSize = Max - 1;\r
1571                                 ConvSJIStoSMB_CAP(&cInfo);\r
1572                                 *(Buf + cInfo.OutLen) = NUL;\r
1573                                 strcpy(Fname, Buf);\r
1574                                 Pos = strchr(Fname, NUL);\r
1575                                 FlushRestData(&cInfo);\r
1576                                 *(Buf + cInfo.OutLen) = NUL;\r
1577                                 strcpy(Pos, Buf);\r
1578                                 break;\r
1579 \r
1580 //                      case KANJI_UTF8N :\r
1581 //                              ConvSJIStoUTF8N(&cInfo);\r
1582 //                              *(Buf + cInfo.OutLen) = NUL;\r
1583 //                              strcpy(Fname, Buf);\r
1584 //                              Pos = strchr(Fname, NUL);\r
1585 //                              FlushRestData(&cInfo);\r
1586 //                              *(Buf + cInfo.OutLen) = NUL;\r
1587 //                              strcpy(Pos, Buf);\r
1588 //                              break;\r
1589                 }\r
1590                 free(Buf);\r
1591                 Sts = FFFTP_SUCCESS;\r
1592         }\r
1593         return(Sts);\r
1594 }\r
1595 \r
1596 \r
1597 /*----- パスの区切り文字をホストに合わせて変更する ----------------------------\r
1598 *\r
1599 *       Parameter\r
1600 *               char *Fname : ファイル名\r
1601 *\r
1602 *       Return Value\r
1603 *               なし\r
1604 *----------------------------------------------------------------------------*/\r
1605 static void ChangeSepaLocal2Remote(char *Fname)\r
1606 {\r
1607         if(AskHostType() == HTYPE_STRATUS)\r
1608         {\r
1609                 ReplaceAll(Fname, '/', '>');\r
1610         }\r
1611         return;\r
1612 }\r
1613 \r
1614 \r
1615 /*----- パスの区切り文字をローカルに合わせて変更する --------------------------\r
1616 *\r
1617 *       Parameter\r
1618 *               char *Fname : ファイル名\r
1619 *\r
1620 *       Return Value\r
1621 *               なし\r
1622 *----------------------------------------------------------------------------*/\r
1623 static void ChangeSepaRemote2Local(char *Fname)\r
1624 {\r
1625         if(AskHostType() == HTYPE_STRATUS)\r
1626         {\r
1627                 ReplaceAll(Fname, '>', '/');\r
1628         }\r
1629         return;\r
1630 }\r
1631 \r
1632 \r
1633 \r
1634 \r
1635 \r
1636 \r
1637 \r