OSDN Git Service

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