OSDN Git Service

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