OSDN Git Service

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