OSDN Git Service

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