FFFTPのソースコードです。
Revision | b0b0e84de915dcf3adb9e90b9b774cfde6546789 (tree) |
---|---|
Zeit | 2012-11-08 17:45:05 |
Autor | Yuji Tanaka <chibi_honu@user...> |
Commiter | Yuji Tanaka |
Change the behavior of Delete of a symbolic link for a directory.
@@ -89,6 +89,7 @@ static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, | ||
89 | 89 | // 64ビット対応 |
90 | 90 | //static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); |
91 | 91 | static INT_PTR CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); |
92 | +static int GetImageIndex(int Win, int Pos); | |
92 | 93 | static void DispListList(FILELIST *Pos, char *Title); |
93 | 94 | static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork); |
94 | 95 | static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork); |
@@ -2627,6 +2628,35 @@ int GetNodeType(int Win, int Pos) | ||
2627 | 2628 | } |
2628 | 2629 | |
2629 | 2630 | |
2631 | +/*----- 指定位置のアイテムのイメージ番号を返す ---------------------------------------- | |
2632 | +* | |
2633 | +* Parameter | |
2634 | +* int Win : ウインドウ番号 (WIN_xxx) | |
2635 | +* int Pos : 位置 | |
2636 | +* | |
2637 | +* Return Value | |
2638 | +* int イメージ番号 | |
2639 | +* 4 Symlink | |
2640 | +*----------------------------------------------------------------------------*/ | |
2641 | +static int GetImageIndex(int Win, int Pos) | |
2642 | +{ | |
2643 | + HWND hWnd; | |
2644 | + LV_ITEM LvItem; | |
2645 | + | |
2646 | + hWnd = GetLocalHwnd(); | |
2647 | + if(Win == WIN_REMOTE) | |
2648 | + hWnd = GetRemoteHwnd(); | |
2649 | + | |
2650 | + // 変数が未初期化のバグ修正 | |
2651 | + memset(&LvItem, 0, sizeof(LV_ITEM)); | |
2652 | + LvItem.mask = LVIF_IMAGE; | |
2653 | + LvItem.iItem = Pos; | |
2654 | + LvItem.iSubItem = 0; | |
2655 | + SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem); | |
2656 | + return LvItem.iImage; | |
2657 | +} | |
2658 | + | |
2659 | + | |
2630 | 2660 | /*----- 指定位置のアイテムのオーナ名を返す ------------------------------------ |
2631 | 2661 | * |
2632 | 2662 | * Parameter |
@@ -2808,26 +2838,31 @@ void MakeSelectedFileList(int Win, int Expand, int All, FILELIST **Base, int *Ca | ||
2808 | 2838 | |
2809 | 2839 | if(Ignore == NO) |
2810 | 2840 | { |
2811 | - Pkt.Node = NODE_DIR; | |
2841 | + if(GetImageIndex(Win, Pos) == 4) // symlink | |
2842 | + Pkt.Node = NODE_FILE; | |
2843 | + else | |
2844 | + Pkt.Node = NODE_DIR; | |
2812 | 2845 | Pkt.Attr = 0; |
2813 | 2846 | Pkt.Size = 0; |
2814 | 2847 | memset(&Pkt.Time, 0, sizeof(FILETIME)); |
2815 | 2848 | AddFileList(&Pkt, Base); |
2816 | 2849 | |
2817 | - if(Win == WIN_LOCAL) | |
2818 | - MakeLocalTree(Name, Base); | |
2819 | - else | |
2820 | - { | |
2821 | - AskRemoteCurDir(Cur, FMAX_PATH); | |
2822 | - | |
2823 | - if((AskListCmdMode() == NO) && | |
2824 | - (AskUseNLST_R() == YES)) | |
2825 | - MakeRemoteTree1(Name, Cur, Base, CancelCheckWork); | |
2850 | + if(GetImageIndex(Win, Pos) != 4) { // symlink | |
2851 | + if(Win == WIN_LOCAL) | |
2852 | + MakeLocalTree(Name, Base); | |
2826 | 2853 | else |
2827 | - MakeRemoteTree2(Name, Cur, Base, CancelCheckWork); | |
2854 | + { | |
2855 | + AskRemoteCurDir(Cur, FMAX_PATH); | |
2856 | + | |
2857 | + if((AskListCmdMode() == NO) && | |
2858 | + (AskUseNLST_R() == YES)) | |
2859 | + MakeRemoteTree1(Name, Cur, Base, CancelCheckWork); | |
2860 | + else | |
2861 | + MakeRemoteTree2(Name, Cur, Base, CancelCheckWork); | |
2828 | 2862 | |
2829 | 2863 | //DispListList(*Base, "LIST"); |
2830 | 2864 | |
2865 | + } | |
2831 | 2866 | } |
2832 | 2867 | } |
2833 | 2868 | } |
@@ -3046,14 +3081,19 @@ static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelC | ||
3046 | 3081 | |
3047 | 3082 | /* まずディレクトリ名をセット */ |
3048 | 3083 | strcpy(Pkt.File, Pos->File); |
3049 | - Pkt.Node = NODE_DIR; | |
3084 | + Pkt.Link = Pos->Link; | |
3085 | + if(Pkt.Link) | |
3086 | + Pkt.Node = NODE_FILE; | |
3087 | + else | |
3088 | + Pkt.Node = NODE_DIR; | |
3050 | 3089 | Pkt.Size = 0; |
3051 | 3090 | Pkt.Attr = 0; |
3052 | 3091 | memset(&Pkt.Time, 0, sizeof(FILETIME)); |
3053 | 3092 | AddFileList(&Pkt, Base); |
3054 | 3093 | |
3055 | 3094 | /* そのディレクトリの中を検索 */ |
3056 | - MakeRemoteTree2(Pos->File, Cur, Base, CancelCheckWork); | |
3095 | + if(!Pkt.Link) | |
3096 | + MakeRemoteTree2(Pos->File, Cur, Base, CancelCheckWork); | |
3057 | 3097 | } |
3058 | 3098 | Pos = Pos->Next; |
3059 | 3099 | } |
@@ -5049,6 +5089,9 @@ static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, | ||
5049 | 5089 | // 不完全な実装のホストが存在するため以下の形式も許容 |
5050 | 5090 | // fact1=value1;fact2=value2;fact3=value3 filename\r\n |
5051 | 5091 | // fact1=value1;fact2=value2;fact3=value3;filename\r\n |
5092 | + // SymlinkはRFC3659の7.7.4. A More Complex Exampleに | |
5093 | + // よるとtype=OS.unix=slink:(target)だが | |
5094 | + // ProFTPDはtype=OS.unix=symlink:(target)となる | |
5052 | 5095 | case LIST_MLSD: |
5053 | 5096 | { |
5054 | 5097 | int i = 0; |
@@ -5056,6 +5099,7 @@ static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, | ||
5056 | 5099 | char Fact[FMAX_PATH + 1]; |
5057 | 5100 | char Name[FMAX_PATH + 1]; |
5058 | 5101 | char Value[FMAX_PATH + 1]; |
5102 | + char Value2[FMAX_PATH + 1]; | |
5059 | 5103 | char* pFileName; |
5060 | 5104 | strncpy(StrBuf, Str, FMAX_PATH * 2); |
5061 | 5105 | StrBuf[FMAX_PATH * 2] = '\0'; |
@@ -5086,6 +5130,12 @@ static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, | ||
5086 | 5130 | Ret = NODE_DIR; |
5087 | 5131 | else if(_stricmp(Value, "file") == 0) |
5088 | 5132 | Ret = NODE_FILE; |
5133 | + else if(_stricmp(Value, "OS.unix") == 0) | |
5134 | + if(FindField2(Fact, Value2, '=', 2, NO) == FFFTP_SUCCESS) | |
5135 | + if(_stricmp(Value2, "symlink") == 0 || _stricmp(Value2, "slink") == 0) { // ProFTPD is symlink. A example of RFC3659 is slink. | |
5136 | + Ret = NODE_DIR; | |
5137 | + *Link = YES; | |
5138 | + } | |
5089 | 5139 | } |
5090 | 5140 | else if(_stricmp(Name, "size") == 0) |
5091 | 5141 | { |