OSDN Git Service

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