OSDN Git Service

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