OSDN Git Service

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