OSDN Git Service

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