OSDN Git Service

Add routines for checking capability of MDTM and MFMT.
[ffftp/ffftp.git] / filelist.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 // UTF-8対応\r
31 //#define _WIN32_WINNT  0x400\r
32 \r
33 #define STRICT\r
34 // IPv6対応\r
35 #include <winsock2.h>\r
36 #include <windows.h>\r
37 #include <stdio.h>\r
38 #include <stdlib.h>\r
39 #include <string.h>\r
40 #include <ctype.h>\r
41 #include <time.h>\r
42 #include <mbstring.h>\r
43 #include <malloc.h>\r
44 #include <windowsx.h>\r
45 #include <commctrl.h>\r
46 #include <sys/types.h>\r
47 #include <sys/stat.h>\r
48 #include <direct.h>\r
49 \r
50 #include "common.h"\r
51 #include "resource.h"\r
52 \r
53 #include <htmlhelp.h>\r
54 #include "helpid.h"\r
55 \r
56 #include <shlobj.h>\r
57 #include "OleDragDrop.h"\r
58 #include "common.h"\r
59 \r
60 // UTF-8対応\r
61 #undef __MBSWRAPPER_H__\r
62 #include "mbswrapper.h"\r
63 \r
64 #define BUF_SIZE                256\r
65 #define CF_CNT 2\r
66 #define WM_DRAGDROP             (WM_APP + 100)\r
67 #define WM_GETDATA              (WM_APP + 101)\r
68 #define WM_DRAGOVER             (WM_APP + 102)\r
69 \r
70 \r
71 /*===== ファイルリストのリスト用ストラクチャ =====*/\r
72 \r
73 typedef struct {\r
74         FILELIST *Top;                  /* ファイルリストの先頭 */\r
75         int Files;                              /* ファイルの数 */\r
76 } FLISTANCHOR;\r
77 \r
78 /*===== プロトタイプ =====*/\r
79 \r
80 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
81 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
82 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
83 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win);\r
84 static void EraseDispFileList(FLISTANCHOR *Anchor);\r
85 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor);\r
86 // ファイルアイコン表示対応\r
87 //static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist);\r
88 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist, int ImageId);\r
89 // 64ビット対応\r
90 //static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
91 static INT_PTR CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
92 static void DispListList(FILELIST *Pos, char *Title);\r
93 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);\r
94 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);\r
95 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List);\r
96 static int GetListOneLine(char *Buf, int Max, FILE *Fd);\r
97 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir);\r
98 static void MakeLocalTree(char *Path, FILELIST **Base);\r
99 static void AddFileList(FILELIST *Pkt, FILELIST **Base);\r
100 static int AnalizeFileInfo(char *Str);\r
101 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day);\r
102 static int CheckHHMMformat(char *Str);\r
103 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3);\r
104 static int CheckYYYYMMDDformat(char *Str, char Sym);\r
105 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist);\r
106 static int FindField(char *Str, char *Buf, int Num, int ToLast);\r
107 // MLSD対応\r
108 static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast);\r
109 static void GetMonth(char *Str, WORD *Month, WORD *Day);\r
110 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day);\r
111 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute);\r
112 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day);\r
113 static int CheckSpecialDirName(char *Fname);\r
114 static int AskFilterStr(char *Fname, int Type);\r
115 // 64ビット対応\r
116 //static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
117 static INT_PTR CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
118 static int atoi_n(const char *Str, int Len);\r
119 \r
120 /*===== 外部参照 =====*/\r
121 \r
122 extern int SepaWidth;\r
123 extern int RemoteWidth;\r
124 extern int ListHeight;\r
125 extern char FilterStr[FILTER_EXT_LEN+1];\r
126 extern HWND hHelpWin;\r
127 // 外部アプリケーションへドロップ後にローカル側のファイル一覧に作業フォルダが表示されるバグ対策\r
128 extern int SuppressRefresh;\r
129 \r
130 /* 設定値 */\r
131 extern int LocalWidth;\r
132 extern int LocalTabWidth[4];\r
133 extern int RemoteTabWidth[6];\r
134 extern char UserMailAdrs[USER_MAIL_LEN+1];\r
135 extern HFONT ListFont;\r
136 extern int ListType;\r
137 extern int FindMode;\r
138 extern int DotFile;\r
139 extern int DispIgnoreHide;\r
140 extern int DispDrives;\r
141 extern int MoveMode;\r
142 \r
143 /*===== ローカルなワーク =====*/\r
144 \r
145 static HWND hWndListLocal = NULL;\r
146 static HWND hWndListRemote = NULL;\r
147 \r
148 static WNDPROC LocalProcPtr;\r
149 static WNDPROC RemoteProcPtr;\r
150 \r
151 static HIMAGELIST ListImg = NULL;\r
152 // ファイルアイコン表示対応\r
153 static HIMAGELIST ListImgFileIcon = NULL;\r
154 \r
155 static char FindStr[40+1] = { "*" };            /* 検索文字列 */\r
156 static int IgnoreNew = NO;\r
157 static int IgnoreOld = NO;\r
158 static int IgnoreExist = NO;\r
159 \r
160 static int Dragging = NO;\r
161 \r
162 static int StratusMode;                 /* 0=ファイル, 1=ディレクトリ, 2=リンク */\r
163 \r
164 \r
165 // リモートファイルリスト (2007.9.3 yutaka)\r
166 static FILELIST *remoteFileListBase;\r
167 static FILELIST *remoteFileListBaseNoExpand;\r
168 static char remoteFileDir[FMAX_PATH + 1];\r
169 \r
170 \r
171 /*----- ファイルリストウインドウを作成する ------------------------------------\r
172 *\r
173 *       Parameter\r
174 *               HWND hWnd : 親ウインドウのウインドウハンドル\r
175 *               HINSTANCE hInst : インスタンスハンドル\r
176 *\r
177 *       Return Value\r
178 *               int ステータス\r
179 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
180 *----------------------------------------------------------------------------*/\r
181 \r
182 int MakeListWin(HWND hWnd, HINSTANCE hInst)\r
183 {\r
184         int Sts;\r
185         LV_COLUMN LvCol;\r
186         long Tmp;\r
187 \r
188         // 変数が未初期化のバグ修正\r
189         memset(&LvCol, 0, sizeof(LV_COLUMN));\r
190 \r
191         /*===== ローカル側のリストビュー =====*/\r
192 \r
193         hWndListLocal = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
194                         WC_LISTVIEWA, NULL,\r
195                         WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,\r
196                         0, TOOLWIN_HEIGHT*2, LocalWidth, ListHeight,\r
197                         GetMainHwnd(), (HMENU)1500, hInst, NULL);\r
198 \r
199         if(hWndListLocal != NULL)\r
200         {\r
201                 // 64ビット対応\r
202 //              LocalProcPtr = (WNDPROC)SetWindowLong(hWndListLocal, GWL_WNDPROC, (LONG)LocalWndProc);\r
203                 LocalProcPtr = (WNDPROC)SetWindowLongPtr(hWndListLocal, GWLP_WNDPROC, (LONG_PTR)LocalWndProc);\r
204 \r
205             Tmp = SendMessage(hWndListLocal, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\r
206             Tmp |= LVS_EX_FULLROWSELECT;\r
207             SendMessage(hWndListLocal, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);\r
208 \r
209                 if(ListFont != NULL)\r
210                         SendMessage(hWndListLocal, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));\r
211 \r
212                 ListImg = ImageList_LoadBitmap(hInst, MAKEINTRESOURCE(dirattr_bmp), 16, 9, RGB(255,0,0));\r
213                 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
214                 ShowWindow(hWndListLocal, SW_SHOW);\r
215 \r
216                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
217                 LvCol.cx = LocalTabWidth[0];\r
218                 LvCol.pszText = MSGJPN038;\r
219                 LvCol.iSubItem = 0;\r
220                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);\r
221 \r
222                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
223                 LvCol.cx = LocalTabWidth[1];\r
224                 LvCol.pszText = MSGJPN039;\r
225                 LvCol.iSubItem = 1;\r
226                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);\r
227 \r
228                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;\r
229                 LvCol.fmt = LVCFMT_RIGHT;\r
230                 LvCol.cx = LocalTabWidth[2];\r
231                 LvCol.pszText = MSGJPN040;\r
232                 LvCol.iSubItem = 2;\r
233                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);\r
234 \r
235                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
236                 LvCol.cx = LocalTabWidth[3];\r
237                 LvCol.pszText = MSGJPN041;\r
238                 LvCol.iSubItem = 3;\r
239                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);\r
240         }\r
241 \r
242         /*===== ホスト側のリストビュー =====*/\r
243 \r
244         hWndListRemote = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
245                         WC_LISTVIEWA, NULL,\r
246                         WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,\r
247                         LocalWidth + SepaWidth, TOOLWIN_HEIGHT*2, RemoteWidth, ListHeight,\r
248                         GetMainHwnd(), (HMENU)1500, hInst, NULL);\r
249 \r
250         if(hWndListRemote != NULL)\r
251         {\r
252                 // 64ビット対応\r
253 //              RemoteProcPtr = (WNDPROC)SetWindowLong(hWndListRemote, GWL_WNDPROC, (LONG)RemoteWndProc);\r
254                 RemoteProcPtr = (WNDPROC)SetWindowLongPtr(hWndListRemote, GWLP_WNDPROC, (LONG_PTR)RemoteWndProc);\r
255 \r
256             Tmp = SendMessage(hWndListRemote, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\r
257             Tmp |= LVS_EX_FULLROWSELECT;\r
258             SendMessage(hWndListRemote, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);\r
259 \r
260                 if(ListFont != NULL)\r
261                         SendMessage(hWndListRemote, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));\r
262 \r
263                 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
264                 ShowWindow(hWndListRemote, SW_SHOW);\r
265 \r
266                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
267                 LvCol.cx = RemoteTabWidth[0];\r
268                 LvCol.pszText = MSGJPN042;\r
269                 LvCol.iSubItem = 0;\r
270                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);\r
271 \r
272                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
273                 LvCol.cx = RemoteTabWidth[1];\r
274                 LvCol.pszText = MSGJPN043;\r
275                 LvCol.iSubItem = 1;\r
276                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);\r
277 \r
278                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;\r
279                 LvCol.fmt = LVCFMT_RIGHT;\r
280                 LvCol.cx = RemoteTabWidth[2];\r
281                 LvCol.pszText = MSGJPN044;\r
282                 LvCol.iSubItem = 2;\r
283                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);\r
284 \r
285                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
286                 LvCol.cx = RemoteTabWidth[3];\r
287                 LvCol.pszText = MSGJPN045;\r
288                 LvCol.iSubItem = 3;\r
289                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);\r
290 \r
291                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
292                 LvCol.cx = RemoteTabWidth[4];\r
293                 LvCol.pszText = MSGJPN046;\r
294                 LvCol.iSubItem = 4;\r
295                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 4, (LPARAM)&LvCol);\r
296 \r
297                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
298                 LvCol.cx = RemoteTabWidth[5];\r
299                 LvCol.pszText = MSGJPN047;\r
300                 LvCol.iSubItem = 5;\r
301                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 5, (LPARAM)&LvCol);\r
302         }\r
303 \r
304         Sts = FFFTP_SUCCESS;\r
305         if((hWndListLocal == NULL) ||\r
306            (hWndListRemote == NULL))\r
307         {\r
308                 Sts = FFFTP_FAIL;\r
309         }\r
310         return(Sts);\r
311 }\r
312 \r
313 \r
314 /*----- ファイルリストウインドウを削除 ----------------------------------------\r
315 *\r
316 *       Parameter\r
317 *               なし\r
318 *\r
319 *       Return Value\r
320 *               なし\r
321 *----------------------------------------------------------------------------*/\r
322 \r
323 void DeleteListWin(void)\r
324 {\r
325 //      if(ListImg != NULL)\r
326 //              ImageList_Destroy(ListImg);\r
327         if(hWndListLocal != NULL)\r
328                 DestroyWindow(hWndListLocal);\r
329         if(hWndListRemote != NULL)\r
330                 DestroyWindow(hWndListRemote);\r
331         return;\r
332 }\r
333 \r
334 \r
335 /*----- ローカル側のファイルリストのウインドウハンドルを返す ------------------\r
336 *\r
337 *       Parameter\r
338 *               なし\r
339 *\r
340 *       Return Value\r
341 *               HWND ウインドウハンドル\r
342 *----------------------------------------------------------------------------*/\r
343 \r
344 HWND GetLocalHwnd(void)\r
345 {\r
346         return(hWndListLocal);\r
347 }\r
348 \r
349 \r
350 /*----- ホスト側のファイルリストのウインドウハンドルを返す --------------------\r
351 *\r
352 *       Parameter\r
353 *               なし\r
354 *\r
355 *       Return Value\r
356 *               HWND ウインドウハンドル\r
357 *----------------------------------------------------------------------------*/\r
358 \r
359 HWND GetRemoteHwnd(void)\r
360 {\r
361         return(hWndListRemote);\r
362 }\r
363 \r
364 \r
365 /*----- ローカル側のファイルリストウインドウのメッセージ処理 ------------------\r
366 *\r
367 *       Parameter\r
368 *               HWND hWnd : ウインドウハンドル\r
369 *               UINT message  : メッセージ番号\r
370 *               WPARAM wParam : メッセージの WPARAM 引数\r
371 *               LPARAM lParam : メッセージの LPARAM 引数\r
372 *\r
373 *       Return Value\r
374 *               メッセージに対応する戻り値\r
375 *----------------------------------------------------------------------------*/\r
376 \r
377 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
378 {\r
379         return(FileListCommonWndProc(hWnd, message, wParam, lParam));\r
380 }\r
381 \r
382 \r
383 /*----- ホスト側のファイルリストウインドウのメッセージ処理 --------------------\r
384 *\r
385 *       Parameter\r
386 *               HWND hWnd : ウインドウハンドル\r
387 *               UINT message  : メッセージ番号\r
388 *               WPARAM wParam : メッセージの WPARAM 引数\r
389 *               LPARAM lParam : メッセージの LPARAM 引数\r
390 *\r
391 *       Return Value\r
392 *               メッセージに対応する戻り値\r
393 *----------------------------------------------------------------------------*/\r
394 \r
395 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
396 {\r
397         return(FileListCommonWndProc(hWnd, message, wParam, lParam));\r
398 }\r
399 \r
400 \r
401 // ダイアログプロシージャ\r
402 static BOOL CALLBACK doOleDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)\r
403 {\r
404 #define TIMER_ID     (100)      // 作成するタイマの識別ID\r
405 #define TIMER_ELAPSE (100)       // WM_TIMERの発生間隔\r
406         MSG message;\r
407 \r
408         switch( msg ){\r
409         case WM_INITDIALOG:  // ダイアログボックスが作成されたとき\r
410                 SetTimer( hDlg, TIMER_ID, 0, NULL);\r
411                 return TRUE;\r
412 \r
413         case WM_TIMER:\r
414                 ShowWindow(hDlg, SW_HIDE);  // ダイアログは隠す\r
415 \r
416                 if (wp != TIMER_ID)\r
417                         break;\r
418 \r
419                 if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {\r
420                                 TranslateMessage(&message);\r
421                                 DispatchMessage(&message);\r
422 \r
423                 } else {\r
424                         if (AskTransferNow() == NO) {\r
425                                 EndDialog( hDlg, 0 );\r
426                                 return TRUE;\r
427                         }\r
428                 }\r
429 \r
430                 SetTimer( hDlg, TIMER_ID, TIMER_ELAPSE, NULL );\r
431                 return TRUE;\r
432 \r
433         case WM_COMMAND:     // ダイアログボックス内の何かが選択されたとき\r
434                 switch( LOWORD( wp ) ){\r
435 //              case IDOK:       // 「OK」ボタンが選択された\r
436                 case IDCANCEL:   // 「キャンセル」ボタンが選択された\r
437                         // ダイアログボックスを消す\r
438                         EndDialog( hDlg, 0 );\r
439                         break;\r
440                 }\r
441                 return TRUE;\r
442         }\r
443 \r
444         return FALSE;  // DefWindowProc()ではなく、FALSEを返すこと!\r
445 #undef TIMER_ID     \r
446 #undef TIMER_ELAPSE \r
447 }\r
448 \r
449 \r
450 static void doTransferRemoteFile(void)\r
451 {\r
452         FILELIST *FileListBase, *FileListBaseNoExpand, *pf;\r
453         int CancelFlg = NO;\r
454         char LocDir[FMAX_PATH+1];\r
455         char TmpDir[FMAX_PATH+1];\r
456         // 環境依存の不具合対策\r
457 //      char buf[32];\r
458         int i;\r
459         // 環境依存の不具合対策\r
460 //      DWORD pid;\r
461 \r
462         // すでにリモートから転送済みなら何もしない。(2007.9.3 yutaka)\r
463         if (remoteFileListBase != NULL)\r
464                 return;\r
465 \r
466         FileListBase = NULL;\r
467         MakeSelectedFileList(WIN_REMOTE, YES, NO, &FileListBase, &CancelFlg);\r
468         FileListBaseNoExpand = NULL;\r
469         MakeSelectedFileList(WIN_REMOTE, NO, NO, &FileListBaseNoExpand, &CancelFlg);\r
470 \r
471         // set temporary folder\r
472         AskLocalCurDir(LocDir, FMAX_PATH);\r
473 \r
474         // アプリを多重起動してもコンフリクトしないように、テンポラリフォルダ名にプロセスID\r
475         // を付加する。(2007.9.13 yutaka)\r
476         // 環境依存の不具合対策\r
477 //      GetTempPath(sizeof(TmpDir), TmpDir);\r
478 //      pid = GetCurrentProcessId();\r
479 //      _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ffftp%d", pid);\r
480 //      strncat_s(TmpDir, sizeof(TmpDir), buf, _TRUNCATE);\r
481         GetAppTempPath(TmpDir);\r
482         _mkdir(TmpDir);\r
483         SetYenTail(TmpDir);\r
484         strcat(TmpDir, "file");\r
485         _mkdir(TmpDir);\r
486 #if 0\r
487         if (TmpDir[strlen(TmpDir) - 1] == '\\') {\r
488                 TmpDir[strlen(TmpDir) - 1] = '\0';\r
489         }\r
490 #endif\r
491 \r
492         // 既存のファイルを削除する\r
493         for (pf = FileListBase ; pf ; pf = pf->Next) {\r
494                 char fn[FMAX_PATH+1];\r
495 \r
496                 strncpy_s(fn, sizeof(fn), TmpDir, _TRUNCATE);\r
497                 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
498                 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
499 \r
500                 remove(fn);\r
501         }\r
502 \r
503         // 同時接続対応\r
504         DisableUserOpe();\r
505         // 外部アプリケーションへドロップ後にローカル側のファイル一覧に作業フォルダが表示されるバグ対策\r
506         SuppressRefresh = 1;\r
507 \r
508         // ダウンロード先をテンポラリに設定\r
509         SetLocalDirHist(TmpDir);\r
510 \r
511         // FFFTPにダウンロード要求を出し、ダウンロードの完了を待つ。\r
512         PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);\r
513 \r
514         for (i = 0 ; i < 10 ; i++) {\r
515                 MSG msg;\r
516 \r
517                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\r
518                         TranslateMessage(&msg);\r
519                         DispatchMessage(&msg);\r
520 \r
521                 } else {\r
522                         // 転送スレッドが動き出したら抜ける。\r
523                         if (AskTransferNow() == YES)\r
524                                 break;\r
525                 }\r
526 \r
527                 Sleep(10);\r
528         }\r
529 \r
530         // OLE D&D中にメインウィンドウをユーザに操作させると、おかしくなるので、\r
531         // 隠しモーダルダイアログを作る。\r
532         // (2007.9.11 yutaka)\r
533         DialogBox(GetFtpInst(), MAKEINTRESOURCE(IDD_OLEDRAG), GetMainHwnd(), (DLGPROC)doOleDlgProc);\r
534 \r
535         // ダウンロード先を元に戻す\r
536         SetLocalDirHist(LocDir);\r
537         SetCurrentDirAsDirHist();\r
538 \r
539         // 外部アプリケーションへドロップ後にローカル側のファイル一覧に作業フォルダが表示されるバグ対策\r
540         SuppressRefresh = 0;\r
541         GetLocalDirForWnd();\r
542         // 同時接続対応\r
543         EnableUserOpe();\r
544 \r
545         remoteFileListBase = FileListBase;  // あとでフリーすること\r
546         remoteFileListBaseNoExpand = FileListBaseNoExpand;  // あとでフリーすること\r
547         strncpy_s(remoteFileDir, sizeof(remoteFileDir), TmpDir, _TRUNCATE);\r
548 \r
549 #if 0\r
550         // add temporary list\r
551         if (remoteFileListBase != NULL) {\r
552                 FILELIST *pf = remoteFileListBase;\r
553                 char fn[FMAX_PATH + 1];\r
554                 while (pf) {\r
555                         strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
556                         strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
557                         strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
558                         AddTempFileList(fn);\r
559                         pf = pf->Next;\r
560                 }\r
561         }\r
562 #endif\r
563 }\r
564 \r
565 \r
566 int isDirectory(char *fn)\r
567 {\r
568         struct _stat buf;\r
569 \r
570         if (_stat(fn, &buf) == 0) {\r
571                 if (buf.st_mode & _S_IFDIR) { // is directory\r
572                         return 1;\r
573                 }\r
574         }\r
575         return 0;\r
576 }\r
577 \r
578 // テンポラリのファイルおよびフォルダを削除する。\r
579 void doDeleteRemoteFile(void)\r
580 {\r
581         if (remoteFileListBase != NULL) {\r
582 #if 0\r
583                 int dirs = 0;\r
584                 int i, count;\r
585                 FILELIST *pf = remoteFileListBase;\r
586                 char fn[FMAX_PATH + 1];\r
587                 while (pf) {\r
588                         strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
589                         strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
590                         strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
591                         if (isDirectory(fn)) {\r
592                                 dirs++;\r
593                         } else {\r
594                                 remove(fn);\r
595                         }\r
596                         pf = pf->Next;\r
597                 }\r
598 \r
599                 count = 0;\r
600                 for (i = 0 ; i < 1000 ; i++) {\r
601                         pf = remoteFileListBase;\r
602                         while (pf) {\r
603                                 strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
604                                 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
605                                 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
606                                 if (isDirectory(fn)) {\r
607                                         if (_rmdir(fn) == 0) { // ディレクトリを消せたらカウントアップ\r
608                                                 count++;\r
609                                                 if (count >= dirs)  // すべて消せたら終わり\r
610                                                         goto skip;\r
611                                         }\r
612                                 }\r
613                                 pf = pf->Next;\r
614                         }\r
615                 }\r
616 skip:\r
617                 _rmdir(remoteFileDir);  // 自分で作ったディレクトリも消す\r
618 #else\r
619                 SHFILEOPSTRUCT FileOp = { NULL, FO_DELETE, remoteFileDir, NULL, \r
620                         FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI, \r
621                         FALSE, NULL, NULL };    \r
622                 SHFileOperation(&FileOp);\r
623 #endif\r
624 \r
625                 DeleteFileList(&remoteFileListBase);\r
626                 remoteFileListBase = NULL;\r
627         }\r
628 \r
629         if (remoteFileListBaseNoExpand != NULL) {\r
630                 DeleteFileList(&remoteFileListBaseNoExpand);\r
631                 remoteFileListBaseNoExpand = NULL;\r
632         }\r
633 }\r
634 \r
635 \r
636 // yutaka\r
637 // cf. http://www.nakka.com/lib/\r
638 /* ドロップファイルの作成 */\r
639 static HDROP APIPRIVATE CreateDropFileMem(char **FileName,int cnt,BOOL fWide)\r
640 {\r
641         HDROP hDrop;\r
642         LPDROPFILES lpDropFile;\r
643         wchar_t wbuf[BUF_SIZE];\r
644         int flen = 0;\r
645         int i;\r
646         \r
647         if(fWide == TRUE){\r
648                 /* ワイドキャラ */\r
649                 for(i = 0;i < cnt;i++){\r
650                         // UTF-8対応\r
651 //                      MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);\r
652 //                      flen += (wcslen(wbuf) + 1) * sizeof(wchar_t);\r
653                         flen += sizeof(wchar_t) * MtoW(NULL, 0, FileName[i], -1);\r
654                 }\r
655                 flen++;\r
656         }else{\r
657                 /* マルチバイト */\r
658                 for(i = 0;i < cnt;i++){\r
659                         // UTF-8対応\r
660 //                      flen += lstrlen(FileName[i]) + 1;\r
661                         MtoW(wbuf, BUF_SIZE, FileName[i], -1);\r
662                         flen += sizeof(char) * WtoA(NULL, 0, wbuf, -1);\r
663                 }\r
664         }\r
665 \r
666         hDrop = (HDROP)GlobalAlloc(GHND,sizeof(DROPFILES) + flen + 1);\r
667         if (hDrop == NULL){\r
668                 return NULL;\r
669         }\r
670 \r
671         lpDropFile = (LPDROPFILES) GlobalLock(hDrop);\r
672         lpDropFile->pFiles = sizeof(DROPFILES);         /* ファイル名のリストまでのオフセット */\r
673         lpDropFile->pt.x = 0;\r
674         lpDropFile->pt.y = 0;\r
675         lpDropFile->fNC = FALSE;\r
676         lpDropFile->fWide = fWide;                                      /* ワイドキャラの場合は TRUE */\r
677 \r
678         /* 構造体の後ろにファイル名のリストをコピーする。(ファイル名\0ファイル名\0ファイル名\0\0) */\r
679         if(fWide == TRUE){\r
680                 /* ワイドキャラ */\r
681                 wchar_t *buf;\r
682 \r
683                 buf = (wchar_t *)(&lpDropFile[1]);\r
684                 for(i = 0;i < cnt;i++){\r
685                         // UTF-8対応\r
686 //                      MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);\r
687 //                      wcscpy(buf,wbuf);\r
688 //                      buf += wcslen(wbuf) + 1;\r
689                         buf += MtoW(buf, BUF_SIZE, FileName[i], -1);\r
690                 }\r
691         }else{\r
692                 /* マルチバイト */\r
693                 char *buf;\r
694 \r
695                 buf = (char *)(&lpDropFile[1]);\r
696                 for(i = 0;i < cnt;i++){\r
697                         // UTF-8対応\r
698 //                      lstrcpy(buf,FileName[i]);\r
699 //                      buf += lstrlen(FileName[i]) + 1;\r
700                         MtoW(wbuf, BUF_SIZE, FileName[i], -1);\r
701                         buf += WtoA(buf, BUF_SIZE, wbuf, -1);\r
702                 }\r
703         }\r
704 \r
705         GlobalUnlock(hDrop);\r
706         return(hDrop);\r
707 }\r
708 \r
709 \r
710 // OLE D&Dを開始する \r
711 // (2007.8.30 yutaka)\r
712 static void doDragDrop(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
713 {\r
714         UINT cf[CF_CNT];\r
715         POINT pt;\r
716         int ret;\r
717 \r
718         // テンポラリをきれいにする (2007.9.3 yutaka)\r
719         doDeleteRemoteFile();\r
720 \r
721         /* ドラッグ&ドロップの開始 */\r
722         cf[0] = CF_HDROP;\r
723         cf[1] = CF_HDROP;       /* ファイル */\r
724         if((ret = OLE_IDropSource_Start(hWnd,WM_GETDATA, WM_DRAGOVER, cf,1,DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK)) == DROPEFFECT_MOVE){\r
725         }\r
726 \r
727         // ドロップ先のアプリに WM_LBUTTONUP を飛ばす。\r
728         GetCursorPos(&pt);\r
729         ScreenToClient(hWnd, &pt);\r
730         PostMessage(hWnd,WM_LBUTTONUP,0,MAKELPARAM(pt.x,pt.y));\r
731 }\r
732 \r
733 \r
734 \r
735 /*----- ファイル一覧ウインドウの共通メッセージ処理 ----------------------------\r
736 *\r
737 *       Parameter\r
738 *               HWND hWnd : ウインドウハンドル\r
739 *               UINT message  : メッセージ番号\r
740 *               WPARAM wParam : メッセージの WPARAM 引数\r
741 *               LPARAM lParam : メッセージの LPARAM 引数\r
742 *\r
743 *       Return Value\r
744 *               メッセージに対応する戻り値\r
745 *----------------------------------------------------------------------------*/\r
746 \r
747 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
748 {\r
749         POINT Point;\r
750         HWND hWndPnt;\r
751         HWND hWndParent;\r
752         static HCURSOR hCsrDrg;\r
753         static HCURSOR hCsrNoDrg;\r
754         static POINT DragPoint;\r
755         static HWND hWndDragStart;\r
756         static int RemoteDropFileIndex = -1;\r
757         int Win;\r
758         HWND hWndDst;\r
759         WNDPROC ProcPtr;\r
760         HWND hWndHistEdit;\r
761 \r
762         Win = WIN_LOCAL;\r
763         hWndDst = hWndListRemote;\r
764         ProcPtr = LocalProcPtr;\r
765         hWndHistEdit = GetLocalHistEditHwnd();\r
766         if(hWnd == hWndListRemote)\r
767         {\r
768                 Win = WIN_REMOTE;\r
769                 hWndDst = hWndListLocal;\r
770                 ProcPtr = RemoteProcPtr;\r
771                 hWndHistEdit = GetRemoteHistEditHwnd();\r
772         }\r
773 \r
774         switch (message)\r
775         {\r
776         case WM_SYSKEYDOWN:\r
777                         if (wParam == 'D') {    // Alt+D\r
778                                 SetFocus(hWndHistEdit);\r
779                                 break;\r
780                         }\r
781                         EraseListViewTips();\r
782                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
783 \r
784         case WM_KEYDOWN:\r
785                         if(wParam == 0x09)\r
786                         {\r
787                                 SetFocus(hWndDst);\r
788                                 break;\r
789                         }\r
790                         EraseListViewTips();\r
791                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
792 \r
793                 case WM_SETFOCUS :\r
794                         SetFocusHwnd(hWnd);\r
795                         MakeButtonsFocus();\r
796                         DispCurrentWindow(Win);\r
797                         DispSelectedSpace();\r
798                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
799 \r
800                 case WM_KILLFOCUS :\r
801                         EraseListViewTips();\r
802                         MakeButtonsFocus();\r
803                         DispCurrentWindow(-1);\r
804                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
805 \r
806                 case WM_DROPFILES :\r
807                         // 同時接続対応\r
808                         if(AskUserOpeDisabled() == YES)\r
809                                 break;\r
810                         // ドラッグ中は処理しない。ドラッグ後にWM_LBUTTONDOWNが飛んでくるため、そこで処理する。\r
811                         if (Dragging == YES) \r
812                                 return (FALSE);\r
813 \r
814                         if(hWnd == hWndListRemote)\r
815                         {\r
816                                 if(AskConnecting() == YES)\r
817                                         UploadDragProc(wParam);\r
818                         }\r
819                         else if(hWnd == hWndListLocal)\r
820                         {\r
821                                 ChangeDirDropFileProc(wParam);\r
822                         }\r
823                         break;\r
824 \r
825                 case WM_LBUTTONDOWN :\r
826                         EraseListViewTips();\r
827                         SetFocus(hWnd);\r
828                         DragPoint.x = LOWORD(lParam);\r
829                         DragPoint.y = HIWORD(lParam);\r
830                         hWndDragStart = hWnd;\r
831                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
832                         break;\r
833 \r
834                 case WM_LBUTTONUP :\r
835                         if(Dragging == YES)\r
836                         {\r
837                                 Dragging = NO;\r
838                                 ReleaseCapture();\r
839                                 hCsrDrg = LoadCursor(NULL, IDC_ARROW);\r
840                                 SetCursor(hCsrDrg);\r
841 \r
842                                 // 同時接続対応\r
843                                 if(AskUserOpeDisabled() == YES)\r
844                                         break;\r
845                                 Point.x = (long)(short)LOWORD(lParam);\r
846                                 Point.y = (long)(short)HIWORD(lParam);\r
847                                 ClientToScreen(hWnd, &Point);\r
848                                 hWndPnt = WindowFromPoint(Point);\r
849                                 if(hWndPnt == hWndDst)  // local <-> remote \r
850                                 {\r
851                                         if(hWndPnt == hWndListRemote) {\r
852                                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_UPLOAD, 0), 0);\r
853                                         } else if(hWndPnt == hWndListLocal) {\r
854                                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);\r
855                                         }\r
856                                 } else { // 同一ウィンドウ内の場合 (yutaka)\r
857                                         if (hWndDragStart == hWndListRemote && hWndPnt == hWndListRemote) {\r
858                                                 // remote <-> remoteの場合は、サーバでのファイルの移動を行う。(2007.9.5 yutaka)\r
859                                                 if (RemoteDropFileIndex != -1) {\r
860                                                         ListView_SetItemState(hWnd, RemoteDropFileIndex, 0, LVIS_DROPHILITED);\r
861                                                         MoveRemoteFileProc(RemoteDropFileIndex);\r
862                                                 }\r
863 \r
864                                         }\r
865 \r
866                                 }\r
867                         }\r
868                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
869 \r
870                 case WM_DRAGDROP:  \r
871                         // OLE D&Dを開始する (yutaka)\r
872                         doDragDrop(hWnd, message, wParam, lParam);\r
873                         return (TRUE);\r
874                         break;\r
875  \r
876                 case WM_GETDATA:  // ファイルのパスをD&D先のアプリへ返す (yutaka)\r
877                         switch(wParam)\r
878                         {\r
879                         case CF_HDROP:          /* ファイル */\r
880                                 {\r
881                                         OSVERSIONINFO os_info;\r
882                                         BOOL NTFlag = FALSE;\r
883                                         char **FileNameList;\r
884                                         int filelen;\r
885                                         int i, j, filenum = 0;\r
886  \r
887                                         FILELIST *FileListBase, *FileListBaseNoExpand, *pf;\r
888                                         int CancelFlg = NO;\r
889                                         char LocDir[FMAX_PATH+1];\r
890                                         char *PathDir;\r
891  \r
892                                         // 変数が未初期化のバグ修正\r
893                                         FileListBaseNoExpand = NULL;\r
894                                         // ローカル側で選ばれているファイルをFileListBaseに登録\r
895                                         if (hWndDragStart == hWndListLocal) {\r
896                                                 AskLocalCurDir(LocDir, FMAX_PATH);\r
897                                                 PathDir = LocDir;\r
898  \r
899                                                 FileListBase = NULL;\r
900                                                 // ローカル側からアプリケーションにD&Dできないバグ修正\r
901 //                                              MakeSelectedFileList(WIN_LOCAL, YES, NO, &FileListBase, &CancelFlg);                    \r
902                                                 MakeSelectedFileList(WIN_LOCAL, NO, NO, &FileListBase, &CancelFlg);                     \r
903                                                 FileListBaseNoExpand = FileListBase;\r
904  \r
905                                         } else if (hWndDragStart == hWndListRemote) {\r
906                                                 GetCursorPos(&Point);\r
907                                                 hWndPnt = WindowFromPoint(Point);\r
908                                                 hWndParent = GetParent(hWndPnt);\r
909                                                 if (hWndPnt == hWndListRemote || hWndPnt == hWndListLocal ||\r
910                                                         hWndParent == hWndListRemote || hWndParent == hWndListLocal) {\r
911                                                         FileListBase = NULL;\r
912  \r
913                                                 } else {\r
914                                                         // 選択されているリモートファイルのリストアップ\r
915                                                         // このタイミングでリモートからローカルの一時フォルダへダウンロードする\r
916                                                         // (2007.8.31 yutaka)\r
917                                                         doTransferRemoteFile();\r
918                                                         PathDir = remoteFileDir;\r
919                                                         FileListBase = remoteFileListBase;\r
920                                                         FileListBaseNoExpand = remoteFileListBaseNoExpand;\r
921                                                 }\r
922  \r
923                                         } \r
924  \r
925 #if defined(HAVE_TANDEM)\r
926                                         if(FileListBaseNoExpand == NULL)\r
927                                                 pf = FileListBase;\r
928                                         else\r
929 #endif\r
930                                         pf = FileListBaseNoExpand;\r
931                                         for (filenum = 0; pf ; filenum++) {\r
932                                                 pf = pf->Next;\r
933                                         }\r
934                                         // ファイルが未選択の場合は何もしない。(yutaka)\r
935                                         if (filenum <= 0) {\r
936                                                 *((HANDLE *)lParam) = NULL;\r
937                                                 return (FALSE);\r
938                                         }\r
939                                         \r
940                                         /* ファイル名の配列を作成する */\r
941                                         // TODO: GlobalAllocが返すのはメモリポインタではなくハンドルだが実際は同じ値\r
942                                         FileNameList = (char **)GlobalAlloc(GPTR,sizeof(char *) * filenum);\r
943                                         if(FileNameList == NULL){\r
944                                                 abort();\r
945                                         }\r
946                                         pf = FileListBaseNoExpand;\r
947                                         for (j = 0; pf ; j++) {\r
948                                                 filelen = strlen(PathDir) + 1 + strlen(pf->File) + 1;\r
949                                                 FileNameList[j] = (char *)GlobalAlloc(GPTR, filelen);\r
950                                                 strncpy_s(FileNameList[j], filelen, PathDir, _TRUNCATE);\r
951                                                 strncat_s(FileNameList[j], filelen, "\\", _TRUNCATE);\r
952                                                 strncat_s(FileNameList[j], filelen, pf->File, _TRUNCATE);\r
953                                                 pf = pf->Next;\r
954 #if 0\r
955                                                 if (FileListBase->Node == NODE_DIR) { \r
956                                                         // フォルダを掴んだ場合はそれ以降展開しない\r
957                                                         filenum = 1;\r
958                                                         break;\r
959                                                 }\r
960 #endif\r
961                                         }\r
962                                         \r
963                                         os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
964                                         GetVersionEx(&os_info);\r
965                                         if(os_info.dwPlatformId == VER_PLATFORM_WIN32_NT){\r
966                                                 NTFlag = TRUE;\r
967                                         }\r
968  \r
969                                         /* ドロップファイルリストの作成 */\r
970                                         /* NTの場合はUNICODEになるようにする */\r
971                                         *((HANDLE *)lParam) = CreateDropFileMem(FileNameList, filenum, NTFlag);\r
972  \r
973                                         /* ファイル名の配列を解放する */\r
974                                         for (i = 0; i < filenum ; i++) {\r
975                                                 GlobalFree(FileNameList[i]);\r
976                                         }\r
977                                         GlobalFree(FileNameList);\r
978  \r
979                                         if (hWndDragStart == hWndListLocal) {\r
980                                                 DeleteFileList(&FileListBase);\r
981                                         } else {\r
982                                                 // あとでファイル削除してフリーする\r
983                                         }\r
984  \r
985                                         return (TRUE);\r
986                                 }\r
987                                 break;\r
988  \r
989                         default:\r
990                                 *((HANDLE *)lParam) = NULL;\r
991                                 break;\r
992                         }\r
993  \r
994                         break;\r
995 \r
996                 case WM_DRAGOVER:\r
997                         {\r
998                                 LVHITTESTINFO hi;\r
999                                 int Node, index;\r
1000                                 static int prev_index = -1;\r
1001 \r
1002                                 // 同一ウィンドウ内でのD&Dはリモート側のみ\r
1003                                 if (Win != WIN_REMOTE)\r
1004                                         break;\r
1005 \r
1006                                 if(MoveMode == MOVE_DISABLE)\r
1007                                         break;\r
1008 \r
1009                                 memset(&hi, 0, sizeof(hi));\r
1010 \r
1011                                 GetCursorPos(&Point);\r
1012                                 hWndPnt = WindowFromPoint(Point);\r
1013                                 ScreenToClient(hWnd, &Point);\r
1014 \r
1015                                 hi.pt = Point;\r
1016 \r
1017                                 // 以前の選択を消す\r
1018                                 ListView_SetItemState(hWnd, prev_index, 0, LVIS_DROPHILITED);\r
1019                                 RemoteDropFileIndex = -1;\r
1020 \r
1021                                 if ((hWndPnt == hWndListRemote) && (ListView_HitTest(hWnd, &hi) != -1)) {\r
1022                                         if (hi.flags == LVHT_ONITEMLABEL) { // The position is over a list-view item's text.\r
1023                                         \r
1024                                                 index = hi.iItem;\r
1025                                                 prev_index = index;\r
1026                                                 Node = GetNodeType(Win, index);\r
1027                                                 if (Node == NODE_DIR) {\r
1028                                                         ListView_SetItemState(hWnd, index, LVIS_DROPHILITED, LVIS_DROPHILITED);\r
1029                                                         RemoteDropFileIndex = index;\r
1030                                                 }\r
1031                                         }\r
1032                                 } \r
1033 \r
1034                         }\r
1035                         break;\r
1036 \r
1037                 case WM_RBUTTONDOWN :\r
1038                         /* ここでファイルを選ぶ */\r
1039                         CallWindowProc(ProcPtr, hWnd, message, wParam, lParam);\r
1040 \r
1041                         EraseListViewTips();\r
1042                         SetFocus(hWnd);\r
1043                         if(hWnd == hWndListRemote)\r
1044                                 RemoteRbuttonMenu(0);\r
1045                         else if(hWnd == hWndListLocal)\r
1046                                 LocalRbuttonMenu(0);\r
1047                         break;\r
1048 \r
1049                 case WM_LBUTTONDBLCLK :\r
1050                         DoubleClickProc(Win, NO, -1);\r
1051                         break;\r
1052 \r
1053                 case WM_MOUSEMOVE :\r
1054                         if(wParam == MK_LBUTTON)\r
1055                         {\r
1056                                 if((Dragging == NO) && \r
1057                                    (hWnd == hWndDragStart) &&\r
1058                                    (AskConnecting() == YES) &&\r
1059                                    (SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0) > 0) &&\r
1060                                    ((abs((short)LOWORD(lParam) - DragPoint.x) > 5) ||\r
1061                                         (abs((short)HIWORD(lParam) - DragPoint.y) > 5)))\r
1062                                 {\r
1063                                         SetCapture(hWnd);\r
1064                                         Dragging = YES;\r
1065                                         hCsrDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(drag_csr));\r
1066                                         hCsrNoDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(nodrop_csr));\r
1067                                         SetCursor(hCsrDrg);\r
1068                                 }\r
1069                                 else if(Dragging == YES)\r
1070                                 {\r
1071                                         Point.x = (long)(short)LOWORD(lParam);\r
1072                                         Point.y = (long)(short)HIWORD(lParam);\r
1073                                         ClientToScreen(hWnd, &Point);\r
1074                                         hWndPnt = WindowFromPoint(Point);\r
1075                                         if((hWndPnt == hWndListRemote) || (hWndPnt == hWndListLocal))\r
1076                                                 SetCursor(hCsrDrg);\r
1077                                         else {\r
1078                                                 // マウスポインタの×表示をやめる (yutaka)\r
1079 #if 0\r
1080                                                 SetCursor(hCsrNoDrg);\r
1081 #endif\r
1082                                         }\r
1083 \r
1084                                         // OLE D&Dの開始を指示する\r
1085                                         PostMessage(hWnd, WM_DRAGDROP, MAKEWPARAM(wParam, lParam), 0);\r
1086 \r
1087                                 }\r
1088                                 else\r
1089                                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1090                         }\r
1091                         else\r
1092                         {\r
1093                                 CheckTipsDisplay(hWnd, lParam);\r
1094                                 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1095                         }\r
1096                         break;\r
1097 \r
1098                 case WM_MOUSEWHEEL :\r
1099                         if(Dragging == NO)\r
1100                         {\r
1101                 short zDelta = (short)HIWORD(wParam);\r
1102 \r
1103                                 EraseListViewTips();\r
1104                                 Point.x = (short)LOWORD(lParam);\r
1105                                 Point.y = (short)HIWORD(lParam);\r
1106                                 hWndPnt = WindowFromPoint(Point);\r
1107 \r
1108                                 if((wParam & MAKEWPARAM(MK_SHIFT, 0)) && \r
1109                                    ((hWndPnt == hWndListRemote) ||\r
1110                                         (hWndPnt == hWndListLocal) || \r
1111                                         (hWndPnt == GetTaskWnd())))\r
1112                                 {\r
1113                                         PostMessage(hWndPnt, WM_VSCROLL, zDelta > 0 ? MAKEWPARAM(SB_PAGEUP, 0) : MAKEWPARAM(SB_PAGEDOWN, 0), 0);\r
1114 //                                      PostMessage(hWndPnt, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, 0), 0);\r
1115                                 }\r
1116                                 else if(hWndPnt == hWnd)\r
1117                                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1118                                 else if((hWndPnt == hWndDst) || (hWndPnt == GetTaskWnd()))\r
1119                                         PostMessage(hWndPnt, message, wParam, lParam);\r
1120                         }\r
1121                         break;\r
1122 \r
1123                 default :\r
1124                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1125         }\r
1126     return(0L);\r
1127 }\r
1128 \r
1129 \r
1130 /*----- ファイルリストのタブ幅を取得する --------------------------------------\r
1131 *\r
1132 *       Parameter\r
1133 *               なし\r
1134 *\r
1135 *       Return Value\r
1136 *               なし\r
1137 *----------------------------------------------------------------------------*/\r
1138 \r
1139 void GetListTabWidth(void)\r
1140 {\r
1141         LV_COLUMN LvCol;\r
1142         int i;\r
1143 \r
1144         // 変数が未初期化のバグ修正\r
1145         memset(&LvCol, 0, sizeof(LV_COLUMN));\r
1146 \r
1147         for(i = 0; i <= 3; i++)\r
1148         {\r
1149                 LvCol.mask = LVCF_WIDTH;\r
1150                 if(SendMessage(hWndListLocal, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)\r
1151                         LocalTabWidth[i] = LvCol.cx;\r
1152         }\r
1153 \r
1154         for(i = 0; i <= 5; i++)\r
1155         {\r
1156                 LvCol.mask = LVCF_WIDTH;\r
1157                 if(SendMessage(hWndListRemote, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)\r
1158                         RemoteTabWidth[i] = LvCol.cx;\r
1159         }\r
1160         return;\r
1161 }\r
1162 \r
1163 \r
1164 /*----- ファイル一覧方法にしたがってリストビューを設定する --------------------\r
1165 *\r
1166 *       Parameter\r
1167 *               なし\r
1168 *\r
1169 *       Return Value\r
1170 *               なし\r
1171 *----------------------------------------------------------------------------*/\r
1172 \r
1173 void SetListViewType(void)\r
1174 {\r
1175         // 64ビット対応\r
1176 //      long lStyle;\r
1177         LONG_PTR lStyle;\r
1178 \r
1179         switch(ListType)\r
1180         {\r
1181                 case LVS_LIST :\r
1182                         // 64ビット対応\r
1183 //                      lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);\r
1184                         lStyle = GetWindowLongPtr(GetLocalHwnd(), GWL_STYLE);\r
1185                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1186                         lStyle |= LVS_LIST;\r
1187                         // 64ビット対応\r
1188 //                      SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1189                         SetWindowLongPtr(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1190 \r
1191                         // 64ビット対応\r
1192 //                      lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);\r
1193                         lStyle = GetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE);\r
1194                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1195                         lStyle |= LVS_LIST;\r
1196                         // 64ビット対応\r
1197 //                      SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1198                         SetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1199                         break;\r
1200 \r
1201                 default :\r
1202                         // 64ビット対応\r
1203 //                      lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);\r
1204                         lStyle = GetWindowLongPtr(GetLocalHwnd(), GWL_STYLE);\r
1205                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1206                         lStyle |= LVS_REPORT;\r
1207                         // 64ビット対応\r
1208 //                      SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1209                         SetWindowLongPtr(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1210 \r
1211                         // 64ビット対応\r
1212 //                      lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);\r
1213                         lStyle = GetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE);\r
1214                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1215                         lStyle |= LVS_REPORT;\r
1216                         // 64ビット対応\r
1217 //                      SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1218                         SetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1219                         break;\r
1220         }\r
1221         return;\r
1222 }\r
1223 \r
1224 \r
1225 /*----- ホスト側のファイル一覧ウインドウにファイル名をセット ------------------\r
1226 *\r
1227 *       Parameter\r
1228 *               int Mode : キャッシュモード (CACHE_xxx)\r
1229 *\r
1230 *       Return Value\r
1231 *               なし\r
1232 *----------------------------------------------------------------------------*/\r
1233 \r
1234 void GetRemoteDirForWnd(int Mode, int *CancelCheckWork)\r
1235 {\r
1236         FILE *fd;\r
1237         LONGLONG Size;\r
1238         char Str[FMAX_PATH+1];\r
1239         char Buf[FMAX_PATH+1];\r
1240         FILETIME Time;\r
1241         int Attr;\r
1242         int Type;\r
1243         int ListType;\r
1244         int Num;\r
1245         FLISTANCHOR Anchor;\r
1246         char Owner[OWNER_NAME_LEN+1];\r
1247         int Link;\r
1248         int InfoExist;\r
1249 \r
1250 //#pragma aaa\r
1251 //DoPrintf("===== GetRemoteDirForWnd");\r
1252 \r
1253         Anchor.Top = NULL;\r
1254         Anchor.Files = 0;\r
1255 \r
1256         if(AskConnecting() == YES)\r
1257         {\r
1258 //              SetCursor(LoadCursor(NULL, IDC_WAIT));\r
1259                 DisableUserOpe();\r
1260 \r
1261                 AskRemoteCurDir(Buf, FMAX_PATH);\r
1262                 SetRemoteDirHist(Buf);\r
1263 \r
1264                 Type = FTP_COMPLETE;\r
1265                 if(Mode != CACHE_LASTREAD)\r
1266                 {\r
1267 \r
1268                         if((Num = AskCached(Buf)) == -1)\r
1269                         {\r
1270                                 Num = AskFreeCache();\r
1271                                 Mode = CACHE_REFRESH;\r
1272                         }\r
1273 \r
1274                         if(Mode == CACHE_REFRESH)\r
1275                         {\r
1276                                 if((Type = DoDirListCmdSkt("", "", Num, CancelCheckWork)) == FTP_COMPLETE)\r
1277                                         SetCache(Num, Buf);\r
1278                                 else\r
1279                                         ClearCache(Num);\r
1280                         }\r
1281                 }\r
1282                 else\r
1283                         Num = AskCurrentFileListNum();\r
1284 \r
1285                 if(Type == FTP_COMPLETE)\r
1286                 {\r
1287                         SetCurrentFileListNum(Num);\r
1288                         MakeCacheFileName(Num, Buf);\r
1289                         if((fd = fopen(Buf, "rb"))!=NULL)\r
1290                         {\r
1291                                 ListType = LIST_UNKNOWN;\r
1292 \r
1293                                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
1294                                 {\r
1295                                         if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)\r
1296                                         {\r
1297                                                 if((Type = ResolvFileInfo(Str, ListType, Buf, &Size, &Time, &Attr, Owner, &Link, &InfoExist)) != NODE_NONE)\r
1298                                                 {\r
1299                                                         if(AskFilterStr(Buf, Type) == YES)\r
1300                                                         {\r
1301                                                                 if((DotFile == YES) || (Buf[0] != '.'))\r
1302                                                                 {\r
1303                                                                         AddDispFileList(&Anchor, Buf, &Time, Size, Attr, Type, Link, Owner, InfoExist, WIN_REMOTE);\r
1304                                                                 }\r
1305                                                         }\r
1306                                                 }\r
1307                                         }\r
1308                                 }\r
1309                                 fclose(fd);\r
1310 \r
1311                                 DispFileList2View(GetRemoteHwnd(), &Anchor);\r
1312                                 EraseDispFileList(&Anchor);\r
1313 \r
1314                                 // 先頭のアイテムを選択\r
1315                                 ListView_SetItemState(GetRemoteHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);\r
1316                         }\r
1317                         else\r
1318                         {\r
1319                                 SetTaskMsg(MSGJPN048);\r
1320                                 SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
1321                         }\r
1322                 }\r
1323                 else\r
1324                 {\r
1325 #if defined(HAVE_OPENVMS)\r
1326                         /* OpenVMSの場合空ディレクトリ移動の時に出るので、メッセージだけ出さない\r
1327                          * ようにする(VIEWはクリアして良い) */\r
1328                         if (AskHostType() != HTYPE_VMS)\r
1329 #endif\r
1330                         SetTaskMsg(MSGJPN049);\r
1331                         SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
1332                 }\r
1333 \r
1334 //              SetCursor(LoadCursor(NULL, IDC_ARROW));\r
1335                 EnableUserOpe();\r
1336 \r
1337         }\r
1338 \r
1339 //#pragma aaa\r
1340 //DoPrintf("===== GetRemoteDirForWnd Done");\r
1341 \r
1342         return;\r
1343 }\r
1344 \r
1345 \r
1346 /*----- ローカル側のファイル一覧ウインドウにファイル名をセット ----------------\r
1347 *\r
1348 *       Parameter\r
1349 *               なし\r
1350 *\r
1351 *       Return Value\r
1352 *               なし\r
1353 *----------------------------------------------------------------------------*/\r
1354 \r
1355 // ファイルアイコン表示対応\r
1356 void RefreshIconImageList(FLISTANCHOR *Anchor)\r
1357 {\r
1358         HBITMAP hBitmap;\r
1359         int ImageId;\r
1360         FILELIST *Pos;\r
1361         int i;\r
1362         char Cur[FMAX_PATH+1];\r
1363         SHFILEINFO FileInfo;\r
1364         if(AskDispFileIcon() == YES)\r
1365         {\r
1366                 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)NULL);\r
1367                 ShowWindow(hWndListLocal, SW_SHOW);\r
1368                 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)NULL);\r
1369                 ShowWindow(hWndListRemote, SW_SHOW);\r
1370                 ImageList_Destroy(ListImgFileIcon);\r
1371                 ListImgFileIcon = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 0, 1);\r
1372                 hBitmap = LoadBitmap(GetFtpInst(), MAKEINTRESOURCE(dirattr16_bmp));\r
1373                 ImageList_AddMasked(ListImgFileIcon, hBitmap, RGB(255, 0, 0));\r
1374                 DeleteObject(hBitmap);\r
1375                 ImageId = 0;\r
1376                 Pos = Anchor->Top;\r
1377                 for(i = 0; i < Anchor->Files; i++)\r
1378                 {\r
1379                         Pos->ImageId = -1;\r
1380                         if(Pos->Node == NODE_DRIVE)\r
1381                                 strcpy(Cur, Pos->File);\r
1382                         else\r
1383                         {\r
1384                                 AskLocalCurDir(Cur, FMAX_PATH);\r
1385                                 SetYenTail(Cur);\r
1386                                 strcat(Cur, Pos->File);\r
1387                         }\r
1388                         if(SHGetFileInfoM(Cur, 0, &FileInfo, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON) != 0)\r
1389                         {\r
1390                                 if(ImageList_AddIcon(ListImgFileIcon, FileInfo.hIcon) >= 0)\r
1391                                 {\r
1392                                         Pos->ImageId = ImageId;\r
1393                                         ImageId++;\r
1394                                 }\r
1395                                 DestroyIcon(FileInfo.hIcon);\r
1396                         }\r
1397                         Pos = Pos->Next;\r
1398                 }\r
1399                 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImgFileIcon);\r
1400                 ShowWindow(hWndListLocal, SW_SHOW);\r
1401                 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImgFileIcon);\r
1402                 ShowWindow(hWndListRemote, SW_SHOW);\r
1403         }\r
1404         else\r
1405         {\r
1406                 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
1407                 ShowWindow(hWndListLocal, SW_SHOW);\r
1408                 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
1409                 ShowWindow(hWndListRemote, SW_SHOW);\r
1410         }\r
1411 }\r
1412 \r
1413 void GetLocalDirForWnd(void)\r
1414 {\r
1415         HANDLE fHnd;\r
1416         WIN32_FIND_DATA Find;\r
1417         char Scan[FMAX_PATH+1];\r
1418         char *Pos;\r
1419         char Buf[10];\r
1420         FILETIME Time;\r
1421         FLISTANCHOR Anchor;\r
1422         DWORD NoDrives;\r
1423         int Tmp;\r
1424 \r
1425         Anchor.Top = NULL;\r
1426         Anchor.Files = 0;\r
1427 \r
1428         DoLocalPWD(Scan);\r
1429         SetLocalDirHist(Scan);\r
1430         DispLocalFreeSpace(Scan);\r
1431 \r
1432         /* ディレクトリ/ファイル */\r
1433 \r
1434         SetYenTail(Scan);\r
1435         strcat(Scan, "*");\r
1436         if((fHnd = FindFirstFileAttr(Scan, &Find, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
1437         {\r
1438                 do\r
1439                 {\r
1440                         if((strcmp(Find.cFileName, ".") != 0) &&\r
1441                            (strcmp(Find.cFileName, "..") != 0))\r
1442                         {\r
1443                                 if((DotFile == YES) || (Find.cFileName[0] != '.'))\r
1444                                 {\r
1445                                         if(Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\r
1446                                                 AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_DIR, NO, "", FINFO_ALL, WIN_LOCAL);\r
1447                                         else\r
1448                                         {\r
1449                                                 if(AskFilterStr(Find.cFileName, NODE_FILE) == YES)\r
1450                                                 {\r
1451                                                         AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_FILE, NO, "", FINFO_ALL, WIN_LOCAL);\r
1452                                                 }\r
1453                                         }\r
1454                                 }\r
1455                         }\r
1456                 }\r
1457                 while(FindNextFileAttr(fHnd, &Find, DispIgnoreHide) == TRUE);\r
1458                 FindClose(fHnd);\r
1459         }\r
1460 \r
1461         /* ドライブ */\r
1462         if(DispDrives)\r
1463         {\r
1464                 GetLogicalDriveStrings(FMAX_PATH, Scan);\r
1465                 NoDrives = LoadHideDriveListRegistry();\r
1466 \r
1467                 Pos = Scan;\r
1468                 while(*Pos != NUL)\r
1469                 {\r
1470                         Tmp = toupper(*Pos) - 'A';\r
1471                         if((NoDrives & (0x00000001 << Tmp)) == 0)\r
1472                         {\r
1473                                 sprintf(Buf, "%s", Pos);\r
1474                                 memset(&Time, 0, sizeof(FILETIME));\r
1475                                 AddDispFileList(&Anchor, Buf, &Time, 0, 0, NODE_DRIVE, NO, "", FINFO_ALL, WIN_LOCAL);\r
1476                         }\r
1477                         Pos = strchr(Pos, NUL) + 1;\r
1478                 }\r
1479         }\r
1480 \r
1481         // ファイルアイコン表示対応\r
1482         RefreshIconImageList(&Anchor);\r
1483         DispFileList2View(GetLocalHwnd(), &Anchor);\r
1484         EraseDispFileList(&Anchor);\r
1485 \r
1486         // 先頭のアイテムを選択\r
1487         ListView_SetItemState(GetLocalHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);\r
1488 \r
1489         return;\r
1490 }\r
1491 \r
1492 \r
1493 /*----- ファイル情報をファイル一覧用リストに登録する --------------------------\r
1494 *\r
1495 *       Parameter\r
1496 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1497 *               char *Name : ファイル名\r
1498 *               FILETIME *Time : 日付\r
1499 *               LONGLONG Size : サイズ\r
1500 *               int Attr : 属性\r
1501 *               int Type : タイプ (NODE_xxxx)\r
1502 *               int Link : リンクかどうか (YES/NO)\r
1503 *               char *Owner : オーナ名\r
1504 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1505 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1506 *\r
1507 *       Return Value\r
1508 *               なし\r
1509 *----------------------------------------------------------------------------*/\r
1510 \r
1511 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win)\r
1512 {\r
1513         int i;\r
1514         FILELIST *Pos;\r
1515         FILELIST *Prev;\r
1516         FILELIST *New;\r
1517         int FileSort;\r
1518         int DirSort;\r
1519         int Sort;\r
1520         LONGLONG Cmp;\r
1521 \r
1522         FileSort = AskSortType(ITEM_LFILE);\r
1523         DirSort = AskSortType(ITEM_LDIR);\r
1524         if(Win == WIN_REMOTE)\r
1525         {\r
1526                 FileSort = AskSortType(ITEM_RFILE);\r
1527                 DirSort = AskSortType(ITEM_RDIR);\r
1528         }\r
1529 \r
1530         Pos = Anchor->Top;\r
1531         for(i = 0; i < Anchor->Files; i++)\r
1532         {\r
1533                 if((Type == NODE_DIR) && (Pos->Node == NODE_FILE))\r
1534                         break;\r
1535                 if((Type == NODE_FILE) && (Pos->Node == NODE_DRIVE))\r
1536                         break;\r
1537 \r
1538                 if(Type == Pos->Node)\r
1539                 {\r
1540                         if(Type == NODE_DIR)\r
1541                                 Sort = DirSort;\r
1542                         else\r
1543                                 Sort = FileSort;\r
1544 \r
1545                         if((Sort & SORT_GET_ORD) == SORT_ASCENT)\r
1546                         {\r
1547                                 // 読みにくいのでリファクタリング\r
1548 //                              if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1549 //                                      ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) < 0)) ||\r
1550 //#if defined(HAVE_TANDEM)\r
1551 //                                 ((AskHostType() == HTYPE_TANDEM) &&\r
1552 //                                  ((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1553 //                                      ((Cmp = Attr - Pos->Attr) < 0)) ||\r
1554 //#endif\r
1555 //                                 (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1556 //                                      ((Cmp = Size - Pos->Size) < 0)) ||\r
1557 //                                 (((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1558 //                                      ((Cmp = CompareFileTime(Time, &Pos->Time)) < 0)))\r
1559 //                              {\r
1560 //                                      break;\r
1561 //                              }\r
1562                                 if(((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1563                                         ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) < 0))\r
1564                                         break;\r
1565 #if defined(HAVE_TANDEM)\r
1566                                 if((AskHostType() == HTYPE_TANDEM) &&\r
1567                                         ((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1568                                         ((Cmp = Attr - Pos->Attr) < 0))\r
1569                                         break;\r
1570 #endif\r
1571                                 if(((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1572                                         ((Cmp = Size - Pos->Size) < 0))\r
1573                                         break;\r
1574                                 if(((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1575                                         ((Cmp = CompareFileTime(Time, &Pos->Time)) < 0))\r
1576                                         break;\r
1577 \r
1578                                 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))\r
1579                                 {\r
1580                                         if(_mbsicmp(Name, Pos->File) < 0)\r
1581                                                 break;\r
1582                                 }\r
1583                         }\r
1584                         else\r
1585                         {\r
1586                                 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1587                                         ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) > 0)) ||\r
1588 #if defined(HAVE_TANDEM)\r
1589                                    ((AskHostType() == HTYPE_TANDEM) &&\r
1590                                     ((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1591                                         ((Cmp = Attr - Pos->Attr) > 0)) ||\r
1592 #endif\r
1593                                    (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1594                                         ((Cmp = Size - Pos->Size) > 0)) ||\r
1595                                    (((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1596                                         ((Cmp = CompareFileTime(Time, &Pos->Time)) > 0)))\r
1597                                 {\r
1598                                         break;\r
1599                                 }\r
1600 \r
1601                                 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))\r
1602                                 {\r
1603                                         if(_mbsicmp(Name, Pos->File) > 0)\r
1604                                                 break;\r
1605                                 }\r
1606                         }\r
1607                 }\r
1608                 Prev = Pos;\r
1609                 Pos = Pos->Next;\r
1610         }\r
1611 \r
1612         if((New = malloc(sizeof(FILELIST))) != NULL)\r
1613         {\r
1614                 strcpy(New->File, Name);\r
1615                 New->Node = Type;\r
1616                 New->Link = Link;\r
1617                 New->Size = Size;\r
1618                 New->Attr = Attr;\r
1619                 New->Time = *Time;\r
1620                 strcpy(New->Owner, Owner);\r
1621                 New->InfoExist = InfoExist;\r
1622 \r
1623                 if(Pos == Anchor->Top)\r
1624                 {\r
1625                         New->Next = Anchor->Top;\r
1626                         Anchor->Top = New;\r
1627                 }\r
1628                 else\r
1629                 {\r
1630                         New->Next = Prev->Next;\r
1631                         Prev->Next = New;\r
1632                 }\r
1633                 Anchor->Files += 1;\r
1634         }\r
1635         return;\r
1636 }\r
1637 \r
1638 \r
1639 /*----- ファイル一覧用リストをクリアする --------------------------------------\r
1640 *\r
1641 *       Parameter\r
1642 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1643 *\r
1644 *       Return Value\r
1645 *               なし\r
1646 *----------------------------------------------------------------------------*/\r
1647 \r
1648 static void EraseDispFileList(FLISTANCHOR *Anchor)\r
1649 {\r
1650         FILELIST *Pos;\r
1651         FILELIST *Next;\r
1652         int i;\r
1653 \r
1654         Pos = Anchor->Top;\r
1655         for(i = 0; i < Anchor->Files; i++)\r
1656         {\r
1657                 Next = Pos->Next;\r
1658                 free(Pos);\r
1659                 Pos = Next;\r
1660         }\r
1661         Anchor->Files = 0;\r
1662         Anchor->Top = NULL;\r
1663         return;\r
1664 }\r
1665 \r
1666 \r
1667 /*----- ファイル一覧用リストの内容をファイル一覧ウインドウにセット ------------\r
1668 *\r
1669 *       Parameter\r
1670 *               HWND hWnd : ウインドウハンドル\r
1671 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1672 *\r
1673 *       Return Value\r
1674 *               なし\r
1675 *----------------------------------------------------------------------------*/\r
1676 \r
1677 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor)\r
1678 {\r
1679         int i;\r
1680         FILELIST *Pos;\r
1681 \r
1682         SendMessage(hWnd, WM_SETREDRAW, (WPARAM)FALSE, 0);\r
1683         SendMessage(hWnd, LVM_DELETEALLITEMS, 0, 0);\r
1684 \r
1685         Pos = Anchor->Top;\r
1686         for(i = 0; i < Anchor->Files; i++)\r
1687         {\r
1688                 // ファイルアイコン表示対応\r
1689 //              AddListView(hWnd, -1, Pos->File, Pos->Node, Pos->Size, &Pos->Time, Pos->Attr, Pos->Owner, Pos->Link, Pos->InfoExist);\r
1690                 AddListView(hWnd, -1, Pos->File, Pos->Node, Pos->Size, &Pos->Time, Pos->Attr, Pos->Owner, Pos->Link, Pos->InfoExist, Pos->ImageId);\r
1691                 Pos = Pos->Next;\r
1692         }\r
1693 \r
1694         SendMessage(hWnd, WM_SETREDRAW, (WPARAM)TRUE, 0);\r
1695         UpdateWindow(hWnd);\r
1696 \r
1697         DispSelectedSpace();\r
1698         return;\r
1699 }\r
1700 \r
1701 \r
1702 /*----- ファイル一覧ウインドウ(リストビュー)に追加 --------------------------\r
1703 *\r
1704 *       Parameter\r
1705 *               HWND hWnd : ウインドウハンドル\r
1706 *               int Pos : 挿入位置\r
1707 *               char *Name : 名前\r
1708 *               int Type : タイプ (NIDE_xxxx)\r
1709 *               LONGLONG Size : サイズ\r
1710 *               FILETIME *Time : 日付\r
1711 *               int Attr : 属性\r
1712 *               char Owner : オーナ名\r
1713 *               int Link : リンクかどうか\r
1714 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1715 *\r
1716 *       Return Value\r
1717 *               なし\r
1718 *----------------------------------------------------------------------------*/\r
1719 \r
1720 // ファイルアイコン表示対応\r
1721 //static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist)\r
1722 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist, int ImageId)\r
1723 {\r
1724         LV_ITEM LvItem;\r
1725         char Tmp[20];\r
1726 \r
1727         if(Pos == -1)\r
1728                 Pos = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);\r
1729 \r
1730         // 変数が未初期化のバグ修正\r
1731         memset(&LvItem, 0, sizeof(LV_ITEM));\r
1732         /* アイコン/ファイル名 */\r
1733         LvItem.mask = LVIF_TEXT | LVIF_IMAGE;\r
1734         LvItem.iItem = Pos;\r
1735         LvItem.iSubItem = 0;\r
1736         LvItem.pszText = Name;\r
1737         if((Type == NODE_FILE) && (AskTransferTypeAssoc(Name, TYPE_X) == TYPE_I))\r
1738                 Type = 3;\r
1739         if(Link == NO)\r
1740                 LvItem.iImage = Type;\r
1741         else\r
1742                 LvItem.iImage = 4;\r
1743         // ファイルアイコン表示対応\r
1744         if(AskDispFileIcon() == YES && hWnd == GetLocalHwnd())\r
1745                 LvItem.iImage = ImageId + 5;\r
1746         LvItem.iItem = SendMessage(hWnd, LVM_INSERTITEM, 0, (LPARAM)&LvItem);\r
1747 \r
1748         /* 日付/時刻 */\r
1749         FileTime2TimeString(Time, Tmp, DISPFORM_LEGACY, InfoExist);\r
1750         LvItem.mask = LVIF_TEXT;\r
1751         LvItem.iItem = Pos;\r
1752         LvItem.iSubItem = 1;\r
1753         LvItem.pszText = Tmp;\r
1754         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1755 \r
1756         /* サイズ */\r
1757         if(Type == NODE_DIR)\r
1758                 strcpy(Tmp, "<DIR>");\r
1759         else if(Type == NODE_DRIVE)\r
1760                 strcpy(Tmp, "<DRIVE>");\r
1761         else if(Size >= 0)\r
1762                 MakeNumString(Size, Tmp, TRUE);\r
1763         else\r
1764                 strcpy(Tmp, "");\r
1765         LvItem.mask = LVIF_TEXT;\r
1766         LvItem.iItem = Pos;\r
1767         LvItem.iSubItem = 2;\r
1768         LvItem.pszText = Tmp;\r
1769         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1770 \r
1771         /* 拡張子 */\r
1772         LvItem.mask = LVIF_TEXT;\r
1773         LvItem.iItem = Pos;\r
1774         LvItem.iSubItem = 3;\r
1775 #if defined(HAVE_TANDEM)\r
1776         if (AskHostType() == HTYPE_TANDEM) {\r
1777                 _itoa_s(Attr, Tmp, sizeof(Tmp), 10);\r
1778                 LvItem.pszText = Tmp;\r
1779         } else\r
1780 #endif\r
1781         LvItem.pszText = GetFileExt(Name);\r
1782         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1783 \r
1784         if(hWnd == GetRemoteHwnd())\r
1785         {\r
1786                 /* 属性 */\r
1787                 strcpy(Tmp, "");\r
1788 #if defined(HAVE_TANDEM)\r
1789                 if((InfoExist & FINFO_ATTR) && (AskHostType() != HTYPE_TANDEM))\r
1790 #else\r
1791                 if(InfoExist & FINFO_ATTR)\r
1792 #endif\r
1793                         AttrValue2String(Attr, Tmp);\r
1794                 LvItem.mask = LVIF_TEXT;\r
1795                 LvItem.iItem = Pos;\r
1796                 LvItem.iSubItem = 4;\r
1797                 LvItem.pszText = Tmp;\r
1798                 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1799 \r
1800                 /* オーナ名 */\r
1801                 LvItem.mask = LVIF_TEXT;\r
1802                 LvItem.iItem = Pos;\r
1803                 LvItem.iSubItem = 5;\r
1804                 LvItem.pszText = Owner;\r
1805                 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1806         }\r
1807         return;\r
1808 }\r
1809 \r
1810 \r
1811 /*----- ファイル名一覧ウインドウをソートし直す --------------------------------\r
1812 *\r
1813 *       Parameter\r
1814 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1815 *\r
1816 *       Return Value\r
1817 *               なし\r
1818 *----------------------------------------------------------------------------*/\r
1819 \r
1820 void ReSortDispList(int Win, int *CancelCheckWork)\r
1821 {\r
1822         if(Win == WIN_REMOTE)\r
1823                 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);\r
1824         else\r
1825                 GetLocalDirForWnd();\r
1826         return;\r
1827 }\r
1828 \r
1829 \r
1830 /*----- ファイル一覧ウインドウのファイルを選択する ----------------------------\r
1831 *\r
1832 *       Parameter\r
1833 *               HWND hWnd : ウインドウハンドル\r
1834 *               int Type : 選択方法 (SELECT_xxx)\r
1835 *\r
1836 *       Return Value\r
1837 *               なし\r
1838 *----------------------------------------------------------------------------*/\r
1839 \r
1840 void SelectFileInList(HWND hWnd, int Type)\r
1841 {\r
1842         int Win;\r
1843         int WinDst;\r
1844         int i;\r
1845         int Num;\r
1846         char RegExp[FMAX_PATH+1];\r
1847         char Name[FMAX_PATH+1];\r
1848         LV_ITEM LvItem;\r
1849         int CsrPos;\r
1850         FILETIME Time1;\r
1851         FILETIME Time2;\r
1852         int Find;\r
1853 \r
1854         // 変数が未初期化のバグ修正\r
1855         memset(&LvItem, 0, sizeof(LV_ITEM));\r
1856         Win = WIN_LOCAL;\r
1857         WinDst = WIN_REMOTE;\r
1858         if(hWnd == GetRemoteHwnd())\r
1859         {\r
1860                 Win = WIN_REMOTE;\r
1861                 WinDst = WIN_LOCAL;\r
1862         }\r
1863 \r
1864         Num = GetItemCount(Win);\r
1865         switch(Type)\r
1866         {\r
1867                 case SELECT_ALL :\r
1868                         LvItem.state = 0;\r
1869                         if(GetSelectedCount(Win) <= 1)\r
1870                                 LvItem.state = LVIS_SELECTED;\r
1871                         for(i = 0; i < Num; i++)\r
1872                         {\r
1873                                 if(GetNodeType(Win, i) != NODE_DRIVE)\r
1874                                 {\r
1875                                         LvItem.mask = LVIF_STATE;\r
1876                                         LvItem.iItem = i;\r
1877                                         LvItem.stateMask = LVIS_SELECTED;\r
1878                                         LvItem.iSubItem = 0;\r
1879                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1880                                 }\r
1881                         }\r
1882                         break;\r
1883 \r
1884                 case SELECT_REGEXP :\r
1885                         if(((Win == WIN_LOCAL) &&\r
1886                                 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_local_dlg), hWnd, SelectDialogCallBack) == YES)) ||\r
1887                            ((Win == WIN_REMOTE) &&\r
1888                                 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_remote_dlg), hWnd, SelectDialogCallBack) == YES)))\r
1889                         {\r
1890                                 strcpy(RegExp, FindStr);\r
1891 //                              if(FindMode == 0)\r
1892 //                                      WildCard2RegExp(RegExp);\r
1893 \r
1894                                 _mbslwr(RegExp);\r
1895                                 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))\r
1896                                 {\r
1897                                         CsrPos = -1;\r
1898                                         for(i = 0; i < Num; i++)\r
1899                                         {\r
1900                                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1901                                                 Find = FindNameNode(WinDst, Name);\r
1902 \r
1903                                                 _mbslwr(Name);\r
1904                                                 LvItem.state = 0;\r
1905                                                 if(GetNodeType(Win, i) != NODE_DRIVE)\r
1906                                                 {\r
1907                                                         if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1908                                                            ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1909                                                         {\r
1910                                                                 LvItem.state = LVIS_SELECTED;\r
1911 \r
1912                                                                 if(Find >= 0)\r
1913                                                                 {\r
1914                                                                         if(IgnoreExist == YES)\r
1915                                                                                 LvItem.state = 0;\r
1916 \r
1917                                                                         if((LvItem.state != 0) && (IgnoreNew == YES))\r
1918                                                                         {\r
1919                                                                                 GetNodeTime(Win, i, &Time1);\r
1920                                                                                 GetNodeTime(WinDst, Find, &Time2);\r
1921                                                                                 if(CompareFileTime(&Time1, &Time2) > 0)\r
1922                                                                                         LvItem.state = 0;\r
1923                                                                         }\r
1924 \r
1925                                                                         if((LvItem.state != 0) && (IgnoreOld == YES))\r
1926                                                                         {\r
1927                                                                                 GetNodeTime(Win, i, &Time1);\r
1928                                                                                 GetNodeTime(WinDst, Find, &Time2);\r
1929                                                                                 if(CompareFileTime(&Time1, &Time2) < 0)\r
1930                                                                                         LvItem.state = 0;\r
1931                                                                         }\r
1932                                                                 }\r
1933                                                         }\r
1934                                                 }\r
1935 \r
1936                                                 if((LvItem.state != 0) && (CsrPos == -1))\r
1937                                                         CsrPos = i;\r
1938 \r
1939                                                 LvItem.mask = LVIF_STATE;\r
1940                                                 LvItem.iItem = i;\r
1941                                                 LvItem.stateMask = LVIS_SELECTED;\r
1942                                                 LvItem.iSubItem = 0;\r
1943                                                 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1944                                         }\r
1945                                         if(CsrPos != -1)\r
1946                                         {\r
1947                                                 LvItem.mask = LVIF_STATE;\r
1948                                                 LvItem.iItem = CsrPos;\r
1949                                                 LvItem.state = LVIS_FOCUSED;\r
1950                                                 LvItem.stateMask = LVIS_FOCUSED;\r
1951                                                 LvItem.iSubItem = 0;\r
1952                                                 SendMessage(hWnd, LVM_SETITEMSTATE, CsrPos, (LPARAM)&LvItem);\r
1953                                                 SendMessage(hWnd, LVM_ENSUREVISIBLE, CsrPos, (LPARAM)TRUE);\r
1954                                         }\r
1955                                 }\r
1956                         }\r
1957                         break;\r
1958         }\r
1959         return;\r
1960 }\r
1961 \r
1962 \r
1963 /*----- 選択ダイアログのコールバック ------------------------------------------\r
1964 *\r
1965 *       Parameter\r
1966 *               HWND hDlg : ウインドウハンドル\r
1967 *               UINT message : メッセージ番号\r
1968 *               WPARAM wParam : メッセージの WPARAM 引数\r
1969 *               LPARAM lParam : メッセージの LPARAM 引数\r
1970 *\r
1971 *       Return Value\r
1972 *               BOOL TRUE/FALSE\r
1973 *----------------------------------------------------------------------------*/\r
1974 \r
1975 // 64ビット対応\r
1976 //static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
1977 static INT_PTR CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
1978 {\r
1979         switch (iMessage)\r
1980         {\r
1981                 case WM_INITDIALOG :\r
1982                         SendDlgItemMessage(hDlg, SEL_FNAME, EM_LIMITTEXT, 40, 0);\r
1983                         SendDlgItemMessage(hDlg, SEL_FNAME, WM_SETTEXT, 0, (LPARAM)FindStr);\r
1984                         SendDlgItemMessage(hDlg, SEL_REGEXP, BM_SETCHECK, FindMode, 0);\r
1985                         SendDlgItemMessage(hDlg, SEL_NOOLD, BM_SETCHECK, IgnoreOld, 0);\r
1986                         SendDlgItemMessage(hDlg, SEL_NONEW, BM_SETCHECK, IgnoreNew, 0);\r
1987                         SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_SETCHECK, IgnoreExist, 0);\r
1988                         return(TRUE);\r
1989 \r
1990                 case WM_COMMAND :\r
1991                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
1992                         {\r
1993                                 case IDOK :\r
1994                                         SendDlgItemMessage(hDlg, SEL_FNAME, WM_GETTEXT, 40+1, (LPARAM)FindStr);\r
1995                                         FindMode = SendDlgItemMessage(hDlg, SEL_REGEXP, BM_GETCHECK, 0, 0);\r
1996                                         IgnoreOld = SendDlgItemMessage(hDlg, SEL_NOOLD, BM_GETCHECK, 0, 0);\r
1997                                         IgnoreNew = SendDlgItemMessage(hDlg, SEL_NONEW, BM_GETCHECK, 0, 0);\r
1998                                         IgnoreExist = SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_GETCHECK, 0, 0);\r
1999                                         EndDialog(hDlg, YES);\r
2000                                         break;\r
2001 \r
2002                                 case IDCANCEL :\r
2003                                         EndDialog(hDlg, NO);\r
2004                                         break;\r
2005 \r
2006                                 case IDHELP :\r
2007                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000061);\r
2008                                         break;\r
2009                         }\r
2010             return(TRUE);\r
2011         }\r
2012         return(FALSE);\r
2013 }\r
2014 \r
2015 \r
2016 /*----- ファイル一覧ウインドウのファイルを検索する ----------------------------\r
2017 *\r
2018 *       Parameter\r
2019 *               HWND hWnd : ウインドウハンドル\r
2020 *               int Type : 検索方法 (FIND_xxx)\r
2021 *\r
2022 *       Return Value\r
2023 *               なし\r
2024 *----------------------------------------------------------------------------*/\r
2025 \r
2026 void FindFileInList(HWND hWnd, int Type)\r
2027 {\r
2028         int Win;\r
2029         int i;\r
2030         int Num;\r
2031         static char RegExp[FMAX_PATH+1] = { "" };\r
2032         char Name[FMAX_PATH+1];\r
2033         LV_ITEM LvItem;\r
2034         char *Title;\r
2035 \r
2036         // 変数が未初期化のバグ修正\r
2037         memset(&LvItem, 0, sizeof(LV_ITEM));\r
2038         Win = WIN_LOCAL;\r
2039         Title = MSGJPN050;\r
2040         if(hWnd == GetRemoteHwnd())\r
2041         {\r
2042                 Win = WIN_REMOTE;\r
2043                 Title = MSGJPN051;\r
2044         }\r
2045 \r
2046         Num = GetItemCount(Win);\r
2047         switch(Type)\r
2048         {\r
2049                 case FIND_FIRST :\r
2050                         if(InputDialogBox(find_dlg, hWnd, Title, FindStr, 40+1, &FindMode, IDH_HELP_TOPIC_0000001) == YES)\r
2051                         {\r
2052                                 strcpy(RegExp, FindStr);\r
2053 //                              if(FindMode == 0)\r
2054 //                                      WildCard2RegExp(RegExp);\r
2055 \r
2056                                 _mbslwr(RegExp);\r
2057                                 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))\r
2058                                 {\r
2059                                         for(i = GetCurrentItem(Win)+1; i < Num; i++)\r
2060                                         {\r
2061                                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
2062                                                 _mbslwr(Name);\r
2063 \r
2064                                                 LvItem.state = 0;\r
2065                                                 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
2066                                                    ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
2067                                                 {\r
2068                                                         LvItem.mask = LVIF_STATE;\r
2069                                                         LvItem.iItem = i;\r
2070                                                         LvItem.state = LVIS_FOCUSED;\r
2071                                                         LvItem.stateMask = LVIS_FOCUSED;\r
2072                                                         LvItem.iSubItem = 0;\r
2073                                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
2074                                                         SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);\r
2075                                                         break;\r
2076                                                 }\r
2077                                         }\r
2078                                 }\r
2079                         }\r
2080                         break;\r
2081 \r
2082                 case FIND_NEXT :\r
2083                         for(i = GetCurrentItem(Win)+1; i < Num; i++)\r
2084                         {\r
2085                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
2086                                 _mbslwr(Name);\r
2087 \r
2088                                 LvItem.state = 0;\r
2089                                 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
2090                                    ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
2091                                 {\r
2092                                         LvItem.mask = LVIF_STATE;\r
2093                                         LvItem.iItem = i;\r
2094                                         LvItem.state = LVIS_FOCUSED;\r
2095                                         LvItem.stateMask = LVIS_FOCUSED;\r
2096                                         LvItem.iSubItem = 0;\r
2097                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
2098                                         SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);\r
2099                                         break;\r
2100                                 }\r
2101                         }\r
2102                         break;\r
2103         }\r
2104         return;\r
2105 }\r
2106 \r
2107 \r
2108 #if 0\r
2109 /*----- ワイルドカードを正規表現に変換する ------------------------------------\r
2110 *\r
2111 *       Parameter\r
2112 *               char *Str : 文字列\r
2113 *\r
2114 *       Return Value\r
2115 *               なし\r
2116 *----------------------------------------------------------------------------*/\r
2117 \r
2118 void WildCard2RegExp(char *Str)\r
2119 {\r
2120         char Tmp[FMAX_PATH+1];\r
2121         char *Org;\r
2122         char *Pos;\r
2123         UINT Ch;\r
2124 \r
2125         Org = Str;\r
2126         Pos = Tmp;\r
2127 \r
2128         *Pos++ = '^';\r
2129         *Pos++ = '(';\r
2130         while(*Str != NUL)\r
2131         {\r
2132                 if(Pos >= Tmp + FMAX_PATH - 3)\r
2133                         break;\r
2134 \r
2135                 Ch = _mbsnextc(Str);\r
2136                 Str = _mbsinc(Str);\r
2137 \r
2138                 if(Ch <= 0x7F)\r
2139                 {\r
2140                         if(strchr("[]()^$.+", Ch) != NULL)\r
2141                         {\r
2142                                 *Pos++ = '\\';\r
2143                                 *Pos++ = Ch;\r
2144                         }\r
2145                         else if(Ch == '*')\r
2146                         {\r
2147                                 *Pos++ = '.';\r
2148                                 *Pos++ = '*';\r
2149                         }\r
2150                         else if(Ch == '?')\r
2151                                 *Pos++ = '.';\r
2152                         else if(Ch == '|')\r
2153                         {\r
2154                                 *Pos++ = '|';\r
2155                         }\r
2156                         else\r
2157                                 *Pos++ = Ch;\r
2158                 }\r
2159                 else\r
2160                 {\r
2161                         _mbsnset(Pos, Ch, 1);\r
2162                         Pos = _mbsinc(Pos);\r
2163                 }\r
2164         }\r
2165         *Pos++ = ')';\r
2166         *Pos++ = '$';\r
2167         *Pos = NUL;\r
2168         strcpy(Org, Tmp);\r
2169 \r
2170         return;\r
2171 }\r
2172 #endif\r
2173 \r
2174 \r
2175 /*----- カーソル位置のアイテム番号を返す --------------------------------------\r
2176 *\r
2177 *       Parameter\r
2178 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2179 *\r
2180 *       Return Value\r
2181 *               int アイテム番号\r
2182 *----------------------------------------------------------------------------*/\r
2183 \r
2184 int GetCurrentItem(int Win)\r
2185 {\r
2186         HWND hWnd;\r
2187         int Ret;\r
2188 \r
2189         hWnd = GetLocalHwnd();\r
2190         if(Win == WIN_REMOTE)\r
2191                 hWnd = GetRemoteHwnd();\r
2192 \r
2193         if((Ret = SendMessage(hWnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_FOCUSED, 0))) == -1)\r
2194                 Ret = 0;\r
2195 \r
2196         return(Ret);\r
2197 }\r
2198 \r
2199 \r
2200 /*----- アイテム数を返す ------------------------------------------------------\r
2201 *\r
2202 *       Parameter\r
2203 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2204 *\r
2205 *       Return Value\r
2206 *               int アイテム数\r
2207 *----------------------------------------------------------------------------*/\r
2208 \r
2209 int GetItemCount(int Win)\r
2210 {\r
2211         HWND hWnd;\r
2212 \r
2213         hWnd = GetLocalHwnd();\r
2214         if(Win == WIN_REMOTE)\r
2215                 hWnd = GetRemoteHwnd();\r
2216 \r
2217         return(SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0));\r
2218 }\r
2219 \r
2220 \r
2221 /*----- 選択されているアイテム数を返す ----------------------------------------\r
2222 *\r
2223 *       Parameter\r
2224 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2225 *\r
2226 *       Return Value\r
2227 *               int 選択されているアイテム数\r
2228 *----------------------------------------------------------------------------*/\r
2229 \r
2230 int GetSelectedCount(int Win)\r
2231 {\r
2232         HWND hWnd;\r
2233 \r
2234         hWnd = GetLocalHwnd();\r
2235         if(Win == WIN_REMOTE)\r
2236                 hWnd = GetRemoteHwnd();\r
2237 \r
2238         return(SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0));\r
2239 }\r
2240 \r
2241 \r
2242 /*----- 選択されている最初のアイテム番号を返す --------------------------------\r
2243 *\r
2244 *       Parameter\r
2245 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2246 *               int All : 選ばれていないものを含める\r
2247 *\r
2248 *       Return Value\r
2249 *               int アイテム番号\r
2250 *                       -1 = 選択されていない\r
2251 *----------------------------------------------------------------------------*/\r
2252 \r
2253 int GetFirstSelected(int Win, int All)\r
2254 {\r
2255         HWND hWnd;\r
2256         int Ope;\r
2257 \r
2258         hWnd = GetLocalHwnd();\r
2259         if(Win == WIN_REMOTE)\r
2260                 hWnd = GetRemoteHwnd();\r
2261 \r
2262         Ope = LVNI_SELECTED;\r
2263         if(All == YES)\r
2264                 Ope = LVNI_ALL;\r
2265 \r
2266         return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)MAKELPARAM(Ope, 0)));\r
2267 }\r
2268 \r
2269 \r
2270 /*----- 選択されている次のアイテム番号を返す ----------------------------------\r
2271 *\r
2272 *       Parameter\r
2273 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2274 *               int Pos : 今のアイテム番号\r
2275 *               int All : 選ばれていないものも含める\r
2276 *\r
2277 *       Return Value\r
2278 *               int アイテム番号\r
2279 *                       -1 = 選択されていない\r
2280 *----------------------------------------------------------------------------*/\r
2281 \r
2282 int GetNextSelected(int Win, int Pos, int All)\r
2283 {\r
2284         HWND hWnd;\r
2285         int Ope;\r
2286 \r
2287         hWnd = GetLocalHwnd();\r
2288         if(Win == WIN_REMOTE)\r
2289                 hWnd = GetRemoteHwnd();\r
2290 \r
2291         Ope = LVNI_SELECTED;\r
2292         if(All == YES)\r
2293                 Ope = LVNI_ALL;\r
2294 \r
2295         return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)Pos, (LPARAM)MAKELPARAM(Ope, 0)));\r
2296 }\r
2297 \r
2298 \r
2299 /*----- 指定された名前のアイテムを探す ----------------------------------------\r
2300 *\r
2301 *       Parameter\r
2302 *               int Win : ウインドウ番号 (WIN_xxx)\r
2303 *               char *Name : 名前\r
2304 *\r
2305 *       Return Value\r
2306 *               int アイテム番号\r
2307 *                       -1=見つからなかった\r
2308 *----------------------------------------------------------------------------*/\r
2309 \r
2310 int FindNameNode(int Win, char *Name)\r
2311 {\r
2312         LV_FINDINFO FindInfo;\r
2313         HWND hWnd;\r
2314 \r
2315         hWnd = GetLocalHwnd();\r
2316         if(Win == WIN_REMOTE)\r
2317                 hWnd = GetRemoteHwnd();\r
2318 \r
2319         // 変数が未初期化のバグ修正\r
2320         memset(&FindInfo, 0, sizeof(LV_FINDINFO));\r
2321         FindInfo.flags = LVFI_STRING;\r
2322         FindInfo.psz = Name;\r
2323         return(SendMessage(hWnd, LVM_FINDITEM, -1, (LPARAM)&FindInfo));\r
2324 }\r
2325 \r
2326 \r
2327 /*----- 指定位置のアイテムの名前を返す ----------------------------------------\r
2328 *\r
2329 *       Parameter\r
2330 *               int Win : ウインドウ番号 (WIN_xxx)\r
2331 *               int Pos : 位置\r
2332 *               char *Buf : 名前を返すバッファ\r
2333 *               int Max : バッファのサイズ\r
2334 *\r
2335 *       Return Value\r
2336 *               なし\r
2337 *----------------------------------------------------------------------------*/\r
2338 \r
2339 void GetNodeName(int Win, int Pos, char *Buf, int Max)\r
2340 {\r
2341         HWND hWnd;\r
2342         LV_ITEM LvItem;\r
2343 \r
2344         hWnd = GetLocalHwnd();\r
2345         if(Win == WIN_REMOTE)\r
2346                 hWnd = GetRemoteHwnd();\r
2347 \r
2348         // 変数が未初期化のバグ修正\r
2349         memset(&LvItem, 0, sizeof(LV_ITEM));\r
2350         LvItem.mask = LVIF_TEXT;\r
2351         LvItem.iItem = Pos;\r
2352         LvItem.iSubItem = 0;\r
2353         LvItem.pszText = Buf;\r
2354         LvItem.cchTextMax = Max;\r
2355         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2356         return;\r
2357 }\r
2358 \r
2359 \r
2360 /*----- 指定位置のアイテムの日付を返す ----------------------------------------\r
2361 *\r
2362 *       Parameter\r
2363 *               int Win : ウインドウ番号 (WIN_xxx)\r
2364 *               int Pos : 位置\r
2365 *               FILETIME *Buf : 日付を返すバッファ\r
2366 *\r
2367 *       Return Value\r
2368 *               int ステータス\r
2369 *                       YES/NO=日付情報がなかった\r
2370 *----------------------------------------------------------------------------*/\r
2371 \r
2372 int GetNodeTime(int Win, int Pos, FILETIME *Buf)\r
2373 {\r
2374         HWND hWnd;\r
2375         LV_ITEM LvItem;\r
2376         char Tmp[20];\r
2377         int Ret;\r
2378 \r
2379         hWnd = GetLocalHwnd();\r
2380         if(Win == WIN_REMOTE)\r
2381                 hWnd = GetRemoteHwnd();\r
2382 \r
2383         // 変数が未初期化のバグ修正\r
2384         memset(&LvItem, 0, sizeof(LV_ITEM));\r
2385         LvItem.mask = LVIF_TEXT;\r
2386         LvItem.iItem = Pos;\r
2387         LvItem.iSubItem = 1;\r
2388         LvItem.pszText = Tmp;\r
2389         LvItem.cchTextMax = 20;\r
2390         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2391         Ret = TimeString2FileTime(Tmp, Buf);\r
2392         return(Ret);\r
2393 }\r
2394 \r
2395 \r
2396 /*----- 指定位置のアイテムのサイズを返す --------------------------------------\r
2397 *\r
2398 *       Parameter\r
2399 *               int Win : ウインドウ番号 (WIN_xxx)\r
2400 *               int Pos : 位置\r
2401 *               int *Buf : サイズを返すワーク\r
2402 *\r
2403 *       Return Value\r
2404 *               int ステータス\r
2405 *                       YES/NO=サイズ情報がなかった\r
2406 *----------------------------------------------------------------------------*/\r
2407 \r
2408 int GetNodeSize(int Win, int Pos, LONGLONG *Buf)\r
2409 {\r
2410         HWND hWnd;\r
2411         LV_ITEM LvItem;\r
2412         char Tmp[40];\r
2413         int Ret;\r
2414 \r
2415         hWnd = GetLocalHwnd();\r
2416         if(Win == WIN_REMOTE)\r
2417                 hWnd = GetRemoteHwnd();\r
2418 \r
2419         // 変数が未初期化のバグ修正\r
2420         memset(&LvItem, 0, sizeof(LV_ITEM));\r
2421         LvItem.mask = LVIF_TEXT;\r
2422         LvItem.iItem = Pos;\r
2423         LvItem.iSubItem = 2;\r
2424         LvItem.pszText = Tmp;\r
2425         LvItem.cchTextMax = 20;\r
2426         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2427         *Buf = -1;\r
2428         Ret = NO;\r
2429 #if defined(HAVE_TANDEM)\r
2430         if(AskHostType() == HTYPE_TANDEM) {\r
2431                 RemoveComma(Tmp);\r
2432                 *Buf = _atoi64(Tmp);\r
2433                 Ret = YES;\r
2434         } else\r
2435 #endif\r
2436         if(strlen(Tmp) > 0)\r
2437         {\r
2438                 RemoveComma(Tmp);\r
2439                 *Buf = _atoi64(Tmp);\r
2440                 Ret = YES;\r
2441         }\r
2442         return(Ret);\r
2443 }\r
2444 \r
2445 \r
2446 /*----- 指定位置のアイテムの属性を返す ----------------------------------------\r
2447 *\r
2448 *       Parameter\r
2449 *               int Win : ウインドウ番号 (WIN_xxx)\r
2450 *               int Pos : 位置\r
2451 *               int *Buf : 属性を返すワーク\r
2452 *\r
2453 *       Return Value\r
2454 *               int ステータス\r
2455 *                       YES/NO=サイズ情報がなかった\r
2456 *----------------------------------------------------------------------------*/\r
2457 \r
2458 int GetNodeAttr(int Win, int Pos, int *Buf)\r
2459 {\r
2460         LV_ITEM LvItem;\r
2461         char Tmp[20];\r
2462         int Ret;\r
2463 \r
2464         *Buf = 0;\r
2465         Ret = NO;\r
2466         if(Win == WIN_REMOTE)\r
2467         {\r
2468                 // 変数が未初期化のバグ修正\r
2469                 memset(&LvItem, 0, sizeof(LV_ITEM));\r
2470                 LvItem.mask = LVIF_TEXT;\r
2471                 LvItem.iItem = Pos;\r
2472 #if defined(HAVE_TANDEM)\r
2473                 if(AskHostType() == HTYPE_TANDEM)\r
2474                         LvItem.iSubItem = 3;\r
2475                 else\r
2476 #endif\r
2477                 LvItem.iSubItem = 4;\r
2478                 LvItem.pszText = Tmp;\r
2479                 LvItem.cchTextMax = 20;\r
2480                 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2481                 if(strlen(Tmp) > 0)\r
2482                 {\r
2483 #if defined(HAVE_TANDEM)\r
2484                         if(AskHostType() == HTYPE_TANDEM)\r
2485                                 *Buf = atoi(Tmp);\r
2486                         else\r
2487 #endif\r
2488                         *Buf = AttrString2Value(Tmp);\r
2489                         Ret = YES;\r
2490                 }\r
2491         }\r
2492         return(Ret);\r
2493 }\r
2494 \r
2495 \r
2496 /*----- 指定位置のアイテムのタイプを返す --------------------------------------\r
2497 *\r
2498 *       Parameter\r
2499 *               int Win : ウインドウ番号 (WIN_xxx)\r
2500 *               int Pos : 位置\r
2501 *\r
2502 *       Return Value\r
2503 *               int タイプ (NODE_xxx)\r
2504 *----------------------------------------------------------------------------*/\r
2505 \r
2506 int GetNodeType(int Win, int Pos)\r
2507 {\r
2508         char Tmp[20];\r
2509         LV_ITEM LvItem;\r
2510         int Ret;\r
2511         HWND hWnd;\r
2512 \r
2513         hWnd = GetLocalHwnd();\r
2514         if(Win == WIN_REMOTE)\r
2515                 hWnd = GetRemoteHwnd();\r
2516 \r
2517         // 変数が未初期化のバグ修正\r
2518         memset(&LvItem, 0, sizeof(LV_ITEM));\r
2519         LvItem.mask = LVIF_TEXT;\r
2520         LvItem.iItem = Pos;\r
2521         LvItem.iSubItem = 2;\r
2522         LvItem.pszText = Tmp;\r
2523         LvItem.cchTextMax = 20;\r
2524         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2525 \r
2526         if(strcmp(Tmp, "<DIR>") == 0)\r
2527                 Ret = NODE_DIR;\r
2528         else if(strcmp(Tmp, "<DRIVE>") == 0)\r
2529                 Ret = NODE_DRIVE;\r
2530         else\r
2531                 Ret = NODE_FILE;\r
2532 \r
2533         return(Ret);\r
2534 }\r
2535 \r
2536 \r
2537 /*----- 指定位置のアイテムのオーナ名を返す ------------------------------------\r
2538 *\r
2539 *       Parameter\r
2540 *               int Win : ウインドウ番号 (WIN_xxx)\r
2541 *               int Pos : 位置\r
2542 *               char *Buf : オーナ名を返すバッファ\r
2543 *               int Max : バッファのサイズ\r
2544 *\r
2545 *       Return Value\r
2546 *               なし\r
2547 *----------------------------------------------------------------------------*/\r
2548 \r
2549 void GetNodeOwner(int Win, int Pos, char *Buf, int Max)\r
2550 {\r
2551         LV_ITEM LvItem;\r
2552 \r
2553         strcpy(Buf, "");\r
2554         if(Win == WIN_REMOTE)\r
2555         {\r
2556                 // 変数が未初期化のバグ修正\r
2557                 memset(&LvItem, 0, sizeof(LV_ITEM));\r
2558                 LvItem.mask = LVIF_TEXT;\r
2559                 LvItem.iItem = Pos;\r
2560                 LvItem.iSubItem = 5;\r
2561                 LvItem.pszText = Buf;\r
2562                 LvItem.cchTextMax = Max;\r
2563                 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2564         }\r
2565         return;\r
2566 }\r
2567 \r
2568 \r
2569 /*----- ホスト側のファイル一覧ウインドウをクリア ------------------------------\r
2570 *\r
2571 *       Parameter\r
2572 *               なし\r
2573 *\r
2574 *       Return Value\r
2575 *               なし\r
2576 *----------------------------------------------------------------------------*/\r
2577 \r
2578 void EraseRemoteDirForWnd(void)\r
2579 {\r
2580         SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
2581         SendMessage(GetRemoteHistHwnd(), CB_RESETCONTENT, 0, 0);\r
2582         return;\r
2583 }\r
2584 \r
2585 \r
2586 /*----- 選択されているファイルの総サイズを返す --------------------------------\r
2587 *\r
2588 *       Parameter\r
2589 *               int Win : ウインドウ番号 (WIN_xxx)\r
2590 *\r
2591 *       Return Value\r
2592 *               double サイズ\r
2593 *----------------------------------------------------------------------------*/\r
2594 \r
2595 double GetSelectedTotalSize(int Win)\r
2596 {\r
2597         double Ret;\r
2598         LONGLONG Size;\r
2599         int Pos;\r
2600 \r
2601         Ret = 0;\r
2602         if(GetSelectedCount(Win) > 0)\r
2603         {\r
2604                 Pos = GetFirstSelected(Win, NO);\r
2605                 while(Pos != -1)\r
2606                 {\r
2607                         GetNodeSize(Win, Pos, &Size);\r
2608                         if(Size >= 0)\r
2609                                 Ret += Size;\r
2610                         Pos = GetNextSelected(Win, Pos, NO);\r
2611                 }\r
2612         }\r
2613         return(Ret);\r
2614 }\r
2615 \r
2616 \r
2617 \r
2618 /*===================================================================\r
2619 \r
2620 ===================================================================*/\r
2621 \r
2622 \r
2623 \r
2624 /*----- ファイル一覧で選ばれているファイルをリストに登録する ------------------\r
2625 *\r
2626 *       Parameter\r
2627 *               int Win : ウインドウ番号 (WIN_xxx)\r
2628 *               int Expand : サブディレクトリを展開する (YES/NO)\r
2629 *               int All : 選ばれていないものもすべて登録する (YES/NO)\r
2630 *               FILELIST **Base : ファイルリストの先頭\r
2631 *\r
2632 *       Return Value\r
2633 *               なし\r
2634 *----------------------------------------------------------------------------*/\r
2635 \r
2636 void MakeSelectedFileList(int Win, int Expand, int All, FILELIST **Base, int *CancelCheckWork)\r
2637 {\r
2638         int Pos;\r
2639         char Name[FMAX_PATH+1];\r
2640         char Cur[FMAX_PATH+1];\r
2641         FILELIST Pkt;\r
2642         int Node;\r
2643         DWORD Attr;\r
2644         int Ignore;\r
2645 \r
2646         if((All == YES) || (GetSelectedCount(Win) > 0))\r
2647         {\r
2648                 /*===== カレントディレクトリのファイル =====*/\r
2649 \r
2650                 Pos = GetFirstSelected(Win, All);\r
2651                 while(Pos != -1)\r
2652                 {\r
2653                         Node = GetNodeType(Win, Pos);\r
2654                         if((Node == NODE_FILE) ||\r
2655                            ((Expand == NO) && (Node == NODE_DIR)))\r
2656                         {\r
2657                                 // 変数が未初期化のバグ修正\r
2658                                 memset(&Pkt, 0, sizeof(FILELIST));\r
2659 \r
2660                                 Pkt.InfoExist = 0;\r
2661                                 GetNodeName(Win, Pos, Pkt.File, FMAX_PATH);\r
2662                                 if(GetNodeSize(Win, Pos, &Pkt.Size) == YES)\r
2663                                         Pkt.InfoExist |= FINFO_SIZE;\r
2664                                 if(GetNodeAttr(Win, Pos, &Pkt.Attr) == YES)\r
2665                                         Pkt.InfoExist |= FINFO_ATTR;\r
2666                                 if(GetNodeTime(Win, Pos, &Pkt.Time) == YES)\r
2667                                         Pkt.InfoExist |= (FINFO_TIME | FINFO_DATE);\r
2668                                 Pkt.Node = Node;\r
2669 \r
2670                                 Ignore = NO;\r
2671                                 if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))\r
2672                                 {\r
2673                                         AskLocalCurDir(Cur, FMAX_PATH);\r
2674                                         SetYenTail(Cur);\r
2675                                         strcat(Cur, Pkt.File);\r
2676                                         Attr = GetFileAttributes(Cur);\r
2677                                         if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))\r
2678                                                 Ignore = YES;\r
2679                                 }\r
2680 \r
2681                                 if(Ignore == NO)\r
2682                                         AddFileList(&Pkt, Base);\r
2683                         }\r
2684                         Pos = GetNextSelected(Win, Pos, All);\r
2685                 }\r
2686 \r
2687                 if(Expand == YES)\r
2688                 {\r
2689                         /*===== ディレクトリツリー =====*/\r
2690 \r
2691                         Pos = GetFirstSelected(Win, All);\r
2692                         while(Pos != -1)\r
2693                         {\r
2694                                 if(GetNodeType(Win, Pos) == NODE_DIR)\r
2695                                 {\r
2696                                         // 変数が未初期化のバグ修正\r
2697                                         memset(&Pkt, 0, sizeof(FILELIST));\r
2698 \r
2699                                         GetNodeName(Win, Pos, Name, FMAX_PATH);\r
2700                                         strcpy(Pkt.File, Name);\r
2701                                         ReplaceAll(Pkt.File, '\\', '/');\r
2702 //8/26\r
2703 \r
2704                                         Ignore = NO;\r
2705                                         if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))\r
2706                                         {\r
2707                                                 AskLocalCurDir(Cur, FMAX_PATH);\r
2708                                                 SetYenTail(Cur);\r
2709                                                 strcat(Cur, Pkt.File);\r
2710                                                 ReplaceAll(Cur, '/', '\\');\r
2711                                                 Attr = GetFileAttributes(Cur);\r
2712                                                 if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))\r
2713                                                         Ignore = YES;\r
2714                                         }\r
2715 \r
2716                                         if(Ignore == NO)\r
2717                                         {\r
2718                                                 Pkt.Node = NODE_DIR;\r
2719                                                 Pkt.Attr = 0;\r
2720                                                 Pkt.Size = 0;\r
2721                                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2722                                                 AddFileList(&Pkt, Base);\r
2723 \r
2724                                                 if(Win == WIN_LOCAL)\r
2725                                                         MakeLocalTree(Name, Base);\r
2726                                                 else\r
2727                                                 {\r
2728                                                         AskRemoteCurDir(Cur, FMAX_PATH);\r
2729 \r
2730                                                         if((AskListCmdMode() == NO) &&\r
2731                                                            (AskUseNLST_R() == YES))\r
2732                                                                 MakeRemoteTree1(Name, Cur, Base, CancelCheckWork);\r
2733                                                         else\r
2734                                                                 MakeRemoteTree2(Name, Cur, Base, CancelCheckWork);\r
2735 \r
2736 //DispListList(*Base, "LIST");\r
2737 \r
2738                                                 }\r
2739                                         }\r
2740                                 }\r
2741                                 Pos = GetNextSelected(Win, Pos, All);\r
2742                         }\r
2743                 }\r
2744         }\r
2745         return;\r
2746 }\r
2747 \r
2748 \r
2749 /* デバッグ用 */\r
2750 /* ファイルリストの内容を表示 */\r
2751 static void DispListList(FILELIST *Pos, char *Title)\r
2752 {\r
2753         DoPrintf("############ %s ############", Title);\r
2754         while(Pos != NULL)\r
2755         {\r
2756                 DoPrintf("%d %s", Pos->Node, Pos->File);\r
2757                 Pos = Pos->Next;\r
2758         }\r
2759         DoPrintf("############ END ############");\r
2760         return;\r
2761 }\r
2762 \r
2763 \r
2764 /*----- Drag&Dropされたファイルをリストに登録する -----------------------------\r
2765 *\r
2766 *       Parameter\r
2767 *               WPARAM wParam : ドロップされたファイルの情報\r
2768 *               char *Cur : カレントディレクトリを返すバッファ\r
2769 *               FILELIST **Base : ファイルリストの先頭\r
2770 *\r
2771 *       Return Value\r
2772 *               なし\r
2773 *----------------------------------------------------------------------------*/\r
2774 \r
2775 void MakeDroppedFileList(WPARAM wParam, char *Cur, FILELIST **Base)\r
2776 {\r
2777         int Max;\r
2778         int i;\r
2779         char Name[FMAX_PATH+1];\r
2780         char Tmp[FMAX_PATH+1];\r
2781         FILELIST Pkt;\r
2782         HANDLE fHnd;\r
2783         WIN32_FIND_DATA Find;\r
2784 \r
2785         Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);\r
2786 \r
2787         DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);\r
2788         GetUpperDir(Cur);\r
2789 \r
2790         for(i = 0; i < Max; i++)\r
2791         {\r
2792                 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);\r
2793 \r
2794                 if((GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY) == 0)\r
2795                 {\r
2796                         // 変数が未初期化のバグ修正\r
2797                         memset(&Pkt, 0, sizeof(FILELIST));\r
2798 \r
2799                         Pkt.Node = NODE_FILE;\r
2800                         strcpy(Pkt.File, GetFileName(Name));\r
2801 \r
2802                         memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2803 #if defined(HAVE_TANDEM)\r
2804                         /* Guardian スペースへのアップロードのためにサイズが必要 */\r
2805                         Pkt.Size = 0;\r
2806                         Pkt.InfoExist = 0;\r
2807 #endif\r
2808                         if((fHnd = FindFirstFile(Name, &Find)) != INVALID_HANDLE_VALUE)\r
2809                         {\r
2810                                 FindClose(fHnd);\r
2811                                 Pkt.Time = Find.ftLastWriteTime;\r
2812 #if defined(HAVE_TANDEM)\r
2813                                 Pkt.Size = MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow);\r
2814                                 Pkt.InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
2815 #endif\r
2816                         }\r
2817                         AddFileList(&Pkt, Base);\r
2818                 }\r
2819         }\r
2820 \r
2821         GetCurrentDirectory(FMAX_PATH, Tmp);\r
2822         SetCurrentDirectory(Cur);\r
2823         for(i = 0; i < Max; i++)\r
2824         {\r
2825                 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);\r
2826 \r
2827                 if(GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY)\r
2828                 {\r
2829                         // 変数が未初期化のバグ修正\r
2830                         memset(&Pkt, 0, sizeof(FILELIST));\r
2831 \r
2832                         Pkt.Node = NODE_DIR;\r
2833                         strcpy(Pkt.File, GetFileName(Name));\r
2834                         AddFileList(&Pkt, Base);\r
2835 \r
2836                         MakeLocalTree(Pkt.File, Base);\r
2837                 }\r
2838         }\r
2839         SetCurrentDirectory(Tmp);\r
2840 \r
2841         DragFinish((HDROP)wParam);\r
2842 \r
2843         return;\r
2844 }\r
2845 \r
2846 \r
2847 /*----- Drag&Dropされたファイルがあるフォルダを取得する -----------------------\r
2848 *\r
2849 *       Parameter\r
2850 *               WPARAM wParam : ドロップされたファイルの情報\r
2851 *               char *Cur : カレントディレクトリを返すバッファ\r
2852 *\r
2853 *       Return Value\r
2854 *               なし\r
2855 *----------------------------------------------------------------------------*/\r
2856 \r
2857 void MakeDroppedDir(WPARAM wParam, char *Cur)\r
2858 {\r
2859         int Max;\r
2860 \r
2861         Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);\r
2862         DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);\r
2863         GetUpperDir(Cur);\r
2864         DragFinish((HDROP)wParam);\r
2865 \r
2866         return;\r
2867 }\r
2868 \r
2869 \r
2870 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(1)-------\r
2871 *\r
2872 *       Parameter\r
2873 *               char *Path : パス名\r
2874 *               char *Cur : カレントディレクトリ\r
2875 *               FILELIST **Base : ファイルリストの先頭\r
2876 *\r
2877 *       Return Value\r
2878 *               なし\r
2879 *\r
2880 *       Note\r
2881 *               NLST -alLR を使う\r
2882 *----------------------------------------------------------------------------*/\r
2883 \r
2884 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)\r
2885 {\r
2886         int Sts;\r
2887 \r
2888         if(DoCWD(Path, NO, NO, NO) == FTP_COMPLETE)\r
2889         {\r
2890                 /* サブフォルダも含めたリストを取得 */\r
2891                 Sts = DoDirListCmdSkt("R", "", 999, CancelCheckWork);   /* NLST -alLR*/\r
2892                 DoCWD(Cur, NO, NO, NO);\r
2893 \r
2894                 if(Sts == FTP_COMPLETE)\r
2895                         AddRemoteTreeToFileList(999, Path, RDIR_NLST, Base);\r
2896         }\r
2897         return;\r
2898 }\r
2899 \r
2900 \r
2901 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(2)-------\r
2902 *\r
2903 *       Parameter\r
2904 *               char *Path : パス名\r
2905 *               char *Cur : カレントディレクトリ\r
2906 *               FILELIST **Base : ファイルリストの先頭\r
2907 *\r
2908 *       Return Value\r
2909 *               なし\r
2910 *\r
2911 *       Note\r
2912 *               各フォルダに移動してリストを取得\r
2913 *----------------------------------------------------------------------------*/\r
2914 \r
2915 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)\r
2916 {\r
2917         int Sts;\r
2918         FILELIST *CurList;\r
2919         FILELIST *Pos;\r
2920         FILELIST Pkt;\r
2921 \r
2922         /* VAX VMS は CWD xxx/yyy という指定ができないので */\r
2923         /* CWD xxx, Cwd yyy と複数に分ける                                       */\r
2924         if(AskHostType() != HTYPE_VMS)\r
2925                 Sts = DoCWD(Path, NO, NO, NO);\r
2926         else\r
2927         {\r
2928 #if defined(HAVE_OPENVMS)\r
2929                 /* OpenVMSの場合、ディレクトリ移動時は"HOGE.DIR;1"を"HOGE"にする */\r
2930                 ReformVMSDirName(Path, TRUE);\r
2931 #endif\r
2932                 Sts = DoCWDStepByStep(Path, Cur);\r
2933         }\r
2934 \r
2935         if(Sts == FTP_COMPLETE)\r
2936         {\r
2937                 Sts = DoDirListCmdSkt("", "", 999, CancelCheckWork);            /* NLST -alL*/\r
2938                 DoCWD(Cur, NO, NO, NO);\r
2939 \r
2940                 if(Sts == FTP_COMPLETE)\r
2941                 {\r
2942                         CurList = NULL;\r
2943                         AddRemoteTreeToFileList(999, Path, RDIR_CWD, &CurList);\r
2944                         CopyTmpListToFileList(Base, CurList);\r
2945 \r
2946                         Pos = CurList;\r
2947                         while(Pos != NULL)\r
2948                         {\r
2949                                 if(Pos->Node == NODE_DIR)\r
2950                                 {\r
2951                                         // 変数が未初期化のバグ修正\r
2952                                         memset(&Pkt, 0, sizeof(FILELIST));\r
2953 \r
2954                                         /* まずディレクトリ名をセット */\r
2955                                         strcpy(Pkt.File, Pos->File);\r
2956                                         Pkt.Node = NODE_DIR;\r
2957                                         Pkt.Size = 0;\r
2958                                         Pkt.Attr = 0;\r
2959                                         memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2960                                         AddFileList(&Pkt, Base);\r
2961 \r
2962                                         /* そのディレクトリの中を検索 */\r
2963                                         MakeRemoteTree2(Pos->File, Cur, Base, CancelCheckWork);\r
2964                                 }\r
2965                                 Pos = Pos->Next;\r
2966                         }\r
2967                         DeleteFileList(&CurList);\r
2968                 }\r
2969         }\r
2970         return;\r
2971 }\r
2972 \r
2973 \r
2974 /*----- ファイルリストの内容を別のファイルリストにコピー ----------------------\r
2975 *\r
2976 *       Parameter\r
2977 *               FILELIST **Base : コピー先\r
2978 *               FILELIST *List : コピー元\r
2979 *\r
2980 *       Return Value\r
2981 *               なし\r
2982 *\r
2983 *       Note\r
2984 *               コピーするのはファイルの情報だけ\r
2985 *               ディレクトリの情報はコピーしない\r
2986 *----------------------------------------------------------------------------*/\r
2987 \r
2988 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List)\r
2989 {\r
2990         while(List != NULL)\r
2991         {\r
2992                 if(List->Node == NODE_FILE)\r
2993                         AddFileList(List, Base);\r
2994 \r
2995                 List = List->Next;\r
2996         }\r
2997         return;\r
2998 }\r
2999 \r
3000 \r
3001 /*----- ホスト側のファイル情報をファイルリストに登録 --------------------------\r
3002 *\r
3003 *       Parameter\r
3004 *               int Num : テンポラリファイルのファイル名番号 (_ffftp.???)\r
3005 *               char *Path : パス名\r
3006 *               int IncDir : 再帰検索の方法 (RDIR_xxx)\r
3007 *               FILELIST **Base : ファイルリストの先頭\r
3008 *\r
3009 *       Return Value\r
3010 *               なし\r
3011 *----------------------------------------------------------------------------*/\r
3012 \r
3013 void AddRemoteTreeToFileList(int Num, char *Path, int IncDir, FILELIST **Base)\r
3014 {\r
3015         char Str[FMAX_PATH+1];\r
3016         char Dir[FMAX_PATH+1];\r
3017         char Name[FMAX_PATH+1];\r
3018         LONGLONG Size;\r
3019         FILETIME Time;\r
3020         int Attr;\r
3021         FILELIST Pkt;\r
3022         FILE *fd;\r
3023         int Node;\r
3024         int ListType;\r
3025         char Owner[OWNER_NAME_LEN+1];\r
3026         int Link;\r
3027         int InfoExist;\r
3028 \r
3029         MakeCacheFileName(Num, Str);\r
3030         if((fd = fopen(Str, "rb")) != NULL)\r
3031         {\r
3032                 strcpy(Dir, Path);\r
3033 \r
3034                 ListType = LIST_UNKNOWN;\r
3035 \r
3036                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
3037                 {\r
3038                         if((ListType = AnalizeFileInfo(Str)) == LIST_UNKNOWN)\r
3039                         {\r
3040                                 if(MakeDirPath(Str, ListType, Path, Dir) == FFFTP_SUCCESS)\r
3041                                 {\r
3042                                         if(IncDir == RDIR_NLST)\r
3043                                         {\r
3044                                                 // 変数が未初期化のバグ修正\r
3045                                                 memset(&Pkt, 0, sizeof(FILELIST));\r
3046 \r
3047                                                 strcpy(Pkt.File, Dir);\r
3048                                                 Pkt.Node = NODE_DIR;\r
3049                                                 Pkt.Size = 0;\r
3050                                                 Pkt.Attr = 0;\r
3051                                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
3052                                                 AddFileList(&Pkt, Base);\r
3053                                         }\r
3054                                 }\r
3055                         }\r
3056                         else\r
3057                         {\r
3058                                 Node = ResolvFileInfo(Str, ListType, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);\r
3059 \r
3060                                 if(AskFilterStr(Name, Node) == YES)\r
3061                                 {\r
3062                                         if((Node == NODE_FILE) ||\r
3063                                            ((IncDir == RDIR_CWD) && (Node == NODE_DIR)))\r
3064                                         {\r
3065                                                 // 変数が未初期化のバグ修正\r
3066                                                 memset(&Pkt, 0, sizeof(FILELIST));\r
3067 \r
3068                                                 strcpy(Pkt.File, Dir);\r
3069                                                 if(strlen(Pkt.File) > 0)\r
3070                                                         SetSlashTail(Pkt.File);\r
3071                                                 strcat(Pkt.File, Name);\r
3072                                                 Pkt.Node = Node;\r
3073                                                 Pkt.Link = Link;\r
3074                                                 Pkt.Size = Size;\r
3075                                                 Pkt.Attr = Attr;\r
3076                                                 Pkt.Time = Time;\r
3077                                                 Pkt.InfoExist = InfoExist;\r
3078                                                 AddFileList(&Pkt, Base);\r
3079                                         }\r
3080                                 }\r
3081                         }\r
3082                 }\r
3083                 fclose(fd);\r
3084         }\r
3085         return;\r
3086 }\r
3087 \r
3088 \r
3089 /*----- ファイル一覧情報の1行を取得 ------------------------------------------\r
3090 *\r
3091 *       Parameter\r
3092 *               char *Buf : 1行の情報をセットするバッファ\r
3093 *               int Max : 最大文字数\r
3094 *               FILE *Fd : ストリーム\r
3095 *\r
3096 *       Return Value\r
3097 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
3098 *\r
3099 *       Note\r
3100 *               VAX VMS以外の時は fgets(Buf, Max, Fd) と同じ\r
3101 *               Vax VMSの時は、複数行のファイル情報を1行にまとめる\r
3102 *----------------------------------------------------------------------------*/\r
3103 \r
3104 static int GetListOneLine(char *Buf, int Max, FILE *Fd)\r
3105 {\r
3106         char Tmp[FMAX_PATH+1];\r
3107         int Sts;\r
3108 \r
3109         Sts = FFFTP_FAIL;\r
3110         while((Sts == FFFTP_FAIL) && (fgets(Buf, Max, Fd) != NULL))\r
3111         {\r
3112                 Sts = FFFTP_SUCCESS;\r
3113                 RemoveReturnCode(Buf);\r
3114                 ReplaceAll(Buf, '\x08', ' ');\r
3115 \r
3116                 /* VAX VMSではファイル情報が複数行にわかれている     */\r
3117                 /* それを1行にまとめる                                                               */\r
3118                 if(AskHostType() == HTYPE_VMS)\r
3119                 {\r
3120                         if(strchr(Buf, ';') == NULL)    /* ファイル名以外の行 */\r
3121                                 Sts = FFFTP_FAIL;\r
3122                         else\r
3123                         {\r
3124                                 Max -= strlen(Buf);\r
3125                                 while(strchr(Buf, ')') == NULL)\r
3126                                 {\r
3127                                         if(fgets(Tmp, FMAX_PATH, Fd) != NULL)\r
3128                                         {\r
3129                                                 RemoveReturnCode(Tmp);\r
3130                                                 ReplaceAll(Buf, '\x08', ' ');\r
3131                                                 if((int)strlen(Tmp) > Max)\r
3132                                                         Tmp[Max] = NUL;\r
3133                                                 Max -= strlen(Tmp);\r
3134                                                 strcat(Buf, Tmp);\r
3135                                         }\r
3136                                         else\r
3137                                                 break;\r
3138                                 }\r
3139                         }\r
3140                 }\r
3141         }\r
3142 \r
3143 //      DoPrintf("List : %s", Buf);\r
3144 \r
3145         return(Sts);\r
3146 }\r
3147 \r
3148 \r
3149 /*----- サブディレクトリ情報の解析 --------------------------------------------\r
3150 *\r
3151 *       Parameter\r
3152 *               char *Str : ファイル情報(1行)\r
3153 *               int ListType : リストのタイプ\r
3154 *               char *Path : 先頭からのパス名\r
3155 *               char *Dir : ディレクトリ名\r
3156 *\r
3157 *       Return Value\r
3158 *               int ステータス\r
3159 *                       FFFTP_SUCCESS/FFFTP_FAIL=ディレクトリ情報でない\r
3160 *----------------------------------------------------------------------------*/\r
3161 \r
3162 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir)\r
3163 {\r
3164         int Sts;\r
3165 \r
3166         Sts = FFFTP_FAIL;\r
3167         switch(ListType)\r
3168         {\r
3169                 case LIST_ACOS :\r
3170                 case LIST_ACOS_4 :\r
3171                         break;\r
3172 \r
3173                 default:\r
3174                         if(*(Str + strlen(Str) - 1) == ':')             /* 最後が : ならサブディレクトリ */\r
3175                         {\r
3176                                 if(strcmp(Str, ".:") != 0)\r
3177                                 {\r
3178                                         if((strncmp(Str, "./", 2) == 0) ||\r
3179                                            (strncmp(Str, ".\\", 2) == 0))\r
3180                                         {\r
3181                                                 Str += 2;\r
3182                                         }\r
3183 \r
3184                                         if(strlen(Str) > 1)\r
3185                                         {\r
3186                                                 strcpy(Dir, Path);\r
3187                                                 SetSlashTail(Dir);\r
3188                                                 strcat(Dir, Str);\r
3189                                                 *(Dir + strlen(Dir) - 1) = NUL;\r
3190 \r
3191                                                 ChangeFnameRemote2Local(Dir, FMAX_PATH);\r
3192 \r
3193                                                 ReplaceAll(Dir, '\\', '/');\r
3194                                         }\r
3195                                 }\r
3196                                 Sts = FFFTP_SUCCESS;\r
3197                         }\r
3198                         break;\r
3199         }\r
3200         return(Sts);\r
3201 }\r
3202 \r
3203 \r
3204 /*----- ローカル側のサブディレクトリ以下のファイルをリストに登録する ----------\r
3205 *\r
3206 *       Parameter\r
3207 *               char *Path : パス名\r
3208 *               FILELIST **Base : ファイルリストの先頭\r
3209 *\r
3210 *       Return Value\r
3211 *               なし\r
3212 *----------------------------------------------------------------------------*/\r
3213 \r
3214 static void MakeLocalTree(char *Path, FILELIST **Base)\r
3215 {\r
3216         char Src[FMAX_PATH+1];\r
3217         HANDLE fHnd;\r
3218         WIN32_FIND_DATA FindBuf;\r
3219         FILELIST Pkt;\r
3220         SYSTEMTIME TmpStime;\r
3221 \r
3222         strcpy(Src, Path);\r
3223         SetYenTail(Src);\r
3224         strcat(Src, "*");\r
3225         ReplaceAll(Src, '/', '\\');\r
3226 \r
3227         if((fHnd = FindFirstFileAttr(Src, &FindBuf, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
3228         {\r
3229                 do\r
3230                 {\r
3231                         if((FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)\r
3232                         {\r
3233                                 if(AskFilterStr(FindBuf.cFileName, NODE_FILE) == YES)\r
3234                                 {\r
3235                                         // 変数が未初期化のバグ修正\r
3236                                         memset(&Pkt, 0, sizeof(FILELIST));\r
3237 \r
3238                                         strcpy(Pkt.File, Path);\r
3239                                         SetSlashTail(Pkt.File);\r
3240                                         strcat(Pkt.File, FindBuf.cFileName);\r
3241                                         ReplaceAll(Pkt.File, '\\', '/');\r
3242                                         Pkt.Node = NODE_FILE;\r
3243                                         Pkt.Size = MakeLongLong(FindBuf.nFileSizeHigh, FindBuf.nFileSizeLow);\r
3244                                         Pkt.Attr = 0;\r
3245                                         Pkt.Time = FindBuf.ftLastWriteTime;\r
3246                                         FileTimeToSystemTime(&Pkt.Time, &TmpStime);\r
3247                                         TmpStime.wSecond = 0;\r
3248                                         TmpStime.wMilliseconds = 0;\r
3249                                         SystemTimeToFileTime(&TmpStime, &Pkt.Time);\r
3250                                         AddFileList(&Pkt, Base);\r
3251                                 }\r
3252                         }\r
3253                 }\r
3254                 while(FindNextFileAttr(fHnd, &FindBuf, DispIgnoreHide) == TRUE);\r
3255                 FindClose(fHnd);\r
3256         }\r
3257 \r
3258         if((fHnd = FindFirstFileAttr(Src, &FindBuf, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
3259         {\r
3260                 do\r
3261                 {\r
3262                         if((FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&\r
3263                            (strcmp(FindBuf.cFileName, ".") != 0) &&\r
3264                            (strcmp(FindBuf.cFileName, "..") != 0))\r
3265                         {\r
3266                                 // 変数が未初期化のバグ修正\r
3267                                 memset(&Pkt, 0, sizeof(FILELIST));\r
3268 \r
3269                                 strcpy(Src, Path);\r
3270                                 SetYenTail(Src);\r
3271                                 strcat(Src, FindBuf.cFileName);\r
3272                                 strcpy(Pkt.File, Src);\r
3273                                 ReplaceAll(Pkt.File, '\\', '/');\r
3274                                 Pkt.Node = NODE_DIR;\r
3275                                 Pkt.Size = 0;\r
3276                                 Pkt.Attr = 0;\r
3277                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
3278                                 AddFileList(&Pkt, Base);\r
3279 \r
3280                                 MakeLocalTree(Src, Base);\r
3281                         }\r
3282                 }\r
3283                 while(FindNextFileAttr(fHnd, &FindBuf, DispIgnoreHide) == TRUE);\r
3284                 FindClose(fHnd);\r
3285         }\r
3286         return;\r
3287 }\r
3288 \r
3289 \r
3290 /*----- ファイルリストに情報を登録する ----------------------------------------\r
3291 *\r
3292 *       Parameter\r
3293 *               FILELIST *Pkt : 登録するファイル情報\r
3294 *               FILELIST **Base : ファイルリストの先頭\r
3295 *\r
3296 *       Return Value\r
3297 *               なし\r
3298 *----------------------------------------------------------------------------*/\r
3299 \r
3300 static void AddFileList(FILELIST *Pkt, FILELIST **Base)\r
3301 {\r
3302         FILELIST *Pos;\r
3303         FILELIST *Prev;\r
3304 \r
3305         DoPrintf("FileList : NODE=%d : %s", Pkt->Node, Pkt->File);\r
3306 \r
3307         /* リストの重複を取り除く */\r
3308         Pos = *Base;\r
3309         while(Pos != NULL)\r
3310         {\r
3311                 if(strcmp(Pkt->File, Pos->File) == 0)\r
3312                 {\r
3313                         DoPrintf(" --> Duplicate!!");\r
3314                         break;\r
3315                 }\r
3316                 Prev = Pos;\r
3317                 Pos = Pos->Next;\r
3318         }\r
3319 \r
3320         if(Pos == NULL)         /* 重複していないので登録する */\r
3321         {\r
3322                 if((Pos = malloc(sizeof(FILELIST))) != NULL)\r
3323                 {\r
3324                         memcpy(Pos, Pkt, sizeof(FILELIST));\r
3325                         Pos->Next = NULL;\r
3326 \r
3327                         if(*Base == NULL)\r
3328                                 *Base = Pos;\r
3329                         else\r
3330                                 Prev->Next = Pos;\r
3331                 }\r
3332         }\r
3333         return;\r
3334 }\r
3335 \r
3336 \r
3337 /*----- ファイルリストをクリアする --------------------------------------------\r
3338 *\r
3339 *       Parameter\r
3340 *               FILELIST **Base : ファイルリストの先頭\r
3341 *\r
3342 *       Return Value\r
3343 *               なし\r
3344 *----------------------------------------------------------------------------*/\r
3345 \r
3346 void DeleteFileList(FILELIST **Base)\r
3347 {\r
3348         FILELIST *New;\r
3349         FILELIST *Next;\r
3350 \r
3351         New = *Base;\r
3352         while(New != NULL)\r
3353         {\r
3354                 Next = New->Next;\r
3355                 free(New);\r
3356                 New = Next;\r
3357         }\r
3358         *Base = NULL;\r
3359         return;\r
3360 }\r
3361 \r
3362 \r
3363 /*----- ファイルリストに指定のファイルがあるかチェック ------------------------\r
3364 *\r
3365 *       Parameter\r
3366 *               char *Fname : ファイル名\r
3367 *               FILELIST *Base : ファイルリストの先頭\r
3368 *               int Caps : 大文字/小文字の区別モード (COMP_xxx)\r
3369 *\r
3370 *       Return Value\r
3371 *               FILELIST *見つかったファイルリストのデータ\r
3372 *                       NULL=見つからない\r
3373 *----------------------------------------------------------------------------*/\r
3374 \r
3375 FILELIST *SearchFileList(char *Fname, FILELIST *Base, int Caps)\r
3376 {\r
3377         char Tmp[FMAX_PATH+1];\r
3378 \r
3379         while(Base != NULL)\r
3380         {\r
3381                 if(Caps == COMP_STRICT)\r
3382                 {\r
3383                         if(_mbscmp(Fname, Base->File) == 0)\r
3384                                 break;\r
3385                 }\r
3386                 else\r
3387                 {\r
3388                         if(_mbsicmp(Fname, Base->File) == 0)\r
3389                         {\r
3390                                 if(Caps == COMP_IGNORE)\r
3391                                         break;\r
3392                                 else\r
3393                                 {\r
3394                                         strcpy(Tmp, Base->File);\r
3395                                         _mbslwr(Tmp);\r
3396                                         if(_mbscmp(Tmp, Base->File) == 0)\r
3397                                                 break;\r
3398                                 }\r
3399                         }\r
3400                 }\r
3401                 Base = Base->Next;\r
3402         }\r
3403         return(Base);\r
3404 }\r
3405 \r
3406 \r
3407 /*----- ファイル情報からリストタイプを求める ----------------------------------\r
3408 *\r
3409 *       Parameter\r
3410 *               char *Str : ファイル情報(1行)\r
3411 *\r
3412 *       Return Value\r
3413 *               int リストタイプ (LIST_xxx)\r
3414 *----------------------------------------------------------------------------*/\r
3415 \r
3416 static int AnalizeFileInfo(char *Str)\r
3417 {\r
3418         int Ret;\r
3419         char Tmp[FMAX_PATH+1];\r
3420         int Add1;\r
3421         int TmpInt;\r
3422         int Flag1;\r
3423         WORD Month;\r
3424         WORD Day;\r
3425 \r
3426 //DoPrintf("LIST : %s", Str);\r
3427 \r
3428         Ret = LIST_UNKNOWN;\r
3429         Flag1 = AskHostType();\r
3430         if(Flag1 == HTYPE_ACOS)\r
3431                 Ret = LIST_ACOS;\r
3432         else if(Flag1 == HTYPE_ACOS_4)\r
3433                 Ret = LIST_ACOS_4;\r
3434         else if(Flag1 == HTYPE_VMS)\r
3435                 Ret = LIST_VMS;\r
3436         else if(Flag1 == HTYPE_IRMX)\r
3437                 Ret = LIST_IRMX;\r
3438         else if(Flag1 == HTYPE_STRATUS)\r
3439                 Ret = LIST_STRATUS;\r
3440         else if(Flag1 == HTYPE_AGILENT)\r
3441                 Ret = LIST_AGILENT;\r
3442         else if(Flag1 == HTYPE_SHIBASOKU)\r
3443                 Ret = LIST_SHIBASOKU;\r
3444         else\r
3445         {\r
3446                 /* 以下のフォーマットをチェック */\r
3447                 /* LIST_UNIX_10, LIST_UNIX_20, LIST_UNIX_12, LIST_UNIX_22, LIST_UNIX_50, LIST_UNIX_60 */\r
3448                 /* MELCOM80 */\r
3449 \r
3450                 if(FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS)\r
3451                 {\r
3452                         /* MELCOM80は "d rwxrwxrwx" のようにスペースが空いている */\r
3453                         Flag1 = NO;\r
3454                         if((strlen(Tmp) == 1) && (strchr("-dDlL", Tmp[0]) != NULL))\r
3455                         {\r
3456                                 if(FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS)\r
3457                                 {\r
3458                                         if((strlen(Tmp) == 9) ||\r
3459                                            ((strlen(Tmp) > 9) && (IsDigit(Tmp[9]) != 0)))\r
3460                                         {\r
3461                                                 memmove(Str+1, Str+2, strlen(Str+2)+1);\r
3462                                                 FindField(Str, Tmp, 0, NO);\r
3463                                                 Flag1 = YES;\r
3464                                         }\r
3465                                 }\r
3466                         }\r
3467 \r
3468                         if(strlen(Tmp) >= 10)\r
3469                         {\r
3470                                 Add1 = 0;\r
3471                                 if((strlen(Tmp) > 10) && (IsDigit(Tmp[10]) != 0))\r
3472                                 {\r
3473                                         /* こういう時 */\r
3474                                         /*   drwxr-xr-x1234  owner group  1024  Nov 6 14:21 Linux/    */\r
3475                                         Add1 = -1;\r
3476                                 }\r
3477 \r
3478 ////////////\r
3479 // LIST_UNIX_60 support\r
3480                                 if(FindField(Str, Tmp, 7+Add1, NO) == FFFTP_SUCCESS)\r
3481                                 {\r
3482                                         GetMonth(Tmp, &Month, &Day);\r
3483                                         if(Month != 0)\r
3484                                         {\r
3485                                                 Ret = CheckUnixType(Str, Tmp, Add1, 2, Day);\r
3486                                         }\r
3487                                 }\r
3488 ///////////\r
3489 \r
3490 ////////////\r
3491 // LIST_UNIX_12 support\r
3492                                 if((Ret == LIST_UNKNOWN) &&\r
3493                                    (FindField(Str, Tmp, 6+Add1, NO) == FFFTP_SUCCESS))\r
3494                                 {\r
3495                                         GetMonth(Tmp, &Month, &Day);\r
3496                                         if(Month != 0)\r
3497                                         {\r
3498                                                 Ret = CheckUnixType(Str, Tmp, Add1, 0, Day);\r
3499                                         }\r
3500                                 }\r
3501 //////////////////\r
3502 \r
3503 ////////////\r
3504 // LIST_UNIX_70 support\r
3505                                 if((Ret == LIST_UNKNOWN) &&\r
3506                                    (FindField(Str, Tmp, 6+Add1, NO) == FFFTP_SUCCESS))\r
3507                                 {\r
3508                                         GetMonth(Tmp, &Month, &Day);\r
3509                                         if(Month != 0)\r
3510                                         {\r
3511                                                 Ret = CheckUnixType(Str, Tmp, Add1, 1, Day);\r
3512                                         }\r
3513                                 }\r
3514 ///////////\r
3515 \r
3516                                 if((Ret == LIST_UNKNOWN) &&\r
3517                                    (FindField(Str, Tmp, 5+Add1, NO) == FFFTP_SUCCESS))\r
3518                                 {\r
3519                                         GetMonth(Tmp, &Month, &Day);\r
3520                                         if(Month != 0)\r
3521                                         {\r
3522                                                 Ret = CheckUnixType(Str, Tmp, Add1, 0, Day);\r
3523                                         }\r
3524                                 }\r
3525 \r
3526                                 if((Ret == LIST_UNKNOWN) &&\r
3527                                    (FindField(Str, Tmp, 4+Add1, NO) == FFFTP_SUCCESS))\r
3528                                 {\r
3529                                         GetMonth(Tmp, &Month, &Day);\r
3530                                         if(Month != 0)\r
3531                                         {\r
3532                                                 Ret = CheckUnixType(Str, Tmp, Add1, -1, Day);\r
3533                                         }\r
3534                                 }\r
3535 \r
3536                                 if((Ret == LIST_UNKNOWN) &&\r
3537                                    (FindField(Str, Tmp, 3+Add1, NO) == FFFTP_SUCCESS))\r
3538                                 {\r
3539                                         GetMonth(Tmp, &Month, &Day);\r
3540                                         if(Month != 0)\r
3541                                         {\r
3542                                                 Ret = CheckUnixType(Str, Tmp, Add1, -2, Day);\r
3543                                         }\r
3544                                 }\r
3545 \r
3546                                 // linux-ftpd\r
3547                                 if((Ret == LIST_UNKNOWN) &&\r
3548                                    (FindField(Str, Tmp, 7+Add1, NO) == FFFTP_SUCCESS))\r
3549                                 {\r
3550                                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3551                                            (CheckYYYYMMDDformat(Tmp, NUL) != 0))\r
3552                                         {\r
3553                                                 if((FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS) &&\r
3554                                                    (CheckHHMMformat(Tmp) == YES))\r
3555                                                 {\r
3556                                                         Ret = LIST_UNIX_16;\r
3557                                                 }\r
3558                                         }\r
3559                                 }\r
3560 \r
3561                                 if((Ret != LIST_UNKNOWN) && (Flag1 == YES))\r
3562                                         Ret |= LIST_MELCOM;\r
3563                         }\r
3564                 }\r
3565 \r
3566                 /* 以下のフォーマットをチェック */\r
3567                 /* LIST_AS400 */\r
3568 \r
3569                 if(Ret == LIST_UNKNOWN)\r
3570                 {\r
3571                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3572                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3573                         {\r
3574                                 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3575                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3576                                 {\r
3577                                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3578                                            (IsDigit(Tmp[0]) != 0))\r
3579                                         {\r
3580                                                 if(FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS)\r
3581                                                 {\r
3582                                                         Ret = LIST_AS400;\r
3583                                                 }\r
3584                                         }\r
3585                                 }\r
3586                         }\r
3587                 }\r
3588 \r
3589                 /* 以下のフォーマットをチェック */\r
3590                 /* LIST_M1800 */\r
3591 \r
3592                 if(Ret == LIST_UNKNOWN)\r
3593                 {\r
3594                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3595                            (CheckYYMMDDformat(Tmp, '*', NO) != 0))\r
3596                         {\r
3597                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3598                                    ((IsDigit(Tmp[0]) != 0) || (StrAllSameChar(Tmp, '*') == YES)))\r
3599                                 {\r
3600                                         if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3601                                            ((IsDigit(Tmp[0]) != 0) || (StrAllSameChar(Tmp, '*') == YES)))\r
3602                                         {\r
3603                                                 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3604                                                    (strlen(Tmp) == 4))\r
3605                                                 {\r
3606                                                         if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)\r
3607                                                         {\r
3608                                                                 Ret = LIST_M1800;\r
3609                                                         }\r
3610                                                 }\r
3611                                         }\r
3612                                 }\r
3613                         }\r
3614                 }\r
3615 \r
3616                 /* 以下のフォーマットをチェック */\r
3617                 /* LIST_GP6000 */\r
3618 \r
3619                 if(Ret == LIST_UNKNOWN)\r
3620                 {\r
3621                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3622                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3623                         {\r
3624                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3625                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3626                                 {\r
3627                                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3628                                            (IsDigit(Tmp[0]) != 0))\r
3629                                         {\r
3630                                                 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)\r
3631                                                 {\r
3632                                                         Ret = LIST_GP6000;\r
3633                                                 }\r
3634                                         }\r
3635                                 }\r
3636                         }\r
3637                 }\r
3638 \r
3639                 /* 以下のフォーマットをチェック */\r
3640                 /* LIST_DOS_1, LIST_DOS_2 */\r
3641 \r
3642                 if(Ret == LIST_UNKNOWN)\r
3643                 {\r
3644                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3645                            (CheckHHMMformat(Tmp) == YES))\r
3646                         {\r
3647                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3648                                    ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3649                                 {\r
3650                                         if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3651                                         {\r
3652                                                 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3653                                                    (CheckYYMMDDformat(Tmp, NUL, YES) != 0))\r
3654                                                 {\r
3655                                                         TmpInt = atoi(Tmp);\r
3656                                                         if((TmpInt >= 1) && (TmpInt <= 12))\r
3657                                                                 Ret = LIST_DOS_2;\r
3658                                                         else\r
3659                                                                 Ret = LIST_DOS_1;\r
3660                                                 }\r
3661                                         }\r
3662                                 }\r
3663                         }\r
3664                 }\r
3665 \r
3666                 /* 以下のフォーマットをチェック */\r
3667                 /* LIST_DOS_3 */\r
3668 \r
3669                 if(Ret == LIST_UNKNOWN)\r
3670                 {\r
3671                         if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3672                            (CheckHHMMformat(Tmp) == YES))\r
3673                         {\r
3674                                 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3675                                    ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3676                                 {\r
3677                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3678                                            (CheckYYMMDDformat(Tmp, NUL, YES) != 0))\r
3679                                         {\r
3680                                                 Ret = LIST_DOS_3;\r
3681                                         }\r
3682                                 }\r
3683                         }\r
3684                 }\r
3685 \r
3686                 /* 以下のフォーマットをチェック */\r
3687                 /* LIST_DOS_4 */\r
3688 \r
3689                 if(Ret == LIST_UNKNOWN)\r
3690                 {\r
3691                         if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3692                            (CheckYYYYMMDDformat(Tmp, NUL) == YES))\r
3693                         {\r
3694                                 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3695                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3696                                 {\r
3697                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3698                                            ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3699                                         {\r
3700                                                 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3701                                                 {\r
3702                                                         Ret = LIST_DOS_4;\r
3703                                                 }\r
3704                                         }\r
3705                                 }\r
3706                         }\r
3707                 }\r
3708 \r
3709                 /* 以下のフォーマットをチェック */\r
3710                 /* LIST_CHAMELEON */\r
3711 \r
3712                 if(Ret == LIST_UNKNOWN)\r
3713                 {\r
3714                         if(FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS)\r
3715                         {\r
3716                                 GetMonth(Tmp, &Month, &Day);\r
3717                                 if((Month != 0) && (Day == 0))\r
3718                                 {\r
3719                                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3720                                            ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3721                                         {\r
3722                                                 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3723                                                    (CheckHHMMformat(Tmp) == YES))\r
3724                                                 {\r
3725                                                         Ret = LIST_CHAMELEON;\r
3726                                                 }\r
3727                                         }\r
3728                                 }\r
3729                         }\r
3730                 }\r
3731 \r
3732                 /* 以下のフォーマットをチェック */\r
3733                 /* LIST_OS2 */\r
3734 \r
3735                 if(Ret == LIST_UNKNOWN)\r
3736                 {\r
3737                         if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3738                            (CheckHHMMformat(Tmp) == YES))\r
3739                         {\r
3740                                 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3741                                    (IsDigit(Tmp[0]) != 0))\r
3742                                 {\r
3743                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3744                                            (CheckYYMMDDformat(Tmp, NUL, YES) != 0))\r
3745                                         {\r
3746                                                 if(FindField(Str, Tmp, 4, NO) == FFFTP_SUCCESS)\r
3747                                                 {\r
3748                                                         Ret = LIST_OS2;\r
3749                                                 }\r
3750                                         }\r
3751                                 }\r
3752                         }\r
3753                 }\r
3754 \r
3755                 /* 以下のフォーマットをチェック */\r
3756                 /* LIST_OS7 */\r
3757 \r
3758                 if(Ret == LIST_UNKNOWN)\r
3759                 {\r
3760                         if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3761                            (strlen(Tmp) == 10))\r
3762                         {\r
3763                                 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3764                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3765                                 {\r
3766                                         if((FindField(Str, Tmp, 4, NO) == FFFTP_SUCCESS) &&\r
3767                                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3768                                         {\r
3769                                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3770                                                    (IsDigit(Tmp[0]) != 0))\r
3771                                                 {\r
3772                                                         if(FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS)\r
3773                                                         {\r
3774                                                                 Ret = LIST_OS7_2;\r
3775                                                         }\r
3776                                                 }\r
3777                                         }\r
3778                                 }\r
3779                                 else if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3780                                                 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3781                                 {\r
3782                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3783                                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3784                                         {\r
3785                                                 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3786                                                 {\r
3787                                                         Ret = LIST_OS7_1;\r
3788                                                 }\r
3789                                         }\r
3790                                 }\r
3791                         }\r
3792                 }\r
3793 \r
3794                 /* 以下のフォーマットをチェック */\r
3795                 /* LIST_ALLIED */\r
3796 \r
3797                 if(Ret == LIST_UNKNOWN)\r
3798                 {\r
3799                         if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3800                            ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3801                         {\r
3802                                 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3803                                    (CheckHHMMformat(Tmp) == YES))\r
3804                                 {\r
3805                                         if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3806                                         {\r
3807                                                 GetMonth(Tmp, &Month, &Day);\r
3808                                                 if(Month != 0)\r
3809                                                 {\r
3810                                                         if((FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS) &&\r
3811                                                            (IsDigit(Tmp[0]) != 0))\r
3812                                                         {\r
3813                                                                 Ret = LIST_ALLIED;\r
3814                                                         }\r
3815                                                 }\r
3816                                         }\r
3817                                 }\r
3818                         }\r
3819                 }\r
3820 \r
3821                 /* 以下のフォーマットをチェック */\r
3822                 /* LIST_OS9 */\r
3823 \r
3824                 if(Ret == LIST_UNKNOWN)\r
3825                 {\r
3826                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3827                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3828                         {\r
3829                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3830                                    (IsDigit(Tmp[0]) != 0) && (strlen(Tmp) == 4))\r
3831                                 {\r
3832                                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3833                                            (IsDigit(Tmp[0]) != 0))\r
3834                                         {\r
3835                                                 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)\r
3836                                                 {\r
3837                                                         Ret = LIST_OS9;\r
3838                                                 }\r
3839                                         }\r
3840                                 }\r
3841                         }\r
3842                 }\r
3843 \r
3844                 /* 以下のフォーマットをチェック */\r
3845                 /* LIST_IBM */\r
3846 \r
3847                 if(Ret == LIST_UNKNOWN)\r
3848                 {\r
3849                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3850                            (CheckYYYYMMDDformat(Tmp, NUL) == YES))\r
3851                         {\r
3852                                 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) && IsDigit(Tmp[0]))\r
3853                                 {\r
3854                                         if((FindField(Str, Tmp, 7, NO) == FFFTP_SUCCESS) && IsDigit(Tmp[0]))\r
3855                                         {\r
3856                                                 if(FindField(Str, Tmp, 9, NO) == FFFTP_SUCCESS)\r
3857                                                 {\r
3858                                                         Ret = LIST_IBM;\r
3859                                                 }\r
3860                                         }\r
3861                                 }\r
3862                         }\r
3863                 }\r
3864 #if defined(HAVE_TANDEM)\r
3865                 /* 以下のフォーマットをチェック */\r
3866                 /* LIST_TANDEM */\r
3867 \r
3868                 /* OSS の場合は自動判別可能のため Ret == LIST_UNKNOWN のチェックは後 */\r
3869                 if(AskRealHostType() == HTYPE_TANDEM) {\r
3870                         if(Ret == LIST_UNKNOWN) {\r
3871                                 SetOSS(NO);\r
3872                                 Ret = LIST_TANDEM;\r
3873                         } else {\r
3874                                 SetOSS(YES);\r
3875                         }\r
3876                 }\r
3877 #endif\r
3878 \r
3879                 // MLSD対応\r
3880                 if(Ret == LIST_UNKNOWN)\r
3881                 {\r
3882                         if(FindField2(Str, Tmp, ';', 1, NO) == FFFTP_SUCCESS && FindField2(Str, Tmp, '=', 1, NO) == FFFTP_SUCCESS)\r
3883                         {\r
3884                                 Ret = LIST_MLSD;\r
3885                         }\r
3886                 }\r
3887         }\r
3888 \r
3889 DoPrintf("ListType=%d", Ret);\r
3890 \r
3891         return(Ret);\r
3892 }\r
3893 \r
3894 \r
3895 /*----- UNIX系リストタイプのチェックを行なう ----------------------------------\r
3896 *\r
3897 *       Parameter\r
3898 *               char *Str : ファイル情報(1行)\r
3899 *               char *Tmp : 一時ワーク\r
3900 *               int Add1 : 加算パラメータ1\r
3901 *               int Add2 : 加算パラメータ2\r
3902 *               int Day : 日 (0=ここで取得する)\r
3903 *\r
3904 *       Return Value\r
3905 *               int リストタイプ (LIST_xxx)\r
3906 *----------------------------------------------------------------------------*/\r
3907 \r
3908 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day)\r
3909 {\r
3910         int Ret;\r
3911         int Add3;\r
3912         WORD Hour;\r
3913         WORD Minute;\r
3914         int Flag;\r
3915 \r
3916         Flag = 0;\r
3917         Ret = LIST_UNKNOWN;\r
3918 \r
3919 //DayによってAdd3を変える\r
3920 \r
3921         Add3 = 0;\r
3922         if(Day != 0)\r
3923                 Add3 = -1;\r
3924 \r
3925         // unix系チェック\r
3926         if((Day != 0) ||\r
3927            ((FindField(Str, Tmp, 6+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3928                 ((atoi(Tmp) >= 1) && (atoi(Tmp) <= 31))))\r
3929         {\r
3930                 if((FindField(Str, Tmp, 7+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3931                    ((atoi(Tmp) >= 1900) || (GetHourAndMinute(Tmp, &Hour, &Minute) == FFFTP_SUCCESS)))\r
3932                 {\r
3933                         if(FindField(Str, Tmp, 8+Add1+Add2+Add3, NO) == FFFTP_SUCCESS)\r
3934                         {\r
3935                                 Flag = 1;\r
3936                         }\r
3937                 }\r
3938         }\r
3939 \r
3940         // 中国語Solaris専用\r
3941         if(Flag == 0)\r
3942         {\r
3943            if((FindField(Str, Tmp, 7+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3944                   ((atoi(Tmp) >= 1) && (atoi(Tmp) <= 31)))\r
3945                 {\r
3946                         if((FindField(Str, Tmp, 5+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3947                            (atoi(Tmp) >= 1900))\r
3948                         {\r
3949                                 if((FindField(Str, Tmp, 6+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3950                                    (((atoi(Tmp) >= 1) && (atoi(Tmp) <= 9) && \r
3951                                          ((unsigned char)Tmp[1] == 0xD4) &&\r
3952                                          ((unsigned char)Tmp[2] == 0xC2)) ||\r
3953                                     ((atoi(Tmp) >= 10) && (atoi(Tmp) <= 12) && \r
3954                                          ((unsigned char)Tmp[2] == 0xD4) && \r
3955                                          ((unsigned char)Tmp[3] == 0xC2))))\r
3956                                 {\r
3957                                         if(FindField(Str, Tmp, 8+Add1+Add2+Add3, NO) == FFFTP_SUCCESS)\r
3958                                         {\r
3959                                                 Flag = 2;\r
3960                                         }\r
3961                                 }\r
3962                         }\r
3963                 }\r
3964         }\r
3965 \r
3966         if(Flag != 0)\r
3967         {\r
3968                 if(Add2 == 2)\r
3969                 {\r
3970                         Ret = LIST_UNIX_60;\r
3971                         if(Flag == 2)\r
3972                                 Ret = LIST_UNIX_64;\r
3973                         if(Day != 0)\r
3974                                 Ret = LIST_UNIX_61;\r
3975 \r
3976                         if(Add1 == -1)\r
3977                         {\r
3978                                 Ret = LIST_UNIX_62;\r
3979                                 if(Flag == 2)\r
3980                                         Ret = LIST_UNIX_65;\r
3981                                 if(Day != 0)\r
3982                                         Ret = LIST_UNIX_63;\r
3983                         }\r
3984                 }\r
3985                 else if(Add2 == 1)\r
3986                 {\r
3987                         Ret = LIST_UNIX_70;\r
3988                         if(Flag == 2)\r
3989                                 Ret = LIST_UNIX_74;\r
3990                         if(Day != 0)\r
3991                                 Ret = LIST_UNIX_71;\r
3992 \r
3993                         if(Add1 == -1)\r
3994                         {\r
3995                                 Ret = LIST_UNIX_72;\r
3996                                 if(Flag == 2)\r
3997                                         Ret = LIST_UNIX_75;\r
3998                                 if(Day != 0)\r
3999                                         Ret = LIST_UNIX_73;\r
4000                         }\r
4001                 }\r
4002                 else if(Add2 == 0)\r
4003                 {\r
4004                         Ret = LIST_UNIX_10;\r
4005                         if(Flag == 2)\r
4006                                 Ret = LIST_UNIX_14;\r
4007                         if(Day != 0)\r
4008                                 Ret = LIST_UNIX_11;\r
4009 \r
4010                         if(Add1 == -1)\r
4011                         {\r
4012                                 Ret = LIST_UNIX_12;\r
4013                                 if(Flag == 2)\r
4014                                         Ret = LIST_UNIX_15;\r
4015                                 if(Day != 0)\r
4016                                         Ret = LIST_UNIX_13;\r
4017                         }\r
4018                 }\r
4019                 else if(Add2 == -1)\r
4020                 {\r
4021                         Ret = LIST_UNIX_20;\r
4022                         if(Flag == 2)\r
4023                                 Ret = LIST_UNIX_24;\r
4024                         if(Day != 0)\r
4025                                 Ret = LIST_UNIX_21;\r
4026 \r
4027                         if(Add1 == -1)\r
4028                         {\r
4029                                 Ret = LIST_UNIX_22;\r
4030                                 if(Flag == 2)\r
4031                                         Ret = LIST_UNIX_25;\r
4032                                 if(Day != 0)\r
4033                                         Ret = LIST_UNIX_23;\r
4034                         }\r
4035                 }\r
4036                 else\r
4037                 {\r
4038                         Ret = LIST_UNIX_50;\r
4039                         if(Flag == 2)\r
4040                                 Ret = LIST_UNIX_54;\r
4041                         if(Day != 0)\r
4042                                 Ret = LIST_UNIX_51;\r
4043                 }\r
4044         }\r
4045         return(Ret);\r
4046 }\r
4047 \r
4048 \r
4049 /*----- HH:MM 形式の文字列かどうかをチェック ----------------------------------\r
4050 *\r
4051 *       Parameter\r
4052 *               char *Str : 文字列\r
4053 *\r
4054 *       Return Value\r
4055 *               int ステータス (YES/NO)\r
4056 *\r
4057 *       Note\r
4058 *               区切り文字は何でもよい\r
4059 *               時分でなくてもよい\r
4060 *               後ろに余分な文字が付いていてもよい\r
4061 *----------------------------------------------------------------------------*/\r
4062 \r
4063 static int CheckHHMMformat(char *Str)\r
4064 {\r
4065         int Ret;\r
4066 \r
4067         Ret = NO;\r
4068         if((strlen(Str) >= 3) &&\r
4069            (IsDigit(Str[0]) != 0))\r
4070         {\r
4071                 if((Str = strchr(Str, ':')) != NULL)\r
4072                 {\r
4073                         if(IsDigit(*(Str+1)) != 0)\r
4074                                 Ret = YES;\r
4075                 }\r
4076         }\r
4077         return(Ret);\r
4078 }\r
4079 \r
4080 \r
4081 /*----- YY/MM/DD 形式の文字列かどうかをチェック -------------------------------\r
4082 *\r
4083 *       Parameter\r
4084 *               char *Str : 文字列\r
4085 *               char Sym : 数字の代わりに使える記号 (NUL=数字以外使えない)\r
4086 *               int Dig3 : 3桁の年を許可\r
4087 *\r
4088 *       Return Value\r
4089 *               int ステータス\r
4090 *                       0 = 該当しない\r
4091 *                       1 = ??/??/??, ??/??/???\r
4092 *                       2 = ???/??/??\r
4093 *\r
4094 *       Note\r
4095 *               区切り文字は何でもよい\r
4096 *               年月日でなくてもよい\r
4097 *----------------------------------------------------------------------------*/\r
4098 \r
4099 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3)\r
4100 {\r
4101         int Ret;\r
4102 \r
4103         Ret = 0;\r
4104         if((strlen(Str) == 8) &&\r
4105            (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&\r
4106            (IsDigit(Str[2]) == 0) &&\r
4107            (IsDigitSym(Str[3], Sym) != 0) && (IsDigitSym(Str[4], Sym) != 0) &&\r
4108            (IsDigit(Str[5]) == 0) &&\r
4109            (IsDigitSym(Str[6], Sym) != 0) && (IsDigitSym(Str[7], Sym) != 0))\r
4110         {\r
4111                 Ret = 1; \r
4112         }\r
4113         if(Dig3 == YES)\r
4114         {\r
4115                 if((strlen(Str) == 9) &&\r
4116                    (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) && (IsDigitSym(Str[2], Sym) != 0) &&\r
4117                    (IsDigit(Str[3]) == 0) &&\r
4118                    (IsDigitSym(Str[4], Sym) != 0) && (IsDigitSym(Str[5], Sym) != 0) &&\r
4119                    (IsDigit(Str[6]) == 0) &&\r
4120                    (IsDigitSym(Str[7], Sym) != 0) && (IsDigitSym(Str[8], Sym) != 0))\r
4121                 {\r
4122                         Ret = 2; \r
4123                 }\r
4124                 else if((strlen(Str) == 9) &&\r
4125                                 (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&\r
4126                                 (IsDigit(Str[2]) == 0) &&\r
4127                                 (IsDigitSym(Str[3], Sym) != 0) && (IsDigitSym(Str[4], Sym) != 0) &&\r
4128                                 (IsDigit(Str[5]) == 0) &&\r
4129                                 (IsDigitSym(Str[6], Sym) != 0) && (IsDigitSym(Str[7], Sym) != 0) && (IsDigitSym(Str[8], Sym) != 0))\r
4130                 {\r
4131                         Ret = 1; \r
4132                 }\r
4133         }\r
4134         return(Ret);\r
4135 }\r
4136 \r
4137 \r
4138 /*----- YYYY/MM/DD 形式の文字列かどうかをチェック -----------------------------\r
4139 *\r
4140 *       Parameter\r
4141 *               char *Str : 文字列\r
4142 *               char Sym : 数字の代わりに使える記号 (NUL=数字以外使えない)\r
4143 *\r
4144 *       Return Value\r
4145 *               int ステータス (YES/NO)\r
4146 *\r
4147 *       Note\r
4148 *               区切り文字は何でもよい\r
4149 *               年月日でなくてもよい\r
4150 *----------------------------------------------------------------------------*/\r
4151 \r
4152 static int CheckYYYYMMDDformat(char *Str, char Sym)\r
4153 {\r
4154         int Ret;\r
4155 \r
4156         Ret = NO;\r
4157         if((strlen(Str) == 10) &&\r
4158            (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&\r
4159            (IsDigitSym(Str[2], Sym) != 0) && (IsDigitSym(Str[3], Sym) != 0) &&\r
4160            (IsDigit(Str[4]) == 0) &&\r
4161            (IsDigitSym(Str[5], Sym) != 0) && (IsDigitSym(Str[6], Sym) != 0) &&\r
4162            (IsDigit(Str[7]) == 0) &&\r
4163            (IsDigitSym(Str[8], Sym) != 0) && (IsDigitSym(Str[9], Sym) != 0))\r
4164         {\r
4165                 Ret = YES; \r
4166         }\r
4167         return(Ret);\r
4168 }\r
4169 \r
4170 \r
4171 /*----- ファイル情報からファイル名、サイズなどを取り出す ----------------------\r
4172 *\r
4173 *       Parameter\r
4174 *               char *Str : ファイル情報(1行)\r
4175 *               int ListType : リストのタイプ\r
4176 *               char *Name : ファイル名のコピー先\r
4177 *               LONGLONG *Size : サイズのコピー先\r
4178 *               FILETIME *Time : 日付のコピー先\r
4179 *               int *Attr : 属性のコピー先\r
4180 *               char *Owner : オーナ名\r
4181 *               int *Link : リンクかどうか (YES/NO)\r
4182 *               int *InfoExist : 時刻の情報があったかどうか (YES/NO)\r
4183 *\r
4184 *       Return Value\r
4185 *               int 種類 (NODE_xxxx)\r
4186 *----------------------------------------------------------------------------*/\r
4187 \r
4188 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist)\r
4189 {\r
4190         SYSTEMTIME sTime;\r
4191         SYSTEMTIME sTimeNow;\r
4192         char Buf[FMAX_PATH+1];\r
4193         char *Pos;\r
4194         char Flag;\r
4195         int Ret;\r
4196         int offs;\r
4197         int offs2;\r
4198         int offs3;\r
4199         int OrgListType;\r
4200         int err;\r
4201         int Flag2;\r
4202 \r
4203         static const int DosPos[3][4] = { { 1, 0, 2, 3 }, { 1, 0, 2, 3 }, { 3, 2, 1, 0 } };\r
4204         static const int DosDate[3][3][2] = { { {0, 0}, {3, 4}, {6, 7} }, { {6, 7}, {0, 0}, {3, 4} }, { {6, 7}, {0, 0}, {3, 4} } };\r
4205         static const int DosLongFname[3] = { YES, YES, NO };\r
4206 \r
4207         /* まずクリアしておく */\r
4208         Ret = NODE_NONE;\r
4209         // バグ対策\r
4210         memset(Fname, NUL, FMAX_PATH+1);\r
4211         *Size = -1;\r
4212         *Attr = 0;\r
4213         *Link = NO;\r
4214         memset(Owner, NUL, OWNER_NAME_LEN+1);\r
4215         Time->dwLowDateTime = 0;\r
4216         Time->dwHighDateTime = 0;\r
4217         *InfoExist = 0;\r
4218         offs = 0;\r
4219         offs2 = 0;\r
4220         offs3 = 0;\r
4221 \r
4222         OrgListType = ListType;\r
4223         ListType &= LIST_MASKFLG;\r
4224         switch(ListType)\r
4225         {\r
4226                 case LIST_DOS_1 :\r
4227                 case LIST_DOS_2 :\r
4228                 case LIST_DOS_3 :\r
4229                         if(ListType == LIST_DOS_1)\r
4230                                 offs = 0;\r
4231                         else if(ListType == LIST_DOS_2)\r
4232                                 offs = 1;\r
4233                         else\r
4234                                 offs = 2;\r
4235 \r
4236                         *InfoExist |= (FINFO_DATE | FINFO_SIZE);\r
4237 \r
4238                         /* 時刻 */\r
4239                         FindField(Str, Buf, DosPos[offs][0], NO);\r
4240                         if((Pos = strchr(Buf, ':')) != NULL)\r
4241                         {\r
4242                                 *InfoExist |= FINFO_TIME;\r
4243                                 sTime.wHour = atoi(Buf);\r
4244                                 sTime.wMinute = atoi(Pos+1);\r
4245                                 sTime.wSecond = 0;\r
4246                                 sTime.wMilliseconds = 0;\r
4247 \r
4248                                 if(strlen(Pos) >= 4)\r
4249                                 {\r
4250                                         if(tolower(Pos[3]) == 'a')\r
4251                                         {\r
4252                                                 if(sTime.wHour == 12)\r
4253                                                         sTime.wHour = 0;\r
4254                                         }\r
4255                                         else if(tolower(Pos[3]) == 'p')\r
4256                                         {\r
4257                                                 if(sTime.wHour != 12)\r
4258                                                         sTime.wHour += 12;\r
4259                                         }\r
4260                                 }\r
4261                         }\r
4262 \r
4263                         /* 日付 */\r
4264                         FindField(Str, Buf, DosPos[offs][1], NO);\r
4265                         if((offs2 = CheckYYMMDDformat(Buf, NUL, YES)) == 0)\r
4266                                 break;\r
4267                         offs2--;\r
4268                         sTime.wYear = Assume1900or2000(atoi(Buf + DosDate[offs][0][offs2]));\r
4269                         sTime.wMonth = atoi(Buf + DosDate[offs][1][offs2]);\r
4270                         sTime.wDay = atoi(Buf + DosDate[offs][2][offs2]);\r
4271                         SystemTimeToFileTime(&sTime, Time);\r
4272                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4273 \r
4274                         /* サイズ */\r
4275                         FindField(Str, Buf, DosPos[offs][2], NO);\r
4276                         *Size = _atoi64(Buf);\r
4277 \r
4278                         /* 名前 */\r
4279                         if(FindField(Str, Fname, DosPos[offs][3], DosLongFname[offs]) == FFFTP_SUCCESS)\r
4280                         {\r
4281                                 Ret = NODE_FILE;\r
4282                                 if(Buf[0] == '<')\r
4283                                         Ret = NODE_DIR;\r
4284                         }\r
4285                         break;\r
4286 \r
4287                 case LIST_DOS_4 :\r
4288                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4289 \r
4290                         /* 日付 */\r
4291                         FindField(Str, Buf, 0, NO);\r
4292                         sTime.wYear = atoi(Buf);\r
4293                         sTime.wMonth = atoi(Buf+5);\r
4294                         sTime.wDay = atoi(Buf+8);\r
4295 \r
4296                         /* 時刻 */\r
4297                         *InfoExist |= FINFO_TIME;\r
4298                         FindField(Str, Buf, 1, NO);\r
4299                         sTime.wHour = atoi(Buf);\r
4300                         sTime.wMinute = atoi(Buf+3);\r
4301                         sTime.wSecond = 0;                              // atoi(Buf+6);\r
4302                         sTime.wMilliseconds = 0;\r
4303                         SystemTimeToFileTime(&sTime, Time);\r
4304                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4305 \r
4306                         /* サイズ */\r
4307                         FindField(Str, Buf, 2, NO);\r
4308                         *Size = _atoi64(Buf);\r
4309 \r
4310                         /* 名前 */\r
4311                         if(FindField(Str, Fname, 3, YES) == FFFTP_SUCCESS)\r
4312                         {\r
4313                                 Ret = NODE_FILE;\r
4314                                 if(Buf[0] == '<')\r
4315                                         Ret = NODE_DIR;\r
4316                         }\r
4317                         break;\r
4318 \r
4319                 case LIST_OS2 :\r
4320                         *InfoExist |= (FINFO_DATE | FINFO_SIZE);\r
4321 \r
4322                         /* 時刻 */\r
4323                         FindField(Str, Buf, 3, NO);\r
4324                         if((Pos = strchr(Buf, ':')) != NULL)\r
4325                         {\r
4326                                 *InfoExist |= FINFO_TIME;\r
4327                                 sTime.wHour = atoi(Buf);\r
4328                                 sTime.wMinute = atoi(Pos+1);\r
4329                                 sTime.wSecond = 0;\r
4330                                 sTime.wMilliseconds = 0;\r
4331                         }\r
4332 \r
4333                         /* 日付 */\r
4334                         FindField(Str, Buf, 2, NO);\r
4335                         sTime.wYear = Assume1900or2000(atoi(Buf+6));\r
4336                         sTime.wMonth = atoi(Buf+0);\r
4337                         sTime.wDay = atoi(Buf+3);\r
4338                         SystemTimeToFileTime(&sTime, Time);\r
4339                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4340 \r
4341                         /* サイズ */\r
4342                         FindField(Str, Buf, 0, NO);\r
4343                         *Size = _atoi64(Buf);\r
4344 \r
4345                         /* 名前 */\r
4346                         if(FindField(Str, Fname, 4, YES) == FFFTP_SUCCESS)\r
4347                         {\r
4348                                 FindField(Str, Buf, 1, NO);\r
4349                                 Ret = NODE_FILE;\r
4350                                 if(strstr(Buf, "DIR") != NULL)\r
4351                                         Ret = NODE_DIR;\r
4352                         }\r
4353                         break;\r
4354 \r
4355                 case LIST_CHAMELEON :\r
4356                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
4357 \r
4358                         /* 属性 */\r
4359                         FindField(Str, Buf, 6, NO);\r
4360                         strcat(Buf, "------");\r
4361                         *Attr = AttrString2Value(Buf+1);\r
4362 \r
4363                         /* 日付 */\r
4364                         FindField(Str, Buf, 2, NO);\r
4365                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);      /* wDayは常に0 */\r
4366                         FindField(Str, Buf, 3, NO);\r
4367                         sTime.wDay = atoi(Buf);\r
4368                         FindField(Str, Buf, 4, NO);\r
4369                         sTime.wYear = atoi(Buf);\r
4370 \r
4371                         /* 時刻 */\r
4372                         FindField(Str, Buf, 5, NO);\r
4373                         sTime.wHour = atoi(Buf);\r
4374                         sTime.wMinute = atoi(Buf+3);\r
4375                         sTime.wSecond = 0;\r
4376                         sTime.wMilliseconds = 0;\r
4377                         SystemTimeToFileTime(&sTime, Time);\r
4378                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4379 \r
4380                         /* サイズ */\r
4381                         FindField(Str, Buf, 1, NO);\r
4382                         *Size = _atoi64(Buf);\r
4383 \r
4384                         /* 名前 */\r
4385                         if(FindField(Str, Fname, 0, NO) == FFFTP_SUCCESS)\r
4386                         {\r
4387                                 Ret = NODE_FILE;\r
4388                                 if(Buf[0] == '<')\r
4389                                         Ret = NODE_DIR;\r
4390                         }\r
4391                         break;\r
4392 \r
4393                 case LIST_AS400 :\r
4394                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4395 \r
4396                         /* オーナ名 */\r
4397                         FindField(Str, Buf, 0, NO);\r
4398                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4399 \r
4400                         /* 時刻 */\r
4401                         FindField(Str, Buf, 3, NO);\r
4402                         sTime.wHour = atoi(Buf);\r
4403                         sTime.wMinute = atoi(Buf+3);\r
4404                         sTime.wSecond = 0;\r
4405                         sTime.wMilliseconds = 0;\r
4406 \r
4407                         /* 日付 */\r
4408                         FindField(Str, Buf, 2, NO);\r
4409                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4410                         sTime.wMonth = atoi(Buf + 3);\r
4411                         sTime.wDay = atoi(Buf + 6);\r
4412                         SystemTimeToFileTime(&sTime, Time);\r
4413                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4414 \r
4415                         /* サイズ */\r
4416                         FindField(Str, Buf, 1, NO);\r
4417                         *Size = _atoi64(Buf);\r
4418 \r
4419                         /* 名前 */\r
4420                         if(FindField(Str, Fname, 5, YES) == FFFTP_SUCCESS)\r
4421                         {\r
4422                                 Ret = NODE_FILE;\r
4423                                 if((Pos = strchr(Fname, '/')) != NULL)\r
4424                                 {\r
4425                                         Ret = NODE_DIR;\r
4426                                         *Pos = NUL;\r
4427                                 }\r
4428                         }\r
4429                         break;\r
4430 \r
4431                 case LIST_M1800 :\r
4432                         *InfoExist |= FINFO_ATTR;\r
4433 \r
4434                         /* 属性 */\r
4435                         FindField(Str, Buf, 0, NO);\r
4436                         strcat(Buf, "------");\r
4437                         *Attr = AttrString2Value(Buf+1);\r
4438 \r
4439                         /* 日付 */\r
4440                         Time->dwLowDateTime = 0;\r
4441                         Time->dwHighDateTime = 0;\r
4442                         FindField(Str, Buf, 5, NO);\r
4443                         if(Buf[0] != '*')\r
4444                         {\r
4445                                 *InfoExist |= FINFO_DATE;\r
4446                                 sTime.wHour = 0;\r
4447                                 sTime.wMinute = 0;\r
4448                                 sTime.wSecond = 0;\r
4449                                 sTime.wMilliseconds = 0;\r
4450 \r
4451                                 sTime.wYear = Assume1900or2000(atoi(Buf));\r
4452                                 sTime.wMonth = atoi(Buf + 3);\r
4453                                 sTime.wDay = atoi(Buf + 6);\r
4454                                 SystemTimeToFileTime(&sTime, Time);\r
4455                                 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4456                         }\r
4457 \r
4458                         /* 名前 */\r
4459                         if(FindField(Str, Fname, 6, YES) == FFFTP_SUCCESS)\r
4460                         {\r
4461                                 RemoveTailingSpaces(Fname);\r
4462                                 Ret = NODE_FILE;\r
4463                                 if((Pos = strchr(Fname, '/')) != NULL)\r
4464                                 {\r
4465                                         Ret = NODE_DIR;\r
4466                                         *Pos = NUL;\r
4467                                 }\r
4468                         }\r
4469                         break;\r
4470 \r
4471                 case LIST_GP6000 :\r
4472                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
4473 \r
4474                         /* オーナ名 */\r
4475                         FindField(Str, Buf, 3, NO);\r
4476                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4477 \r
4478                         /* 時刻 */\r
4479                         FindField(Str, Buf, 2, NO);\r
4480                         sTime.wHour = atoi(Buf);\r
4481                         sTime.wMinute = atoi(Buf+3);\r
4482                         sTime.wSecond = 0;\r
4483                         sTime.wMilliseconds = 0;\r
4484 \r
4485                         /* 日付 */\r
4486                         FindField(Str, Buf, 1, NO);\r
4487                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4488                         sTime.wMonth = atoi(Buf + 3);\r
4489                         sTime.wDay = atoi(Buf + 6);\r
4490                         SystemTimeToFileTime(&sTime, Time);\r
4491                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4492 \r
4493                         /* サイズ */\r
4494                         FindField(Str, Buf, 5, NO);\r
4495                         *Size = _atoi64(Buf);\r
4496 \r
4497                         /* 属性 */\r
4498                         FindField(Str, Buf, 0, NO);\r
4499                         *Attr = AttrString2Value(Buf+1);\r
4500 \r
4501                         /* 名前 */\r
4502                         if(FindField(Str, Fname, 6, YES) == FFFTP_SUCCESS)\r
4503                         {\r
4504                                 Ret = NODE_FILE;\r
4505                                 if(strchr("dl", Buf[0]) != NULL)\r
4506                                         Ret = NODE_DIR;\r
4507                         }\r
4508                         break;\r
4509 \r
4510                 case LIST_ACOS :\r
4511                 case LIST_ACOS_4 :\r
4512                         /* 名前 */\r
4513                         FindField(Str, Fname, 0, NO);\r
4514                         Ret = NODE_FILE;\r
4515                         break;\r
4516 \r
4517                 case LIST_VMS :\r
4518                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4519 \r
4520                         /* サイズ */\r
4521                         FindField(Str, Buf, 1, NO);\r
4522                         *Size = _atoi64(Buf) * BLOCK_SIZE;\r
4523 \r
4524                         /* 時刻/日付 */\r
4525                         FindField(Str, Buf, 2, NO);\r
4526                         GetVMSdate(Buf, &sTime.wYear, &sTime.wMonth, &sTime.wDay);\r
4527 \r
4528                         FindField(Str, Buf, 3, NO);\r
4529                         GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute);\r
4530 \r
4531                         sTime.wSecond = 0;\r
4532                         sTime.wMilliseconds = 0;\r
4533                         SystemTimeToFileTime(&sTime, Time);\r
4534                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4535 \r
4536                         /* 名前 */\r
4537                         FindField(Str, Fname, 0, NO);\r
4538 \r
4539                         Ret = NODE_FILE;\r
4540                         if((Pos = strchr(Fname, '.')) != NULL)\r
4541                         {\r
4542                                 if(_strnicmp(Pos, ".DIR;", 5) == 0)\r
4543                                 {\r
4544                                         /* OpenVMSの場合、ファイル/ディレクトリ削除時には".DIR;?"までないと\r
4545                                          * 削除できないので、ここではつぶさない */\r
4546 #if !defined(HAVE_OPENVMS)\r
4547                                         *Pos = NUL;\r
4548 #endif\r
4549                                         Ret = NODE_DIR;\r
4550                                 }\r
4551                         }\r
4552                         break;\r
4553 \r
4554                 case LIST_OS7_2 :\r
4555                         *InfoExist |= FINFO_SIZE;\r
4556                         offs = 2;\r
4557 \r
4558                         /* サイズ */\r
4559                         FindField(Str, Buf, 2, NO);\r
4560                         *Size = _atoi64(Buf);\r
4561                         /* ここにbreakはない */\r
4562 \r
4563                 case LIST_OS7_1 :\r
4564                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_ATTR);\r
4565 \r
4566                         /* 日付 */\r
4567                         FindField(Str, Buf, 1+offs, NO);\r
4568                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4569                         sTime.wMonth = atoi(Buf + 3);\r
4570                         sTime.wDay = atoi(Buf + 6);\r
4571 \r
4572                         /* 時刻 */\r
4573                         FindField(Str, Buf, 2+offs, NO);\r
4574                         sTime.wHour = atoi(Buf);\r
4575                         sTime.wMinute = atoi(Buf+3);\r
4576                         sTime.wSecond = 0;\r
4577                         sTime.wMilliseconds = 0;\r
4578                         SystemTimeToFileTime(&sTime, Time);\r
4579                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4580 \r
4581                         /* 属性 */\r
4582                         FindField(Str, Buf, 0, NO);\r
4583                         *Attr = AttrString2Value(Buf+1);\r
4584 \r
4585                         /* 名前 */\r
4586                         if(FindField(Str, Fname, 3+offs, YES) == FFFTP_SUCCESS)\r
4587                         {\r
4588                                 RemoveTailingSpaces(Fname);\r
4589                                 Ret = NODE_FILE;\r
4590                                 if(strchr("dl", Buf[0]) != NULL)\r
4591                                         Ret = NODE_DIR;\r
4592                         }\r
4593                         break;\r
4594 \r
4595                 case LIST_STRATUS :\r
4596                         if(FindField(Str, Buf, 0, NO) != FFFTP_SUCCESS)\r
4597                                 break;\r
4598                         if(_strnicmp(Buf, "Files:", 6) == 0)\r
4599                                 StratusMode = 0;\r
4600                         else if(_strnicmp(Buf, "Dirs:", 5) == 0)\r
4601                                 StratusMode = 1;\r
4602                         else if(_strnicmp(Buf, "Links:", 6) == 0)\r
4603                                 StratusMode = 2;\r
4604                         else\r
4605                         {\r
4606                                 if(StratusMode == 0)\r
4607                                         offs = 1;\r
4608                                 else if(StratusMode == 1)\r
4609                                         offs = 0;\r
4610                                 else\r
4611                                         break;\r
4612 \r
4613                                 *InfoExist |= (FINFO_TIME | FINFO_DATE);\r
4614 \r
4615                                 /* 日付 */\r
4616                                 if(FindField(Str, Buf, 2+offs, NO) != FFFTP_SUCCESS)\r
4617                                         break;\r
4618                                 sTime.wYear = Assume1900or2000(atoi(Buf));\r
4619                                 sTime.wMonth = atoi(Buf + 3);\r
4620                                 sTime.wDay = atoi(Buf + 6);\r
4621 \r
4622                                 /* 時刻 */\r
4623                                 if(FindField(Str, Buf, 3+offs, NO) != FFFTP_SUCCESS)\r
4624                                         break;\r
4625                                 sTime.wHour = atoi(Buf);\r
4626                                 sTime.wMinute = atoi(Buf+3);\r
4627                                 sTime.wSecond = 0;\r
4628                                 sTime.wMilliseconds = 0;\r
4629                                 SystemTimeToFileTime(&sTime, Time);\r
4630                                 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4631 \r
4632                                 /* 名前 */\r
4633                                 if(FindField(Str, Fname, 4+offs, YES) != FFFTP_SUCCESS)\r
4634                                         break;\r
4635 \r
4636                                 if(StratusMode == 0)\r
4637                                 {\r
4638                                         *InfoExist |= FINFO_SIZE;\r
4639 \r
4640                                         /* サイズ */\r
4641                                         if(FindField(Str, Buf, 1, NO) != FFFTP_SUCCESS)\r
4642                                                 break;\r
4643                                         *Size = _atoi64(Buf) * 4096;\r
4644 \r
4645                                         /* 種類(オーナ名のフィールドにいれる) */\r
4646                                         if(FindField(Str, Buf, 2, NO) != FFFTP_SUCCESS)\r
4647                                                 break;\r
4648                                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4649 \r
4650                                         Ret = NODE_FILE;\r
4651                                 }\r
4652                                 else\r
4653                                         Ret = NODE_DIR;\r
4654                         }\r
4655                         break;\r
4656 \r
4657                 case LIST_IRMX :\r
4658                         *InfoExist |= (FINFO_DATE | FINFO_SIZE);\r
4659 \r
4660                         /* 日付 */\r
4661                         for(offs = 11; offs > 7; offs--)\r
4662                         {\r
4663                                 if((err = FindField(Str, Buf, offs, NO)) == FFFTP_SUCCESS)\r
4664                                         break;\r
4665                         }\r
4666                         if(err != FFFTP_SUCCESS)\r
4667                                 break;\r
4668                         if(IsDigit(*Buf) == 0)\r
4669                                 break;\r
4670                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4671                         if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)\r
4672                                 break;\r
4673                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);\r
4674                         if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)\r
4675                                 break;\r
4676                         if(IsDigit(*Buf) == 0)\r
4677                                 break;\r
4678                         sTime.wDay = atoi(Buf);\r
4679                         sTime.wHour = 0;\r
4680                         sTime.wMinute = 0;\r
4681                         sTime.wSecond = 0;\r
4682                         sTime.wMilliseconds = 0;\r
4683                         SystemTimeToFileTime(&sTime, Time);\r
4684                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4685 \r
4686                         /* オーナ名 */\r
4687                         if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)\r
4688                                 break;\r
4689                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4690 \r
4691                         /* サイズ */\r
4692                         do\r
4693                         {\r
4694                                 if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)\r
4695                                         break;\r
4696                         }\r
4697                         while(IsDigit(*Buf) == 0);\r
4698                         --offs;\r
4699                         if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)\r
4700                                 break;\r
4701                         RemoveComma(Buf);\r
4702                         *Size = _atoi64(Buf);\r
4703                         if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)\r
4704                                 break;\r
4705                         if(IsDigit(*Buf) == 0)\r
4706                                 break;\r
4707                         /* 名前 */\r
4708                         if(FindField(Str, Fname, 0, NO) != FFFTP_SUCCESS)\r
4709                                 break;\r
4710                         /* 種類 */\r
4711                         if(offs == 0)\r
4712                                 Ret = NODE_FILE;\r
4713                         else\r
4714                         {\r
4715                                 if((FindField(Str, Buf, 1, NO) == FFFTP_SUCCESS) &&\r
4716                                    (strcmp(Buf, "DR") == 0))\r
4717                                         Ret = NODE_DIR;\r
4718                                 else\r
4719                                         Ret = NODE_FILE;\r
4720                         }\r
4721                         break;\r
4722 \r
4723                 case LIST_ALLIED :\r
4724                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4725 \r
4726                         /* 日付 */\r
4727                         FindField(Str, Buf, 3, NO);\r
4728                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);      /* wDayは常に0 */\r
4729                         FindField(Str, Buf, 4, NO);\r
4730                         sTime.wDay = atoi(Buf);\r
4731                         FindField(Str, Buf, 6, NO);\r
4732                         sTime.wYear = atoi(Buf);\r
4733 \r
4734                         /* 時刻 */\r
4735                         FindField(Str, Buf, 5, NO);\r
4736                         sTime.wHour = atoi(Buf);\r
4737                         sTime.wMinute = atoi(Buf+3);\r
4738                         sTime.wSecond = 0;\r
4739                         sTime.wMilliseconds = 0;\r
4740                         SystemTimeToFileTime(&sTime, Time);\r
4741                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4742 \r
4743                         /* サイズ */\r
4744                         FindField(Str, Buf, 0, NO);\r
4745                         *Size = _atoi64(Buf);\r
4746 \r
4747                         /* 名前 */\r
4748                         if(FindField(Str, Fname, 1, NO) == FFFTP_SUCCESS)\r
4749                         {\r
4750                                 Ret = NODE_FILE;\r
4751                                 if(Buf[0] == '<')\r
4752                                         Ret = NODE_DIR;\r
4753                         }\r
4754                         break;\r
4755 \r
4756                 case LIST_OS9 :\r
4757                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4758 \r
4759                         /* 日付 */\r
4760                         FindField(Str, Buf, 1, NO);\r
4761                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4762                         sTime.wMonth = atoi(Buf + 3);\r
4763                         sTime.wDay = atoi(Buf + 6);\r
4764                         SystemTimeToFileTime(&sTime, Time);\r
4765                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4766 \r
4767                         /* 時刻 */\r
4768                         FindField(Str, Buf, 2, NO);\r
4769                         sTime.wHour = atoi_n(Buf, 2);\r
4770                         sTime.wMinute = atoi(Buf+2);\r
4771                         sTime.wSecond = 0;\r
4772                         sTime.wMilliseconds = 0;\r
4773                         SystemTimeToFileTime(&sTime, Time);\r
4774                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4775 \r
4776                         /* サイズ */\r
4777                         FindField(Str, Buf, 5, NO);\r
4778                         *Size = _atoi64(Buf);\r
4779 \r
4780                         /* オーナ名 */\r
4781                         FindField(Str, Buf, 0, NO);\r
4782                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4783 \r
4784                         /* オーナ名 */\r
4785                         FindField(Str, Buf, 3, NO);\r
4786 \r
4787                         /* 名前 */\r
4788                         if(FindField(Str, Fname, 6, NO) == FFFTP_SUCCESS)\r
4789                         {\r
4790                                 if((Buf[0] == 'd') || (Buf[0] == 'D'))\r
4791                                         Ret = NODE_DIR;\r
4792                                 else\r
4793                                         Ret = NODE_FILE;\r
4794                         }\r
4795                         break;\r
4796 \r
4797                 case LIST_IBM :\r
4798                         *InfoExist |= FINFO_DATE;\r
4799 \r
4800 \r
4801                         /* 日付 */\r
4802                         FindField(Str, Buf, 2, NO);\r
4803                         sTime.wYear = atoi(Buf);\r
4804                         sTime.wMonth = atoi(Buf + 5);\r
4805                         sTime.wDay = atoi(Buf + 8);\r
4806                         sTime.wHour = 0;\r
4807                         sTime.wMinute = 0;\r
4808                         sTime.wSecond = 0;\r
4809                         sTime.wMilliseconds = 0;\r
4810                         SystemTimeToFileTime(&sTime, Time);\r
4811                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4812 \r
4813                         /* 名前 */\r
4814                         FindField(Str, Buf, 8, NO);\r
4815                         if(FindField(Str, Fname, 9, NO) == FFFTP_SUCCESS)\r
4816                         {\r
4817                                 if(strcmp(Buf, "PO") == 0)\r
4818                                         Ret = NODE_DIR;\r
4819                                 else if(strcmp(Buf, "PS") == 0)\r
4820                                         Ret = NODE_FILE;\r
4821                         }\r
4822                         break;\r
4823 \r
4824                 case LIST_AGILENT :\r
4825                         *InfoExist |= (FINFO_SIZE | FINFO_ATTR);\r
4826 \r
4827                         /* オーナ名 */\r
4828                         FindField(Str, Buf, 2, NO);\r
4829                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4830 \r
4831                         /* サイズ */\r
4832                         FindField(Str, Buf, 4, NO);\r
4833                         *Size = _atoi64(Buf);\r
4834 \r
4835                         /* 属性 */\r
4836                         FindField(Str, Buf, 0, NO);\r
4837                         *Attr = AttrString2Value(Buf+1);\r
4838 \r
4839                         /* 名前 */\r
4840                         if(FindField(Str, Fname, 5, YES) == FFFTP_SUCCESS)\r
4841                         {\r
4842                                 Ret = NODE_FILE;\r
4843                                 if(strchr("dl", Buf[0]) != NULL)\r
4844                                         Ret = NODE_DIR;\r
4845                         }\r
4846                         break;\r
4847 \r
4848                 case LIST_SHIBASOKU :\r
4849                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4850 \r
4851                         /* サイズ */\r
4852                         FindField(Str, Buf, 0, NO);\r
4853                         if(IsDigit(Buf[0]))\r
4854                         {\r
4855                                 *Size = _atoi64(Buf);\r
4856 \r
4857                                 /* 日付 */\r
4858                                 FindField(Str, Buf, 1, NO);\r
4859                                 Buf[3] = '\0';\r
4860                                 GetMonth(Buf, &sTime.wMonth, &sTime.wDay);\r
4861                                 sTime.wDay = atoi(Buf+4);\r
4862                                 sTime.wYear = atoi(Buf+7);\r
4863 \r
4864                                 /* 時刻 */\r
4865                                 FindField(Str, Buf, 2, NO);\r
4866                                 sTime.wHour = atoi(Buf);\r
4867                                 sTime.wMinute = atoi(Buf+3);\r
4868                                 sTime.wSecond = 0;\r
4869                                 sTime.wMilliseconds = 0;\r
4870                                 SystemTimeToFileTime(&sTime, Time);\r
4871                                 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4872 \r
4873                                 /* 名前 */\r
4874                                 FindField(Str, Fname, 3, NO);\r
4875 \r
4876                                 /* 種類 */\r
4877                                 Ret = NODE_FILE;\r
4878                                 if(FindField(Str, Buf, 4, NO) == FFFTP_SUCCESS)\r
4879                                 {\r
4880                                         if(strcmp(Buf, "<DIR>") == 0)\r
4881                                                 Ret = NODE_DIR;\r
4882                                 }\r
4883                         }\r
4884                         break;\r
4885 \r
4886 #if defined(HAVE_TANDEM)\r
4887                 case LIST_TANDEM :\r
4888                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
4889                         /* Open 中だったらずらす */\r
4890                         if(FindField(Str, Buf, 1, NO) != FFFTP_SUCCESS)\r
4891                                 break;\r
4892                         if (!strncmp(Buf, "O", 1)) {\r
4893                                 offs = 1;\r
4894                         }\r
4895                         /* 日付 */\r
4896                         if(FindField(Str, Buf, 3 + offs, NO) != FFFTP_SUCCESS)\r
4897                                 break;\r
4898                         if (Buf[1] == '-') {  /* 日付が 1桁 */\r
4899                                 sTime.wYear = Assume1900or2000(atoi(Buf + 6));\r
4900                                 Buf[5] = 0;\r
4901                                 GetMonth(Buf+2, &sTime.wMonth, &sTime.wDay);    /* wDayは常に0 */\r
4902                                 sTime.wDay = atoi(Buf);\r
4903                                 sTime.wDayOfWeek = 0;\r
4904                         } else {\r
4905                                 sTime.wYear = Assume1900or2000(atoi(Buf + 7));\r
4906                                 Buf[6] = 0;\r
4907                                 GetMonth(Buf+3, &sTime.wMonth, &sTime.wDay);    /* wDayは常に0 */\r
4908                                 sTime.wDay = atoi(Buf);\r
4909                                 sTime.wDayOfWeek = 0;\r
4910                         }\r
4911                         /* 時刻 */\r
4912                         FindField(Str, Buf, 4 + offs, NO);\r
4913                         sTime.wHour = atoi(Buf);\r
4914                         sTime.wMinute = atoi(Buf+3);\r
4915                         sTime.wSecond = atoi(Buf+6);\r
4916                         sTime.wMilliseconds = 0;\r
4917                         SystemTimeToFileTime(&sTime, Time);\r
4918                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4919 \r
4920                         /* 属性 セキュリティではなく FileCode を保存する */\r
4921                         FindField(Str, Buf, 1 + offs, NO);\r
4922                         *Attr = atoi(Buf);\r
4923                         /* サイズ */\r
4924                         FindField(Str, Buf, 2 + offs, NO);\r
4925                         *Size = _atoi64(Buf);\r
4926                         /* オーナ名 */\r
4927                         if(FindField(Str, Buf, 5 + offs, NO) == FFFTP_SUCCESS) {\r
4928                                 if(strncmp(Buf, "Owner", sizeof("Owner"))) {\r
4929                                         memset(Owner, NUL, OWNER_NAME_LEN+1);\r
4930                                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4931                                         /* 通常は 255,255 だが、20, 33 などにも対応する */\r
4932                                         /* 最後の文字が , だったら後ろとつなげる */\r
4933                                         if (Buf[strlen(Buf)-1] == ',') {\r
4934                                                 FindField(Str, Buf, 6 + offs, NO);\r
4935                                                 strncat(Owner, Buf, OWNER_NAME_LEN - strlen(Buf));\r
4936                                         }\r
4937                                         /* ファイル名 */\r
4938                                         if(FindField(Str, Fname, 0, NO) == FFFTP_SUCCESS) {\r
4939                                                 Ret = NODE_FILE;\r
4940                                         }\r
4941                                 }\r
4942                         }\r
4943                         break;\r
4944 #endif\r
4945 \r
4946                         // MLSD対応\r
4947                         // 以下の形式に対応\r
4948                         // fact1=value1;fact2=value2;fact3=value3; filename\r\n\r
4949                         // 不完全な実装のホストが存在するため以下の形式も許容\r
4950                         // fact1=value1;fact2=value2;fact3=value3 filename\r\n\r
4951                         // fact1=value1;fact2=value2;fact3=value3;filename\r\n\r
4952                 case LIST_MLSD:\r
4953                         {\r
4954                                 int i = 0;\r
4955                                 char StrBuf[(FMAX_PATH * 2) + 1];\r
4956                                 char Fact[FMAX_PATH + 1];\r
4957                                 char Name[FMAX_PATH + 1];\r
4958                                 char Value[FMAX_PATH + 1];\r
4959                                 char* pFileName;\r
4960                                 strncpy(StrBuf, Str, FMAX_PATH * 2);\r
4961                                 StrBuf[FMAX_PATH * 2] = '\0';\r
4962                                 if((pFileName = strstr(StrBuf, "; ")) != NULL)\r
4963                                 {\r
4964                                         *pFileName = '\0';\r
4965                                         pFileName += 2;\r
4966                                 }\r
4967                                 else if((pFileName = strchr(StrBuf, ' ')) != NULL)\r
4968                                 {\r
4969                                         *pFileName = '\0';\r
4970                                         pFileName++;\r
4971                                 }\r
4972                                 else if((pFileName = strrchr(StrBuf, ';')) != NULL)\r
4973                                 {\r
4974                                         *pFileName = '\0';\r
4975                                         pFileName++;\r
4976                                 }\r
4977                                 if(pFileName != NULL)\r
4978                                         strcpy(Fname, pFileName);\r
4979                                 while(FindField2(StrBuf, Fact, ';', i, NO) == FFFTP_SUCCESS)\r
4980                                 {\r
4981                                         if(FindField2(Fact, Name, '=', 0, NO) == FFFTP_SUCCESS && FindField2(Fact, Value, '=', 1, NO) == FFFTP_SUCCESS)\r
4982                                         {\r
4983                                                 if(_stricmp(Name, "type") == 0)\r
4984                                                 {\r
4985                                                         if(_stricmp(Value, "dir") == 0)\r
4986                                                                 Ret = NODE_DIR;\r
4987                                                         else if(_stricmp(Value, "file") == 0)\r
4988                                                                 Ret = NODE_FILE;\r
4989                                                 }\r
4990                                                 else if(_stricmp(Name, "size") == 0)\r
4991                                                 {\r
4992                                                         *Size = _atoi64(Value);\r
4993                                                         *InfoExist |= FINFO_SIZE;\r
4994                                                 }\r
4995                                                 else if(_stricmp(Name, "modify") == 0)\r
4996                                                 {\r
4997                                                         sTime.wYear = atoi_n(Value, 4);\r
4998                                                         sTime.wMonth = atoi_n(Value + 4, 2);\r
4999                                                         sTime.wDay = atoi_n(Value + 6, 2);\r
5000                                                         sTime.wHour = atoi_n(Value + 8, 2);\r
5001                                                         sTime.wMinute = atoi_n(Value + 10, 2);\r
5002                                                         sTime.wSecond = atoi_n(Value + 12, 2);\r
5003                                                         sTime.wMilliseconds = 0;\r
5004                                                         SystemTimeToFileTime(&sTime, Time);\r
5005                                                         // 時刻はGMT\r
5006 //                                                      SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
5007                                                         *InfoExist |= FINFO_DATE | FINFO_TIME;\r
5008                                                 }\r
5009                                                 else if(_stricmp(Name, "UNIX.mode") == 0)\r
5010                                                 {\r
5011                                                         *Attr = strtol(Value, NULL, 16);\r
5012                                                         *InfoExist |= FINFO_ATTR;\r
5013                                                 }\r
5014                                                 else if(_stricmp(Name, "UNIX.owner") == 0)\r
5015                                                         strcpy(Owner, Value);\r
5016                                         }\r
5017                                         i++;\r
5018                                 }\r
5019                         }\r
5020                         break;\r
5021 \r
5022                 case LIST_UNIX_10 :\r
5023                 case LIST_UNIX_11 :\r
5024                 case LIST_UNIX_12 :\r
5025                 case LIST_UNIX_13 :\r
5026                 case LIST_UNIX_14 :\r
5027                 case LIST_UNIX_15 :\r
5028                 case LIST_UNIX_20 :\r
5029                 case LIST_UNIX_21 :\r
5030                 case LIST_UNIX_22 :\r
5031                 case LIST_UNIX_23 :\r
5032                 case LIST_UNIX_24 :\r
5033                 case LIST_UNIX_25 :\r
5034                 case LIST_UNIX_50 :\r
5035                 case LIST_UNIX_51 :\r
5036                 case LIST_UNIX_54 :\r
5037                 case LIST_UNIX_60 :\r
5038                 case LIST_UNIX_61 :\r
5039                 case LIST_UNIX_62 :\r
5040                 case LIST_UNIX_63 :\r
5041                 case LIST_UNIX_64 :\r
5042                 case LIST_UNIX_65 :\r
5043                 case LIST_UNIX_70 :\r
5044                 case LIST_UNIX_71 :\r
5045                 case LIST_UNIX_72 :\r
5046                 case LIST_UNIX_73 :\r
5047                 case LIST_UNIX_74 :\r
5048                 case LIST_UNIX_75 :\r
5049 // MELCOMはビットフラグになっている\r
5050 //              case LIST_MELCOM :\r
5051                 // linux-ftpd\r
5052                 case LIST_UNIX_16 :\r
5053                 default:\r
5054                         /* offsはサイズの位置, offs=0はカラム4 */\r
5055                         offs = 0;\r
5056                         if((ListType == LIST_UNIX_12) ||\r
5057                            (ListType == LIST_UNIX_13) ||\r
5058                            (ListType == LIST_UNIX_15) ||\r
5059                            (ListType == LIST_UNIX_20) ||\r
5060                            (ListType == LIST_UNIX_21) ||\r
5061                            (ListType == LIST_UNIX_24))\r
5062                                 offs = -1;\r
5063 \r
5064                         if((ListType == LIST_UNIX_22) ||\r
5065                            (ListType == LIST_UNIX_23) ||\r
5066                            (ListType == LIST_UNIX_25) ||\r
5067                            (ListType == LIST_UNIX_50) ||\r
5068                            (ListType == LIST_UNIX_51) ||\r
5069                            (ListType == LIST_UNIX_54))\r
5070                                 offs = -2;\r
5071 \r
5072                         if((ListType == LIST_UNIX_60) ||\r
5073                            (ListType == LIST_UNIX_61) ||\r
5074                            (ListType == LIST_UNIX_64))\r
5075                                 offs = 2;\r
5076 \r
5077                         if((ListType == LIST_UNIX_62) ||\r
5078                            (ListType == LIST_UNIX_63) ||\r
5079                            (ListType == LIST_UNIX_65) ||\r
5080                            (ListType == LIST_UNIX_70) ||\r
5081                            (ListType == LIST_UNIX_71) ||\r
5082                            (ListType == LIST_UNIX_74))\r
5083                                 offs = 1;\r
5084 \r
5085                         /* offs2は時間(もしくは年)の位置 */\r
5086                         offs2 = 0;\r
5087                         // linux-ftpd\r
5088 //                      if((ListType == LIST_UNIX_11) ||\r
5089 //                         (ListType == LIST_UNIX_13) ||\r
5090 //                         (ListType == LIST_UNIX_21) ||\r
5091 //                         (ListType == LIST_UNIX_23) ||\r
5092 //                         (ListType == LIST_UNIX_51) ||\r
5093 //                         (ListType == LIST_UNIX_61) ||\r
5094 //                         (ListType == LIST_UNIX_63) ||\r
5095 //                         (ListType == LIST_UNIX_71) ||\r
5096 //                         (ListType == LIST_UNIX_73))\r
5097                         if((ListType == LIST_UNIX_11) ||\r
5098                            (ListType == LIST_UNIX_13) ||\r
5099                            (ListType == LIST_UNIX_21) ||\r
5100                            (ListType == LIST_UNIX_23) ||\r
5101                            (ListType == LIST_UNIX_51) ||\r
5102                            (ListType == LIST_UNIX_61) ||\r
5103                            (ListType == LIST_UNIX_63) ||\r
5104                            (ListType == LIST_UNIX_71) ||\r
5105                            (ListType == LIST_UNIX_73) ||\r
5106                            (ListType == LIST_UNIX_16))\r
5107                                 offs2 = -1;\r
5108 \r
5109                         /* offs3はオーナ名の位置 */\r
5110                         offs3 = 0;\r
5111                         if((ListType == LIST_UNIX_12) ||\r
5112                            (ListType == LIST_UNIX_13) ||\r
5113                            (ListType == LIST_UNIX_15) ||\r
5114                            (ListType == LIST_UNIX_22) ||\r
5115                            (ListType == LIST_UNIX_23) ||\r
5116                            (ListType == LIST_UNIX_25) ||\r
5117                            (ListType == LIST_UNIX_50) ||\r
5118                            (ListType == LIST_UNIX_51) ||\r
5119                            (ListType == LIST_UNIX_62) ||\r
5120                            (ListType == LIST_UNIX_63) ||\r
5121                            (ListType == LIST_UNIX_65) ||\r
5122                            (ListType == LIST_UNIX_72) ||\r
5123                            (ListType == LIST_UNIX_73) ||\r
5124                            (ListType == LIST_UNIX_75))\r
5125                                 offs3 = -1;\r
5126 \r
5127                         Flag2 = 0;\r
5128                         if((ListType == LIST_UNIX_14) ||\r
5129                            (ListType == LIST_UNIX_15) ||\r
5130                            (ListType == LIST_UNIX_24) ||\r
5131                            (ListType == LIST_UNIX_25) ||\r
5132                            (ListType == LIST_UNIX_54) ||\r
5133                            (ListType == LIST_UNIX_64) ||\r
5134                            (ListType == LIST_UNIX_65) ||\r
5135                            (ListType == LIST_UNIX_74) ||\r
5136                            (ListType == LIST_UNIX_75))\r
5137                                 Flag2 = 1;\r
5138 \r
5139                         *InfoExist |= (FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
5140 \r
5141                         /* 属性 */\r
5142                         FindField(Str, Buf, 0, NO);\r
5143                         *Attr = AttrString2Value(Buf+1);\r
5144 \r
5145                         /* オーナ名 */\r
5146                         FindField(Str, Buf, 2+offs3, NO);\r
5147                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
5148 \r
5149                         /* サイズ */\r
5150                         FindField(Str, Buf, 4+offs, NO);\r
5151                         Pos = Buf;\r
5152                         if((*Pos != NUL) && (IsDigit(*Pos) == 0))\r
5153                         {\r
5154                                 Pos = strchr(Pos, NUL) - 1;\r
5155                                 for(; Pos > Buf; Pos--)\r
5156                                 {\r
5157                                         if(IsDigit(*Pos) == 0)\r
5158                                         {\r
5159                                                 Pos++;\r
5160                                                 break;\r
5161                                         }\r
5162                                 }\r
5163                         }\r
5164                         *Size = _atoi64(Pos);\r
5165 \r
5166                         if(Flag2 == 0)\r
5167                         {\r
5168                                 /* 時刻/日付 */\r
5169                                 GetLocalTime(&sTime);\r
5170                                 memcpy(&sTimeNow, &sTime, sizeof(SYSTEMTIME));\r
5171                                 sTime.wSecond = 0;\r
5172                                 sTime.wMilliseconds = 0;\r
5173 \r
5174                                 FindField(Str, Buf, 5+offs, NO);\r
5175                                 /* 日付が yy/mm/dd の場合に対応 */\r
5176                                 if(GetYearMonthDay(Buf, &sTime.wYear, &sTime.wMonth, &sTime.wDay) == FFFTP_SUCCESS)\r
5177                                 {\r
5178                                         sTime.wYear = Assume1900or2000(sTime.wYear);\r
5179 \r
5180                                         FindField(Str, Buf, 7+offs+offs2, NO);\r
5181                                         if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_SUCCESS)\r
5182                                                 *InfoExist |= FINFO_TIME;\r
5183                                 }\r
5184                                 // linux-ftpd\r
5185                                 else if(CheckYYYYMMDDformat(Buf, NUL) != 0)\r
5186                                 {\r
5187                                         sTime.wYear = atoi(Buf);\r
5188                                         sTime.wMonth = atoi(Buf+5);\r
5189                                         sTime.wDay = atoi(Buf+8);\r
5190                                         FindField(Str, Buf, 7+offs+offs2, NO);\r
5191                                         if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_SUCCESS)\r
5192                                                 *InfoExist |= FINFO_TIME;\r
5193                                 }\r
5194                                 else\r
5195                                 {\r
5196                                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);\r
5197                                         if(offs2 == 0)\r
5198                                         {\r
5199                                                 FindField(Str, Buf, 6+offs, NO);\r
5200                                                 sTime.wDay = atoi(Buf);\r
5201                                         }\r
5202 \r
5203                                         FindField(Str, Buf, 7+offs+offs2, NO);\r
5204                                         if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_FAIL)\r
5205                                         {\r
5206                                                 sTime.wYear = atoi(Buf);\r
5207                                         }\r
5208                                         else\r
5209                                         {\r
5210                                                 *InfoExist |= FINFO_TIME;\r
5211 \r
5212                                                 /* 年がない */\r
5213                                                 /* 現在の日付から推定 */\r
5214                                                 // 恐らくホストとローカルの時刻が異なる場合の対処のようだがとりあえず無効にする\r
5215 //                                              if((sTimeNow.wMonth == 12) && (sTime.wMonth == 1))\r
5216 //                                                      sTime.wYear++;\r
5217 //                                              else if(sTimeNow.wMonth+1 == sTime.wMonth)\r
5218                                                 if(sTimeNow.wMonth+1 == sTime.wMonth)\r
5219                                                         /* nothing */;\r
5220                                                 else if(sTimeNow.wMonth < sTime.wMonth)\r
5221                                                         sTime.wYear--;\r
5222 \r
5223 \r
5224 //#################\r
5225                                                 /* 今年の今日以降のファイルは、実は去年のファイル */\r
5226                                                 if((sTime.wYear == sTimeNow.wYear) &&\r
5227                                                    ((sTime.wMonth > sTimeNow.wMonth) ||\r
5228                                                         ((sTime.wMonth == sTimeNow.wMonth) && (sTime.wDay > sTimeNow.wDay))))\r
5229                                                 {\r
5230                                                         sTime.wYear--;\r
5231                                                 }\r
5232                                         }\r
5233                                 }\r
5234                         }\r
5235                         else\r
5236                         {\r
5237                                 /* LIST_UNIX_?4, LIST_UNIX_?5 の時 */\r
5238                                 FindField(Str, Buf, 5+offs, NO);\r
5239                                 sTime.wYear = atoi(Buf);\r
5240                                 FindField(Str, Buf, 6+offs, NO);\r
5241                                 sTime.wMonth = atoi(Buf);\r
5242                                 FindField(Str, Buf, 7+offs, NO);\r
5243                                 sTime.wDay = atoi(Buf);\r
5244                                 sTime.wHour = 0;\r
5245                                 sTime.wMinute = 0;\r
5246                                 sTime.wSecond = 0;\r
5247                                 sTime.wMilliseconds = 0;\r
5248                         }\r
5249                         SystemTimeToFileTime(&sTime, Time);\r
5250                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
5251 \r
5252                         /* 名前 */\r
5253                         if(FindField(Str, Fname, 8+offs+offs2, YES) == FFFTP_SUCCESS)\r
5254                         {\r
5255                                 Flag = 'B';\r
5256                                 if(OrgListType & LIST_MELCOM)\r
5257                                 {\r
5258                                         Flag = Fname[14];\r
5259                                         Fname[14] = NUL;\r
5260                                         RemoveTailingSpaces(Fname);\r
5261                                 }\r
5262                                 else\r
5263                                 {\r
5264                                         if((Pos = strstr(Fname, " -> ")) != NULL)\r
5265                                                 *Pos = NUL;\r
5266                                 }\r
5267 \r
5268                                 if(strchr("dl", *Str) != NULL)\r
5269                                 {\r
5270                                         // 0x5Cが含まれる文字列を扱えないバグ修正\r
5271 //                                      if((_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "/") == 0) ||\r
5272 //                                         (_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "\\") == 0))\r
5273 //                                      {\r
5274 //                                              *(Fname + strlen(Fname) - 1) = NUL;\r
5275 //                                      }\r
5276                                         Ret = NODE_DIR;\r
5277                                         if(*Str == 'l')\r
5278                                                 *Link = YES;\r
5279                                 }\r
5280                                 else if(strchr("-+f", *Str) != NULL)\r
5281                                         Ret = NODE_FILE;\r
5282 \r
5283                                 if((Ret == NODE_FILE) && (Flag != 'B'))\r
5284                                         Ret = NODE_NONE;\r
5285                         }\r
5286                         break;\r
5287         }\r
5288 \r
5289         // UTF-8対応\r
5290 //      if((Ret != NODE_NONE) && (strlen(Fname) > 0))\r
5291         if(!(OrgListType & LIST_RAW_NAME) && (Ret != NODE_NONE) && (strlen(Fname) > 0))\r
5292         {\r
5293                 // UTF-8対応\r
5294 //              if(CheckSpecialDirName(Fname) == YES)\r
5295 //                      Ret = NODE_NONE;\r
5296 //              else\r
5297 //                      ChangeFnameRemote2Local(Fname, FMAX_PATH);\r
5298                 ChangeFnameRemote2Local(Fname, FMAX_PATH);\r
5299                 // UTF-8の冗長表現によるディレクトリトラバーサル対策\r
5300                 FixStringM(Fname, Fname);\r
5301                 // 0x5Cが含まれる文字列を扱えないバグ修正\r
5302                 if((_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "/") == 0)\r
5303                         || (_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "\\") == 0))\r
5304                         *(Fname + strlen(Fname) - 1) = NUL;\r
5305                 if(CheckSpecialDirName(Fname) == YES)\r
5306                         Ret = NODE_NONE;\r
5307                 // 文字コードが正しくないために長さが0になったファイル名は表示しない\r
5308                 if(strlen(Fname) == 0)\r
5309                         Ret = NODE_NONE;\r
5310         }\r
5311         return(Ret);\r
5312 }\r
5313 \r
5314 \r
5315 /*----- 指定の番号のフィールドを求める ----------------------------------------\r
5316 *\r
5317 *       Parameter\r
5318 *               char *Str : 文字列\r
5319 *               char *Buf : 文字列のコピー先\r
5320 *               int Num : フィールド番号\r
5321 *               int ToLast : 文字列の最後までコピー (YES/NO)\r
5322 *\r
5323 *       Return Value\r
5324 *               int ステータス\r
5325 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
5326 *----------------------------------------------------------------------------*/\r
5327 \r
5328 static int FindField(char *Str, char *Buf, int Num, int ToLast)\r
5329 {\r
5330         char *Pos;\r
5331         int Sts;\r
5332 \r
5333         Sts = FFFTP_FAIL;\r
5334         *Buf = NUL;\r
5335         if(Num >= 0)\r
5336         {\r
5337                 while(*Str == ' ')\r
5338                         Str++;\r
5339 \r
5340                 for(; Num > 0; Num--)\r
5341                 {\r
5342                         if((Str = strchr(Str, ' ')) != NULL)\r
5343                         {\r
5344                                 while(*Str == ' ')\r
5345                                 {\r
5346                                         if(*Str == NUL)\r
5347                                         {\r
5348                                                 Str = NULL;\r
5349                                                 break;\r
5350                                         }\r
5351                                         Str++;\r
5352                                 }\r
5353                         }\r
5354                         else\r
5355                                 break;\r
5356                 }\r
5357         }\r
5358 \r
5359         if(Str != NULL)\r
5360         {\r
5361                 if((ToLast == YES) || ((Pos = strchr(Str, ' ')) == NULL))\r
5362                         strcpy(Buf, Str);\r
5363                 else\r
5364                 {\r
5365                         strncpy(Buf, Str, Pos - Str);\r
5366                         *(Buf + (Pos - Str)) = NUL;\r
5367                 }\r
5368                 Sts = FFFTP_SUCCESS;\r
5369         }\r
5370         return(Sts);\r
5371 }\r
5372 \r
5373 \r
5374 // MLSD対応\r
5375 static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast)\r
5376 {\r
5377         char *Pos;\r
5378         int Sts;\r
5379 \r
5380         Sts = FFFTP_FAIL;\r
5381         *Buf = NUL;\r
5382         if(Num >= 0)\r
5383         {\r
5384                 while(*Str == Separator)\r
5385                         Str++;\r
5386 \r
5387                 for(; Num > 0; Num--)\r
5388                 {\r
5389                         if((Str = strchr(Str, Separator)) != NULL)\r
5390                         {\r
5391                                 while(*Str == Separator)\r
5392                                 {\r
5393                                         if(*Str == NUL)\r
5394                                         {\r
5395                                                 Str = NULL;\r
5396                                                 break;\r
5397                                         }\r
5398                                         Str++;\r
5399                                 }\r
5400                         }\r
5401                         else\r
5402                                 break;\r
5403                 }\r
5404         }\r
5405 \r
5406         if(Str != NULL)\r
5407         {\r
5408                 if((ToLast == YES) || ((Pos = strchr(Str, Separator)) == NULL))\r
5409                         strcpy(Buf, Str);\r
5410                 else\r
5411                 {\r
5412                         strncpy(Buf, Str, Pos - Str);\r
5413                         *(Buf + (Pos - Str)) = NUL;\r
5414                 }\r
5415                 Sts = FFFTP_SUCCESS;\r
5416         }\r
5417         return(Sts);\r
5418 }\r
5419 \r
5420 \r
5421 /*----- 文字列から月を求める --------------------------------------------------\r
5422 *\r
5423 *       Parameter\r
5424 *               char *Str : 文字列\r
5425 *               WORD *Month : 月 (0=月を表す文字列ではない)\r
5426 *               WORD *Day : 日 (0=日は含まれていない)\r
5427 *\r
5428 *       Return Value\r
5429 *               なし\r
5430 *----------------------------------------------------------------------------*/\r
5431 \r
5432 static void GetMonth(char *Str, WORD *Month, WORD *Day)\r
5433 {\r
5434         static const char DateStr[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" };\r
5435         char *Pos;\r
5436 \r
5437         *Month = 0;\r
5438         *Day = 0;\r
5439 \r
5440         if(IsDigit(*Str) == 0)\r
5441         {\r
5442                 _strlwr(Str);\r
5443                 *Str = toupper(*Str);\r
5444                 if((Pos = strstr(DateStr, Str)) != NULL)\r
5445                         *Month = ((Pos - DateStr) / 3) + 1;\r
5446         }\r
5447         else\r
5448         {\r
5449                 /* 「10月」のような日付を返すものがある */\r
5450                 /* 漢字がJISの時のみSJISに変換 */\r
5451                 ConvAutoToSJIS(Str, KANJI_NOCNV);\r
5452 \r
5453                 Pos = Str;\r
5454                 while(*Pos != NUL)\r
5455                 {\r
5456                         if(!IsDigit(*Pos))\r
5457                         {\r
5458                                 // UTF-8対応\r
5459 //                              if((_mbsncmp(Pos, "月", 1) == 0) ||\r
5460 //                                 (memcmp(Pos, "\xB7\xEE", 2) == 0) || /* EUCの「月」 */\r
5461 //                                 (memcmp(Pos, "\xD4\xC2", 2) == 0))   /* GBコードの「月」 */\r
5462                                 if(memcmp(Pos, "\xE6\x9C\x88", 3) == 0 || memcmp(Pos, "\x8C\x8E", 2) == 0 || memcmp(Pos, "\xB7\xEE", 2) == 0 || memcmp(Pos, "\xD4\xC2", 2) == 0)\r
5463                                 {\r
5464                                         Pos += 2;\r
5465                                         *Month = atoi(Str);\r
5466                                         if((*Month < 1) || (*Month > 12))\r
5467                                                 *Month = 0;\r
5468                                         else\r
5469                                         {\r
5470                                                 /* 「10月11日」のように日がくっついている事がある */\r
5471                                                 if(*Pos != NUL)\r
5472                                                 {\r
5473                                                         *Day = atoi(Pos);\r
5474                                                         if((*Day < 1) || (*Day > 31))\r
5475                                                                 *Day = 0;\r
5476                                                 }\r
5477                                         }\r
5478                                 }\r
5479                                 else if(_mbsncmp(Pos, "/", 1) == 0)\r
5480                                 {\r
5481                                         /* 「10/」のような日付を返すものがある */\r
5482                                         Pos += 1;\r
5483                                         *Month = atoi(Str);\r
5484                                         if((*Month < 1) || (*Month > 12))\r
5485                                                 *Month = 0;\r
5486                                         else\r
5487                                         {\r
5488                                                 /* 「10/11」のように日がくっついている事がある */\r
5489                                                 if(*Pos != NUL)\r
5490                                                 {\r
5491                                                         *Day = atoi(Pos);\r
5492                                                         if((*Day < 1) || (*Day > 31))\r
5493                                                                 *Day = 0;\r
5494                                                 }\r
5495                                         }\r
5496                                 }\r
5497                                 break;\r
5498                         }\r
5499                         Pos++;\r
5500                 }\r
5501         }\r
5502         return;\r
5503 }\r
5504 \r
5505 \r
5506 /*----- 文字列から年月日を求める ----------------------------------------------\r
5507 *\r
5508 *       Parameter\r
5509 *               char *Str : 文字列\r
5510 *               WORD *Year : 年\r
5511 *               WORD *Month : 月\r
5512 *               WORD *Day : 日\r
5513 *\r
5514 *       Return Value\r
5515 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=日付を表す文字ではない)\r
5516 *\r
5517 *       Note\r
5518 *               以下の形式をサポート\r
5519 *                       01/07/25\r
5520 *               FFFTP_FAILを返す時は *Year = 0; *Month = 0; *Day = 0\r
5521 *----------------------------------------------------------------------------*/\r
5522 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day)\r
5523 {\r
5524         int Sts;\r
5525 \r
5526         Sts = FFFTP_FAIL;\r
5527         if(strlen(Str) == 8)\r
5528         {\r
5529                 if(IsDigit(Str[0]) && IsDigit(Str[1]) && !IsDigit(Str[2]) &&\r
5530                    IsDigit(Str[3]) && IsDigit(Str[4]) && !IsDigit(Str[5]) &&\r
5531                    IsDigit(Str[6]) && IsDigit(Str[7]))\r
5532                 {\r
5533                         *Year = atoi(&Str[0]);\r
5534                         *Month = atoi(&Str[3]);\r
5535                         *Day = atoi(&Str[6]);\r
5536                         Sts = FFFTP_SUCCESS;\r
5537                 }\r
5538         }\r
5539         return(Sts);\r
5540 }\r
5541 \r
5542 \r
5543 /*----- 文字列から時刻を取り出す ----------------------------------------------\r
5544 *\r
5545 *       Parameter\r
5546 *               char *Str : 文字列\r
5547 *               WORD *Hour : 時\r
5548 *               WORD *Minute : 分\r
5549 *\r
5550 *       Return Value\r
5551 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=時刻を表す文字ではない)\r
5552 *\r
5553 *       Note\r
5554 *               以下の形式をサポート\r
5555 *                       HH:MM\r
5556 *                       HH時MM分\r
5557 *               FFFTP_FAILを返す時は *Hour = 0; *Minute = 0\r
5558 *----------------------------------------------------------------------------*/\r
5559 \r
5560 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute)\r
5561 {\r
5562         int Ret;\r
5563         char *Pos;\r
5564 \r
5565         Ret = FFFTP_FAIL;\r
5566         if((_mbslen(Str) >= 3) && (isdigit(Str[0]) != 0))\r
5567         {\r
5568                 *Hour = atoi(Str);\r
5569                 if(*Hour <= 24)\r
5570                 {\r
5571                         if((Pos = _mbschr(Str, ':')) != NULL)\r
5572                         {\r
5573                                 Pos++;\r
5574                                 if(IsDigit(*Pos) != 0)\r
5575                                 {\r
5576                                         *Minute = atoi(Pos);\r
5577                                         if(*Minute < 60)\r
5578                                                 Ret = FFFTP_SUCCESS;\r
5579                                 }\r
5580                         }\r
5581                         else\r
5582                         {\r
5583                                 /* 漢字がJISの時のみSJISに変換 */\r
5584                                 ConvAutoToSJIS(Str, KANJI_NOCNV);\r
5585 \r
5586                                 Pos = Str;\r
5587                                 while(*Pos != NUL)\r
5588                                 {\r
5589                                         if(IsDigit(*Pos) == 0)\r
5590                                         {\r
5591                                                 // UTF-8対応\r
5592 //                                              if((_mbsncmp(Pos, "時", 1) == 0) ||\r
5593 //                                                 (memcmp(Pos, "\xBB\xFE", 2) == 0))   /* EUCの「時」 */\r
5594                                                 if(memcmp(Pos, "\xE6\x99\x82", 3) == 0 || memcmp(Pos, "\x8E\x9E", 2) == 0 || memcmp(Pos, "\xBB\xFE", 2) == 0)\r
5595                                                 {\r
5596                                                         Pos += 2;\r
5597                                                         if(*Pos != NUL)\r
5598                                                         {\r
5599                                                                 *Minute = atoi(Pos);\r
5600                                                                 if(*Minute < 60)\r
5601                                                                         Ret = FFFTP_SUCCESS;\r
5602                                                         }\r
5603                                                 }\r
5604                                                 break;\r
5605                                         }\r
5606                                         Pos++;\r
5607                                 }\r
5608                         }\r
5609                 }\r
5610         }\r
5611         else if((_stricmp(Str, "a:m") == 0) || (_stricmp(Str, "p:m") == 0))\r
5612         {\r
5613                 *Hour = 0;\r
5614                 *Minute = 0;\r
5615                 Ret = FFFTP_SUCCESS;\r
5616         }\r
5617 \r
5618         if(Ret == FFFTP_FAIL)\r
5619         {\r
5620                 *Hour = 0;\r
5621                 *Minute = 0;\r
5622         }\r
5623         return(Ret);\r
5624 }\r
5625 \r
5626 \r
5627 /*----- VAX VMSの日付文字列から日付を取り出す ---------------------------------\r
5628 *\r
5629 *       Parameter\r
5630 *               char *Str : 文字列\r
5631 *               WORD *Year : 年\r
5632 *               WORD *Month : 月\r
5633 *               WORD *Day : 日\r
5634 *\r
5635 *       Return Value\r
5636 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=日付を表す文字ではない)\r
5637 *\r
5638 *       Note\r
5639 *               以下の形式をサポート\r
5640 *                       18-SEP-1998\r
5641 *               FFFTP_FAILを返す時は *Year = 0; *Month = 0; *Day = 0\r
5642 *----------------------------------------------------------------------------*/\r
5643 \r
5644 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day)\r
5645 {\r
5646         char *Pos;\r
5647         int Ret;\r
5648         WORD Tmp;\r
5649         char Buf[4];\r
5650 \r
5651         Ret = FFFTP_FAIL;\r
5652         *Day = atoi(Str);\r
5653         if((Pos = strchr(Str, '-')) != NULL)\r
5654         {\r
5655                 Pos++;\r
5656                 strncpy(Buf, Pos, 3);\r
5657                 Buf[3] = NUL;\r
5658                 GetMonth(Buf, Month, &Tmp);\r
5659                 if((Pos = strchr(Pos, '-')) != NULL)\r
5660                 {\r
5661                         Pos++;\r
5662                         *Year = atoi(Pos);\r
5663                         Ret = FFFTP_SUCCESS;\r
5664                 }\r
5665         }\r
5666 \r
5667         if(Ret == FFFTP_FAIL)\r
5668         {\r
5669                 *Year = 0;\r
5670                 *Month = 0;\r
5671                 *Day = 0;\r
5672         }\r
5673         return(Ret);\r
5674 }\r
5675 \r
5676 \r
5677 /*----- 1900年代か2000年代かを決める ------------------------------------------\r
5678 *\r
5679 *       Parameter\r
5680 *               int Year : 年(2桁)\r
5681 *\r
5682 *       Return Value\r
5683 *               int 年\r
5684 *----------------------------------------------------------------------------*/\r
5685 \r
5686 int Assume1900or2000(int Year)\r
5687 {\r
5688         if(Year >= 60)\r
5689                 Year += 1900;\r
5690         else\r
5691                 Year += 2000;\r
5692         return(Year);\r
5693 }\r
5694 \r
5695 \r
5696 \r
5697 /*----- "."や".."かどうかを返す -----------------------------------------------\r
5698 *\r
5699 *       Parameter\r
5700 *               char *Fname : ファイル名\r
5701 *\r
5702 *       Return Value\r
5703 *               int ステータス (YES="."か".."のどちらか/NO)\r
5704 *----------------------------------------------------------------------------*/\r
5705 \r
5706 static int CheckSpecialDirName(char *Fname)\r
5707 {\r
5708         int Sts;\r
5709 \r
5710         Sts = NO;\r
5711         if((strcmp(Fname, ".") == 0) || (strcmp(Fname, "..") == 0))\r
5712                 Sts = YES;\r
5713 \r
5714         return(Sts);\r
5715 }\r
5716 \r
5717 \r
5718 /*----- フィルタに指定されたファイル名かどうかを返す --------------------------\r
5719 *\r
5720 *       Parameter\r
5721 *               char Fname : ファイル名\r
5722 *               int Type : ファイルのタイプ (NODE_xxx)\r
5723 *\r
5724 *       Return Value\r
5725 *               int ステータス\r
5726 *                       YES/NO=表示しない\r
5727 *\r
5728 *       Note\r
5729 *               フィルタ文字列は以下の形式\r
5730 *                       *.txt;*.log\r
5731 *----------------------------------------------------------------------------*/\r
5732 \r
5733 static int AskFilterStr(char *Fname, int Type)\r
5734 {\r
5735         int Ret;\r
5736         char *Tbl;\r
5737         char *Pos;\r
5738         char Tmp[FILTER_EXT_LEN+1];\r
5739 \r
5740         Tbl = FilterStr;\r
5741         Ret = YES;\r
5742         if((strlen(Tbl) > 0) && (Type == NODE_FILE))\r
5743         {\r
5744                 Ret = NO;\r
5745                 while((Tbl != NULL) && (*Tbl != NUL))\r
5746                 {\r
5747                         while(*Tbl == ';')\r
5748                                 Tbl++;\r
5749                         if(*Tbl == NUL)\r
5750                                 break;\r
5751 \r
5752                         strcpy(Tmp, Tbl);\r
5753                         if((Pos = strchr(Tmp, ';')) != NULL)\r
5754                                 *Pos = NUL;\r
5755 \r
5756                         if(CheckFname(Fname, Tmp) == FFFTP_SUCCESS)\r
5757                         {\r
5758                                 Ret = YES;\r
5759                                 break;\r
5760                         }\r
5761 \r
5762                         Tbl = strchr(Tbl, ';');\r
5763                 }\r
5764         }\r
5765         return(Ret);\r
5766 }\r
5767 \r
5768 \r
5769 /*----- フィルタを設定する ----------------------------------------------------\r
5770 *\r
5771 *       Parameter\r
5772 *               なし\r
5773 *\r
5774 *       Return Value\r
5775 *               なし\r
5776 *----------------------------------------------------------------------------*/\r
5777 \r
5778 void SetFilter(int *CancelCheckWork)\r
5779 {\r
5780         if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(filter_dlg), GetMainHwnd(), FilterWndProc) == YES)\r
5781         {\r
5782                 DispWindowTitle();\r
5783                 GetLocalDirForWnd();\r
5784                 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);\r
5785         }\r
5786         return;\r
5787 }\r
5788 \r
5789 \r
5790 /*----- フィルタ入力ダイアログのコールバック ----------------------------------\r
5791 *\r
5792 *       Parameter\r
5793 *               HWND hDlg : ウインドウハンドル\r
5794 *               UINT message : メッセージ番号\r
5795 *               WPARAM wParam : メッセージの WPARAM 引数\r
5796 *               LPARAM lParam : メッセージの LPARAM 引数\r
5797 *\r
5798 *       Return Value\r
5799 *               BOOL TRUE/FALSE\r
5800 *----------------------------------------------------------------------------*/\r
5801 \r
5802 // 64ビット対応\r
5803 //static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
5804 static INT_PTR CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
5805 {\r
5806         switch (iMessage)\r
5807         {\r
5808                 case WM_INITDIALOG :\r
5809                         SendDlgItemMessage(hDlg, FILTER_STR, EM_LIMITTEXT, FILTER_EXT_LEN+1, 0);\r
5810                         SendDlgItemMessage(hDlg, FILTER_STR, WM_SETTEXT, 0, (LPARAM)FilterStr);\r
5811                         return(TRUE);\r
5812 \r
5813                 case WM_COMMAND :\r
5814                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
5815                         {\r
5816                                 case IDOK :\r
5817                                         SendDlgItemMessage(hDlg, FILTER_STR, WM_GETTEXT, FILTER_EXT_LEN, (LPARAM)FilterStr);\r
5818                                         EndDialog(hDlg, YES);\r
5819                                         break;\r
5820 \r
5821                                 case IDCANCEL :\r
5822                                         EndDialog(hDlg, NO);\r
5823                                         break;\r
5824 \r
5825                                 case FILTER_NOR :\r
5826                                         strcpy(FilterStr, "*");\r
5827                                         EndDialog(hDlg, YES);\r
5828                                         break;\r
5829 \r
5830                                 case IDHELP :\r
5831                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000021);\r
5832                                         break;\r
5833                         }\r
5834             return(TRUE);\r
5835         }\r
5836         return(FALSE);\r
5837 }\r
5838 \r
5839 \r
5840 \r
5841 \r
5842 \r
5843 static int atoi_n(const char *Str, int Len)\r
5844 {\r
5845         char *Tmp;\r
5846         int Ret;\r
5847 \r
5848         Ret = 0;\r
5849         if((Tmp = malloc(Len+1)) != NULL)\r
5850         {\r
5851                 memset(Tmp, 0, Len+1);\r
5852                 strncpy(Tmp, Str, Len);\r
5853                 Ret = atoi(Tmp);\r
5854                 free(Tmp);\r
5855         }\r
5856         return(Ret);\r
5857 }\r
5858 \r
5859 \r
5860 \r
5861 \r
5862 // UTF-8対応\r
5863 // ファイル一覧から漢字コードを推測\r
5864 // 優先度はUTF-8、Shift_JIS、EUC、JISの順\r
5865 int AnalyzeNameKanjiCode(int Num)\r
5866 {\r
5867         char Str[FMAX_PATH+1];\r
5868         char Name[FMAX_PATH+1];\r
5869         LONGLONG Size;\r
5870         FILETIME Time;\r
5871         int Attr;\r
5872         FILE *fd;\r
5873         int Node;\r
5874         int ListType;\r
5875         char Owner[OWNER_NAME_LEN+1];\r
5876         int Link;\r
5877         int InfoExist;\r
5878         int NameKanjiCode;\r
5879         int Point;\r
5880         int PointSJIS;\r
5881         int PointJIS;\r
5882         int PointEUC;\r
5883         int PointUTF8N;\r
5884         char* p;\r
5885 \r
5886         NameKanjiCode = KANJI_AUTO;\r
5887         Point = 0;\r
5888         PointSJIS = 0;\r
5889         PointJIS = 0;\r
5890         PointEUC = 0;\r
5891         PointUTF8N = 0;\r
5892         MakeCacheFileName(Num, Str);\r
5893         if((fd = fopen(Str, "rb")) != NULL)\r
5894         {\r
5895                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
5896                 {\r
5897                         if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)\r
5898                         {\r
5899                                 strcpy(Name, "");\r
5900                                 Node = ResolvFileInfo(Str, ListType | LIST_RAW_NAME, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);\r
5901                                 p = Name;\r
5902                                 while(*p != '\0')\r
5903                                 {\r
5904                                         if(*p & 0x80)\r
5905                                         {\r
5906                                                 p = NULL;\r
5907                                                 break;\r
5908                                         }\r
5909                                         p++;\r
5910                                 }\r
5911                                 if(!p)\r
5912                                 {\r
5913                                         if(!CheckStringM(Name))\r
5914                                                 PointUTF8N++;\r
5915                                         else\r
5916                                         {\r
5917                                                 switch(CheckKanjiCode(Name, strlen(Name), KANJI_SJIS))\r
5918                                                 {\r
5919                                                 case KANJI_SJIS:\r
5920                                                         PointSJIS++;\r
5921                                                         break;\r
5922                                                 case KANJI_JIS:\r
5923                                                         PointJIS++;\r
5924                                                         break;\r
5925                                                 case KANJI_EUC:\r
5926                                                         PointEUC++;\r
5927                                                         break;\r
5928                                                 }\r
5929                                         }\r
5930                                 }\r
5931                         }\r
5932                 }\r
5933                 fclose(fd);\r
5934         }\r
5935         if(PointJIS >= Point)\r
5936         {\r
5937                 NameKanjiCode = KANJI_JIS;\r
5938                 Point = PointJIS;\r
5939         }\r
5940         if(PointEUC >= Point)\r
5941         {\r
5942                 NameKanjiCode = KANJI_EUC;\r
5943                 Point = PointEUC;\r
5944         }\r
5945         if(PointSJIS >= Point)\r
5946         {\r
5947                 NameKanjiCode = KANJI_SJIS;\r
5948                 Point = PointSJIS;\r
5949         }\r
5950         if(PointUTF8N >= Point)\r
5951         {\r
5952                 NameKanjiCode = KANJI_UTF8N;\r
5953                 Point = PointUTF8N;\r
5954         }\r
5955         return NameKanjiCode;\r
5956 }\r
5957 \r