OSDN Git Service

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