OSDN Git Service

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