OSDN Git Service

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