OSDN Git Service

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