OSDN Git Service

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