OSDN Git Service

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