1 /*=============================================================================
\r
5 ===============================================================================
\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.
\r
8 / Redistribution and use in source and binary forms, with or without
\r
9 / modification, are permitted provided that the following conditions
\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
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
30 #define _WIN32_WINNT 0x400
\r
33 #include <windows.h>
\r
39 #include <mbstring.h>
\r
41 #include <windowsx.h>
\r
42 #include <commctrl.h>
\r
43 #include <sys/types.h>
\r
44 #include <sys/stat.h>
\r
48 #include "resource.h"
\r
50 #include <htmlhelp.h>
\r
54 #include "OleDragDrop.h"
\r
58 #undef __MBSWRAPPER_H__
\r
59 #include "mbswrapper.h"
\r
61 #define BUF_SIZE 256
\r
63 #define WM_DRAGDROP (WM_APP + 100)
\r
64 #define WM_GETDATA (WM_APP + 101)
\r
65 #define WM_DRAGOVER (WM_APP + 102)
\r
68 /*===== ファイルリストのリスト用ストラクチャ =====*/
\r
71 FILELIST *Top; /* ファイルリストの先頭 */
\r
72 int Files; /* ファイルの数 */
\r
75 /*===== プロトタイプ =====*/
\r
77 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
\r
78 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
\r
79 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
\r
80 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win);
\r
81 static void EraseDispFileList(FLISTANCHOR *Anchor);
\r
82 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor);
\r
83 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist);
\r
84 static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
\r
85 static void DispListList(FILELIST *Pos, char *Title);
\r
86 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);
\r
87 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);
\r
88 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List);
\r
89 static int GetListOneLine(char *Buf, int Max, FILE *Fd);
\r
90 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir);
\r
91 static void MakeLocalTree(char *Path, FILELIST **Base);
\r
92 static void AddFileList(FILELIST *Pkt, FILELIST **Base);
\r
93 static int AnalizeFileInfo(char *Str);
\r
94 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day);
\r
95 static int CheckHHMMformat(char *Str);
\r
96 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3);
\r
97 static int CheckYYYYMMDDformat(char *Str, char Sym);
\r
98 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist);
\r
99 static int FindField(char *Str, char *Buf, int Num, int ToLast);
\r
100 static void GetMonth(char *Str, WORD *Month, WORD *Day);
\r
101 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day);
\r
102 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute);
\r
103 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day);
\r
104 static int CheckSpecialDirName(char *Fname);
\r
105 static int AskFilterStr(char *Fname, int Type);
\r
106 static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
\r
107 static int atoi_n(const char *Str, int Len);
\r
109 /*===== 外部参照 =====*/
\r
111 extern int SepaWidth;
\r
112 extern int RemoteWidth;
\r
113 extern int ListHeight;
\r
114 extern char FilterStr[FILTER_EXT_LEN+1];
\r
115 extern HWND hHelpWin;
\r
118 extern int LocalWidth;
\r
119 extern int LocalTabWidth[4];
\r
120 extern int RemoteTabWidth[6];
\r
121 extern char UserMailAdrs[USER_MAIL_LEN+1];
\r
122 extern HFONT ListFont;
\r
123 extern int ListType;
\r
124 extern int FindMode;
\r
125 extern int DotFile;
\r
126 extern int DispIgnoreHide;
\r
127 extern int DispDrives;
\r
128 extern int MoveMode;
\r
130 /*===== ローカルなワーク =====*/
\r
132 static HWND hWndListLocal = NULL;
\r
133 static HWND hWndListRemote = NULL;
\r
135 static WNDPROC LocalProcPtr;
\r
136 static WNDPROC RemoteProcPtr;
\r
138 static HIMAGELIST ListImg = NULL;
\r
140 static char FindStr[40+1] = { "*" }; /* 検索文字列 */
\r
141 static int IgnoreNew = NO;
\r
142 static int IgnoreOld = NO;
\r
143 static int IgnoreExist = NO;
\r
145 static int Dragging = NO;
\r
147 static int StratusMode; /* 0=ファイル, 1=ディレクトリ, 2=リンク */
\r
150 // リモートファイルリスト (2007.9.3 yutaka)
\r
151 static FILELIST *remoteFileListBase;
\r
152 static FILELIST *remoteFileListBaseNoExpand;
\r
153 static char remoteFileDir[FMAX_PATH + 1];
\r
156 /*----- ファイルリストウインドウを作成する ------------------------------------
\r
159 * HWND hWnd : 親ウインドウのウインドウハンドル
\r
160 * HINSTANCE hInst : インスタンスハンドル
\r
164 * FFFTP_SUCCESS/FFFTP_FAIL
\r
165 *----------------------------------------------------------------------------*/
\r
167 int MakeListWin(HWND hWnd, HINSTANCE hInst)
\r
173 /*===== ローカル側のリストビュー =====*/
\r
175 hWndListLocal = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,
\r
176 WC_LISTVIEWA, NULL,
\r
177 WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,
\r
178 0, TOOLWIN_HEIGHT*2, LocalWidth, ListHeight,
\r
179 GetMainHwnd(), (HMENU)1500, hInst, NULL);
\r
181 if(hWndListLocal != NULL)
\r
183 LocalProcPtr = (WNDPROC)SetWindowLong(hWndListLocal, GWL_WNDPROC, (LONG)LocalWndProc);
\r
185 Tmp = SendMessage(hWndListLocal, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
\r
186 Tmp |= LVS_EX_FULLROWSELECT;
\r
187 SendMessage(hWndListLocal, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);
\r
189 if(ListFont != NULL)
\r
190 SendMessage(hWndListLocal, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));
\r
192 ListImg = ImageList_LoadBitmap(hInst, MAKEINTRESOURCE(dirattr_bmp), 16, 9, RGB(255,0,0));
\r
193 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);
\r
194 ShowWindow(hWndListLocal, SW_SHOW);
\r
196 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
197 LvCol.cx = LocalTabWidth[0];
\r
198 LvCol.pszText = MSGJPN038;
\r
199 LvCol.iSubItem = 0;
\r
200 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);
\r
202 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
203 LvCol.cx = LocalTabWidth[1];
\r
204 LvCol.pszText = MSGJPN039;
\r
205 LvCol.iSubItem = 1;
\r
206 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);
\r
208 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
\r
209 LvCol.fmt = LVCFMT_RIGHT;
\r
210 LvCol.cx = LocalTabWidth[2];
\r
211 LvCol.pszText = MSGJPN040;
\r
212 LvCol.iSubItem = 2;
\r
213 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);
\r
215 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
216 LvCol.cx = LocalTabWidth[3];
\r
217 LvCol.pszText = MSGJPN041;
\r
218 LvCol.iSubItem = 3;
\r
219 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);
\r
222 /*===== ホスト側のリストビュー =====*/
\r
224 hWndListRemote = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,
\r
225 WC_LISTVIEWA, NULL,
\r
226 WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,
\r
227 LocalWidth + SepaWidth, TOOLWIN_HEIGHT*2, RemoteWidth, ListHeight,
\r
228 GetMainHwnd(), (HMENU)1500, hInst, NULL);
\r
230 if(hWndListRemote != NULL)
\r
232 RemoteProcPtr = (WNDPROC)SetWindowLong(hWndListRemote, GWL_WNDPROC, (LONG)RemoteWndProc);
\r
234 Tmp = SendMessage(hWndListRemote, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
\r
235 Tmp |= LVS_EX_FULLROWSELECT;
\r
236 SendMessage(hWndListRemote, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);
\r
238 if(ListFont != NULL)
\r
239 SendMessage(hWndListRemote, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));
\r
241 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);
\r
242 ShowWindow(hWndListRemote, SW_SHOW);
\r
244 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
245 LvCol.cx = RemoteTabWidth[0];
\r
246 LvCol.pszText = MSGJPN042;
\r
247 LvCol.iSubItem = 0;
\r
248 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);
\r
250 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
251 LvCol.cx = RemoteTabWidth[1];
\r
252 LvCol.pszText = MSGJPN043;
\r
253 LvCol.iSubItem = 1;
\r
254 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);
\r
256 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
\r
257 LvCol.fmt = LVCFMT_RIGHT;
\r
258 LvCol.cx = RemoteTabWidth[2];
\r
259 LvCol.pszText = MSGJPN044;
\r
260 LvCol.iSubItem = 2;
\r
261 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);
\r
263 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
264 LvCol.cx = RemoteTabWidth[3];
\r
265 LvCol.pszText = MSGJPN045;
\r
266 LvCol.iSubItem = 3;
\r
267 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);
\r
269 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
270 LvCol.cx = RemoteTabWidth[4];
\r
271 LvCol.pszText = MSGJPN046;
\r
272 LvCol.iSubItem = 4;
\r
273 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 4, (LPARAM)&LvCol);
\r
275 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
\r
276 LvCol.cx = RemoteTabWidth[5];
\r
277 LvCol.pszText = MSGJPN047;
\r
278 LvCol.iSubItem = 5;
\r
279 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 5, (LPARAM)&LvCol);
\r
282 Sts = FFFTP_SUCCESS;
\r
283 if((hWndListLocal == NULL) ||
\r
284 (hWndListRemote == NULL))
\r
292 /*----- ファイルリストウインドウを削除 ----------------------------------------
\r
299 *----------------------------------------------------------------------------*/
\r
301 void DeleteListWin(void)
\r
303 // if(ListImg != NULL)
\r
304 // ImageList_Destroy(ListImg);
\r
305 if(hWndListLocal != NULL)
\r
306 DestroyWindow(hWndListLocal);
\r
307 if(hWndListRemote != NULL)
\r
308 DestroyWindow(hWndListRemote);
\r
313 /*----- ローカル側のファイルリストのウインドウハンドルを返す ------------------
\r
320 *----------------------------------------------------------------------------*/
\r
322 HWND GetLocalHwnd(void)
\r
324 return(hWndListLocal);
\r
328 /*----- ホスト側のファイルリストのウインドウハンドルを返す --------------------
\r
335 *----------------------------------------------------------------------------*/
\r
337 HWND GetRemoteHwnd(void)
\r
339 return(hWndListRemote);
\r
343 /*----- ローカル側のファイルリストウインドウのメッセージ処理 ------------------
\r
346 * HWND hWnd : ウインドウハンドル
\r
347 * UINT message : メッセージ番号
\r
348 * WPARAM wParam : メッセージの WPARAM 引数
\r
349 * LPARAM lParam : メッセージの LPARAM 引数
\r
353 *----------------------------------------------------------------------------*/
\r
355 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
357 return(FileListCommonWndProc(hWnd, message, wParam, lParam));
\r
361 /*----- ホスト側のファイルリストウインドウのメッセージ処理 --------------------
\r
364 * HWND hWnd : ウインドウハンドル
\r
365 * UINT message : メッセージ番号
\r
366 * WPARAM wParam : メッセージの WPARAM 引数
\r
367 * LPARAM lParam : メッセージの LPARAM 引数
\r
371 *----------------------------------------------------------------------------*/
\r
373 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
375 return(FileListCommonWndProc(hWnd, message, wParam, lParam));
\r
380 static BOOL CALLBACK doOleDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
\r
382 #define TIMER_ID (100) // 作成するタイマの識別ID
\r
383 #define TIMER_ELAPSE (100) // WM_TIMERの発生間隔
\r
387 case WM_INITDIALOG: // ダイアログボックスが作成されたとき
\r
388 SetTimer( hDlg, TIMER_ID, 0, NULL);
\r
392 ShowWindow(hDlg, SW_HIDE); // ダイアログは隠す
\r
394 if (wp != TIMER_ID)
\r
397 if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
\r
398 TranslateMessage(&message);
\r
399 DispatchMessage(&message);
\r
402 if (AskTransferNow() == NO) {
\r
403 EndDialog( hDlg, 0 );
\r
408 SetTimer( hDlg, TIMER_ID, TIMER_ELAPSE, NULL );
\r
411 case WM_COMMAND: // ダイアログボックス内の何かが選択されたとき
\r
412 switch( LOWORD( wp ) ){
\r
413 // case IDOK: // 「OK」ボタンが選択された
\r
414 case IDCANCEL: // 「キャンセル」ボタンが選択された
\r
416 EndDialog( hDlg, 0 );
\r
422 return FALSE; // DefWindowProc()ではなく、FALSEを返すこと!
\r
424 #undef TIMER_ELAPSE
\r
428 static void doTransferRemoteFile(void)
\r
430 FILELIST *FileListBase, *FileListBaseNoExpand, *pf;
\r
431 int CancelFlg = NO;
\r
432 char LocDir[FMAX_PATH+1];
\r
433 char TmpDir[FMAX_PATH+1];
\r
438 // すでにリモートから転送済みなら何もしない。(2007.9.3 yutaka)
\r
439 if (remoteFileListBase != NULL)
\r
442 FileListBase = NULL;
\r
443 MakeSelectedFileList(WIN_REMOTE, YES, NO, &FileListBase, &CancelFlg);
\r
444 FileListBaseNoExpand = NULL;
\r
445 MakeSelectedFileList(WIN_REMOTE, NO, NO, &FileListBaseNoExpand, &CancelFlg);
\r
447 // set temporary folder
\r
448 AskLocalCurDir(LocDir, FMAX_PATH);
\r
450 // アプリを多重起動してもコンフリクトしないように、テンポラリフォルダ名にプロセスID
\r
451 // を付加する。(2007.9.13 yutaka)
\r
452 GetTempPath(sizeof(TmpDir), TmpDir);
\r
453 pid = GetCurrentProcessId();
\r
454 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ffftp%d", pid);
\r
455 strncat_s(TmpDir, sizeof(TmpDir), buf, _TRUNCATE);
\r
458 if (TmpDir[strlen(TmpDir) - 1] == '\\') {
\r
459 TmpDir[strlen(TmpDir) - 1] = '\0';
\r
464 for (pf = FileListBase ; pf ; pf = pf->Next) {
\r
465 char fn[FMAX_PATH+1];
\r
467 strncpy_s(fn, sizeof(fn), TmpDir, _TRUNCATE);
\r
468 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);
\r
469 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);
\r
474 // ダウンロード先をテンポラリに設定
\r
475 SetLocalDirHist(TmpDir);
\r
477 // FFFTPにダウンロード要求を出し、ダウンロードの完了を待つ。
\r
478 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);
\r
480 for (i = 0 ; i < 10 ; i++) {
\r
483 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
\r
484 TranslateMessage(&msg);
\r
485 DispatchMessage(&msg);
\r
488 // 転送スレッドが動き出したら抜ける。
\r
489 if (AskTransferNow() == YES)
\r
496 // OLE D&D中にメインウィンドウをユーザに操作させると、おかしくなるので、
\r
498 // (2007.9.11 yutaka)
\r
499 DialogBox(GetFtpInst(), MAKEINTRESOURCE(IDD_OLEDRAG), GetMainHwnd(), (DLGPROC)doOleDlgProc);
\r
502 SetLocalDirHist(LocDir);
\r
503 SetCurrentDirAsDirHist();
\r
505 remoteFileListBase = FileListBase; // あとでフリーすること
\r
506 remoteFileListBaseNoExpand = FileListBaseNoExpand; // あとでフリーすること
\r
507 strncpy_s(remoteFileDir, sizeof(remoteFileDir), TmpDir, _TRUNCATE);
\r
510 // add temporary list
\r
511 if (remoteFileListBase != NULL) {
\r
512 FILELIST *pf = remoteFileListBase;
\r
513 char fn[FMAX_PATH + 1];
\r
515 strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);
\r
516 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);
\r
517 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);
\r
518 AddTempFileList(fn);
\r
526 int isDirectory(char *fn)
\r
530 if (_stat(fn, &buf) == 0) {
\r
531 if (buf.st_mode & _S_IFDIR) { // is directory
\r
538 // テンポラリのファイルおよびフォルダを削除する。
\r
539 void doDeleteRemoteFile(void)
\r
541 if (remoteFileListBase != NULL) {
\r
545 FILELIST *pf = remoteFileListBase;
\r
546 char fn[FMAX_PATH + 1];
\r
548 strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);
\r
549 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);
\r
550 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);
\r
551 if (isDirectory(fn)) {
\r
560 for (i = 0 ; i < 1000 ; i++) {
\r
561 pf = remoteFileListBase;
\r
563 strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);
\r
564 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);
\r
565 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);
\r
566 if (isDirectory(fn)) {
\r
567 if (_rmdir(fn) == 0) { // ディレクトリを消せたらカウントアップ
\r
569 if (count >= dirs) // すべて消せたら終わり
\r
577 _rmdir(remoteFileDir); // 自分で作ったディレクトリも消す
\r
579 SHFILEOPSTRUCT FileOp = { NULL, FO_DELETE, remoteFileDir, NULL,
\r
580 FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI,
\r
581 FALSE, NULL, NULL };
\r
582 SHFileOperation(&FileOp);
\r
585 DeleteFileList(&remoteFileListBase);
\r
586 remoteFileListBase = NULL;
\r
589 if (remoteFileListBaseNoExpand != NULL) {
\r
590 DeleteFileList(&remoteFileListBaseNoExpand);
\r
591 remoteFileListBaseNoExpand = NULL;
\r
597 // cf. http://www.nakka.com/lib/
\r
599 static HDROP APIPRIVATE CreateDropFileMem(char **FileName,int cnt,BOOL fWide)
\r
602 LPDROPFILES lpDropFile;
\r
603 wchar_t wbuf[BUF_SIZE];
\r
609 for(i = 0;i < cnt;i++){
\r
611 // MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);
\r
612 // flen += (wcslen(wbuf) + 1) * sizeof(wchar_t);
\r
613 flen += sizeof(wchar_t) * MtoW(NULL, 0, FileName[i], -1);
\r
618 for(i = 0;i < cnt;i++){
\r
620 // flen += lstrlen(FileName[i]) + 1;
\r
621 MtoW(wbuf, BUF_SIZE, FileName[i], -1);
\r
622 flen += sizeof(char) * WtoA(NULL, 0, wbuf, -1);
\r
626 hDrop = (HDROP)GlobalAlloc(GHND,sizeof(DROPFILES) + flen + 1);
\r
627 if (hDrop == NULL){
\r
631 lpDropFile = (LPDROPFILES) GlobalLock(hDrop);
\r
632 lpDropFile->pFiles = sizeof(DROPFILES); /* ファイル名のリストまでのオフセット */
\r
633 lpDropFile->pt.x = 0;
\r
634 lpDropFile->pt.y = 0;
\r
635 lpDropFile->fNC = FALSE;
\r
636 lpDropFile->fWide = fWide; /* ワイドキャラの場合は TRUE */
\r
638 /* 構造体の後ろにファイル名のリストをコピーする。(ファイル名\0ファイル名\0ファイル名\0\0) */
\r
643 buf = (wchar_t *)(&lpDropFile[1]);
\r
644 for(i = 0;i < cnt;i++){
\r
646 // MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);
\r
647 // wcscpy(buf,wbuf);
\r
648 // buf += wcslen(wbuf) + 1;
\r
649 buf += MtoW(buf, BUF_SIZE, FileName[i], -1);
\r
655 buf = (char *)(&lpDropFile[1]);
\r
656 for(i = 0;i < cnt;i++){
\r
658 // lstrcpy(buf,FileName[i]);
\r
659 // buf += lstrlen(FileName[i]) + 1;
\r
660 MtoW(wbuf, BUF_SIZE, FileName[i], -1);
\r
661 buf += WtoA(buf, BUF_SIZE, wbuf, -1);
\r
665 GlobalUnlock(hDrop);
\r
671 // (2007.8.30 yutaka)
\r
672 static void doDragDrop(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
678 // テンポラリをきれいにする (2007.9.3 yutaka)
\r
679 doDeleteRemoteFile();
\r
683 cf[1] = CF_HDROP; /* ファイル */
\r
684 if((ret = OLE_IDropSource_Start(hWnd,WM_GETDATA, WM_DRAGOVER, cf,1,DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK)) == DROPEFFECT_MOVE){
\r
687 // ドロップ先のアプリに WM_LBUTTONUP を飛ばす。
\r
689 ScreenToClient(hWnd, &pt);
\r
690 PostMessage(hWnd,WM_LBUTTONUP,0,MAKELPARAM(pt.x,pt.y));
\r
695 /*----- ファイル一覧ウインドウの共通メッセージ処理 ----------------------------
\r
698 * HWND hWnd : ウインドウハンドル
\r
699 * UINT message : メッセージ番号
\r
700 * WPARAM wParam : メッセージの WPARAM 引数
\r
701 * LPARAM lParam : メッセージの LPARAM 引数
\r
705 *----------------------------------------------------------------------------*/
\r
707 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
712 static HCURSOR hCsrDrg;
\r
713 static HCURSOR hCsrNoDrg;
\r
714 static POINT DragPoint;
\r
715 static HWND hWndDragStart;
\r
716 static int RemoteDropFileIndex = -1;
\r
723 hWndDst = hWndListRemote;
\r
724 ProcPtr = LocalProcPtr;
\r
725 hWndHistEdit = GetLocalHistEditHwnd();
\r
726 if(hWnd == hWndListRemote)
\r
729 hWndDst = hWndListLocal;
\r
730 ProcPtr = RemoteProcPtr;
\r
731 hWndHistEdit = GetRemoteHistEditHwnd();
\r
736 case WM_SYSKEYDOWN:
\r
737 if (wParam == 'D') { // Alt+D
\r
738 SetFocus(hWndHistEdit);
\r
741 EraseListViewTips();
\r
742 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
750 EraseListViewTips();
\r
751 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
754 SetFocusHwnd(hWnd);
\r
755 MakeButtonsFocus();
\r
756 DispCurrentWindow(Win);
\r
757 DispSelectedSpace();
\r
758 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
760 case WM_KILLFOCUS :
\r
761 EraseListViewTips();
\r
762 MakeButtonsFocus();
\r
763 DispCurrentWindow(-1);
\r
764 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
766 case WM_DROPFILES :
\r
767 // ドラッグ中は処理しない。ドラッグ後にWM_LBUTTONDOWNが飛んでくるため、そこで処理する。
\r
768 if (Dragging == YES)
\r
771 if(hWnd == hWndListRemote)
\r
773 if(AskConnecting() == YES)
\r
774 UpLoadDragProc(wParam);
\r
776 else if(hWnd == hWndListLocal)
\r
778 ChangeDirDropFileProc(wParam);
\r
782 case WM_LBUTTONDOWN :
\r
783 EraseListViewTips();
\r
785 DragPoint.x = LOWORD(lParam);
\r
786 DragPoint.y = HIWORD(lParam);
\r
787 hWndDragStart = hWnd;
\r
788 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
791 case WM_LBUTTONUP :
\r
792 if(Dragging == YES)
\r
796 hCsrDrg = LoadCursor(NULL, IDC_ARROW);
\r
797 SetCursor(hCsrDrg);
\r
799 Point.x = (long)(short)LOWORD(lParam);
\r
800 Point.y = (long)(short)HIWORD(lParam);
\r
801 ClientToScreen(hWnd, &Point);
\r
802 hWndPnt = WindowFromPoint(Point);
\r
803 if(hWndPnt == hWndDst) // local <-> remote
\r
805 if(hWndPnt == hWndListRemote) {
\r
806 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_UPLOAD, 0), 0);
\r
807 } else if(hWndPnt == hWndListLocal) {
\r
808 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);
\r
810 } else { // 同一ウィンドウ内の場合 (yutaka)
\r
811 if (hWndDragStart == hWndListRemote && hWndPnt == hWndListRemote) {
\r
812 // remote <-> remoteの場合は、サーバでのファイルの移動を行う。(2007.9.5 yutaka)
\r
813 if (RemoteDropFileIndex != -1) {
\r
814 ListView_SetItemState(hWnd, RemoteDropFileIndex, 0, LVIS_DROPHILITED);
\r
815 MoveRemoteFileProc(RemoteDropFileIndex);
\r
822 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
825 // OLE D&Dを開始する (yutaka)
\r
826 doDragDrop(hWnd, message, wParam, lParam);
\r
830 case WM_GETDATA: // ファイルのパスをD&D先のアプリへ返す (yutaka)
\r
833 case CF_HDROP: /* ファイル */
\r
835 OSVERSIONINFO os_info;
\r
836 BOOL NTFlag = FALSE;
\r
837 char **FileNameList;
\r
839 int i, j, filenum = 0;
\r
841 FILELIST *FileListBase, *FileListBaseNoExpand, *pf;
\r
842 int CancelFlg = NO;
\r
843 char LocDir[FMAX_PATH+1];
\r
847 FileListBaseNoExpand = NULL;
\r
848 // ローカル側で選ばれているファイルをFileListBaseに登録
\r
849 if (hWndDragStart == hWndListLocal) {
\r
850 AskLocalCurDir(LocDir, FMAX_PATH);
\r
853 FileListBase = NULL;
\r
854 MakeSelectedFileList(WIN_LOCAL, YES, NO, &FileListBase, &CancelFlg);
\r
856 } else if (hWndDragStart == hWndListRemote) {
\r
857 GetCursorPos(&Point);
\r
858 hWndPnt = WindowFromPoint(Point);
\r
859 hWndParent = GetParent(hWndPnt);
\r
860 if (hWndPnt == hWndListRemote || hWndPnt == hWndListLocal ||
\r
861 hWndParent == hWndListRemote || hWndParent == hWndListLocal) {
\r
862 FileListBase = NULL;
\r
865 // 選択されているリモートファイルのリストアップ
\r
866 // このタイミングでリモートからローカルの一時フォルダへダウンロードする
\r
867 // (2007.8.31 yutaka)
\r
868 doTransferRemoteFile();
\r
869 PathDir = remoteFileDir;
\r
870 FileListBase = remoteFileListBase;
\r
871 FileListBaseNoExpand = remoteFileListBaseNoExpand;
\r
876 pf = FileListBaseNoExpand;
\r
877 for (filenum = 0; pf ; filenum++) {
\r
880 // ファイルが未選択の場合は何もしない。(yutaka)
\r
881 if (filenum <= 0) {
\r
882 *((HANDLE *)lParam) = NULL;
\r
886 /* ファイル名の配列を作成する */
\r
887 // TODO: GlobalAllocが返すのはメモリポインタではなくハンドルだが実際は同じ値
\r
888 FileNameList = (char **)GlobalAlloc(GPTR,sizeof(char *) * filenum);
\r
889 if(FileNameList == NULL){
\r
892 pf = FileListBaseNoExpand;
\r
893 for (j = 0; pf ; j++) {
\r
894 filelen = strlen(PathDir) + 1 + strlen(pf->File) + 1;
\r
895 FileNameList[j] = (char *)GlobalAlloc(GPTR, filelen);
\r
896 strncpy_s(FileNameList[j], filelen, PathDir, _TRUNCATE);
\r
897 strncat_s(FileNameList[j], filelen, "\\", _TRUNCATE);
\r
898 strncat_s(FileNameList[j], filelen, pf->File, _TRUNCATE);
\r
901 if (FileListBase->Node == NODE_DIR) {
\r
902 // フォルダを掴んだ場合はそれ以降展開しない
\r
909 os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
\r
910 GetVersionEx(&os_info);
\r
911 if(os_info.dwPlatformId == VER_PLATFORM_WIN32_NT){
\r
915 /* ドロップファイルリストの作成 */
\r
916 /* NTの場合はUNICODEになるようにする */
\r
917 *((HANDLE *)lParam) = CreateDropFileMem(FileNameList, filenum, NTFlag);
\r
919 /* ファイル名の配列を解放する */
\r
920 for (i = 0; i < filenum ; i++) {
\r
921 GlobalFree(FileNameList[i]);
\r
923 GlobalFree(FileNameList);
\r
925 if (hWndDragStart == hWndListLocal) {
\r
926 DeleteFileList(&FileListBase);
\r
928 // あとでファイル削除してフリーする
\r
936 *((HANDLE *)lParam) = NULL;
\r
946 static int prev_index = -1;
\r
948 // 同一ウィンドウ内でのD&Dはリモート側のみ
\r
949 if (Win != WIN_REMOTE)
\r
952 if(MoveMode == MOVE_DISABLE)
\r
955 memset(&hi, 0, sizeof(hi));
\r
957 GetCursorPos(&Point);
\r
958 hWndPnt = WindowFromPoint(Point);
\r
959 ScreenToClient(hWnd, &Point);
\r
964 ListView_SetItemState(hWnd, prev_index, 0, LVIS_DROPHILITED);
\r
965 RemoteDropFileIndex = -1;
\r
967 if ((hWndPnt == hWndListRemote) && (ListView_HitTest(hWnd, &hi) != -1)) {
\r
968 if (hi.flags == LVHT_ONITEMLABEL) { // The position is over a list-view item's text.
\r
971 prev_index = index;
\r
972 Node = GetNodeType(Win, index);
\r
973 if (Node == NODE_DIR) {
\r
974 ListView_SetItemState(hWnd, index, LVIS_DROPHILITED, LVIS_DROPHILITED);
\r
975 RemoteDropFileIndex = index;
\r
983 case WM_RBUTTONDOWN :
\r
985 CallWindowProc(ProcPtr, hWnd, message, wParam, lParam);
\r
987 EraseListViewTips();
\r
989 if(hWnd == hWndListRemote)
\r
990 RemoteRbuttonMenu(0);
\r
991 else if(hWnd == hWndListLocal)
\r
992 LocalRbuttonMenu(0);
\r
995 case WM_LBUTTONDBLCLK :
\r
996 DoubleClickProc(Win, NO, -1);
\r
999 case WM_MOUSEMOVE :
\r
1000 if(wParam == MK_LBUTTON)
\r
1002 if((Dragging == NO) &&
\r
1003 (hWnd == hWndDragStart) &&
\r
1004 (AskConnecting() == YES) &&
\r
1005 (SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0) > 0) &&
\r
1006 ((abs((short)LOWORD(lParam) - DragPoint.x) > 5) ||
\r
1007 (abs((short)HIWORD(lParam) - DragPoint.y) > 5)))
\r
1011 hCsrDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(drag_csr));
\r
1012 hCsrNoDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(nodrop_csr));
\r
1013 SetCursor(hCsrDrg);
\r
1015 else if(Dragging == YES)
\r
1017 Point.x = (long)(short)LOWORD(lParam);
\r
1018 Point.y = (long)(short)HIWORD(lParam);
\r
1019 ClientToScreen(hWnd, &Point);
\r
1020 hWndPnt = WindowFromPoint(Point);
\r
1021 if((hWndPnt == hWndListRemote) || (hWndPnt == hWndListLocal))
\r
1022 SetCursor(hCsrDrg);
\r
1024 // マウスポインタの×表示をやめる (yutaka)
\r
1026 SetCursor(hCsrNoDrg);
\r
1030 // OLE D&Dの開始を指示する
\r
1031 PostMessage(hWnd, WM_DRAGDROP, MAKEWPARAM(wParam, lParam), 0);
\r
1035 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
1039 CheckTipsDisplay(hWnd, lParam);
\r
1040 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
1044 case WM_MOUSEWHEEL :
\r
1045 if(Dragging == NO)
\r
1047 short zDelta = (short)HIWORD(wParam);
\r
1049 EraseListViewTips();
\r
1050 Point.x = (short)LOWORD(lParam);
\r
1051 Point.y = (short)HIWORD(lParam);
\r
1052 hWndPnt = WindowFromPoint(Point);
\r
1054 if((wParam & MAKEWPARAM(MK_SHIFT, 0)) &&
\r
1055 ((hWndPnt == hWndListRemote) ||
\r
1056 (hWndPnt == hWndListLocal) ||
\r
1057 (hWndPnt == GetTaskWnd())))
\r
1059 PostMessage(hWndPnt, WM_VSCROLL, zDelta > 0 ? MAKEWPARAM(SB_PAGEUP, 0) : MAKEWPARAM(SB_PAGEDOWN, 0), 0);
\r
1060 // PostMessage(hWndPnt, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, 0), 0);
\r
1062 else if(hWndPnt == hWnd)
\r
1063 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
1064 else if((hWndPnt == hWndDst) || (hWndPnt == GetTaskWnd()))
\r
1065 PostMessage(hWndPnt, message, wParam, lParam);
\r
1070 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));
\r
1076 /*----- ファイルリストのタブ幅を取得する --------------------------------------
\r
1083 *----------------------------------------------------------------------------*/
\r
1085 void GetListTabWidth(void)
\r
1090 for(i = 0; i <= 3; i++)
\r
1092 LvCol.mask = LVCF_WIDTH;
\r
1093 if(SendMessage(hWndListLocal, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)
\r
1094 LocalTabWidth[i] = LvCol.cx;
\r
1097 for(i = 0; i <= 5; i++)
\r
1099 LvCol.mask = LVCF_WIDTH;
\r
1100 if(SendMessage(hWndListRemote, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)
\r
1101 RemoteTabWidth[i] = LvCol.cx;
\r
1107 /*----- ファイル一覧方法にしたがってリストビューを設定する --------------------
\r
1114 *----------------------------------------------------------------------------*/
\r
1116 void SetListViewType(void)
\r
1123 lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);
\r
1124 lStyle &= ~(LVS_REPORT | LVS_LIST);
\r
1125 lStyle |= LVS_LIST;
\r
1126 SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);
\r
1128 lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);
\r
1129 lStyle &= ~(LVS_REPORT | LVS_LIST);
\r
1130 lStyle |= LVS_LIST;
\r
1131 SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);
\r
1135 lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);
\r
1136 lStyle &= ~(LVS_REPORT | LVS_LIST);
\r
1137 lStyle |= LVS_REPORT;
\r
1138 SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);
\r
1140 lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);
\r
1141 lStyle &= ~(LVS_REPORT | LVS_LIST);
\r
1142 lStyle |= LVS_REPORT;
\r
1143 SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);
\r
1150 /*----- ホスト側のファイル一覧ウインドウにファイル名をセット ------------------
\r
1153 * int Mode : キャッシュモード (CACHE_xxx)
\r
1157 *----------------------------------------------------------------------------*/
\r
1159 void GetRemoteDirForWnd(int Mode, int *CancelCheckWork)
\r
1163 char Str[FMAX_PATH+1];
\r
1164 char Buf[FMAX_PATH+1];
\r
1170 FLISTANCHOR Anchor;
\r
1171 char Owner[OWNER_NAME_LEN+1];
\r
1176 //DoPrintf("===== GetRemoteDirForWnd");
\r
1178 Anchor.Top = NULL;
\r
1181 if(AskConnecting() == YES)
\r
1183 // SetCursor(LoadCursor(NULL, IDC_WAIT));
\r
1186 AskRemoteCurDir(Buf, FMAX_PATH);
\r
1187 SetRemoteDirHist(Buf);
\r
1189 Type = FTP_COMPLETE;
\r
1190 if(Mode != CACHE_LASTREAD)
\r
1193 if((Num = AskCached(Buf)) == -1)
\r
1195 Num = AskFreeCache();
\r
1196 Mode = CACHE_REFRESH;
\r
1199 if(Mode == CACHE_REFRESH)
\r
1201 if((Type = DoDirListCmdSkt("", "", Num, CancelCheckWork)) == FTP_COMPLETE)
\r
1202 SetCache(Num, Buf);
\r
1208 Num = AskCurrentFileListNum();
\r
1210 if(Type == FTP_COMPLETE)
\r
1212 SetCurrentFileListNum(Num);
\r
1213 MakeCacheFileName(Num, Buf);
\r
1214 if((fd = fopen(Buf, "rb"))!=NULL)
\r
1216 ListType = LIST_UNKNOWN;
\r
1218 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)
\r
1220 if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)
\r
1222 if((Type = ResolvFileInfo(Str, ListType, Buf, &Size, &Time, &Attr, Owner, &Link, &InfoExist)) != NODE_NONE)
\r
1224 if(AskFilterStr(Buf, Type) == YES)
\r
1226 if((DotFile == YES) || (Buf[0] != '.'))
\r
1228 AddDispFileList(&Anchor, Buf, &Time, Size, Attr, Type, Link, Owner, InfoExist, WIN_REMOTE);
\r
1236 DispFileList2View(GetRemoteHwnd(), &Anchor);
\r
1237 EraseDispFileList(&Anchor);
\r
1240 ListView_SetItemState(GetRemoteHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);
\r
1244 SetTaskMsg(MSGJPN048);
\r
1245 SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);
\r
1250 #if defined(HAVE_OPENVMS)
\r
1251 /* OpenVMSの場合空ディレクトリ移動の時に出るので、メッセージだけ出さない
\r
1252 * ようにする(VIEWはクリアして良い) */
\r
1253 if (AskHostType() != HTYPE_VMS)
\r
1255 SetTaskMsg(MSGJPN049);
\r
1256 SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);
\r
1259 // SetCursor(LoadCursor(NULL, IDC_ARROW));
\r
1265 //DoPrintf("===== GetRemoteDirForWnd Done");
\r
1271 /*----- ローカル側のファイル一覧ウインドウにファイル名をセット ----------------
\r
1278 *----------------------------------------------------------------------------*/
\r
1280 void GetLocalDirForWnd(void)
\r
1283 WIN32_FIND_DATA Find;
\r
1284 char Scan[FMAX_PATH+1];
\r
1288 FLISTANCHOR Anchor;
\r
1292 Anchor.Top = NULL;
\r
1296 SetLocalDirHist(Scan);
\r
1297 DispLocalFreeSpace(Scan);
\r
1302 strcat(Scan, "*");
\r
1303 if((fHnd = FindFirstFileAttr(Scan, &Find, DispIgnoreHide)) != INVALID_HANDLE_VALUE)
\r
1307 if((strcmp(Find.cFileName, ".") != 0) &&
\r
1308 (strcmp(Find.cFileName, "..") != 0))
\r
1310 if((DotFile == YES) || (Find.cFileName[0] != '.'))
\r
1312 if(Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
\r
1313 AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_DIR, NO, "", FINFO_ALL, WIN_LOCAL);
\r
1316 if(AskFilterStr(Find.cFileName, NODE_FILE) == YES)
\r
1318 AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_FILE, NO, "", FINFO_ALL, WIN_LOCAL);
\r
1324 while(FindNextFileAttr(fHnd, &Find, DispIgnoreHide) == TRUE);
\r
1331 GetLogicalDriveStrings(FMAX_PATH, Scan);
\r
1332 NoDrives = LoadHideDriveListRegistory();
\r
1335 while(*Pos != NUL)
\r
1337 Tmp = toupper(*Pos) - 'A';
\r
1338 if((NoDrives & (0x00000001 << Tmp)) == 0)
\r
1340 sprintf(Buf, "%s", Pos);
\r
1341 memset(&Time, 0, sizeof(FILETIME));
\r
1342 AddDispFileList(&Anchor, Buf, &Time, 0, 0, NODE_DRIVE, NO, "", FINFO_ALL, WIN_LOCAL);
\r
1344 Pos = strchr(Pos, NUL) + 1;
\r
1348 DispFileList2View(GetLocalHwnd(), &Anchor);
\r
1349 EraseDispFileList(&Anchor);
\r
1352 ListView_SetItemState(GetLocalHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);
\r
1358 /*----- ファイル情報をファイル一覧用リストに登録する --------------------------
\r
1361 * FLISTANCHOR *Anchor : ファイルリストの先頭
\r
1362 * char *Name : ファイル名
\r
1363 * FILETIME *Time : 日付
\r
1364 * LONGLONG Size : サイズ
\r
1366 * int Type : タイプ (NODE_xxxx)
\r
1367 * int Link : リンクかどうか (YES/NO)
\r
1368 * char *Owner : オーナ名
\r
1369 * int InfoExist : 情報があるかどうか (FINFO_xxx)
\r
1370 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
1374 *----------------------------------------------------------------------------*/
\r
1376 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win)
\r
1387 FileSort = AskSortType(ITEM_LFILE);
\r
1388 DirSort = AskSortType(ITEM_LDIR);
\r
1389 if(Win == WIN_REMOTE)
\r
1391 FileSort = AskSortType(ITEM_RFILE);
\r
1392 DirSort = AskSortType(ITEM_RDIR);
\r
1395 Pos = Anchor->Top;
\r
1396 for(i = 0; i < Anchor->Files; i++)
\r
1398 if((Type == NODE_DIR) && (Pos->Node == NODE_FILE))
\r
1400 if((Type == NODE_FILE) && (Pos->Node == NODE_DRIVE))
\r
1403 if(Type == Pos->Node)
\r
1405 if(Type == NODE_DIR)
\r
1410 if((Sort & SORT_GET_ORD) == SORT_ASCENT)
\r
1412 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&
\r
1413 ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) < 0)) ||
\r
1414 (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&
\r
1415 ((Cmp = Size - Pos->Size) < 0)) ||
\r
1416 (((Sort & SORT_MASK_ORD) == SORT_DATE) &&
\r
1417 ((Cmp = CompareFileTime(Time, &Pos->Time)) < 0)))
\r
1422 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))
\r
1424 if(_mbsicmp(Name, Pos->File) < 0)
\r
1430 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&
\r
1431 ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) > 0)) ||
\r
1432 (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&
\r
1433 ((Cmp = Size - Pos->Size) > 0)) ||
\r
1434 (((Sort & SORT_MASK_ORD) == SORT_DATE) &&
\r
1435 ((Cmp = CompareFileTime(Time, &Pos->Time)) > 0)))
\r
1440 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))
\r
1442 if(_mbsicmp(Name, Pos->File) > 0)
\r
1451 if((New = malloc(sizeof(FILELIST))) != NULL)
\r
1453 strcpy(New->File, Name);
\r
1458 New->Time = *Time;
\r
1459 strcpy(New->Owner, Owner);
\r
1460 New->InfoExist = InfoExist;
\r
1462 if(Pos == Anchor->Top)
\r
1464 New->Next = Anchor->Top;
\r
1465 Anchor->Top = New;
\r
1469 New->Next = Prev->Next;
\r
1472 Anchor->Files += 1;
\r
1478 /*----- ファイル一覧用リストをクリアする --------------------------------------
\r
1481 * FLISTANCHOR *Anchor : ファイルリストの先頭
\r
1485 *----------------------------------------------------------------------------*/
\r
1487 static void EraseDispFileList(FLISTANCHOR *Anchor)
\r
1493 Pos = Anchor->Top;
\r
1494 for(i = 0; i < Anchor->Files; i++)
\r
1500 Anchor->Files = 0;
\r
1501 Anchor->Top = NULL;
\r
1506 /*----- ファイル一覧用リストの内容をファイル一覧ウインドウにセット ------------
\r
1509 * HWND hWnd : ウインドウハンドル
\r
1510 * FLISTANCHOR *Anchor : ファイルリストの先頭
\r
1514 *----------------------------------------------------------------------------*/
\r
1516 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor)
\r
1521 SendMessage(hWnd, WM_SETREDRAW, (WPARAM)FALSE, 0);
\r
1522 SendMessage(hWnd, LVM_DELETEALLITEMS, 0, 0);
\r
1524 Pos = Anchor->Top;
\r
1525 for(i = 0; i < Anchor->Files; i++)
\r
1527 AddListView(hWnd, -1, Pos->File, Pos->Node, Pos->Size, &Pos->Time, Pos->Attr, Pos->Owner, Pos->Link, Pos->InfoExist);
\r
1531 SendMessage(hWnd, WM_SETREDRAW, (WPARAM)TRUE, 0);
\r
1532 UpdateWindow(hWnd);
\r
1534 DispSelectedSpace();
\r
1539 /*----- ファイル一覧ウインドウ(リストビュー)に追加 --------------------------
\r
1542 * HWND hWnd : ウインドウハンドル
\r
1545 * int Type : タイプ (NIDE_xxxx)
\r
1546 * LONGLONG Size : サイズ
\r
1547 * FILETIME *Time : 日付
\r
1549 * char Owner : オーナ名
\r
1550 * int Link : リンクかどうか
\r
1551 * int InfoExist : 情報があるかどうか (FINFO_xxx)
\r
1555 *----------------------------------------------------------------------------*/
\r
1557 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist)
\r
1563 Pos = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);
\r
1566 LvItem.mask = LVIF_TEXT | LVIF_IMAGE;
\r
1567 LvItem.iItem = Pos;
\r
1568 LvItem.iSubItem = 0;
\r
1569 LvItem.pszText = Name;
\r
1570 if((Type == NODE_FILE) && (AskTransferTypeAssoc(Name, TYPE_X) == TYPE_I))
\r
1573 LvItem.iImage = Type;
\r
1575 LvItem.iImage = 4;
\r
1576 LvItem.iItem = SendMessage(hWnd, LVM_INSERTITEM, 0, (LPARAM)&LvItem);
\r
1579 FileTime2TimeString(Time, Tmp, DISPFORM_LEGACY, InfoExist);
\r
1580 LvItem.mask = LVIF_TEXT;
\r
1581 LvItem.iItem = Pos;
\r
1582 LvItem.iSubItem = 1;
\r
1583 LvItem.pszText = Tmp;
\r
1584 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);
\r
1587 if(Type == NODE_DIR)
\r
1588 strcpy(Tmp, "<DIR>");
\r
1589 else if(Type == NODE_DRIVE)
\r
1590 strcpy(Tmp, "<DRIVE>");
\r
1591 else if(Size >= 0)
\r
1592 MakeNumString(Size, Tmp, TRUE);
\r
1595 LvItem.mask = LVIF_TEXT;
\r
1596 LvItem.iItem = Pos;
\r
1597 LvItem.iSubItem = 2;
\r
1598 LvItem.pszText = Tmp;
\r
1599 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);
\r
1602 LvItem.mask = LVIF_TEXT;
\r
1603 LvItem.iItem = Pos;
\r
1604 LvItem.iSubItem = 3;
\r
1605 LvItem.pszText = GetFileExt(Name);
\r
1606 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);
\r
1608 if(hWnd == GetRemoteHwnd())
\r
1612 if(InfoExist & FINFO_ATTR)
\r
1613 AttrValue2String(Attr, Tmp);
\r
1614 LvItem.mask = LVIF_TEXT;
\r
1615 LvItem.iItem = Pos;
\r
1616 LvItem.iSubItem = 4;
\r
1617 LvItem.pszText = Tmp;
\r
1618 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);
\r
1621 LvItem.mask = LVIF_TEXT;
\r
1622 LvItem.iItem = Pos;
\r
1623 LvItem.iSubItem = 5;
\r
1624 LvItem.pszText = Owner;
\r
1625 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);
\r
1631 /*----- ファイル名一覧ウインドウをソートし直す --------------------------------
\r
1634 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
1638 *----------------------------------------------------------------------------*/
\r
1640 void ReSortDispList(int Win, int *CancelCheckWork)
\r
1642 if(Win == WIN_REMOTE)
\r
1643 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);
\r
1645 GetLocalDirForWnd();
\r
1650 /*----- ファイル一覧ウインドウのファイルを選択する ----------------------------
\r
1653 * HWND hWnd : ウインドウハンドル
\r
1654 * int Type : 選択方法 (SELECT_xxx)
\r
1658 *----------------------------------------------------------------------------*/
\r
1660 void SelectFileInList(HWND hWnd, int Type)
\r
1666 char RegExp[FMAX_PATH+1];
\r
1667 char Name[FMAX_PATH+1];
\r
1675 WinDst = WIN_REMOTE;
\r
1676 if(hWnd == GetRemoteHwnd())
\r
1679 WinDst = WIN_LOCAL;
\r
1682 Num = GetItemCount(Win);
\r
1687 if(GetSelectedCount(Win) <= 1)
\r
1688 LvItem.state = LVIS_SELECTED;
\r
1689 for(i = 0; i < Num; i++)
\r
1691 if(GetNodeType(Win, i) != NODE_DRIVE)
\r
1693 LvItem.mask = LVIF_STATE;
\r
1695 LvItem.stateMask = LVIS_SELECTED;
\r
1696 LvItem.iSubItem = 0;
\r
1697 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);
\r
1702 case SELECT_REGEXP :
\r
1703 if(((Win == WIN_LOCAL) &&
\r
1704 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_local_dlg), hWnd, SelectDialogCallBack) == YES)) ||
\r
1705 ((Win == WIN_REMOTE) &&
\r
1706 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_remote_dlg), hWnd, SelectDialogCallBack) == YES)))
\r
1708 strcpy(RegExp, FindStr);
\r
1709 // if(FindMode == 0)
\r
1710 // WildCard2RegExp(RegExp);
\r
1713 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))
\r
1716 for(i = 0; i < Num; i++)
\r
1718 GetNodeName(Win, i, Name, FMAX_PATH);
\r
1719 Find = FindNameNode(WinDst, Name);
\r
1723 if(GetNodeType(Win, i) != NODE_DRIVE)
\r
1725 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||
\r
1726 ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))
\r
1728 LvItem.state = LVIS_SELECTED;
\r
1732 if(IgnoreExist == YES)
\r
1735 if((LvItem.state != 0) && (IgnoreNew == YES))
\r
1737 GetNodeTime(Win, i, &Time1);
\r
1738 GetNodeTime(WinDst, Find, &Time2);
\r
1739 if(CompareFileTime(&Time1, &Time2) > 0)
\r
1743 if((LvItem.state != 0) && (IgnoreOld == YES))
\r
1745 GetNodeTime(Win, i, &Time1);
\r
1746 GetNodeTime(WinDst, Find, &Time2);
\r
1747 if(CompareFileTime(&Time1, &Time2) < 0)
\r
1754 if((LvItem.state != 0) && (CsrPos == -1))
\r
1757 LvItem.mask = LVIF_STATE;
\r
1759 LvItem.stateMask = LVIS_SELECTED;
\r
1760 LvItem.iSubItem = 0;
\r
1761 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);
\r
1765 LvItem.mask = LVIF_STATE;
\r
1766 LvItem.iItem = CsrPos;
\r
1767 LvItem.state = LVIS_FOCUSED;
\r
1768 LvItem.stateMask = LVIS_FOCUSED;
\r
1769 LvItem.iSubItem = 0;
\r
1770 SendMessage(hWnd, LVM_SETITEMSTATE, CsrPos, (LPARAM)&LvItem);
\r
1771 SendMessage(hWnd, LVM_ENSUREVISIBLE, CsrPos, (LPARAM)TRUE);
\r
1781 /*----- 選択ダイアログのコールバック ------------------------------------------
\r
1784 * HWND hDlg : ウインドウハンドル
\r
1785 * UINT message : メッセージ番号
\r
1786 * WPARAM wParam : メッセージの WPARAM 引数
\r
1787 * LPARAM lParam : メッセージの LPARAM 引数
\r
1791 *----------------------------------------------------------------------------*/
\r
1793 static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
\r
1797 case WM_INITDIALOG :
\r
1798 SendDlgItemMessage(hDlg, SEL_FNAME, EM_LIMITTEXT, 40, 0);
\r
1799 SendDlgItemMessage(hDlg, SEL_FNAME, WM_SETTEXT, 0, (LPARAM)FindStr);
\r
1800 SendDlgItemMessage(hDlg, SEL_REGEXP, BM_SETCHECK, FindMode, 0);
\r
1801 SendDlgItemMessage(hDlg, SEL_NOOLD, BM_SETCHECK, IgnoreOld, 0);
\r
1802 SendDlgItemMessage(hDlg, SEL_NONEW, BM_SETCHECK, IgnoreNew, 0);
\r
1803 SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_SETCHECK, IgnoreExist, 0);
\r
1807 switch(GET_WM_COMMAND_ID(wParam, lParam))
\r
1810 SendDlgItemMessage(hDlg, SEL_FNAME, WM_GETTEXT, 40+1, (LPARAM)FindStr);
\r
1811 FindMode = SendDlgItemMessage(hDlg, SEL_REGEXP, BM_GETCHECK, 0, 0);
\r
1812 IgnoreOld = SendDlgItemMessage(hDlg, SEL_NOOLD, BM_GETCHECK, 0, 0);
\r
1813 IgnoreNew = SendDlgItemMessage(hDlg, SEL_NONEW, BM_GETCHECK, 0, 0);
\r
1814 IgnoreExist = SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_GETCHECK, 0, 0);
\r
1815 EndDialog(hDlg, YES);
\r
1819 EndDialog(hDlg, NO);
\r
1823 hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000061);
\r
1832 /*----- ファイル一覧ウインドウのファイルを検索する ----------------------------
\r
1835 * HWND hWnd : ウインドウハンドル
\r
1836 * int Type : 検索方法 (FIND_xxx)
\r
1840 *----------------------------------------------------------------------------*/
\r
1842 void FindFileInList(HWND hWnd, int Type)
\r
1847 static char RegExp[FMAX_PATH+1] = { "" };
\r
1848 char Name[FMAX_PATH+1];
\r
1853 Title = MSGJPN050;
\r
1854 if(hWnd == GetRemoteHwnd())
\r
1857 Title = MSGJPN051;
\r
1860 Num = GetItemCount(Win);
\r
1864 if(InputDialogBox(find_dlg, hWnd, Title, FindStr, 40+1, &FindMode, IDH_HELP_TOPIC_0000001) == YES)
\r
1866 strcpy(RegExp, FindStr);
\r
1867 // if(FindMode == 0)
\r
1868 // WildCard2RegExp(RegExp);
\r
1871 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))
\r
1873 for(i = GetCurrentItem(Win)+1; i < Num; i++)
\r
1875 GetNodeName(Win, i, Name, FMAX_PATH);
\r
1879 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||
\r
1880 ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))
\r
1882 LvItem.mask = LVIF_STATE;
\r
1884 LvItem.state = LVIS_FOCUSED;
\r
1885 LvItem.stateMask = LVIS_FOCUSED;
\r
1886 LvItem.iSubItem = 0;
\r
1887 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);
\r
1888 SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);
\r
1897 for(i = GetCurrentItem(Win)+1; i < Num; i++)
\r
1899 GetNodeName(Win, i, Name, FMAX_PATH);
\r
1903 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||
\r
1904 ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))
\r
1906 LvItem.mask = LVIF_STATE;
\r
1908 LvItem.state = LVIS_FOCUSED;
\r
1909 LvItem.stateMask = LVIS_FOCUSED;
\r
1910 LvItem.iSubItem = 0;
\r
1911 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);
\r
1912 SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);
\r
1923 /*----- ワイルドカードを正規表現に変換する ------------------------------------
\r
1930 *----------------------------------------------------------------------------*/
\r
1932 void WildCard2RegExp(char *Str)
\r
1934 char Tmp[FMAX_PATH+1];
\r
1944 while(*Str != NUL)
\r
1946 if(Pos >= Tmp + FMAX_PATH - 3)
\r
1949 Ch = _mbsnextc(Str);
\r
1950 Str = _mbsinc(Str);
\r
1954 if(strchr("[]()^$.+", Ch) != NULL)
\r
1959 else if(Ch == '*')
\r
1964 else if(Ch == '?')
\r
1966 else if(Ch == '|')
\r
1975 _mbsnset(Pos, Ch, 1);
\r
1976 Pos = _mbsinc(Pos);
\r
1989 /*----- カーソル位置のアイテム番号を返す --------------------------------------
\r
1992 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
1996 *----------------------------------------------------------------------------*/
\r
1998 int GetCurrentItem(int Win)
\r
2003 hWnd = GetLocalHwnd();
\r
2004 if(Win == WIN_REMOTE)
\r
2005 hWnd = GetRemoteHwnd();
\r
2007 if((Ret = SendMessage(hWnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_FOCUSED, 0))) == -1)
\r
2014 /*----- アイテム数を返す ------------------------------------------------------
\r
2017 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
2021 *----------------------------------------------------------------------------*/
\r
2023 int GetItemCount(int Win)
\r
2027 hWnd = GetLocalHwnd();
\r
2028 if(Win == WIN_REMOTE)
\r
2029 hWnd = GetRemoteHwnd();
\r
2031 return(SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0));
\r
2035 /*----- 選択されているアイテム数を返す ----------------------------------------
\r
2038 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
2041 * int 選択されているアイテム数
\r
2042 *----------------------------------------------------------------------------*/
\r
2044 int GetSelectedCount(int Win)
\r
2048 hWnd = GetLocalHwnd();
\r
2049 if(Win == WIN_REMOTE)
\r
2050 hWnd = GetRemoteHwnd();
\r
2052 return(SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0));
\r
2056 /*----- 選択されている最初のアイテム番号を返す --------------------------------
\r
2059 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
2060 * int All : 選ばれていないものを含める
\r
2065 *----------------------------------------------------------------------------*/
\r
2067 int GetFirstSelected(int Win, int All)
\r
2072 hWnd = GetLocalHwnd();
\r
2073 if(Win == WIN_REMOTE)
\r
2074 hWnd = GetRemoteHwnd();
\r
2076 Ope = LVNI_SELECTED;
\r
2080 return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)MAKELPARAM(Ope, 0)));
\r
2084 /*----- 選択されている次のアイテム番号を返す ----------------------------------
\r
2087 * int Win : ウィンドウ番号 (WIN_xxxx)
\r
2088 * int Pos : 今のアイテム番号
\r
2089 * int All : 選ばれていないものも含める
\r
2094 *----------------------------------------------------------------------------*/
\r
2096 int GetNextSelected(int Win, int Pos, int All)
\r
2101 hWnd = GetLocalHwnd();
\r
2102 if(Win == WIN_REMOTE)
\r
2103 hWnd = GetRemoteHwnd();
\r
2105 Ope = LVNI_SELECTED;
\r
2109 return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)Pos, (LPARAM)MAKELPARAM(Ope, 0)));
\r
2113 /*----- 指定された名前のアイテムを探す ----------------------------------------
\r
2116 * int Win : ウインドウ番号 (WIN_xxx)
\r
2122 *----------------------------------------------------------------------------*/
\r
2124 int FindNameNode(int Win, char *Name)
\r
2126 LV_FINDINFO FindInfo;
\r
2129 hWnd = GetLocalHwnd();
\r
2130 if(Win == WIN_REMOTE)
\r
2131 hWnd = GetRemoteHwnd();
\r
2133 FindInfo.flags = LVFI_STRING;
\r
2134 FindInfo.psz = Name;
\r
2135 return(SendMessage(hWnd, LVM_FINDITEM, -1, (LPARAM)&FindInfo));
\r
2139 /*----- 指定位置のアイテムの名前を返す ----------------------------------------
\r
2142 * int Win : ウインドウ番号 (WIN_xxx)
\r
2144 * char *Buf : 名前を返すバッファ
\r
2145 * int Max : バッファのサイズ
\r
2149 *----------------------------------------------------------------------------*/
\r
2151 void GetNodeName(int Win, int Pos, char *Buf, int Max)
\r
2156 hWnd = GetLocalHwnd();
\r
2157 if(Win == WIN_REMOTE)
\r
2158 hWnd = GetRemoteHwnd();
\r
2160 LvItem.mask = LVIF_TEXT;
\r
2161 LvItem.iItem = Pos;
\r
2162 LvItem.iSubItem = 0;
\r
2163 LvItem.pszText = Buf;
\r
2164 LvItem.cchTextMax = Max;
\r
2165 SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);
\r
2170 /*----- 指定位置のアイテムの日付を返す ----------------------------------------
\r
2173 * int Win : ウインドウ番号 (WIN_xxx)
\r
2175 * FILETIME *Buf : 日付を返すバッファ
\r
2179 * YES/NO=日付情報がなかった
\r
2180 *----------------------------------------------------------------------------*/
\r
2182 int GetNodeTime(int Win, int Pos, FILETIME *Buf)
\r
2189 hWnd = GetLocalHwnd();
\r
2190 if(Win == WIN_REMOTE)
\r
2191 hWnd = GetRemoteHwnd();
\r
2193 LvItem.mask = LVIF_TEXT;
\r
2194 LvItem.iItem = Pos;
\r
2195 LvItem.iSubItem = 1;
\r
2196 LvItem.pszText = Tmp;
\r
2197 LvItem.cchTextMax = 20;
\r
2198 SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);
\r
2199 Ret = TimeString2FileTime(Tmp, Buf);
\r
2204 /*----- 指定位置のアイテムのサイズを返す --------------------------------------
\r
2207 * int Win : ウインドウ番号 (WIN_xxx)
\r
2209 * int *Buf : サイズを返すワーク
\r
2213 * YES/NO=サイズ情報がなかった
\r
2214 *----------------------------------------------------------------------------*/
\r
2216 int GetNodeSize(int Win, int Pos, LONGLONG *Buf)
\r
2223 hWnd = GetLocalHwnd();
\r
2224 if(Win == WIN_REMOTE)
\r
2225 hWnd = GetRemoteHwnd();
\r
2227 LvItem.mask = LVIF_TEXT;
\r
2228 LvItem.iItem = Pos;
\r
2229 LvItem.iSubItem = 2;
\r
2230 LvItem.pszText = Tmp;
\r
2231 LvItem.cchTextMax = 20;
\r
2232 SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);
\r
2235 if(strlen(Tmp) > 0)
\r
2238 *Buf = _atoi64(Tmp);
\r
2245 /*----- 指定位置のアイテムの属性を返す ----------------------------------------
\r
2248 * int Win : ウインドウ番号 (WIN_xxx)
\r
2250 * int *Buf : 属性を返すワーク
\r
2254 * YES/NO=サイズ情報がなかった
\r
2255 *----------------------------------------------------------------------------*/
\r
2257 int GetNodeAttr(int Win, int Pos, int *Buf)
\r
2265 if(Win == WIN_REMOTE)
\r
2267 LvItem.mask = LVIF_TEXT;
\r
2268 LvItem.iItem = Pos;
\r
2269 LvItem.iSubItem = 4;
\r
2270 LvItem.pszText = Tmp;
\r
2271 LvItem.cchTextMax = 20;
\r
2272 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);
\r
2273 if(strlen(Tmp) > 0)
\r
2275 *Buf = AttrString2Value(Tmp);
\r
2283 /*----- 指定位置のアイテムのタイプを返す --------------------------------------
\r
2286 * int Win : ウインドウ番号 (WIN_xxx)
\r
2290 * int タイプ (NODE_xxx)
\r
2291 *----------------------------------------------------------------------------*/
\r
2293 int GetNodeType(int Win, int Pos)
\r
2300 hWnd = GetLocalHwnd();
\r
2301 if(Win == WIN_REMOTE)
\r
2302 hWnd = GetRemoteHwnd();
\r
2304 LvItem.mask = LVIF_TEXT;
\r
2305 LvItem.iItem = Pos;
\r
2306 LvItem.iSubItem = 2;
\r
2307 LvItem.pszText = Tmp;
\r
2308 LvItem.cchTextMax = 20;
\r
2309 SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);
\r
2311 if(strcmp(Tmp, "<DIR>") == 0)
\r
2313 else if(strcmp(Tmp, "<DRIVE>") == 0)
\r
2322 /*----- 指定位置のアイテムのオーナ名を返す ------------------------------------
\r
2325 * int Win : ウインドウ番号 (WIN_xxx)
\r
2327 * char *Buf : オーナ名を返すバッファ
\r
2328 * int Max : バッファのサイズ
\r
2332 *----------------------------------------------------------------------------*/
\r
2334 void GetNodeOwner(int Win, int Pos, char *Buf, int Max)
\r
2339 if(Win == WIN_REMOTE)
\r
2341 LvItem.mask = LVIF_TEXT;
\r
2342 LvItem.iItem = Pos;
\r
2343 LvItem.iSubItem = 5;
\r
2344 LvItem.pszText = Buf;
\r
2345 LvItem.cchTextMax = Max;
\r
2346 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);
\r
2352 /*----- ホスト側のファイル一覧ウインドウをクリア ------------------------------
\r
2359 *----------------------------------------------------------------------------*/
\r
2361 void EraseRemoteDirForWnd(void)
\r
2363 SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);
\r
2364 SendMessage(GetRemoteHistHwnd(), CB_RESETCONTENT, 0, 0);
\r
2369 /*----- 選択されているファイルの総サイズを返す --------------------------------
\r
2372 * int Win : ウインドウ番号 (WIN_xxx)
\r
2376 *----------------------------------------------------------------------------*/
\r
2378 double GetSelectedTotalSize(int Win)
\r
2385 if(GetSelectedCount(Win) > 0)
\r
2387 Pos = GetFirstSelected(Win, NO);
\r
2390 GetNodeSize(Win, Pos, &Size);
\r
2393 Pos = GetNextSelected(Win, Pos, NO);
\r
2401 /*===================================================================
\r
2403 ===================================================================*/
\r
2407 /*----- ファイル一覧で選ばれているファイルをリストに登録する ------------------
\r
2410 * int Win : ウインドウ番号 (WIN_xxx)
\r
2411 * int Expand : サブディレクトリを展開する (YES/NO)
\r
2412 * int All : 選ばれていないものもすべて登録する (YES/NO)
\r
2413 * FILELIST **Base : ファイルリストの先頭
\r
2417 *----------------------------------------------------------------------------*/
\r
2419 void MakeSelectedFileList(int Win, int Expand, int All, FILELIST **Base, int *CancelCheckWork)
\r
2422 char Name[FMAX_PATH+1];
\r
2423 char Cur[FMAX_PATH+1];
\r
2429 if((All == YES) || (GetSelectedCount(Win) > 0))
\r
2431 /*===== カレントディレクトリのファイル =====*/
\r
2433 Pos = GetFirstSelected(Win, All);
\r
2436 Node = GetNodeType(Win, Pos);
\r
2437 if((Node == NODE_FILE) ||
\r
2438 ((Expand == NO) && (Node == NODE_DIR)))
\r
2440 Pkt.InfoExist = 0;
\r
2441 GetNodeName(Win, Pos, Pkt.File, FMAX_PATH);
\r
2442 if(GetNodeSize(Win, Pos, &Pkt.Size) == YES)
\r
2443 Pkt.InfoExist |= FINFO_SIZE;
\r
2444 if(GetNodeAttr(Win, Pos, &Pkt.Attr) == YES)
\r
2445 Pkt.InfoExist |= FINFO_ATTR;
\r
2446 if(GetNodeTime(Win, Pos, &Pkt.Time) == YES)
\r
2447 Pkt.InfoExist |= (FINFO_TIME | FINFO_DATE);
\r
2451 if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))
\r
2453 AskLocalCurDir(Cur, FMAX_PATH);
\r
2455 strcat(Cur, Pkt.File);
\r
2456 Attr = GetFileAttributes(Cur);
\r
2457 if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))
\r
2462 AddFileList(&Pkt, Base);
\r
2464 Pos = GetNextSelected(Win, Pos, All);
\r
2469 /*===== ディレクトリツリー =====*/
\r
2471 Pos = GetFirstSelected(Win, All);
\r
2474 if(GetNodeType(Win, Pos) == NODE_DIR)
\r
2476 GetNodeName(Win, Pos, Name, FMAX_PATH);
\r
2477 strcpy(Pkt.File, Name);
\r
2478 ReplaceAll(Pkt.File, '\\', '/');
\r
2482 if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))
\r
2484 AskLocalCurDir(Cur, FMAX_PATH);
\r
2486 strcat(Cur, Pkt.File);
\r
2487 ReplaceAll(Cur, '/', '\\');
\r
2488 Attr = GetFileAttributes(Cur);
\r
2489 if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))
\r
2495 Pkt.Node = NODE_DIR;
\r
2498 memset(&Pkt.Time, 0, sizeof(FILETIME));
\r
2499 AddFileList(&Pkt, Base);
\r
2501 if(Win == WIN_LOCAL)
\r
2502 MakeLocalTree(Name, Base);
\r
2505 AskRemoteCurDir(Cur, FMAX_PATH);
\r
2507 if((AskListCmdMode() == NO) &&
\r
2508 (AskUseNLST_R() == YES))
\r
2509 MakeRemoteTree1(Name, Cur, Base, CancelCheckWork);
\r
2511 MakeRemoteTree2(Name, Cur, Base, CancelCheckWork);
\r
2513 //DispListList(*Base, "LIST");
\r
2518 Pos = GetNextSelected(Win, Pos, All);
\r
2527 /* ファイルリストの内容を表示 */
\r
2528 static void DispListList(FILELIST *Pos, char *Title)
\r
2530 DoPrintf("############ %s ############", Title);
\r
2531 while(Pos != NULL)
\r
2533 DoPrintf("%d %s", Pos->Node, Pos->File);
\r
2536 DoPrintf("############ END ############");
\r
2541 /*----- Drag&Dropされたファイルをリストに登録する -----------------------------
\r
2544 * WPARAM wParam : ドロップされたファイルの情報
\r
2545 * char *Cur : カレントディレクトリを返すバッファ
\r
2546 * FILELIST **Base : ファイルリストの先頭
\r
2550 *----------------------------------------------------------------------------*/
\r
2552 void MakeDroppedFileList(WPARAM wParam, char *Cur, FILELIST **Base)
\r
2556 char Name[FMAX_PATH+1];
\r
2557 char Tmp[FMAX_PATH+1];
\r
2560 WIN32_FIND_DATA Find;
\r
2562 Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
\r
2564 DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);
\r
2567 for(i = 0; i < Max; i++)
\r
2569 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);
\r
2571 if((GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY) == 0)
\r
2573 Pkt.Node = NODE_FILE;
\r
2574 strcpy(Pkt.File, GetFileName(Name));
\r
2576 memset(&Pkt.Time, 0, sizeof(FILETIME));
\r
2577 if((fHnd = FindFirstFile(Name, &Find)) != INVALID_HANDLE_VALUE)
\r
2580 Pkt.Time = Find.ftLastWriteTime;
\r
2582 AddFileList(&Pkt, Base);
\r
2586 GetCurrentDirectory(FMAX_PATH, Tmp);
\r
2587 SetCurrentDirectory(Cur);
\r
2588 for(i = 0; i < Max; i++)
\r
2590 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);
\r
2592 if(GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY)
\r
2594 Pkt.Node = NODE_DIR;
\r
2595 strcpy(Pkt.File, GetFileName(Name));
\r
2596 AddFileList(&Pkt, Base);
\r
2598 MakeLocalTree(Pkt.File, Base);
\r
2601 SetCurrentDirectory(Tmp);
\r
2603 DragFinish((HDROP)wParam);
\r
2609 /*----- Drag&Dropされたファイルがあるフォルダを取得する -----------------------
\r
2612 * WPARAM wParam : ドロップされたファイルの情報
\r
2613 * char *Cur : カレントディレクトリを返すバッファ
\r
2617 *----------------------------------------------------------------------------*/
\r
2619 void MakeDroppedDir(WPARAM wParam, char *Cur)
\r
2623 Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
\r
2624 DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);
\r
2626 DragFinish((HDROP)wParam);
\r
2632 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(1)-------
\r
2635 * char *Path : パス名
\r
2636 * char *Cur : カレントディレクトリ
\r
2637 * FILELIST **Base : ファイルリストの先頭
\r
2644 *----------------------------------------------------------------------------*/
\r
2646 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)
\r
2650 if(DoCWD(Path, NO, NO, NO) == FTP_COMPLETE)
\r
2652 /* サブフォルダも含めたリストを取得 */
\r
2653 Sts = DoDirListCmdSkt("R", "", 999, CancelCheckWork); /* NLST -alLR*/
\r
2654 DoCWD(Cur, NO, NO, NO);
\r
2656 if(Sts == FTP_COMPLETE)
\r
2657 AddRemoteTreeToFileList(999, Path, RDIR_NLST, Base);
\r
2663 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(2)-------
\r
2666 * char *Path : パス名
\r
2667 * char *Cur : カレントディレクトリ
\r
2668 * FILELIST **Base : ファイルリストの先頭
\r
2674 * 各フォルダに移動してリストを取得
\r
2675 *----------------------------------------------------------------------------*/
\r
2677 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)
\r
2680 FILELIST *CurList;
\r
2684 /* VAX VMS は CWD xxx/yyy という指定ができないので */
\r
2685 /* CWD xxx, Cwd yyy と複数に分ける */
\r
2686 if(AskHostType() != HTYPE_VMS)
\r
2687 Sts = DoCWD(Path, NO, NO, NO);
\r
2690 #if defined(HAVE_OPENVMS)
\r
2691 /* OpenVMSの場合、ディレクトリ移動時は"HOGE.DIR;1"を"HOGE"にする */
\r
2692 ReformVMSDirName(Path, TRUE);
\r
2694 Sts = DoCWDStepByStep(Path, Cur);
\r
2697 if(Sts == FTP_COMPLETE)
\r
2699 Sts = DoDirListCmdSkt("", "", 999, CancelCheckWork); /* NLST -alL*/
\r
2700 DoCWD(Cur, NO, NO, NO);
\r
2702 if(Sts == FTP_COMPLETE)
\r
2705 AddRemoteTreeToFileList(999, Path, RDIR_CWD, &CurList);
\r
2706 CopyTmpListToFileList(Base, CurList);
\r
2709 while(Pos != NULL)
\r
2711 if(Pos->Node == NODE_DIR)
\r
2713 /* まずディレクトリ名をセット */
\r
2714 strcpy(Pkt.File, Pos->File);
\r
2715 Pkt.Node = NODE_DIR;
\r
2718 memset(&Pkt.Time, 0, sizeof(FILETIME));
\r
2719 AddFileList(&Pkt, Base);
\r
2721 /* そのディレクトリの中を検索 */
\r
2722 MakeRemoteTree2(Pos->File, Cur, Base, CancelCheckWork);
\r
2726 DeleteFileList(&CurList);
\r
2733 /*----- ファイルリストの内容を別のファイルリストにコピー ----------------------
\r
2736 * FILELIST **Base : コピー先
\r
2737 * FILELIST *List : コピー元
\r
2743 * コピーするのはファイルの情報だけ
\r
2744 * ディレクトリの情報はコピーしない
\r
2745 *----------------------------------------------------------------------------*/
\r
2747 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List)
\r
2749 while(List != NULL)
\r
2751 if(List->Node == NODE_FILE)
\r
2752 AddFileList(List, Base);
\r
2754 List = List->Next;
\r
2760 /*----- ホスト側のファイル情報をファイルリストに登録 --------------------------
\r
2763 * int Num : テンポラリファイルのファイル名番号 (_ffftp.???)
\r
2764 * char *Path : パス名
\r
2765 * int IncDir : 再帰検索の方法 (RDIR_xxx)
\r
2766 * FILELIST **Base : ファイルリストの先頭
\r
2770 *----------------------------------------------------------------------------*/
\r
2772 void AddRemoteTreeToFileList(int Num, char *Path, int IncDir, FILELIST **Base)
\r
2774 char Str[FMAX_PATH+1];
\r
2775 char Dir[FMAX_PATH+1];
\r
2776 char Name[FMAX_PATH+1];
\r
2784 char Owner[OWNER_NAME_LEN+1];
\r
2788 MakeCacheFileName(Num, Str);
\r
2789 if((fd = fopen(Str, "rb")) != NULL)
\r
2791 strcpy(Dir, Path);
\r
2793 ListType = LIST_UNKNOWN;
\r
2795 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)
\r
2797 if((ListType = AnalizeFileInfo(Str)) == LIST_UNKNOWN)
\r
2799 if(MakeDirPath(Str, ListType, Path, Dir) == FFFTP_SUCCESS)
\r
2801 if(IncDir == RDIR_NLST)
\r
2803 strcpy(Pkt.File, Dir);
\r
2804 Pkt.Node = NODE_DIR;
\r
2807 memset(&Pkt.Time, 0, sizeof(FILETIME));
\r
2808 AddFileList(&Pkt, Base);
\r
2814 Node = ResolvFileInfo(Str, ListType, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);
\r
2816 if(AskFilterStr(Name, Node) == YES)
\r
2818 if((Node == NODE_FILE) ||
\r
2819 ((IncDir == RDIR_CWD) && (Node == NODE_DIR)))
\r
2821 strcpy(Pkt.File, Dir);
\r
2822 if(strlen(Pkt.File) > 0)
\r
2823 SetSlashTail(Pkt.File);
\r
2824 strcat(Pkt.File, Name);
\r
2830 Pkt.InfoExist = InfoExist;
\r
2831 AddFileList(&Pkt, Base);
\r
2842 /*----- ファイル一覧情報の1行を取得 ------------------------------------------
\r
2845 * char *Buf : 1行の情報をセットするバッファ
\r
2847 * FILE *Fd : ストリーム
\r
2850 * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)
\r
2853 * VAX VMS以外の時は fgets(Buf, Max, Fd) と同じ
\r
2854 * Vax VMSの時は、複数行のファイル情報を1行にまとめる
\r
2855 *----------------------------------------------------------------------------*/
\r
2857 static int GetListOneLine(char *Buf, int Max, FILE *Fd)
\r
2859 char Tmp[FMAX_PATH+1];
\r
2863 while((Sts == FFFTP_FAIL) && (fgets(Buf, Max, Fd) != NULL))
\r
2865 Sts = FFFTP_SUCCESS;
\r
2866 RemoveReturnCode(Buf);
\r
2867 ReplaceAll(Buf, '\x08', ' ');
\r
2869 /* VAX VMSではファイル情報が複数行にわかれている */
\r
2871 if(AskHostType() == HTYPE_VMS)
\r
2873 if(strchr(Buf, ';') == NULL) /* ファイル名以外の行 */
\r
2877 Max -= strlen(Buf);
\r
2878 while(strchr(Buf, ')') == NULL)
\r
2880 if(fgets(Tmp, FMAX_PATH, Fd) != NULL)
\r
2882 RemoveReturnCode(Tmp);
\r
2883 ReplaceAll(Buf, '\x08', ' ');
\r
2884 if((int)strlen(Tmp) > Max)
\r
2886 Max -= strlen(Tmp);
\r
2896 // DoPrintf("List : %s", Buf);
\r
2902 /*----- サブディレクトリ情報の解析 --------------------------------------------
\r
2905 * char *Str : ファイル情報(1行)
\r
2906 * int ListType : リストのタイプ
\r
2907 * char *Path : 先頭からのパス名
\r
2908 * char *Dir : ディレクトリ名
\r
2912 * FFFTP_SUCCESS/FFFTP_FAIL=ディレクトリ情報でない
\r
2913 *----------------------------------------------------------------------------*/
\r
2915 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir)
\r
2923 case LIST_ACOS_4 :
\r
2927 if(*(Str + strlen(Str) - 1) == ':') /* 最後が : ならサブディレクトリ */
\r
2929 if(strcmp(Str, ".:") != 0)
\r
2931 if((strncmp(Str, "./", 2) == 0) ||
\r
2932 (strncmp(Str, ".\\", 2) == 0))
\r
2937 if(strlen(Str) > 1)
\r
2939 strcpy(Dir, Path);
\r
2940 SetSlashTail(Dir);
\r
2942 *(Dir + strlen(Dir) - 1) = NUL;
\r
2944 ChangeFnameRemote2Local(Dir, FMAX_PATH);
\r
2946 ReplaceAll(Dir, '\\', '/');
\r
2949 Sts = FFFTP_SUCCESS;
\r
2957 /*----- ローカル側のサブディレクトリ以下のファイルをリストに登録する ----------
\r
2960 * char *Path : パス名
\r
2961 * FILELIST **Base : ファイルリストの先頭
\r
2965 *----------------------------------------------------------------------------*/
\r
2967 static void MakeLocalTree(char *Path, FILELIST **Base)
\r
2969 char Src[FMAX_PATH+1];
\r
2971 WIN32_FIND_DATA FindBuf;
\r
2973 SYSTEMTIME TmpStime;
\r
2975 strcpy(Src, Path);
\r
2978 ReplaceAll(Src, '/', '\\');
\r
2980 if((fHnd = FindFirstFileAttr(Src, &FindBuf, DispIgnoreHide)) != INVALID_HANDLE_VALUE)
\r
2984 if((FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
\r
2986 if(AskFilterStr(FindBuf.cFileName, NODE_FILE) == YES)
\r
2988 strcpy(Pkt.File, Path);
\r
2989 SetSlashTail(Pkt.File);
\r
2990 strcat(Pkt.File, FindBuf.cFileName);
\r
2991 ReplaceAll(Pkt.File, '\\', '/');
\r
2992 Pkt.Node = NODE_FILE;
\r
2993 Pkt.Size = MakeLongLong(FindBuf.nFileSizeHigh, FindBuf.nFileSizeLow);
\r
2995 Pkt.Time = FindBuf.ftLastWriteTime;
\r
2996 FileTimeToSystemTime(&Pkt.Time, &TmpStime);
\r
2997 TmpStime.wSecond = 0;
\r
2998 TmpStime.wMilliseconds = 0;
\r
2999 SystemTimeToFileTime(&TmpStime, &Pkt.Time);
\r
3000 AddFileList(&Pkt, Base);
\r
3004 while(FindNextFileAttr(fHnd, &FindBuf, DispIgnoreHide) == TRUE);
\r
3008 if((fHnd = FindFirstFileAttr(Src, &FindBuf, DispIgnoreHide)) != INVALID_HANDLE_VALUE)
\r
3012 if((FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
\r
3013 (strcmp(FindBuf.cFileName, ".") != 0) &&
\r
3014 (strcmp(FindBuf.cFileName, "..") != 0))
\r
3016 strcpy(Src, Path);
\r
3018 strcat(Src, FindBuf.cFileName);
\r
3019 strcpy(Pkt.File, Src);
\r
3020 ReplaceAll(Pkt.File, '\\', '/');
\r
3021 Pkt.Node = NODE_DIR;
\r
3024 memset(&Pkt.Time, 0, sizeof(FILETIME));
\r
3025 AddFileList(&Pkt, Base);
\r
3027 MakeLocalTree(Src, Base);
\r
3030 while(FindNextFileAttr(fHnd, &FindBuf, DispIgnoreHide) == TRUE);
\r
3037 /*----- ファイルリストに情報を登録する ----------------------------------------
\r
3040 * FILELIST *Pkt : 登録するファイル情報
\r
3041 * FILELIST **Base : ファイルリストの先頭
\r
3045 *----------------------------------------------------------------------------*/
\r
3047 static void AddFileList(FILELIST *Pkt, FILELIST **Base)
\r
3052 DoPrintf("FileList : NODE=%d : %s", Pkt->Node, Pkt->File);
\r
3056 while(Pos != NULL)
\r
3058 if(strcmp(Pkt->File, Pos->File) == 0)
\r
3060 DoPrintf(" --> Duplicate!!");
\r
3067 if(Pos == NULL) /* 重複していないので登録する */
\r
3069 if((Pos = malloc(sizeof(FILELIST))) != NULL)
\r
3071 memcpy(Pos, Pkt, sizeof(FILELIST));
\r
3084 /*----- ファイルリストをクリアする --------------------------------------------
\r
3087 * FILELIST **Base : ファイルリストの先頭
\r
3091 *----------------------------------------------------------------------------*/
\r
3093 void DeleteFileList(FILELIST **Base)
\r
3099 while(New != NULL)
\r
3110 /*----- ファイルリストに指定のファイルがあるかチェック ------------------------
\r
3113 * char *Fname : ファイル名
\r
3114 * FILELIST *Base : ファイルリストの先頭
\r
3115 * int Caps : 大文字/小文字の区別モード (COMP_xxx)
\r
3118 * FILELIST *見つかったファイルリストのデータ
\r
3120 *----------------------------------------------------------------------------*/
\r
3122 FILELIST *SearchFileList(char *Fname, FILELIST *Base, int Caps)
\r
3124 char Tmp[FMAX_PATH+1];
\r
3126 while(Base != NULL)
\r
3128 if(Caps == COMP_STRICT)
\r
3130 if(_mbscmp(Fname, Base->File) == 0)
\r
3135 if(_mbsicmp(Fname, Base->File) == 0)
\r
3137 if(Caps == COMP_IGNORE)
\r
3141 strcpy(Tmp, Base->File);
\r
3143 if(_mbscmp(Tmp, Base->File) == 0)
\r
3148 Base = Base->Next;
\r
3154 /*----- ファイル情報からリストタイプを求める ----------------------------------
\r
3157 * char *Str : ファイル情報(1行)
\r
3160 * int リストタイプ (LIST_xxx)
\r
3161 *----------------------------------------------------------------------------*/
\r
3163 static int AnalizeFileInfo(char *Str)
\r
3166 char Tmp[FMAX_PATH+1];
\r
3173 //DoPrintf("LIST : %s", Str);
\r
3175 Ret = LIST_UNKNOWN;
\r
3176 Flag1 = AskHostType();
\r
3177 if(Flag1 == HTYPE_ACOS)
\r
3179 else if(Flag1 == HTYPE_ACOS_4)
\r
3180 Ret = LIST_ACOS_4;
\r
3181 else if(Flag1 == HTYPE_VMS)
\r
3183 else if(Flag1 == HTYPE_IRMX)
\r
3185 else if(Flag1 == HTYPE_STRATUS)
\r
3186 Ret = LIST_STRATUS;
\r
3187 else if(Flag1 == HTYPE_AGILENT)
\r
3188 Ret = LIST_AGILENT;
\r
3189 else if(Flag1 == HTYPE_SHIBASOKU)
\r
3190 Ret = LIST_SHIBASOKU;
\r
3193 /* 以下のフォーマットをチェック */
\r
3194 /* LIST_UNIX_10, LIST_UNIX_20, LIST_UNIX_12, LIST_UNIX_22, LIST_UNIX_50, LIST_UNIX_60 */
\r
3197 if(FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS)
\r
3199 /* MELCOM80は "d rwxrwxrwx" のようにスペースが空いている */
\r
3201 if((strlen(Tmp) == 1) && (strchr("-dDlL", Tmp[0]) != NULL))
\r
3203 if(FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS)
\r
3205 if((strlen(Tmp) == 9) ||
\r
3206 ((strlen(Tmp) > 9) && (IsDigit(Tmp[9]) != 0)))
\r
3208 memmove(Str+1, Str+2, strlen(Str+2)+1);
\r
3209 FindField(Str, Tmp, 0, NO);
\r
3215 if(strlen(Tmp) >= 10)
\r
3218 if((strlen(Tmp) > 10) && (IsDigit(Tmp[10]) != 0))
\r
3221 /* drwxr-xr-x1234 owner group 1024 Nov 6 14:21 Linux/ */
\r
3226 // LIST_UNIX_60 support
\r
3227 if(FindField(Str, Tmp, 7+Add1, NO) == FFFTP_SUCCESS)
\r
3229 GetMonth(Tmp, &Month, &Day);
\r
3232 Ret = CheckUnixType(Str, Tmp, Add1, 2, Day);
\r
3238 // LIST_UNIX_12 support
\r
3239 if((Ret == LIST_UNKNOWN) &&
\r
3240 (FindField(Str, Tmp, 6+Add1, NO) == FFFTP_SUCCESS))
\r
3242 GetMonth(Tmp, &Month, &Day);
\r
3245 Ret = CheckUnixType(Str, Tmp, Add1, 0, Day);
\r
3248 //////////////////
\r
3251 // LIST_UNIX_70 support
\r
3252 if((Ret == LIST_UNKNOWN) &&
\r
3253 (FindField(Str, Tmp, 6+Add1, NO) == FFFTP_SUCCESS))
\r
3255 GetMonth(Tmp, &Month, &Day);
\r
3258 Ret = CheckUnixType(Str, Tmp, Add1, 1, Day);
\r
3263 if((Ret == LIST_UNKNOWN) &&
\r
3264 (FindField(Str, Tmp, 5+Add1, NO) == FFFTP_SUCCESS))
\r
3266 GetMonth(Tmp, &Month, &Day);
\r
3269 Ret = CheckUnixType(Str, Tmp, Add1, 0, Day);
\r
3273 if((Ret == LIST_UNKNOWN) &&
\r
3274 (FindField(Str, Tmp, 4+Add1, NO) == FFFTP_SUCCESS))
\r
3276 GetMonth(Tmp, &Month, &Day);
\r
3279 Ret = CheckUnixType(Str, Tmp, Add1, -1, Day);
\r
3283 if((Ret == LIST_UNKNOWN) &&
\r
3284 (FindField(Str, Tmp, 3+Add1, NO) == FFFTP_SUCCESS))
\r
3286 GetMonth(Tmp, &Month, &Day);
\r
3289 Ret = CheckUnixType(Str, Tmp, Add1, -2, Day);
\r
3293 if((Ret != LIST_UNKNOWN) && (Flag1 == YES))
\r
3294 Ret |= LIST_MELCOM;
\r
3298 /* 以下のフォーマットをチェック */
\r
3301 if(Ret == LIST_UNKNOWN)
\r
3303 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3304 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3306 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&
\r
3307 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3309 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3310 (IsDigit(Tmp[0]) != 0))
\r
3312 if(FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS)
\r
3321 /* 以下のフォーマットをチェック */
\r
3324 if(Ret == LIST_UNKNOWN)
\r
3326 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&
\r
3327 (CheckYYMMDDformat(Tmp, '*', NO) != 0))
\r
3329 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3330 ((IsDigit(Tmp[0]) != 0) || (StrAllSameChar(Tmp, '*') == YES)))
\r
3332 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&
\r
3333 ((IsDigit(Tmp[0]) != 0) || (StrAllSameChar(Tmp, '*') == YES)))
\r
3335 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&
\r
3336 (strlen(Tmp) == 4))
\r
3338 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)
\r
3348 /* 以下のフォーマットをチェック */
\r
3351 if(Ret == LIST_UNKNOWN)
\r
3353 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3354 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3356 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3357 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3359 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&
\r
3360 (IsDigit(Tmp[0]) != 0))
\r
3362 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)
\r
3364 Ret = LIST_GP6000;
\r
3371 /* 以下のフォーマットをチェック */
\r
3372 /* LIST_DOS_1, LIST_DOS_2 */
\r
3374 if(Ret == LIST_UNKNOWN)
\r
3376 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3377 (CheckHHMMformat(Tmp) == YES))
\r
3379 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3380 ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))
\r
3382 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)
\r
3384 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&
\r
3385 (CheckYYMMDDformat(Tmp, NUL, YES) != 0))
\r
3387 TmpInt = atoi(Tmp);
\r
3388 if((TmpInt >= 1) && (TmpInt <= 12))
\r
3398 /* 以下のフォーマットをチェック */
\r
3401 if(Ret == LIST_UNKNOWN)
\r
3403 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&
\r
3404 (CheckHHMMformat(Tmp) == YES))
\r
3406 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3407 ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))
\r
3409 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3410 (CheckYYMMDDformat(Tmp, NUL, YES) != 0))
\r
3418 /* 以下のフォーマットをチェック */
\r
3421 if(Ret == LIST_UNKNOWN)
\r
3423 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&
\r
3424 (CheckYYYYMMDDformat(Tmp, NUL) == YES))
\r
3426 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3427 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3429 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3430 ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))
\r
3432 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)
\r
3441 /* 以下のフォーマットをチェック */
\r
3442 /* LIST_CHAMELEON */
\r
3444 if(Ret == LIST_UNKNOWN)
\r
3446 if(FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS)
\r
3448 GetMonth(Tmp, &Month, &Day);
\r
3449 if((Month != 0) && (Day == 0))
\r
3451 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3452 ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))
\r
3454 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&
\r
3455 (CheckHHMMformat(Tmp) == YES))
\r
3457 Ret = LIST_CHAMELEON;
\r
3464 /* 以下のフォーマットをチェック */
\r
3467 if(Ret == LIST_UNKNOWN)
\r
3469 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&
\r
3470 (CheckHHMMformat(Tmp) == YES))
\r
3472 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&
\r
3473 (IsDigit(Tmp[0]) != 0))
\r
3475 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3476 (CheckYYMMDDformat(Tmp, NUL, YES) != 0))
\r
3478 if(FindField(Str, Tmp, 4, NO) == FFFTP_SUCCESS)
\r
3487 /* 以下のフォーマットをチェック */
\r
3490 if(Ret == LIST_UNKNOWN)
\r
3492 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&
\r
3493 (strlen(Tmp) == 10))
\r
3495 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&
\r
3496 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3498 if((FindField(Str, Tmp, 4, NO) == FFFTP_SUCCESS) &&
\r
3499 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3501 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3502 (IsDigit(Tmp[0]) != 0))
\r
3504 if(FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS)
\r
3511 else if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3512 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3514 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3515 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3517 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)
\r
3526 /* 以下のフォーマットをチェック */
\r
3529 if(Ret == LIST_UNKNOWN)
\r
3531 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&
\r
3532 ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))
\r
3534 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&
\r
3535 (CheckHHMMformat(Tmp) == YES))
\r
3537 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)
\r
3539 GetMonth(Tmp, &Month, &Day);
\r
3542 if((FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS) &&
\r
3543 (IsDigit(Tmp[0]) != 0))
\r
3545 Ret = LIST_ALLIED;
\r
3553 /* 以下のフォーマットをチェック */
\r
3556 if(Ret == LIST_UNKNOWN)
\r
3558 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&
\r
3559 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))
\r
3561 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3562 (IsDigit(Tmp[0]) != 0) && (strlen(Tmp) == 4))
\r
3564 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&
\r
3565 (IsDigit(Tmp[0]) != 0))
\r
3567 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)
\r
3576 /* 以下のフォーマットをチェック */
\r
3579 if(Ret == LIST_UNKNOWN)
\r
3581 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&
\r
3582 (CheckYYYYMMDDformat(Tmp, NUL) == YES))
\r
3584 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) && IsDigit(Tmp[0]))
\r
3586 if((FindField(Str, Tmp, 7, NO) == FFFTP_SUCCESS) && IsDigit(Tmp[0]))
\r
3588 if(FindField(Str, Tmp, 9, NO) == FFFTP_SUCCESS)
\r
3599 DoPrintf("ListType=%d", Ret);
\r
3605 /*----- UNIX系リストタイプのチェックを行なう ----------------------------------
\r
3608 * char *Str : ファイル情報(1行)
\r
3609 * char *Tmp : 一時ワーク
\r
3610 * int Add1 : 加算パラメータ1
\r
3611 * int Add2 : 加算パラメータ2
\r
3612 * int Day : 日 (0=ここで取得する)
\r
3615 * int リストタイプ (LIST_xxx)
\r
3616 *----------------------------------------------------------------------------*/
\r
3618 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day)
\r
3627 Ret = LIST_UNKNOWN;
\r
3637 ((FindField(Str, Tmp, 6+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&
\r
3638 ((atoi(Tmp) >= 1) && (atoi(Tmp) <= 31))))
\r
3640 if((FindField(Str, Tmp, 7+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&
\r
3641 ((atoi(Tmp) >= 1900) || (GetHourAndMinute(Tmp, &Hour, &Minute) == FFFTP_SUCCESS)))
\r
3643 if(FindField(Str, Tmp, 8+Add1+Add2+Add3, NO) == FFFTP_SUCCESS)
\r
3653 if((FindField(Str, Tmp, 7+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&
\r
3654 ((atoi(Tmp) >= 1) && (atoi(Tmp) <= 31)))
\r
3656 if((FindField(Str, Tmp, 5+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&
\r
3657 (atoi(Tmp) >= 1900))
\r
3659 if((FindField(Str, Tmp, 6+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&
\r
3660 (((atoi(Tmp) >= 1) && (atoi(Tmp) <= 9) &&
\r
3661 ((unsigned char)Tmp[1] == 0xD4) &&
\r
3662 ((unsigned char)Tmp[2] == 0xC2)) ||
\r
3663 ((atoi(Tmp) >= 10) && (atoi(Tmp) <= 12) &&
\r
3664 ((unsigned char)Tmp[2] == 0xD4) &&
\r
3665 ((unsigned char)Tmp[3] == 0xC2))))
\r
3667 if(FindField(Str, Tmp, 8+Add1+Add2+Add3, NO) == FFFTP_SUCCESS)
\r
3680 Ret = LIST_UNIX_60;
\r
3682 Ret = LIST_UNIX_64;
\r
3684 Ret = LIST_UNIX_61;
\r
3688 Ret = LIST_UNIX_62;
\r
3690 Ret = LIST_UNIX_65;
\r
3692 Ret = LIST_UNIX_63;
\r
3695 else if(Add2 == 1)
\r
3697 Ret = LIST_UNIX_70;
\r
3699 Ret = LIST_UNIX_74;
\r
3701 Ret = LIST_UNIX_71;
\r
3705 Ret = LIST_UNIX_72;
\r
3707 Ret = LIST_UNIX_75;
\r
3709 Ret = LIST_UNIX_73;
\r
3712 else if(Add2 == 0)
\r
3714 Ret = LIST_UNIX_10;
\r
3716 Ret = LIST_UNIX_14;
\r
3718 Ret = LIST_UNIX_11;
\r
3722 Ret = LIST_UNIX_12;
\r
3724 Ret = LIST_UNIX_15;
\r
3726 Ret = LIST_UNIX_13;
\r
3729 else if(Add2 == -1)
\r
3731 Ret = LIST_UNIX_20;
\r
3733 Ret = LIST_UNIX_24;
\r
3735 Ret = LIST_UNIX_21;
\r
3739 Ret = LIST_UNIX_22;
\r
3741 Ret = LIST_UNIX_25;
\r
3743 Ret = LIST_UNIX_23;
\r
3748 Ret = LIST_UNIX_50;
\r
3750 Ret = LIST_UNIX_54;
\r
3752 Ret = LIST_UNIX_51;
\r
3759 /*----- HH:MM 形式の文字列かどうかをチェック ----------------------------------
\r
3765 * int ステータス (YES/NO)
\r
3770 * 後ろに余分な文字が付いていてもよい
\r
3771 *----------------------------------------------------------------------------*/
\r
3773 static int CheckHHMMformat(char *Str)
\r
3778 if((strlen(Str) >= 3) &&
\r
3779 (IsDigit(Str[0]) != 0))
\r
3781 if((Str = strchr(Str, ':')) != NULL)
\r
3783 if(IsDigit(*(Str+1)) != 0)
\r
3791 /*----- YY/MM/DD 形式の文字列かどうかをチェック -------------------------------
\r
3795 * char Sym : 数字の代わりに使える記号 (NUL=数字以外使えない)
\r
3796 * int Dig3 : 3桁の年を許可
\r
3801 * 1 = ??/??/??, ??/??/???
\r
3807 *----------------------------------------------------------------------------*/
\r
3809 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3)
\r
3814 if((strlen(Str) == 8) &&
\r
3815 (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&
\r
3816 (IsDigit(Str[2]) == 0) &&
\r
3817 (IsDigitSym(Str[3], Sym) != 0) && (IsDigitSym(Str[4], Sym) != 0) &&
\r
3818 (IsDigit(Str[5]) == 0) &&
\r
3819 (IsDigitSym(Str[6], Sym) != 0) && (IsDigitSym(Str[7], Sym) != 0))
\r
3825 if((strlen(Str) == 9) &&
\r
3826 (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) && (IsDigitSym(Str[2], Sym) != 0) &&
\r
3827 (IsDigit(Str[3]) == 0) &&
\r
3828 (IsDigitSym(Str[4], Sym) != 0) && (IsDigitSym(Str[5], Sym) != 0) &&
\r
3829 (IsDigit(Str[6]) == 0) &&
\r
3830 (IsDigitSym(Str[7], Sym) != 0) && (IsDigitSym(Str[8], Sym) != 0))
\r
3834 else if((strlen(Str) == 9) &&
\r
3835 (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&
\r
3836 (IsDigit(Str[2]) == 0) &&
\r
3837 (IsDigitSym(Str[3], Sym) != 0) && (IsDigitSym(Str[4], Sym) != 0) &&
\r
3838 (IsDigit(Str[5]) == 0) &&
\r
3839 (IsDigitSym(Str[6], Sym) != 0) && (IsDigitSym(Str[7], Sym) != 0) && (IsDigitSym(Str[8], Sym) != 0))
\r
3848 /*----- YYYY/MM/DD 形式の文字列かどうかをチェック -----------------------------
\r
3852 * char Sym : 数字の代わりに使える記号 (NUL=数字以外使えない)
\r
3855 * int ステータス (YES/NO)
\r
3860 *----------------------------------------------------------------------------*/
\r
3862 static int CheckYYYYMMDDformat(char *Str, char Sym)
\r
3867 if((strlen(Str) == 10) &&
\r
3868 (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&
\r
3869 (IsDigitSym(Str[2], Sym) != 0) && (IsDigitSym(Str[3], Sym) != 0) &&
\r
3870 (IsDigit(Str[4]) == 0) &&
\r
3871 (IsDigitSym(Str[5], Sym) != 0) && (IsDigitSym(Str[6], Sym) != 0) &&
\r
3872 (IsDigit(Str[7]) == 0) &&
\r
3873 (IsDigitSym(Str[8], Sym) != 0) && (IsDigitSym(Str[9], Sym) != 0))
\r
3881 /*----- ファイル情報からファイル名、サイズなどを取り出す ----------------------
\r
3884 * char *Str : ファイル情報(1行)
\r
3885 * int ListType : リストのタイプ
\r
3886 * char *Name : ファイル名のコピー先
\r
3887 * LONGLONG *Size : サイズのコピー先
\r
3888 * FILETIME *Time : 日付のコピー先
\r
3889 * int *Attr : 属性のコピー先
\r
3890 * char *Owner : オーナ名
\r
3891 * int *Link : リンクかどうか (YES/NO)
\r
3892 * int *InfoExist : 時刻の情報があったかどうか (YES/NO)
\r
3895 * int 種類 (NODE_xxxx)
\r
3896 *----------------------------------------------------------------------------*/
\r
3898 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist)
\r
3901 SYSTEMTIME sTimeNow;
\r
3902 char Buf[FMAX_PATH+1];
\r
3913 static const int DosPos[3][4] = { { 1, 0, 2, 3 }, { 1, 0, 2, 3 }, { 3, 2, 1, 0 } };
\r
3914 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
3915 static const int DosLongFname[3] = { YES, YES, NO };
\r
3922 memset(Owner, NUL, OWNER_NAME_LEN+1);
\r
3923 Time->dwLowDateTime = 0;
\r
3924 Time->dwHighDateTime = 0;
\r
3930 OrgListType = ListType;
\r
3931 ListType &= LIST_MASKFLG;
\r
3937 if(ListType == LIST_DOS_1)
\r
3939 else if(ListType == LIST_DOS_2)
\r
3944 *InfoExist |= (FINFO_DATE | FINFO_SIZE);
\r
3947 FindField(Str, Buf, DosPos[offs][0], NO);
\r
3948 if((Pos = strchr(Buf, ':')) != NULL)
\r
3950 *InfoExist |= FINFO_TIME;
\r
3951 sTime.wHour = atoi(Buf);
\r
3952 sTime.wMinute = atoi(Pos+1);
\r
3953 sTime.wSecond = 0;
\r
3954 sTime.wMilliseconds = 0;
\r
3956 if(strlen(Pos) >= 4)
\r
3958 if(tolower(Pos[3]) == 'a')
\r
3960 if(sTime.wHour == 12)
\r
3963 else if(tolower(Pos[3]) == 'p')
\r
3965 if(sTime.wHour != 12)
\r
3966 sTime.wHour += 12;
\r
3972 FindField(Str, Buf, DosPos[offs][1], NO);
\r
3973 if((offs2 = CheckYYMMDDformat(Buf, NUL, YES)) == 0)
\r
3976 sTime.wYear = Assume1900or2000(atoi(Buf + DosDate[offs][0][offs2]));
\r
3977 sTime.wMonth = atoi(Buf + DosDate[offs][1][offs2]);
\r
3978 sTime.wDay = atoi(Buf + DosDate[offs][2][offs2]);
\r
3979 SystemTimeToFileTime(&sTime, Time);
\r
3980 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
3983 FindField(Str, Buf, DosPos[offs][2], NO);
\r
3984 *Size = _atoi64(Buf);
\r
3987 if(FindField(Str, Fname, DosPos[offs][3], DosLongFname[offs]) == FFFTP_SUCCESS)
\r
3996 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);
\r
3999 FindField(Str, Buf, 0, NO);
\r
4000 sTime.wYear = atoi(Buf);
\r
4001 sTime.wMonth = atoi(Buf+5);
\r
4002 sTime.wDay = atoi(Buf+8);
\r
4005 *InfoExist |= FINFO_TIME;
\r
4006 FindField(Str, Buf, 1, NO);
\r
4007 sTime.wHour = atoi(Buf);
\r
4008 sTime.wMinute = atoi(Buf+3);
\r
4009 sTime.wSecond = 0; // atoi(Buf+6);
\r
4010 sTime.wMilliseconds = 0;
\r
4011 SystemTimeToFileTime(&sTime, Time);
\r
4012 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4015 FindField(Str, Buf, 2, NO);
\r
4016 *Size = _atoi64(Buf);
\r
4019 if(FindField(Str, Fname, 3, YES) == FFFTP_SUCCESS)
\r
4028 *InfoExist |= (FINFO_DATE | FINFO_SIZE);
\r
4031 FindField(Str, Buf, 3, NO);
\r
4032 if((Pos = strchr(Buf, ':')) != NULL)
\r
4034 *InfoExist |= FINFO_TIME;
\r
4035 sTime.wHour = atoi(Buf);
\r
4036 sTime.wMinute = atoi(Pos+1);
\r
4037 sTime.wSecond = 0;
\r
4038 sTime.wMilliseconds = 0;
\r
4042 FindField(Str, Buf, 2, NO);
\r
4043 sTime.wYear = Assume1900or2000(atoi(Buf+6));
\r
4044 sTime.wMonth = atoi(Buf+0);
\r
4045 sTime.wDay = atoi(Buf+3);
\r
4046 SystemTimeToFileTime(&sTime, Time);
\r
4047 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4050 FindField(Str, Buf, 0, NO);
\r
4051 *Size = _atoi64(Buf);
\r
4054 if(FindField(Str, Fname, 4, YES) == FFFTP_SUCCESS)
\r
4056 FindField(Str, Buf, 1, NO);
\r
4058 if(strstr(Buf, "DIR") != NULL)
\r
4063 case LIST_CHAMELEON :
\r
4064 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);
\r
4067 FindField(Str, Buf, 6, NO);
\r
4068 strcat(Buf, "------");
\r
4069 *Attr = AttrString2Value(Buf+1);
\r
4072 FindField(Str, Buf, 2, NO);
\r
4073 GetMonth(Buf, &sTime.wMonth, &sTime.wDay); /* wDayは常に0 */
\r
4074 FindField(Str, Buf, 3, NO);
\r
4075 sTime.wDay = atoi(Buf);
\r
4076 FindField(Str, Buf, 4, NO);
\r
4077 sTime.wYear = atoi(Buf);
\r
4080 FindField(Str, Buf, 5, NO);
\r
4081 sTime.wHour = atoi(Buf);
\r
4082 sTime.wMinute = atoi(Buf+3);
\r
4083 sTime.wSecond = 0;
\r
4084 sTime.wMilliseconds = 0;
\r
4085 SystemTimeToFileTime(&sTime, Time);
\r
4086 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4089 FindField(Str, Buf, 1, NO);
\r
4090 *Size = _atoi64(Buf);
\r
4093 if(FindField(Str, Fname, 0, NO) == FFFTP_SUCCESS)
\r
4102 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);
\r
4105 FindField(Str, Buf, 0, NO);
\r
4106 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4109 FindField(Str, Buf, 3, NO);
\r
4110 sTime.wHour = atoi(Buf);
\r
4111 sTime.wMinute = atoi(Buf+3);
\r
4112 sTime.wSecond = 0;
\r
4113 sTime.wMilliseconds = 0;
\r
4116 FindField(Str, Buf, 2, NO);
\r
4117 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4118 sTime.wMonth = atoi(Buf + 3);
\r
4119 sTime.wDay = atoi(Buf + 6);
\r
4120 SystemTimeToFileTime(&sTime, Time);
\r
4121 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4124 FindField(Str, Buf, 1, NO);
\r
4125 *Size = _atoi64(Buf);
\r
4128 if(FindField(Str, Fname, 5, YES) == FFFTP_SUCCESS)
\r
4131 if((Pos = strchr(Fname, '/')) != NULL)
\r
4140 *InfoExist |= FINFO_ATTR;
\r
4143 FindField(Str, Buf, 0, NO);
\r
4144 strcat(Buf, "------");
\r
4145 *Attr = AttrString2Value(Buf+1);
\r
4148 Time->dwLowDateTime = 0;
\r
4149 Time->dwHighDateTime = 0;
\r
4150 FindField(Str, Buf, 5, NO);
\r
4153 *InfoExist |= FINFO_DATE;
\r
4155 sTime.wMinute = 0;
\r
4156 sTime.wSecond = 0;
\r
4157 sTime.wMilliseconds = 0;
\r
4159 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4160 sTime.wMonth = atoi(Buf + 3);
\r
4161 sTime.wDay = atoi(Buf + 6);
\r
4162 SystemTimeToFileTime(&sTime, Time);
\r
4163 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4167 if(FindField(Str, Fname, 6, YES) == FFFTP_SUCCESS)
\r
4169 RemoveTailingSpaces(Fname);
\r
4171 if((Pos = strchr(Fname, '/')) != NULL)
\r
4179 case LIST_GP6000 :
\r
4180 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);
\r
4183 FindField(Str, Buf, 3, NO);
\r
4184 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4187 FindField(Str, Buf, 2, NO);
\r
4188 sTime.wHour = atoi(Buf);
\r
4189 sTime.wMinute = atoi(Buf+3);
\r
4190 sTime.wSecond = 0;
\r
4191 sTime.wMilliseconds = 0;
\r
4194 FindField(Str, Buf, 1, NO);
\r
4195 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4196 sTime.wMonth = atoi(Buf + 3);
\r
4197 sTime.wDay = atoi(Buf + 6);
\r
4198 SystemTimeToFileTime(&sTime, Time);
\r
4199 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4202 FindField(Str, Buf, 5, NO);
\r
4203 *Size = _atoi64(Buf);
\r
4206 FindField(Str, Buf, 0, NO);
\r
4207 *Attr = AttrString2Value(Buf+1);
\r
4210 if(FindField(Str, Fname, 6, YES) == FFFTP_SUCCESS)
\r
4213 if(strchr("dl", Buf[0]) != NULL)
\r
4219 case LIST_ACOS_4 :
\r
4221 FindField(Str, Fname, 0, NO);
\r
4226 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);
\r
4229 FindField(Str, Buf, 1, NO);
\r
4230 *Size = _atoi64(Buf) * BLOCK_SIZE;
\r
4233 FindField(Str, Buf, 2, NO);
\r
4234 GetVMSdate(Buf, &sTime.wYear, &sTime.wMonth, &sTime.wDay);
\r
4236 FindField(Str, Buf, 3, NO);
\r
4237 GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute);
\r
4239 sTime.wSecond = 0;
\r
4240 sTime.wMilliseconds = 0;
\r
4241 SystemTimeToFileTime(&sTime, Time);
\r
4242 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4245 FindField(Str, Fname, 0, NO);
\r
4248 if((Pos = strchr(Fname, '.')) != NULL)
\r
4250 if(_strnicmp(Pos, ".DIR;", 5) == 0)
\r
4252 /* OpenVMSの場合、ファイル/ディレクトリ削除時には".DIR;?"までないと
\r
4253 * 削除できないので、ここではつぶさない */
\r
4254 #if !defined(HAVE_OPENVMS)
\r
4263 *InfoExist |= FINFO_SIZE;
\r
4267 FindField(Str, Buf, 2, NO);
\r
4268 *Size = _atoi64(Buf);
\r
4272 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_ATTR);
\r
4275 FindField(Str, Buf, 1+offs, NO);
\r
4276 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4277 sTime.wMonth = atoi(Buf + 3);
\r
4278 sTime.wDay = atoi(Buf + 6);
\r
4281 FindField(Str, Buf, 2+offs, NO);
\r
4282 sTime.wHour = atoi(Buf);
\r
4283 sTime.wMinute = atoi(Buf+3);
\r
4284 sTime.wSecond = 0;
\r
4285 sTime.wMilliseconds = 0;
\r
4286 SystemTimeToFileTime(&sTime, Time);
\r
4287 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4290 FindField(Str, Buf, 0, NO);
\r
4291 *Attr = AttrString2Value(Buf+1);
\r
4294 if(FindField(Str, Fname, 3+offs, YES) == FFFTP_SUCCESS)
\r
4296 RemoveTailingSpaces(Fname);
\r
4298 if(strchr("dl", Buf[0]) != NULL)
\r
4303 case LIST_STRATUS :
\r
4304 if(FindField(Str, Buf, 0, NO) != FFFTP_SUCCESS)
\r
4306 if(_strnicmp(Buf, "Files:", 6) == 0)
\r
4308 else if(_strnicmp(Buf, "Dirs:", 5) == 0)
\r
4310 else if(_strnicmp(Buf, "Links:", 6) == 0)
\r
4314 if(StratusMode == 0)
\r
4316 else if(StratusMode == 1)
\r
4321 *InfoExist |= (FINFO_TIME | FINFO_DATE);
\r
4324 if(FindField(Str, Buf, 2+offs, NO) != FFFTP_SUCCESS)
\r
4326 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4327 sTime.wMonth = atoi(Buf + 3);
\r
4328 sTime.wDay = atoi(Buf + 6);
\r
4331 if(FindField(Str, Buf, 3+offs, NO) != FFFTP_SUCCESS)
\r
4333 sTime.wHour = atoi(Buf);
\r
4334 sTime.wMinute = atoi(Buf+3);
\r
4335 sTime.wSecond = 0;
\r
4336 sTime.wMilliseconds = 0;
\r
4337 SystemTimeToFileTime(&sTime, Time);
\r
4338 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4341 if(FindField(Str, Fname, 4+offs, YES) != FFFTP_SUCCESS)
\r
4344 if(StratusMode == 0)
\r
4346 *InfoExist |= FINFO_SIZE;
\r
4349 if(FindField(Str, Buf, 1, NO) != FFFTP_SUCCESS)
\r
4351 *Size = _atoi64(Buf) * 4096;
\r
4353 /* 種類(オーナ名のフィールドにいれる) */
\r
4354 if(FindField(Str, Buf, 2, NO) != FFFTP_SUCCESS)
\r
4356 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4366 *InfoExist |= (FINFO_DATE | FINFO_SIZE);
\r
4369 for(offs = 11; offs > 7; offs--)
\r
4371 if((err = FindField(Str, Buf, offs, NO)) == FFFTP_SUCCESS)
\r
4374 if(err != FFFTP_SUCCESS)
\r
4376 if(IsDigit(*Buf) == 0)
\r
4378 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4379 if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)
\r
4381 GetMonth(Buf, &sTime.wMonth, &sTime.wDay);
\r
4382 if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)
\r
4384 if(IsDigit(*Buf) == 0)
\r
4386 sTime.wDay = atoi(Buf);
\r
4388 sTime.wMinute = 0;
\r
4389 sTime.wSecond = 0;
\r
4390 sTime.wMilliseconds = 0;
\r
4391 SystemTimeToFileTime(&sTime, Time);
\r
4392 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4395 if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)
\r
4397 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4402 if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)
\r
4405 while(IsDigit(*Buf) == 0);
\r
4407 if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)
\r
4410 *Size = _atoi64(Buf);
\r
4411 if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)
\r
4413 if(IsDigit(*Buf) == 0)
\r
4416 if(FindField(Str, Fname, 0, NO) != FFFTP_SUCCESS)
\r
4423 if((FindField(Str, Buf, 1, NO) == FFFTP_SUCCESS) &&
\r
4424 (strcmp(Buf, "DR") == 0))
\r
4431 case LIST_ALLIED :
\r
4432 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);
\r
4435 FindField(Str, Buf, 3, NO);
\r
4436 GetMonth(Buf, &sTime.wMonth, &sTime.wDay); /* wDayは常に0 */
\r
4437 FindField(Str, Buf, 4, NO);
\r
4438 sTime.wDay = atoi(Buf);
\r
4439 FindField(Str, Buf, 6, NO);
\r
4440 sTime.wYear = atoi(Buf);
\r
4443 FindField(Str, Buf, 5, NO);
\r
4444 sTime.wHour = atoi(Buf);
\r
4445 sTime.wMinute = atoi(Buf+3);
\r
4446 sTime.wSecond = 0;
\r
4447 sTime.wMilliseconds = 0;
\r
4448 SystemTimeToFileTime(&sTime, Time);
\r
4449 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4452 FindField(Str, Buf, 0, NO);
\r
4453 *Size = _atoi64(Buf);
\r
4456 if(FindField(Str, Fname, 1, NO) == FFFTP_SUCCESS)
\r
4465 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);
\r
4468 FindField(Str, Buf, 1, NO);
\r
4469 sTime.wYear = Assume1900or2000(atoi(Buf));
\r
4470 sTime.wMonth = atoi(Buf + 3);
\r
4471 sTime.wDay = atoi(Buf + 6);
\r
4472 SystemTimeToFileTime(&sTime, Time);
\r
4473 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4476 FindField(Str, Buf, 2, NO);
\r
4477 sTime.wHour = atoi_n(Buf, 2);
\r
4478 sTime.wMinute = atoi(Buf+2);
\r
4479 sTime.wSecond = 0;
\r
4480 sTime.wMilliseconds = 0;
\r
4481 SystemTimeToFileTime(&sTime, Time);
\r
4482 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4485 FindField(Str, Buf, 5, NO);
\r
4486 *Size = _atoi64(Buf);
\r
4489 FindField(Str, Buf, 0, NO);
\r
4490 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4493 FindField(Str, Buf, 3, NO);
\r
4496 if(FindField(Str, Fname, 6, NO) == FFFTP_SUCCESS)
\r
4498 if((Buf[0] == 'd') || (Buf[0] == 'D'))
\r
4506 *InfoExist |= FINFO_DATE;
\r
4510 FindField(Str, Buf, 2, NO);
\r
4511 sTime.wYear = atoi(Buf);
\r
4512 sTime.wMonth = atoi(Buf + 5);
\r
4513 sTime.wDay = atoi(Buf + 8);
\r
4515 sTime.wMinute = 0;
\r
4516 sTime.wSecond = 0;
\r
4517 sTime.wMilliseconds = 0;
\r
4518 SystemTimeToFileTime(&sTime, Time);
\r
4519 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4522 FindField(Str, Buf, 8, NO);
\r
4523 if(FindField(Str, Fname, 9, NO) == FFFTP_SUCCESS)
\r
4525 if(strcmp(Buf, "PO") == 0)
\r
4527 else if(strcmp(Buf, "PS") == 0)
\r
4532 case LIST_AGILENT :
\r
4533 *InfoExist |= (FINFO_SIZE | FINFO_ATTR);
\r
4536 FindField(Str, Buf, 2, NO);
\r
4537 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4540 FindField(Str, Buf, 4, NO);
\r
4541 *Size = _atoi64(Buf);
\r
4544 FindField(Str, Buf, 0, NO);
\r
4545 *Attr = AttrString2Value(Buf+1);
\r
4548 if(FindField(Str, Fname, 5, YES) == FFFTP_SUCCESS)
\r
4551 if(strchr("dl", Buf[0]) != NULL)
\r
4556 case LIST_SHIBASOKU :
\r
4557 *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);
\r
4560 FindField(Str, Buf, 0, NO);
\r
4561 if(IsDigit(Buf[0]))
\r
4563 *Size = _atoi64(Buf);
\r
4566 FindField(Str, Buf, 1, NO);
\r
4568 GetMonth(Buf, &sTime.wMonth, &sTime.wDay);
\r
4569 sTime.wDay = atoi(Buf+4);
\r
4570 sTime.wYear = atoi(Buf+7);
\r
4573 FindField(Str, Buf, 2, NO);
\r
4574 sTime.wHour = atoi(Buf);
\r
4575 sTime.wMinute = atoi(Buf+3);
\r
4576 sTime.wSecond = 0;
\r
4577 sTime.wMilliseconds = 0;
\r
4578 SystemTimeToFileTime(&sTime, Time);
\r
4579 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4582 FindField(Str, Fname, 3, NO);
\r
4586 if(FindField(Str, Buf, 4, NO) == FFFTP_SUCCESS)
\r
4588 if(strcmp(Buf, "<DIR>") == 0)
\r
4594 case LIST_UNIX_10 :
\r
4595 case LIST_UNIX_11 :
\r
4596 case LIST_UNIX_12 :
\r
4597 case LIST_UNIX_13 :
\r
4598 case LIST_UNIX_14 :
\r
4599 case LIST_UNIX_15 :
\r
4600 case LIST_UNIX_20 :
\r
4601 case LIST_UNIX_21 :
\r
4602 case LIST_UNIX_22 :
\r
4603 case LIST_UNIX_23 :
\r
4604 case LIST_UNIX_24 :
\r
4605 case LIST_UNIX_25 :
\r
4606 case LIST_UNIX_50 :
\r
4607 case LIST_UNIX_51 :
\r
4608 case LIST_UNIX_54 :
\r
4609 case LIST_UNIX_60 :
\r
4610 case LIST_UNIX_61 :
\r
4611 case LIST_UNIX_62 :
\r
4612 case LIST_UNIX_63 :
\r
4613 case LIST_UNIX_64 :
\r
4614 case LIST_UNIX_65 :
\r
4615 case LIST_UNIX_70 :
\r
4616 case LIST_UNIX_71 :
\r
4617 case LIST_UNIX_72 :
\r
4618 case LIST_UNIX_73 :
\r
4619 case LIST_UNIX_74 :
\r
4620 case LIST_UNIX_75 :
\r
4621 // MELCOMはビットフラグになっている
\r
4622 // case LIST_MELCOM :
\r
4624 /* offsはサイズの位置, offs=0はカラム4 */
\r
4626 if((ListType == LIST_UNIX_12) ||
\r
4627 (ListType == LIST_UNIX_13) ||
\r
4628 (ListType == LIST_UNIX_15) ||
\r
4629 (ListType == LIST_UNIX_20) ||
\r
4630 (ListType == LIST_UNIX_21) ||
\r
4631 (ListType == LIST_UNIX_24))
\r
4634 if((ListType == LIST_UNIX_22) ||
\r
4635 (ListType == LIST_UNIX_23) ||
\r
4636 (ListType == LIST_UNIX_25) ||
\r
4637 (ListType == LIST_UNIX_50) ||
\r
4638 (ListType == LIST_UNIX_51) ||
\r
4639 (ListType == LIST_UNIX_54))
\r
4642 if((ListType == LIST_UNIX_60) ||
\r
4643 (ListType == LIST_UNIX_61) ||
\r
4644 (ListType == LIST_UNIX_64))
\r
4647 if((ListType == LIST_UNIX_62) ||
\r
4648 (ListType == LIST_UNIX_63) ||
\r
4649 (ListType == LIST_UNIX_65) ||
\r
4650 (ListType == LIST_UNIX_70) ||
\r
4651 (ListType == LIST_UNIX_71) ||
\r
4652 (ListType == LIST_UNIX_74))
\r
4655 /* offs2は時間(もしくは年)の位置 */
\r
4657 if((ListType == LIST_UNIX_11) ||
\r
4658 (ListType == LIST_UNIX_13) ||
\r
4659 (ListType == LIST_UNIX_21) ||
\r
4660 (ListType == LIST_UNIX_23) ||
\r
4661 (ListType == LIST_UNIX_51) ||
\r
4662 (ListType == LIST_UNIX_61) ||
\r
4663 (ListType == LIST_UNIX_63) ||
\r
4664 (ListType == LIST_UNIX_71) ||
\r
4665 (ListType == LIST_UNIX_73))
\r
4668 /* offs3はオーナ名の位置 */
\r
4670 if((ListType == LIST_UNIX_12) ||
\r
4671 (ListType == LIST_UNIX_13) ||
\r
4672 (ListType == LIST_UNIX_15) ||
\r
4673 (ListType == LIST_UNIX_22) ||
\r
4674 (ListType == LIST_UNIX_23) ||
\r
4675 (ListType == LIST_UNIX_25) ||
\r
4676 (ListType == LIST_UNIX_50) ||
\r
4677 (ListType == LIST_UNIX_51) ||
\r
4678 (ListType == LIST_UNIX_62) ||
\r
4679 (ListType == LIST_UNIX_63) ||
\r
4680 (ListType == LIST_UNIX_65) ||
\r
4681 (ListType == LIST_UNIX_72) ||
\r
4682 (ListType == LIST_UNIX_73) ||
\r
4683 (ListType == LIST_UNIX_75))
\r
4687 if((ListType == LIST_UNIX_14) ||
\r
4688 (ListType == LIST_UNIX_15) ||
\r
4689 (ListType == LIST_UNIX_24) ||
\r
4690 (ListType == LIST_UNIX_25) ||
\r
4691 (ListType == LIST_UNIX_54) ||
\r
4692 (ListType == LIST_UNIX_64) ||
\r
4693 (ListType == LIST_UNIX_65) ||
\r
4694 (ListType == LIST_UNIX_74) ||
\r
4695 (ListType == LIST_UNIX_75))
\r
4698 *InfoExist |= (FINFO_DATE | FINFO_SIZE | FINFO_ATTR);
\r
4701 FindField(Str, Buf, 0, NO);
\r
4702 *Attr = AttrString2Value(Buf+1);
\r
4705 FindField(Str, Buf, 2+offs3, NO);
\r
4706 strncpy(Owner, Buf, OWNER_NAME_LEN);
\r
4709 FindField(Str, Buf, 4+offs, NO);
\r
4711 if((*Pos != NUL) && (IsDigit(*Pos) == 0))
\r
4713 Pos = strchr(Pos, NUL) - 1;
\r
4714 for(; Pos > Buf; Pos--)
\r
4716 if(IsDigit(*Pos) == 0)
\r
4723 *Size = _atoi64(Pos);
\r
4728 GetLocalTime(&sTime);
\r
4729 memcpy(&sTimeNow, &sTime, sizeof(SYSTEMTIME));
\r
4730 sTime.wSecond = 0;
\r
4731 sTime.wMilliseconds = 0;
\r
4733 FindField(Str, Buf, 5+offs, NO);
\r
4734 /* 日付が yy/mm/dd の場合に対応 */
\r
4735 if(GetYearMonthDay(Buf, &sTime.wYear, &sTime.wMonth, &sTime.wDay) == FFFTP_SUCCESS)
\r
4737 sTime.wYear = Assume1900or2000(sTime.wYear);
\r
4739 FindField(Str, Buf, 7+offs+offs2, NO);
\r
4740 if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_SUCCESS)
\r
4741 *InfoExist |= FINFO_TIME;
\r
4745 GetMonth(Buf, &sTime.wMonth, &sTime.wDay);
\r
4748 FindField(Str, Buf, 6+offs, NO);
\r
4749 sTime.wDay = atoi(Buf);
\r
4752 FindField(Str, Buf, 7+offs+offs2, NO);
\r
4753 if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_FAIL)
\r
4755 sTime.wYear = atoi(Buf);
\r
4759 *InfoExist |= FINFO_TIME;
\r
4763 if((sTimeNow.wMonth == 12) && (sTime.wMonth == 1))
\r
4765 else if(sTimeNow.wMonth+1 == sTime.wMonth)
\r
4767 else if(sTimeNow.wMonth < sTime.wMonth)
\r
4771 //#################
\r
4772 /* 今年の今日以降のファイルは、実は去年のファイル */
\r
4773 if((sTime.wYear == sTimeNow.wYear) &&
\r
4774 ((sTime.wMonth > sTimeNow.wMonth) ||
\r
4775 ((sTime.wMonth == sTimeNow.wMonth) && (sTime.wDay > sTimeNow.wDay))))
\r
4784 /* LIST_UNIX_?4, LIST_UNIX_?5 の時 */
\r
4785 FindField(Str, Buf, 5+offs, NO);
\r
4786 sTime.wYear = atoi(Buf);
\r
4787 FindField(Str, Buf, 6+offs, NO);
\r
4788 sTime.wMonth = atoi(Buf);
\r
4789 FindField(Str, Buf, 7+offs, NO);
\r
4790 sTime.wDay = atoi(Buf);
\r
4792 sTime.wMinute = 0;
\r
4793 sTime.wSecond = 0;
\r
4794 sTime.wMilliseconds = 0;
\r
4796 SystemTimeToFileTime(&sTime, Time);
\r
4797 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());
\r
4800 if(FindField(Str, Fname, 8+offs+offs2, YES) == FFFTP_SUCCESS)
\r
4803 if(OrgListType & LIST_MELCOM)
\r
4807 RemoveTailingSpaces(Fname);
\r
4811 if((Pos = strstr(Fname, " -> ")) != NULL)
\r
4815 if(strchr("dl", *Str) != NULL)
\r
4817 if((_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "/") == 0) ||
\r
4818 (_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "\\") == 0))
\r
4820 *(Fname + strlen(Fname) - 1) = NUL;
\r
4826 else if(strchr("-+f", *Str) != NULL)
\r
4829 if((Ret == NODE_FILE) && (Flag != 'B'))
\r
4835 if((Ret != NODE_NONE) && (strlen(Fname) > 0))
\r
4837 if(CheckSpecialDirName(Fname) == YES)
\r
4840 ChangeFnameRemote2Local(Fname, FMAX_PATH);
\r
4846 /*----- 指定の番号のフィールドを求める ----------------------------------------
\r
4850 * char *Buf : 文字列のコピー先
\r
4851 * int Num : フィールド番号
\r
4852 * int ToLast : 文字列の最後までコピー (YES/NO)
\r
4856 * FFFTP_SUCCESS/FFFTP_FAIL
\r
4857 *----------------------------------------------------------------------------*/
\r
4859 static int FindField(char *Str, char *Buf, int Num, int ToLast)
\r
4868 while(*Str == ' ')
\r
4871 for(; Num > 0; Num--)
\r
4873 if((Str = strchr(Str, ' ')) != NULL)
\r
4875 while(*Str == ' ')
\r
4892 if((ToLast == YES) || ((Pos = strchr(Str, ' ')) == NULL))
\r
4896 strncpy(Buf, Str, Pos - Str);
\r
4897 *(Buf + (Pos - Str)) = NUL;
\r
4899 Sts = FFFTP_SUCCESS;
\r
4905 /*----- 文字列から月を求める --------------------------------------------------
\r
4909 * WORD *Month : 月 (0=月を表す文字列ではない)
\r
4910 * WORD *Day : 日 (0=日は含まれていない)
\r
4914 *----------------------------------------------------------------------------*/
\r
4916 static void GetMonth(char *Str, WORD *Month, WORD *Day)
\r
4918 static const char DateStr[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" };
\r
4924 if(IsDigit(*Str) == 0)
\r
4927 *Str = toupper(*Str);
\r
4928 if((Pos = strstr(DateStr, Str)) != NULL)
\r
4929 *Month = ((Pos - DateStr) / 3) + 1;
\r
4933 /* 「10月」のような日付を返すものがある */
\r
4934 /* 漢字がJISの時のみSJISに変換 */
\r
4935 ConvAutoToSJIS(Str, KANJI_NOCNV);
\r
4938 while(*Pos != NUL)
\r
4940 if(!IsDigit(*Pos))
\r
4943 // if((_mbsncmp(Pos, "月", 1) == 0) ||
\r
4944 // (memcmp(Pos, "\xB7\xEE", 2) == 0) || /* EUCの「月」 */
\r
4945 // (memcmp(Pos, "\xD4\xC2", 2) == 0)) /* GBコードの「月」 */
\r
4946 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
4949 *Month = atoi(Str);
\r
4950 if((*Month < 1) || (*Month > 12))
\r
4954 /* 「10月11日」のように日がくっついている事がある */
\r
4958 if((*Day < 1) || (*Day > 31))
\r
4963 else if(_mbsncmp(Pos, "/", 1) == 0)
\r
4965 /* 「10/」のような日付を返すものがある */
\r
4967 *Month = atoi(Str);
\r
4968 if((*Month < 1) || (*Month > 12))
\r
4972 /* 「10/11」のように日がくっついている事がある */
\r
4976 if((*Day < 1) || (*Day > 31))
\r
4990 /*----- 文字列から年月日を求める ----------------------------------------------
\r
4999 * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=日付を表す文字ではない)
\r
5004 * FFFTP_FAILを返す時は *Year = 0; *Month = 0; *Day = 0
\r
5005 *----------------------------------------------------------------------------*/
\r
5006 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day)
\r
5011 if(strlen(Str) == 8)
\r
5013 if(IsDigit(Str[0]) && IsDigit(Str[1]) && !IsDigit(Str[2]) &&
\r
5014 IsDigit(Str[3]) && IsDigit(Str[4]) && !IsDigit(Str[5]) &&
\r
5015 IsDigit(Str[6]) && IsDigit(Str[7]))
\r
5017 *Year = atoi(&Str[0]);
\r
5018 *Month = atoi(&Str[3]);
\r
5019 *Day = atoi(&Str[6]);
\r
5020 Sts = FFFTP_SUCCESS;
\r
5027 /*----- 文字列から時刻を取り出す ----------------------------------------------
\r
5032 * WORD *Minute : 分
\r
5035 * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=時刻を表す文字ではない)
\r
5041 * FFFTP_FAILを返す時は *Hour = 0; *Minute = 0
\r
5042 *----------------------------------------------------------------------------*/
\r
5044 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute)
\r
5050 if((_mbslen(Str) >= 3) && (isdigit(Str[0]) != 0))
\r
5052 *Hour = atoi(Str);
\r
5055 if((Pos = _mbschr(Str, ':')) != NULL)
\r
5058 if(IsDigit(*Pos) != 0)
\r
5060 *Minute = atoi(Pos);
\r
5062 Ret = FFFTP_SUCCESS;
\r
5067 /* 漢字がJISの時のみSJISに変換 */
\r
5068 ConvAutoToSJIS(Str, KANJI_NOCNV);
\r
5071 while(*Pos != NUL)
\r
5073 if(IsDigit(*Pos) == 0)
\r
5076 // if((_mbsncmp(Pos, "時", 1) == 0) ||
\r
5077 // (memcmp(Pos, "\xBB\xFE", 2) == 0)) /* EUCの「時」 */
\r
5078 if(memcmp(Pos, "\xE6\x99\x82", 3) == 0 || memcmp(Pos, "\x8E\x9E", 2) == 0 || memcmp(Pos, "\xBB\xFE", 2) == 0)
\r
5083 *Minute = atoi(Pos);
\r
5085 Ret = FFFTP_SUCCESS;
\r
5095 else if((_stricmp(Str, "a:m") == 0) || (_stricmp(Str, "p:m") == 0))
\r
5099 Ret = FFFTP_SUCCESS;
\r
5102 if(Ret == FFFTP_FAIL)
\r
5111 /*----- VAX VMSの日付文字列から日付を取り出す ---------------------------------
\r
5120 * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=日付を表す文字ではない)
\r
5125 * FFFTP_FAILを返す時は *Year = 0; *Month = 0; *Day = 0
\r
5126 *----------------------------------------------------------------------------*/
\r
5128 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day)
\r
5137 if((Pos = strchr(Str, '-')) != NULL)
\r
5140 strncpy(Buf, Pos, 3);
\r
5142 GetMonth(Buf, Month, &Tmp);
\r
5143 if((Pos = strchr(Pos, '-')) != NULL)
\r
5146 *Year = atoi(Pos);
\r
5147 Ret = FFFTP_SUCCESS;
\r
5151 if(Ret == FFFTP_FAIL)
\r
5161 /*----- 1900年代か2000年代かを決める ------------------------------------------
\r
5164 * int Year : 年(2桁)
\r
5168 *----------------------------------------------------------------------------*/
\r
5170 int Assume1900or2000(int Year)
\r
5181 /*----- "."や".."かどうかを返す -----------------------------------------------
\r
5184 * char *Fname : ファイル名
\r
5187 * int ステータス (YES="."か".."のどちらか/NO)
\r
5188 *----------------------------------------------------------------------------*/
\r
5190 static int CheckSpecialDirName(char *Fname)
\r
5195 if((strcmp(Fname, ".") == 0) || (strcmp(Fname, "..") == 0))
\r
5202 /*----- フィルタに指定されたファイル名かどうかを返す --------------------------
\r
5205 * char Fname : ファイル名
\r
5206 * int Type : ファイルのタイプ (NODE_xxx)
\r
5215 *----------------------------------------------------------------------------*/
\r
5217 static int AskFilterStr(char *Fname, int Type)
\r
5222 char Tmp[FILTER_EXT_LEN+1];
\r
5226 if((strlen(Tbl) > 0) && (Type == NODE_FILE))
\r
5229 while((Tbl != NULL) && (*Tbl != NUL))
\r
5231 while(*Tbl == ';')
\r
5237 if((Pos = strchr(Tmp, ';')) != NULL)
\r
5240 if(CheckFname(Fname, Tmp) == FFFTP_SUCCESS)
\r
5246 Tbl = strchr(Tbl, ';');
\r
5253 /*----- フィルタを設定する ----------------------------------------------------
\r
5260 *----------------------------------------------------------------------------*/
\r
5262 void SetFilter(int *CancelCheckWork)
\r
5264 if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(filter_dlg), GetMainHwnd(), FilterWndProc) == YES)
\r
5266 DispWindowTitle();
\r
5267 GetLocalDirForWnd();
\r
5268 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);
\r
5274 /*----- フィルタ入力ダイアログのコールバック ----------------------------------
\r
5277 * HWND hDlg : ウインドウハンドル
\r
5278 * UINT message : メッセージ番号
\r
5279 * WPARAM wParam : メッセージの WPARAM 引数
\r
5280 * LPARAM lParam : メッセージの LPARAM 引数
\r
5284 *----------------------------------------------------------------------------*/
\r
5286 static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
\r
5290 case WM_INITDIALOG :
\r
5291 SendDlgItemMessage(hDlg, FILTER_STR, EM_LIMITTEXT, FILTER_EXT_LEN+1, 0);
\r
5292 SendDlgItemMessage(hDlg, FILTER_STR, WM_SETTEXT, 0, (LPARAM)FilterStr);
\r
5296 switch(GET_WM_COMMAND_ID(wParam, lParam))
\r
5299 SendDlgItemMessage(hDlg, FILTER_STR, WM_GETTEXT, FILTER_EXT_LEN, (LPARAM)FilterStr);
\r
5300 EndDialog(hDlg, YES);
\r
5304 EndDialog(hDlg, NO);
\r
5308 strcpy(FilterStr, "*");
\r
5309 EndDialog(hDlg, YES);
\r
5313 hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000021);
\r
5325 static int atoi_n(const char *Str, int Len)
\r
5331 if((Tmp = malloc(Len+1)) != NULL)
\r
5333 memset(Tmp, 0, Len+1);
\r
5334 strncpy(Tmp, Str, Len);
\r