OSDN Git Service

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