FFFTPのソースコードです。
Revision | f9a20c32d16076be27e54bff43e4eb98795c5fa4 (tree) |
---|---|
Time | 2011-09-23 01:10:11 |
Author | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Fix bugs of UTF-8 to UTF-16 API bridge.
Add support for additional features of hosts.
Add support for MLSD command.
@@ -292,6 +292,8 @@ | ||
292 | 292 | #define LIST_UNIX_73 45 /* UNIX 73 */ |
293 | 293 | #define LIST_UNIX_74 46 /* UNIX 74 */ |
294 | 294 | #define LIST_UNIX_75 47 /* UNIX 75 */ |
295 | +// MLSD対応 | |
296 | +#define LIST_MLSD 48 | |
295 | 297 | |
296 | 298 | #define LIST_MELCOM 0x100 /* MELCOM80 */ |
297 | 299 |
@@ -868,6 +870,12 @@ LIST_UNIX_70 | ||
868 | 870 | #define CRYPT_FTPIS 2 |
869 | 871 | #define CRYPT_SFTP 3 |
870 | 872 | |
873 | +// FEAT対応 | |
874 | +// UTF-8対応 | |
875 | +#define FEATURE_UTF8 0x00000001 | |
876 | +// MLSD対応 | |
877 | +#define FEATURE_MLSD 0x00000002 | |
878 | + | |
871 | 879 | |
872 | 880 | /*================================================= |
873 | 881 | * ストラクチャ |
@@ -918,6 +926,10 @@ typedef struct { | ||
918 | 926 | int UseSFTP; /* SFTPで接続する (YES/NO) */ |
919 | 927 | // 同時接続対応 |
920 | 928 | int MaxThreadCount; /* 同時接続数 */ |
929 | + // FEAT対応 | |
930 | + int Feature; /* 利用可能な機能のフラグ (FEATURE_xxx) */ | |
931 | + // MLSD対応 | |
932 | + int UseMLSD; /* "MLSD"コマンドを使用する */ | |
921 | 933 | } HOSTDATA; |
922 | 934 | |
923 | 935 |
@@ -970,6 +982,8 @@ typedef struct historydata { | ||
970 | 982 | int UseSFTP; /* SFTPで接続する (YES/NO) */ |
971 | 983 | // 同時接続対応 |
972 | 984 | int MaxThreadCount; /* 同時接続数 */ |
985 | + // MLSD対応 | |
986 | + int UseMLSD; /* "MLSD"コマンドを使用する */ | |
973 | 987 | struct historydata *Next; |
974 | 988 | } HISTORYDATA; |
975 | 989 |
@@ -1383,6 +1397,10 @@ int AskUseFTPIS(void); | ||
1383 | 1397 | int AskUseSFTP(void); |
1384 | 1398 | // 同時接続対応 |
1385 | 1399 | int AskMaxThreadCount(void); |
1400 | +// FEAT対応 | |
1401 | +int AskHostFeature(void); | |
1402 | +// MLSD対応 | |
1403 | +int AskUseMLSD(void); | |
1386 | 1404 | |
1387 | 1405 | /*===== cache.c =====*/ |
1388 | 1406 |
@@ -957,7 +957,7 @@ int ReConnectCmdSkt(void) | ||
957 | 957 | // 同時接続対応 |
958 | 958 | int ReConnectTrnSkt(SOCKET *Skt) |
959 | 959 | { |
960 | - char Path[FMAX_PATH+1]; | |
960 | +// char Path[FMAX_PATH+1]; | |
961 | 961 | int Sts; |
962 | 962 | |
963 | 963 | Sts = FFFTP_FAIL; |
@@ -1476,6 +1476,29 @@ static SOCKET DoConnect(char *Host, char *User, char *Pass, char *Acct, int Port | ||
1476 | 1476 | #endif |
1477 | 1477 | TryConnect = NO; |
1478 | 1478 | |
1479 | + // FEAT対応 | |
1480 | + // ホストの機能を確認 | |
1481 | + if(ContSock != INVALID_SOCKET) | |
1482 | + { | |
1483 | + if((Sts = command(ContSock, Reply, &CancelFlg, "FEAT")) == 211) | |
1484 | + { | |
1485 | + // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用 | |
1486 | + // UTF-8対応 | |
1487 | + if(strstr(Reply, " UTF8 ")) | |
1488 | + CurHost.Feature |= FEATURE_UTF8; | |
1489 | + // MLST対応 | |
1490 | + if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD ")) | |
1491 | + CurHost.Feature |= FEATURE_MLSD; | |
1492 | + } | |
1493 | + // UTF-8対応 | |
1494 | + if(CurHost.NameKanjiCode == KANJI_AUTO && (CurHost.Feature & FEATURE_UTF8)) | |
1495 | + { | |
1496 | + if((Sts = command(ContSock, Reply, &CancelFlg, "OPTS UTF8 ON")) == 200) | |
1497 | + { | |
1498 | + } | |
1499 | + } | |
1500 | + } | |
1501 | + | |
1479 | 1502 | return(ContSock); |
1480 | 1503 | } |
1481 | 1504 |
@@ -2238,3 +2261,15 @@ int AskMaxThreadCount(void) | ||
2238 | 2261 | return(CurHost.MaxThreadCount); |
2239 | 2262 | } |
2240 | 2263 | |
2264 | +// FEAT対応 | |
2265 | +int AskHostFeature(void) | |
2266 | +{ | |
2267 | + return(CurHost.Feature); | |
2268 | +} | |
2269 | + | |
2270 | +// MLSD対応 | |
2271 | +int AskUseMLSD(void) | |
2272 | +{ | |
2273 | + return(CurHost.UseMLSD); | |
2274 | +} | |
2275 | + |
@@ -97,6 +97,8 @@ static int CheckYYMMDDformat(char *Str, char Sym, int Dig3); | ||
97 | 97 | static int CheckYYYYMMDDformat(char *Str, char Sym); |
98 | 98 | static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist); |
99 | 99 | static int FindField(char *Str, char *Buf, int Num, int ToLast); |
100 | +// MLSD対応 | |
101 | +static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast); | |
100 | 102 | static void GetMonth(char *Str, WORD *Month, WORD *Day); |
101 | 103 | static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day); |
102 | 104 | static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute); |
@@ -3594,6 +3596,14 @@ static int AnalizeFileInfo(char *Str) | ||
3594 | 3596 | } |
3595 | 3597 | } |
3596 | 3598 | |
3599 | + // MLSD対応 | |
3600 | + if(Ret == LIST_UNKNOWN) | |
3601 | + { | |
3602 | + if(FindField2(Str, Tmp, ';', 1, NO) == FFFTP_SUCCESS && FindField2(Str, Tmp, '=', 1, NO) == FFFTP_SUCCESS) | |
3603 | + { | |
3604 | + Ret = LIST_MLSD; | |
3605 | + } | |
3606 | + } | |
3597 | 3607 | } |
3598 | 3608 | |
3599 | 3609 | DoPrintf("ListType=%d", Ret); |
@@ -4830,6 +4840,56 @@ static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, | ||
4830 | 4840 | Ret = NODE_NONE; |
4831 | 4841 | } |
4832 | 4842 | break; |
4843 | + | |
4844 | + // MLSD対応 | |
4845 | + case LIST_MLSD: | |
4846 | + { | |
4847 | + int i = 0; | |
4848 | + char Tmp[FMAX_PATH + 1]; | |
4849 | + char Name[FMAX_PATH + 1]; | |
4850 | + char Value[FMAX_PATH + 1]; | |
4851 | + while(FindField2(Str, Tmp, ';', i, NO) == FFFTP_SUCCESS) | |
4852 | + { | |
4853 | + if(strncmp(Tmp, " ", 1) == 0) | |
4854 | + strcpy(Fname, Tmp + 1); | |
4855 | + else if(FindField2(Tmp, Name, '=', 0, NO) == FFFTP_SUCCESS && FindField2(Tmp, Value, '=', 1, NO) == FFFTP_SUCCESS) | |
4856 | + { | |
4857 | + if(_stricmp(Name, "type") == 0) | |
4858 | + { | |
4859 | + if(_stricmp(Value, "dir") == 0) | |
4860 | + Ret = NODE_DIR; | |
4861 | + else if(_stricmp(Value, "file") == 0) | |
4862 | + Ret = NODE_FILE; | |
4863 | + } | |
4864 | + else if(_stricmp(Name, "size") == 0) | |
4865 | + { | |
4866 | + *Size = _atoi64(Value); | |
4867 | + *InfoExist |= FINFO_SIZE; | |
4868 | + } | |
4869 | + else if(_stricmp(Name, "modify") == 0) | |
4870 | + { | |
4871 | + sTime.wYear = atoi_n(Value, 4); | |
4872 | + sTime.wMonth = atoi_n(Value + 4, 2); | |
4873 | + sTime.wDay = atoi_n(Value + 6, 2); | |
4874 | + sTime.wHour = atoi_n(Value + 8, 2); | |
4875 | + sTime.wMinute = atoi_n(Value + 10, 2); | |
4876 | + sTime.wSecond = atoi_n(Value + 12, 2); | |
4877 | + SystemTimeToFileTime(&sTime, Time); | |
4878 | + SpecificLocalFileTime2FileTime(Time, AskHostTimeZone()); | |
4879 | + *InfoExist |= FINFO_DATE | FINFO_TIME; | |
4880 | + } | |
4881 | + else if(_stricmp(Name, "UNIX.mode") == 0) | |
4882 | + { | |
4883 | + *Attr = strtol(Value, NULL, 16); | |
4884 | + *InfoExist |= FINFO_ATTR; | |
4885 | + } | |
4886 | + else if(_stricmp(Name, "UNIX.owner") == 0) | |
4887 | + strcpy(Owner, Value); | |
4888 | + } | |
4889 | + i++; | |
4890 | + } | |
4891 | + } | |
4892 | + break; | |
4833 | 4893 | } |
4834 | 4894 | |
4835 | 4895 | if((Ret != NODE_NONE) && (strlen(Fname) > 0)) |
@@ -4902,6 +4962,53 @@ static int FindField(char *Str, char *Buf, int Num, int ToLast) | ||
4902 | 4962 | } |
4903 | 4963 | |
4904 | 4964 | |
4965 | +// MLSD対応 | |
4966 | +static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast) | |
4967 | +{ | |
4968 | + char *Pos; | |
4969 | + int Sts; | |
4970 | + | |
4971 | + Sts = FFFTP_FAIL; | |
4972 | + *Buf = NUL; | |
4973 | + if(Num >= 0) | |
4974 | + { | |
4975 | + while(*Str == Separator) | |
4976 | + Str++; | |
4977 | + | |
4978 | + for(; Num > 0; Num--) | |
4979 | + { | |
4980 | + if((Str = strchr(Str, Separator)) != NULL) | |
4981 | + { | |
4982 | + while(*Str == Separator) | |
4983 | + { | |
4984 | + if(*Str == NUL) | |
4985 | + { | |
4986 | + Str = NULL; | |
4987 | + break; | |
4988 | + } | |
4989 | + Str++; | |
4990 | + } | |
4991 | + } | |
4992 | + else | |
4993 | + break; | |
4994 | + } | |
4995 | + } | |
4996 | + | |
4997 | + if(Str != NULL) | |
4998 | + { | |
4999 | + if((ToLast == YES) || ((Pos = strchr(Str, Separator)) == NULL)) | |
5000 | + strcpy(Buf, Str); | |
5001 | + else | |
5002 | + { | |
5003 | + strncpy(Buf, Str, Pos - Str); | |
5004 | + *(Buf + (Pos - Str)) = NUL; | |
5005 | + } | |
5006 | + Sts = FFFTP_SUCCESS; | |
5007 | + } | |
5008 | + return(Sts); | |
5009 | +} | |
5010 | + | |
5011 | + | |
4905 | 5012 | /*----- 文字列から月を求める -------------------------------------------------- |
4906 | 5013 | * |
4907 | 5014 | * Parameter |
@@ -229,6 +229,8 @@ static void CopyHostToHistory(HOSTDATA *Host, HISTORYDATA *New) | ||
229 | 229 | New->UseSFTP = Host->UseSFTP; |
230 | 230 | // 同時接続対応 |
231 | 231 | New->MaxThreadCount = Host->MaxThreadCount; |
232 | + // MLSD対応 | |
233 | + New->UseMLSD = Host->UseMLSD; | |
232 | 234 | return; |
233 | 235 | } |
234 | 236 |
@@ -284,6 +286,8 @@ void CopyHistoryToHost(HISTORYDATA *Hist, HOSTDATA *Host) | ||
284 | 286 | Host->UseSFTP = Hist->UseSFTP; |
285 | 287 | // 同時接続対応 |
286 | 288 | Host->MaxThreadCount = Hist->MaxThreadCount; |
289 | + // MLSD対応 | |
290 | + Host->UseMLSD = Hist->UseMLSD; | |
287 | 291 | return; |
288 | 292 | } |
289 | 293 |
@@ -1029,6 +1029,8 @@ int CopyHostFromListInConnect(int Num, HOSTDATA *Set) | ||
1029 | 1029 | Set->UseSFTP = Pos->Set.UseSFTP; |
1030 | 1030 | // 同時接続対応 |
1031 | 1031 | Set->MaxThreadCount = Pos->Set.MaxThreadCount; |
1032 | + // MLSD対応 | |
1033 | + Set->UseMLSD = Pos->Set.UseMLSD; | |
1032 | 1034 | Sts = FFFTP_SUCCESS; |
1033 | 1035 | } |
1034 | 1036 | return(Sts); |
@@ -1309,6 +1311,9 @@ void CopyDefaultHost(HOSTDATA *Set) | ||
1309 | 1311 | Set->UseSFTP = YES; |
1310 | 1312 | // 同時接続対応 |
1311 | 1313 | Set->MaxThreadCount = 1; |
1314 | + // MLSD対応 | |
1315 | + Set->Feature = 0; | |
1316 | + Set->UseMLSD = YES; | |
1312 | 1317 | return; |
1313 | 1318 | } |
1314 | 1319 |
@@ -355,6 +355,18 @@ void FreeDuplicatedString(void* p) | ||
355 | 355 | #define END_ROUTINE }while(0);end_of_routine: |
356 | 356 | #define QUIT_ROUTINE goto end_of_routine; |
357 | 357 | |
358 | +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) | |
359 | +{ | |
360 | + int r = 0; | |
361 | + char* pm0 = NULL; | |
362 | +START_ROUTINE | |
363 | + pm0 = DuplicateWtoM(lpCmdLine, -1); | |
364 | + r = WinMainM(hInstance, hPrevInstance, pm0, nCmdShow); | |
365 | +END_ROUTINE | |
366 | + FreeDuplicatedString(pm0); | |
367 | + return r; | |
368 | +} | |
369 | + | |
358 | 370 | HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) |
359 | 371 | { |
360 | 372 | HANDLE r = INVALID_HANDLE_VALUE; |
@@ -11,6 +11,9 @@ | ||
11 | 11 | |
12 | 12 | #ifndef DO_NOT_REPLACE |
13 | 13 | |
14 | +#undef WinMain | |
15 | +#define WinMain WinMainM | |
16 | +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow); | |
14 | 17 | #undef CreateFile |
15 | 18 | #define CreateFile CreateFileM |
16 | 19 | HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); |
@@ -222,5 +225,7 @@ char* DuplicateWtoM(LPCWSTR lpString, int c); | ||
222 | 225 | char* DuplicateWtoA(LPCWSTR lpString, int c); |
223 | 226 | void FreeDuplicatedString(void* p); |
224 | 227 | |
228 | +int WINAPI WinMainM(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); | |
229 | + | |
225 | 230 | #endif |
226 | 231 |
@@ -468,6 +468,8 @@ void SaveRegistory(void) | ||
468 | 468 | SaveIntNum(hKey5, "SFTP", Hist.UseSFTP, DefaultHist.UseSFTP); |
469 | 469 | // 同時接続対応 |
470 | 470 | SaveIntNum(hKey5, "ThreadCount", Hist.MaxThreadCount, DefaultHist.MaxThreadCount); |
471 | + // MLSD対応 | |
472 | + SaveIntNum(hKey5, "MLSD", Hist.UseMLSD, DefaultHist.UseMLSD); | |
471 | 473 | |
472 | 474 | CloseSubKey(hKey5); |
473 | 475 | n++; |
@@ -542,6 +544,8 @@ void SaveRegistory(void) | ||
542 | 544 | SaveIntNum(hKey5, "SFTP", Host.UseSFTP, DefaultHost.UseSFTP); |
543 | 545 | // 同時接続対応 |
544 | 546 | SaveIntNum(hKey5, "ThreadCount", Host.MaxThreadCount, DefaultHost.MaxThreadCount); |
547 | + // MLSD対応 | |
548 | + SaveIntNum(hKey5, "MLSD", Host.UseMLSD, DefaultHost.UseMLSD); | |
545 | 549 | } |
546 | 550 | CloseSubKey(hKey5); |
547 | 551 | } |
@@ -798,6 +802,8 @@ int LoadRegistory(void) | ||
798 | 802 | ReadIntValueFromReg(hKey5, "SFTP", &Hist.UseSFTP); |
799 | 803 | // 同時接続対応 |
800 | 804 | ReadIntValueFromReg(hKey5, "ThreadCount", &Hist.MaxThreadCount); |
805 | + // MLSD対応 | |
806 | + ReadIntValueFromReg(hKey5, "MLSD", &Hist.UseMLSD); | |
801 | 807 | |
802 | 808 | CloseSubKey(hKey5); |
803 | 809 | AddHistoryToHistory(&Hist); |
@@ -871,6 +877,8 @@ int LoadRegistory(void) | ||
871 | 877 | ReadIntValueFromReg(hKey5, "SFTP", &Host.UseSFTP); |
872 | 878 | // 同時接続対応 |
873 | 879 | ReadIntValueFromReg(hKey5, "ThreadCount", &Host.MaxThreadCount); |
880 | + // MLSD対応 | |
881 | + ReadIntValueFromReg(hKey5, "MLSD", &Host.UseMLSD); | |
874 | 882 | |
875 | 883 | CloseSubKey(hKey5); |
876 | 884 |
@@ -593,7 +593,12 @@ static int DoDirList(HWND hWnd, SOCKET cSkt, char *AddOpt, char *Path, int Num, | ||
593 | 593 | } |
594 | 594 | else |
595 | 595 | { |
596 | - strcpy(MainTransPkt.Cmd, "LIST"); | |
596 | + // MLSD対応 | |
597 | +// strcpy(MainTransPkt.Cmd, "LIST"); | |
598 | + if(AskUseMLSD() && (AskHostFeature() & FEATURE_MLSD)) | |
599 | + strcpy(MainTransPkt.Cmd, "MLSD"); | |
600 | + else | |
601 | + strcpy(MainTransPkt.Cmd, "LIST"); | |
597 | 602 | if(strlen(AddOpt) > 0) |
598 | 603 | { |
599 | 604 | strcat(MainTransPkt.Cmd, " -"); |