OSDN Git Service

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