OSDN Git Service

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