OSDN Git Service

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