OSDN Git Service

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