MiscSupport.cpp
资源名称:warftpd.zip [点击查看]
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:30k
源码类别:
Ftp客户端
开发平台:
Visual C++
- // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
- // Copyright 1996 by Jarle Aase. All rights reserved.
- // See the "War Software Series Licende Agreement" for details concerning
- // use and distribution.
- // ---
- // This source code, executables and programs containing source code or
- // binaries or proprietetary technology from the War Software Series are
- // NOT alloed used, viewed or tested by any governmental agencies in
- // any countries. This includes the government, departments, police,
- // military etc.
- // ---
- // This file is intended for use with Tab space = 2
- // Created and maintained in MSVC Developer Studio
- // ---
- // NAME : MiscSupport.cpp
- // PURPOSE : Misc. support functions
- // PROGRAM :
- // DATE : Sept. 21 1996
- // AUTHOR : Jarle Aase
- // ---
- // REVISION HISTORY
- //
- #include "stdafx.h"
- #include "WarSoftware.h"
- #include "parser.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- ////////////////////////////////////////////////////////////////////////////////
- // Global variable initialization
- LPSTR StrDataTypeName[] =
- {
- "CString",
- "int",
- "BOOL",
- "LPSTR",
- ""
- };
- ////////////////////////////////////////////////////////////////////////////////
- // Timer functions
- // class CWarTimer
- CWarTimer::CWarTimer()
- {
- Reset();
- }
- void CWarTimer::Reset()
- {
- m_TimerVal = GetTickCount();
- }
- BOOL CWarTimer::TimeOut(DWORD Milliseconds)
- {
- return TimeDiff() >= Milliseconds;
- }
- DWORD CWarTimer::TimeLeft(DWORD Milliseconds)
- {
- if (!TimeOut(Milliseconds))
- return Milliseconds - TimeDiff();
- else
- return 0;
- }
- DWORD CWarTimer::TimeDiff()
- {
- return TimeDiff(GetTickCount());
- }
- DWORD CWarTimer::TimeDiff(DWORD Milliseconds)
- {
- if (Milliseconds < m_TimerVal)
- {
- // Scroll around.
- // This is not exact, but good enough for the timeout stuff.
- // It will only happen each 37th day or something like that...
- // 64 bit aretmetics will only add overhead.
- m_TimerVal = 0;
- }
- return Milliseconds - m_TimerVal;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // System query functions
- BOOL IsNT()
- {
- OSVERSIONINFO os;
- os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- return (GetVersionEx(&os) && (os.dwPlatformId == VER_PLATFORM_WIN32_NT));
- }
- BOOL HasShell()
- {
- static int Rval = -1;
- if (Rval == -1)
- {
- OSVERSIONINFO os;
- os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (!GetVersionEx(&os))
- Rval = FALSE;
- else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
- Rval = TRUE;
- else if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT) && (os.dwMajorVersion >= 4))
- Rval = TRUE;
- else
- Rval = FALSE;
- }
- return Rval;
- }
- LPCSTR OsName()
- {
- OSVERSIONINFO os;
- static char Rval[32];
- if (*Rval)
- return Rval;
- os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (GetVersionEx(&os))
- {
- sprintf(Rval,"WIN32 (%s %d.%d %d)",
- (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ? "Win95"
- : (os.dwPlatformId == VER_PLATFORM_WIN32_NT) ? "NT" : "Unknown",
- os.dwMajorVersion,
- os.dwMinorVersion,
- os.dwBuildNumber);
- }
- return Rval;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Generic data manipulation
- // class CLinkedListItem
- IMPLEMENT_DYNCREATE(CLinkedListItem, CObject)
- CLinkedListItem::CLinkedListItem()
- {
- m_Next = NULL;
- m_Prev = NULL;
- m_Ptr = NULL;
- }
- CLinkedListItem::~CLinkedListItem()
- {
- #ifdef _DEBUG
- ASSERT(m_Next == NULL);
- ASSERT(m_Prev == NULL);
- ASSERT(m_Ptr == NULL);
- #endif
- }
- // Class CLinkedList
- IMPLEMENT_DYNCREATE(CLinkedList, CObject)
- CLinkedList::CLinkedList()
- {
- m_NumItems = 0;
- m_First = NULL,
- m_Last = NULL;
- }
- CLinkedList::~CLinkedList()
- {
- #ifdef _DEBUG
- ASSERT(m_NumItems == 0);
- #endif
- }
- // Delete all pointrs and the object.
- void CLinkedList::Kill()
- {
- KillAll();
- delete this;
- }
- void CLinkedList::KillAll()
- {
- LPVOID p;
- while((p = GetAndDeleteFirst()) != NULL)
- delete p;
- }
- void CLinkedList::Empty()
- {
- while(GetAndDeleteFirst())
- ;
- }
- CLinkedListItem *CLinkedList::First()
- {
- ASSERT(m_First ? m_First->m_Prev == NULL : TRUE);
- return m_First;
- }
- CLinkedListItem *CLinkedList::Last()
- {
- ASSERT(m_Last ? m_Last->m_Next == NULL : TRUE);
- return m_Last;
- }
- LPVOID CLinkedList::FirstPtr()
- {
- ASSERT(m_First ? m_First->m_Prev == NULL : TRUE);
- return m_First ? m_First->m_Ptr : NULL;
- }
- LPVOID CLinkedList::LastPtr()
- {
- ASSERT(m_Last ? m_Last->m_Next == NULL : TRUE);
- return m_Last ? m_Last->m_Ptr : NULL;
- }
- LPVOID CLinkedList::Ptr(CLinkedListItem *Item)
- {
- ASSERT(Item);
- return Item->m_Ptr;
- }
- CLinkedListItem *CLinkedList::Next(CLinkedListItem *Item)
- {
- ASSERT(Item);
- return Item->m_Next;
- }
- CLinkedListItem *CLinkedList::Prev(CLinkedListItem *Item)
- {
- ASSERT(Item);
- return Item->m_Prev;
- }
- CLinkedListItem *CLinkedList::FindPtr(LPVOID Ptr)
- {
- CLinkedListItem *SearchItem = First();
- while(SearchItem)
- {
- if (SearchItem->m_Ptr == Ptr)
- break;
- SearchItem = Next(SearchItem);
- }
- return SearchItem;
- }
- BOOL CLinkedList::DeletePtr(LPVOID Ptr)
- {
- ASSERT(Ptr);
- CLinkedListItem *Item = FindPtr(Ptr);
- if (Item)
- DeleteItem(Item);
- return Item != NULL;
- }
- void CLinkedList::DeleteItem(CLinkedListItem *Item)
- {
- ASSERT(Item);
- if (Item->m_Prev)
- Item->m_Prev->m_Next = Item->m_Next;
- else
- m_First = Item->m_Next;
- if (Item->m_Next)
- Item->m_Next->m_Prev = Item->m_Prev;
- else
- m_Last = Item->m_Prev;
- --m_NumItems;
- ASSERT(m_NumItems >= 0);
- #ifdef _DEBUG
- Item->m_Next = NULL;
- Item->m_Prev = NULL;
- Item->m_Ptr = NULL;
- #endif
- delete Item;
- }
- void CLinkedList::AddFirst(LPVOID Ptr)
- {
- CLinkedListItem *Item = First();
- AddPtr(Item, NULL, Ptr);
- }
- void CLinkedList::AddLast(LPVOID Ptr)
- {
- CLinkedListItem *Item = Last();
- AddPtr(NULL, Item, Ptr);
- }
- void CLinkedList::AddPtr(CLinkedListItem *Next, CLinkedListItem *Prev, LPVOID Ptr)
- {
- CLinkedListItem *NewItem = new CLinkedListItem;
- NewItem->m_Ptr = Ptr;
- if ((NewItem->m_Prev = Prev) != NULL)
- NewItem->m_Prev->m_Next = NewItem;
- else
- m_First = NewItem;
- if ((NewItem->m_Next = Next) != NULL)
- NewItem->m_Next->m_Prev = NewItem;
- else
- m_Last = NewItem;
- ++m_NumItems;
- }
- LPVOID CLinkedList::GetAndDeleteFirst()
- {
- if (!First())
- return NULL;
- LPVOID Ptr = FirstPtr();
- DeleteItem(First());
- return Ptr;
- }
- LPVOID CLinkedList::GetAndDeleteLast()
- {
- if (!Last())
- return NULL;
- LPVOID Ptr = LastPtr();
- DeleteItem(Last());
- return Ptr;
- }
- void CLinkedList::Sort(int (*SortFunc)(const void *, const void *))
- {
- CLinkedListItem **array = new CLinkedListItem *[m_NumItems];
- CLinkedListItem *Curr = m_First;
- int Index;
- if (!m_NumItems)
- return; // Nothing to sort...
- for(Index = 0; Index < m_NumItems; Index++, Curr = Curr->m_Next)
- array[Index] = Curr;
- ASSERT(Curr == NULL);
- qsort((LPVOID) array, m_NumItems, sizeof(CLinkedListItem *), SortFunc);
- // Relink list
- m_First = array[0];
- m_Last = array[m_NumItems - 1];
- for(Index = 0; Index < m_NumItems; Index++)
- {
- Curr = array[Index];
- if (Index)
- {
- Curr->m_Prev = array[Index - 1];
- Curr->m_Prev->m_Next = Curr;
- }
- else
- Curr->m_Prev = NULL;
- Curr->m_Next = NULL;
- }
- delete array;
- }
- void CLinkedList::operator = (CLinkedList& List)
- {
- Empty();
- Cat(List);
- }
- void CLinkedList::Cat(CLinkedList& List)
- {
- CLinkedListItem *Item;
- for(Item = List.First(); Item; Item = List.Next(Item))
- AddLast(List.Ptr(Item));
- }
- ////////////////////////////////////////////////////////////////////////////////
- // CHistory - derived from CLinkedList
- // Newest on bottom, oldest on top.
- void CHistory::Add(LPVOID Ptr, int MaxItems, BOOL DeletePtr)
- {
- // Decrease the items
- while (m_NumItems && (m_NumItems >= MaxItems))
- {
- if (DeletePtr)
- delete (CString *)FirstPtr();
- DeleteItem(First());
- }
- AddLast(Ptr);
- }
- void CHistory::Add(LPCSTR Ptr, int MaxItems)
- {
- CString *cs = new CString((LPCSTR)Ptr);
- cs->TrimRight();
- Add((LPVOID)cs, MaxItems, TRUE);
- }
- void CHistory::KillAll()
- {
- CString *cs;
- while(cs = (CString *)GetAndDeleteFirst())
- delete cs;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // CLookupListItem
- // Only used by CLookupList, and destroyed by
- CLookupListItem::CLookupListItem(LPVOID Ptr, DWORD NumSymbol, LPCSTR TextSymbol, int DataType)
- {
- m_Name = strdup(TextSymbol);
- m_Number = NumSymbol;
- m_Ptr = Ptr;
- m_DataType = DataType;
- };
- CLookupListItem::~CLookupListItem()
- {
- delete m_Name;
- }
- LPCSTR CLookupListItem::GetData(CString& cBuf)
- {
- return ::GetData(Ptr(),m_DataType,cBuf);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // CLookupList
- // Used to store pointers to objects that can be searched by name or symbolic number
- CLookupList::~CLookupList()
- {
- while(m_List.First())
- m_List.GetAndDeleteFirst();
- }
- void CLookupList::AddItem(LPVOID Ptr, DWORD NumSymbol, LPCSTR TextSymbol, int DataType)
- {
- ASSERT(NumSymbol != 0);
- m_List.AddLast((LPVOID)(new CLookupListItem(Ptr,NumSymbol,TextSymbol,DataType)));
- }
- CLinkedListItem *CLookupList::FindItem(DWORD NumSymbol, LPCSTR TextSymbol)
- {
- CLinkedListItem *ListItem = m_List.First();
- CLookupListItem *Item;
- while(ListItem)
- {
- Item = (CLookupListItem *) (m_List.Ptr(ListItem));
- if (NumSymbol == Item->m_Number)
- break;
- if (TextSymbol && !strcmp(TextSymbol,Item->m_Name))
- break;
- ListItem = m_List.Next(ListItem);
- }
- return ListItem;
- }
- LPVOID CLookupList::Find(DWORD NumSymbol, LPCSTR TextSymbol)
- {
- CLinkedListItem *ListItem = FindItem(NumSymbol, TextSymbol);
- if (!ListItem)
- return NULL;
- ASSERT(ListItem);
- ASSERT(AfxIsValidAddress(ListItem,sizeof(CLinkedListItem)));
- ASSERT(AfxIsValidAddress(ListItem->m_Ptr,4));
- return Ptr(ListItem);
- }
- void CLookupList::DeleteItem(DWORD NumSymbol, LPCSTR TextSymbol)
- {
- CLinkedListItem *Item = FindItem(NumSymbol, TextSymbol);
- if (Item)
- {
- CLookupListItem *LookupItem = (CLookupListItem *)m_List.Ptr(Item);
- delete LookupItem;
- m_List.DeleteItem(Item);
- }
- }
- CLinkedListItem *CLookupList::First()
- {
- return m_List.First();
- }
- CLinkedListItem *CLookupList::Next(CLinkedListItem *Item)
- {
- ASSERT(Item);
- return m_List.Next(Item);
- }
- // Return pointer to the CLookup list node
- CLookupListItem *CLookupList::LookupPtr(CLinkedListItem *Item)
- {
- ASSERT(Item);
- ASSERT(AfxIsValidAddress(Item,sizeof(CLinkedListItem)));
- ASSERT(AfxIsValidAddress(Item->m_Ptr,4));
- return ((CLookupListItem*)m_List.Ptr(Item));
- }
- // Return pointer to the actual data (Name list --> Name node --> Ptr)
- LPVOID CLookupList::Ptr(CLookupListItem *LookupItem)
- {
- ASSERT(LookupItem);
- ASSERT(AfxIsValidAddress(LookupItem,sizeof(CLookupListItem)));
- ASSERT(AfxIsValidAddress(LookupItem->m_Ptr,4));
- ASSERT(AfxIsValidString(LookupItem->m_Name));
- return LookupItem->m_Ptr;
- }
- // Return pointer to the actual data (Name list --> Name node --> Ptr)
- // from pointer to the underlaying list
- LPVOID CLookupList::Ptr(CLinkedListItem *LookupItem)
- {
- return Ptr(LookupPtr(LookupItem));
- }
- // Get data for use in printf()
- LPCSTR CLookupList::GetData(CLinkedListItem *Item, CString& cBuf)
- {
- return GetData(LookupPtr(Item), cBuf);
- }
- // Get data for use in printf
- LPCSTR CLookupList::GetData(CLookupListItem *LookupItem, CString& cBuf)
- {
- ASSERT(LookupItem);
- ASSERT(AfxIsValidAddress(LookupItem,sizeof(CLookupListItem)));
- ASSERT(AfxIsValidAddress(LookupItem->m_Ptr,4));
- return LookupItem->GetData(cBuf);
- }
- void CLookupList::KillAll()
- {
- //m_List.KillAll();
- CLinkedListItem *Item;
- while(Item = m_List.First())
- {
- CLookupListItem *pLI = (CLookupListItem *)m_List.Ptr(Item);
- delete pLI;
- m_List.DeleteItem(Item);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // CString derived class to handle va_list argList
- void CWarString::FormatVaList(LPCTSTR lpszFormat, va_list argList)
- {
- va_list argListSave = argList;
- FormatV(lpszFormat,argList);
- va_end(argListSave);
- }
- void CWarString::FormatCat(LPCTSTR lpszFormat, ...)
- {
- va_list argList = va_start(argList, lpszFormat);
- FormatCatV(lpszFormat,argList);
- va_end(argList);
- }
- int CWarString::FormatCatV(LPCTSTR lpszFormat, va_list argList)
- {
- int OldLen = GetLength();
- va_list argListSave = argList;
- CString cBuf = *this;
- Empty();
- FormatV(lpszFormat,argList);
- va_end(argListSave);
- cBuf += *this;
- Format("%s", cBuf);
- return GetLength() - OldLen;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Safe string array
- LPCSTR SafeStringIndexExp(LPCSTR File, int Line, LPCSTR *StrIndex, int Index, int Limit)
- {
- if ((Index < 0) || (Index >= Limit))
- {
- LPSTR Buf = new char[512];
- sprintf(Buf,"Error: String[%d] in file %s line %d is invalid.",
- Index, File, Line);
- return Buf;
- }
- ASSERT(AfxIsValidString(StrIndex[Index]));
- return StrIndex[Index];
- }
- ////////////////////////////////////////////////////////////////////////////////
- // CCmdArgs
- CCmdArgs::CCmdArgs()
- {
- Initialize();
- }
- CCmdArgs::CCmdArgs(LPCSTR Name, LPCSTR CommandLine, CCommandParser& Parser)
- {
- Initialize();
- AddArg(Name);
- LPCSTR LexCmdLine = CommandLine;
- while(Parser.yyLex(
- &LexCmdLine,
- Parser.m_Tokens,
- ' ',
- LEX_WANT_STRING | LEX_PARSE_QUOTES,
- *this) == TOK_STRING)
- {
- ;
- }
- }
- CCmdArgs::~CCmdArgs()
- {
- Empty();
- }
- void CCmdArgs::Empty()
- {
- IsReInitialized = FALSE;
- int Index;
- AssertValid();
- for(Index = 0; Index < m_argc; Index++)
- delete m_argv[Index];
- delete m_argv;
- }
- void CCmdArgs::Initialize()
- {
- IsReInitialized = TRUE;
- m_argc = 0;
- m_argc_max = 16;
- m_argv = new LPSTR[16];
- }
- void CCmdArgs::PrepereNew()
- {
- if (!IsReInitialized)
- {
- Empty();
- Initialize();
- }
- }
- LPCSTR CCmdArgs::Insert(int Index, LPCSTR Arg, int Len)
- {
- if (Index > m_argc)
- {
- ASSERT(FALSE); // Bad index
- return NULL;
- }
- if (Index == m_argc)
- return AddArg(Arg, Len);
- void Check();
- for(int i = Index; i < m_argc; i++)
- {
- m_argv[i +1] = m_argv[i];
- }
- ++m_argc;
- if (!Len)
- Len = strlen(Arg);
- m_argv[Index] = new char[Len + 1];
- memcpy(m_argv[Index], Arg, Len);
- m_argv[Index][Len] = 0;
- return m_argv[Index];
- };
- LPCSTR CCmdArgs::Replace(int Index, LPCSTR Arg, int Len)
- {
- if (Index > m_argc)
- {
- ASSERT(FALSE); // Bad index
- return NULL;
- }
- if (Index < m_argc)
- delete m_argv[Index];
- if (Arg == NULL)
- m_argv[Index] = NULL;
- else
- {
- if (!Len)
- Len = strlen(Arg);
- m_argv[Index] = new char[Len + 1];
- memcpy(m_argv[Index], Arg, Len);
- m_argv[Index][Len] = 0;
- }
- return m_argv[Index];
- }
- LPCSTR CCmdArgs::AddArg(LPCSTR Arg, int Len)
- {
- ASSERT(AfxIsValidAddress(Arg,sizeof(LPCSTR)));
- ASSERT(AfxIsValidString(Arg));
- IsReInitialized = FALSE;
- Check();
- if (!Len)
- Len = strlen(Arg);
- m_argv[m_argc] = new char[Len + 1];
- memcpy(m_argv[m_argc], Arg, Len);
- m_argv[m_argc][Len] = 0;
- return m_argv[m_argc++];
- }
- void CCmdArgs::Check()
- {
- if (m_argc >= (m_argc_max - 1))
- {
- // Realloc argv
- LPSTR *tmp = new LPSTR[m_argc_max + 256];
- memcpy(tmp, m_argv, sizeof(char *) * m_argc_max);
- m_argc_max += 256;
- delete m_argv;
- m_argv = tmp;
- }
- }
- void CCmdArgs::AssertValid()
- {
- int Index;
- ASSERT(AfxIsValidAddress(this,sizeof(CCmdArgs)));
- ASSERT(m_argc >= 0);
- for(Index = 0; Index < m_argc; Index++)
- {
- ASSERT(AfxIsValidAddress(m_argv[Index],sizeof(LPCSTR)));
- ASSERT(AfxIsValidString(m_argv[Index]));
- }
- }
- // Return an argument
- LPCSTR CCmdArgs::Arg(int Index)
- {
- AssertValid();
- if ((Index < 0) || (Index >= m_argc))
- return "error: CCmdArgs::Arg: Invalid argument number requested.";
- return m_argv[Index];
- }
- int CCmdArgs::operator = (CCmdArgs& Arg)
- {
- int i;
- PrepereNew();
- for(i = 0; i < Arg.m_argc; i++)
- AddArg(Arg[i]);
- return m_argc;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // GetData() - return pointer (or value) for use in printf.
- LPCSTR GetData(LPVOID Ptr, int DataType, CString& cBuf)
- {
- ASSERT(AfxIsValidAddress(Ptr,sizeof(LPVOID)));
- LPCSTR ReturnPtr = "";
- switch(DataType)
- {
- case DATATYPE_CSTRING:
- cBuf = (*(CString *)Ptr);
- break;
- case DATATYPE_INT:
- cBuf.Format("%d",(*(int *)Ptr));
- break;
- case DATATYPE_BOOL:
- cBuf.Format("%s",(*(int *)Ptr) ? "TRUE" : "FALSE");
- break;
- case DATATYPE_LPSTR:
- ASSERT(AfxIsValidString((LPCSTR)Ptr));
- cBuf = (LPCSTR)Ptr;
- break;
- default:
- ReturnPtr = "Error: Invalid Datatype";
- break;
- }
- ReturnPtr = (LPCSTR)cBuf;
- ASSERT(AfxIsValidString(ReturnPtr));
- return ReturnPtr;
- }
- BOOL PutData(LPVOID Ptr, int DataType, LPCSTR Value)
- {
- switch(DataType)
- {
- case DATATYPE_CSTRING:
- (*(CString *)Ptr) = Value;
- break;
- case DATATYPE_INT:
- (*(int *)Ptr) = atoi(Value);
- break;
- case DATATYPE_BOOL:
- (*(int *)Ptr) = atoi(Value) ? TRUE
- : (!stricmp(Value,"TRUE") || !stricmp(Value,"YES")) ? TRUE : FALSE;
- break;
- case DATATYPE_LPSTR:
- ASSERT(FALSE);
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- return TRUE;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // GetlastErrorText()
- CString GetLastErrorText()
- {
- return GetLastErrorText(GetLastError());
- }
- CString GetLastErrorText(int Errno)
- {
- LPVOID lpMsgBuf = NULL;
- CString cBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- Errno,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL);
- if (lpMsgBuf)
- {
- ASSERT(AfxIsValidString((LPCSTR)lpMsgBuf));
- cBuf = (LPCSTR)lpMsgBuf;
- LocalFree(lpMsgBuf);
- }
- else
- {
- cBuf.Format("%d", GetLastError());
- }
- ASSERT(AfxIsValidString(cBuf));
- cBuf.TrimRight();
- return cBuf;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // MySscanf()
- // Does a little better job than the standard lib function...
- // Handles %I64. %C is CString. %O automatically detects octal or binary
- // based on the first digit. (0 = octal, and other digit = 10base).
- int Digits[127];
- int MySscanf(LPCSTR buf, LPCSTR Format, ...)
- {
- va_list marker;
- va_start(marker, Format);
- int Rval = 0;
- char *p;
- int *i;
- __int64 *i64;
- int base;
- int IntegerLength = 32;
- CString *pC;
- Digits['1'] = 1;
- Digits['2'] = 2;
- Digits['3'] = 3;
- Digits['4'] = 4;
- Digits['5'] = 5;
- Digits['6'] = 6;
- Digits['7'] = 7;
- Digits['8'] = 8;
- Digits['9'] = 9;
- Digits['a'] = 10;
- Digits['b'] = 11;
- Digits['c'] = 12;
- Digits['d'] = 13;
- Digits['e'] = 14;
- Digits['f'] = 15;
- Digits['A'] = 10;
- Digits['B'] = 11;
- Digits['C'] = 12;
- Digits['D'] = 13;
- Digits['E'] = 14;
- Digits['F'] = 15;
- while(*Format)
- {
- if (*Format == '%')
- {
- again:
- switch(*++Format)
- {
- case 'c':
- p = va_arg(marker,char *);
- *p = *buf++;
- ++Rval;
- break;
- case 's':
- p = va_arg(marker,char *);
- while(*buf && (!Format[1] || (*buf != Format[1])))
- *p++ = *buf++;
- *p = 0;
- ++Rval;
- break;
- case 'C':
- pC = va_arg(marker,CString *);
- pC->Empty();
- while(*buf && (!Format[1] || (*buf != Format[1])))
- *pC += *buf++;
- ++Rval;
- break;
- case 'I':
- if (!memcmp(Format, "I64", 3))
- {
- Format += 2;
- IntegerLength = 64;
- goto again;
- }
- break;
- case 'l':
- IntegerLength = 32;
- goto again;
- case 'O':
- base = 10;
- if (*buf == '0')
- base = 8; // Octal
- goto scandigit;
- case 'o':
- base = 8;
- goto scandigit;
- case 'd':
- base = 10;
- scandigit:
- if (IntegerLength == 64)
- {
- i64 = va_arg(marker, __int64 *);
- *i64 = 0;
- }
- else
- {
- i = va_arg(marker, int *);
- *i = 0;
- }
- while(*buf && ((*buf == '0') || (Digits[*buf] && (Digits[*buf] < base))))
- {
- if (IntegerLength == 64)
- {
- *i64 *= base;
- *i64 += Digits[*buf];
- }
- else
- {
- *i *= base;
- *i += Digits[*buf];
- }
- ++buf;
- }
- IntegerLength = 32;
- ++Rval;
- break;
- case 'x':
- case 'X':
- base = 16;
- goto scandigit;
- }
- ++Format;
- }
- else
- {
- while(*buf && (*buf != *Format))
- ++buf;
- while(*buf && (*buf == *Format))
- ++buf;
- ++Format;
- //++buf;
- }
- }
- va_end(marker);
- return Rval;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Generic pattern compare function. Several patterns can exist,
- // seperated with rn
- BOOL PatternMatchesName(LPCSTR OrgName, LPCSTR Pattern)
- {
- LPCSTR Name = OrgName, MarkerName = NULL, MarkerPattern = NULL;
- for(;*Pattern ; Pattern++)
- {
- again:
- if ((*Pattern == 'r') || (*Pattern == 'n'))
- {
- if (MarkerName)
- {
- Name = MarkerName;
- Pattern = MarkerPattern;
- MarkerPattern = NULL;
- MarkerName = NULL;
- goto again;
- }
- if (!*Name)
- return TRUE;
- Name = OrgName;
- continue;
- }
- if ((*Pattern == '*') && (!Pattern[1] || (Pattern[1] == 'r') || (Pattern[1] == 'n')))
- return TRUE;
- if (*Pattern == '*')
- {
- MarkerPattern = Pattern;
- while(tolower(*Name) != tolower(Pattern[1]))
- {
- if (!*Name)
- goto next_file;
- ++Name;
- }
- MarkerName = Name +1;
- }
- else if (*Pattern == '?')
- {
- ++Name;
- }
- else if (tolower(*Pattern) != tolower(*Name++))
- {
- if (MarkerName)
- {
- Name = MarkerName;
- Pattern = MarkerPattern;
- MarkerPattern = NULL;
- MarkerName = NULL;
- goto again;
- }
- next_file:
- // Skip to next file
- while(*Pattern && (*Pattern != 'r') && (*Pattern != 'n'))
- ++Pattern;
- Name = OrgName;
- if (!*Pattern)
- return FALSE;
- }
- else if (!*Name)
- {
- MarkerName = NULL;
- MarkerPattern = NULL;
- }
- }
- return *Name == ' ';
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Load a resource string
- LPCSTR LoadString(UINT nID, CString& cBuf)
- {
- if (cBuf.LoadString(nID))
- return (LPCSTR)cBuf;
- else
- return "*ERR*";
- }
- //////////////////////////////////////////////////////////////////////////////////////
- // CDaemonStatus
- // Current server state
- IMPLEMENT_SERIAL(CDaemonStatus, CObject, VERSIONABLE_SCHEMA | 1)
- CDaemonStatus * CDaemonStatus::m_pMe = NULL;
- CDaemonStatus::CDaemonStatus()
- {
- GetSystemTime(&m_ServerStarted);
- m_UserConnections = 0;
- m_OperatorConnections = 0;
- m_UserConnectionsTotal = 0;
- m_OperatorConnectionsTotal = 0;
- m_FileXfers = 0;
- m_FileXfersTotal = 0;
- m_IsOnline = FALSE;
- m_ShutdownPending = FALSE;
- m_ServerName = "";
- m_ServerEmail = "";
- m_ServerType = "";
- m_ServerPort = 0;
- m_ServerListeningIP = "";
- if (!m_pMe)
- m_pMe = this;
- }
- CDaemonStatus::~CDaemonStatus()
- {
- m_ServerName.Empty();
- m_ServerEmail.Empty();
- m_ServerType.Empty();
- m_ServerListeningIP.Empty();
- if (m_pMe == this)
- m_pMe = NULL;
- }
- // Extract the data from a formatted notification from the server
- BOOL CDaemonStatus::Extract(LPSTR Msg)
- {
- LPSTR p, pp;
- for(p = strtok(Msg,"1"); p; p = strtok(NULL, "1"))
- {
- pp = p;
- while(isdigit(*pp))
- ++pp;
- if (*pp == ' ')
- ++pp;
- switch(atoi(p))
- {
- case 1: m_ServerType = pp; break;
- case 2: m_ServerName = pp; break;
- case 3: m_ServerStartedFmt = pp; break;
- case 4: m_ShutdownPending = (stricmp(pp, "Pending") == 0); break;
- case 5: m_IsOnline = (stricmp(pp, "YES") == 0); break;
- case 6: m_ServerListeningIP = pp; break;
- case 7: m_ServerPort = atoi(pp); break;
- case 8: m_UserConnections = atoi(pp); break;
- case 9: m_OperatorConnections = atoi(pp); break;
- case 10: m_FileXfers = atoi(pp); break;
- case 11: m_UserConnectionsTotal = atoi(pp); break;
- case 12: m_OperatorConnectionsTotal = atoi(pp); break;
- case 13: m_FileXfersTotal = atoi(pp); break;
- }
- }
- return TRUE;
- }
- void CDaemonStatus::Serialize(CArchive& ar)
- {
- CObject::Serialize(ar);
- int nVersion = 1;
- if (ar.IsLoading())
- {
- ar >> nVersion;
- if (nVersion != 1)
- {
- AfxThrowFileException(ERROR_BAD_FORMAT);
- return;
- }
- ar >> m_ServerName;
- ar >> m_ServerEmail;
- ar >> m_ServerType;
- ar >> m_ServerPort;
- ar >> m_ServerListeningIP;
- }
- else
- {
- ar << nVersion;
- ar << m_ServerName;
- ar << m_ServerEmail;
- ar << m_ServerType;
- ar << m_ServerPort;
- ar << m_ServerListeningIP;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Get a command line option
- LPCSTR GetLineParam(LPCSTR Tag, CString& cValue, LPCSTR Default)
- {
- LPCSTR p = AfxGetApp()->m_lpCmdLine;
- ASSERT(AfxIsValidString(p));
- ASSERT(AfxIsValidString(Tag));
- ASSERT(AfxIsValidString(Default));
- int len = strlen(Tag);
- ASSERT(len > 0);
- cValue.Empty();
- char TagCh = ' ';
- while(*p)
- {
- if (!strnicmp(p, Tag, len) && ((p == Tag) || (p[-1] == ' ')))
- {
- p += len;
- while(*p && (*p == ' '))
- ++p;
- if (*p == '"')
- TagCh = *(p++);
- while(*p && (*p != TagCh))
- cValue += *p++;
- return cValue;
- }
- ++p;
- }
- cValue = Default;
- return cValue;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Expand string macros
- // String macros as as in CTime.Format()
- // Extentions:
- // %T Type - FTP, MAIL etc.
- // %P Service Port number
- // %R Remote interface port number
- LPCSTR ExpandStringMacros(LPCSTR Str, CString& cValue, CDaemonStatus *Stat)
- { ASSERT(AfxIsValidString(Str));
- cValue.Empty();
- CString cBuf;
- CTime ct = CTime::GetCurrentTime();
- char buf[64];
- if (!Stat)
- Stat = CDaemonStatus::GetStat();
- while(*Str)
- {
- if (*Str == '%')
- {
- if (Str[1] == 'T')
- {
- if (Stat)
- cBuf += Stat->m_ServerType;
- Str += 2;
- continue;
- }
- if (Str[1] == 'P')
- {
- if (Stat)
- cBuf += itoa(Stat->m_ServerPort, buf, 10);
- Str += 2;
- continue;
- }
- if (Str[1] == 'R')
- {
- if (Stat)
- cBuf += itoa(Stat->m_RemoteAPort, buf, 10);
- Str += 2;
- continue;
- }
- }
- cBuf += *Str;
- ++Str;
- }
- cValue = ct.Format(cBuf);
- return cValue;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Make sure that the path exist.
- // Eventually, create the directories
- BOOL ExpandPath(LPCSTR Path)
- {
- CString cBuf("");
- while(*Path)
- {
- if (*Path == '\')
- {
- if (!cBuf.IsEmpty())
- {
- DWORD attr = GetFileAttributes(cBuf);
- if (attr == 0xFFFFFFFF)
- {
- if (!CreateDirectory(cBuf, NULL))
- return FALSE;
- }
- else if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
- return FALSE;
- }
- }
- cBuf += *(Path++);
- }
- return TRUE;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Get free disk space
- __int64 GetFreeDiskSpace(LPCSTR Path)
- {
- CString cBuf(Path);
- char *DriveLetter = cBuf.GetBuffer(1);
- if (DriveLetter[2] == '\' && (cBuf.GetLength() > 3))
- DriveLetter[3] = 0;
- cBuf.ReleaseBuffer();
- DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
- if (!GetDiskFreeSpace(cBuf,&SectorsPerCluster,&BytesPerSector,&NumberOfFreeClusters,&TotalNumberOfClusters))
- return 0;
- return (__int64)NumberOfFreeClusters * (__int64)SectorsPerCluster * (__int64)BytesPerSector / (__int64)1024;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Get the starrtup dir
- CString GetStartupPath()
- {
- extern char far *_pgmptr;
- CString cPath = _pgmptr;
- LPSTR p = strrchr(cPath.GetBuffer(1),'\');
- if (p && *p)
- *p = 0;
- cPath.ReleaseBuffer();
- return cPath;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Time conversion
- // Does not convert to/from local time..
- __int64 CTimeToDate(const CTime& ct)
- {
- SYSTEMTIME st;
- st.wYear = ct.GetYear();
- st.wMonth = ct.GetMonth();
- st.wDayOfWeek = ct.GetDayOfWeek();
- st.wDay = ct.GetDay();
- st.wHour = ct.GetHour();
- st.wMinute = ct.GetMinute();
- st.wSecond = ct.GetSecond();
- st.wMilliseconds = 0;
- FILETIME ft, utcft;
- SystemTimeToFileTime(&st, &ft);
- LocalFileTimeToFileTime(&ft,&utcft);
- return FiletimeToDate(utcft);
- }
- CTime DateToCTime(const __int64 dt)
- {
- return CTime(DateToFiletime(dt));
- }
- __int64 FiletimeToDate(const FILETIME& ft)
- {
- __int64 MyDate = 0;
- MyDate = ft.dwHighDateTime;
- MyDate = MyDate << 32;
- MyDate |= ft.dwLowDateTime;
- return MyDate;
- }
- FILETIME DateToFiletime(const __int64 dt)
- {
- FILETIME ft;
- __int64 MyDate = dt;
- ft.dwLowDateTime = (DWORD)(MyDate & 0xffffffff);
- MyDate = MyDate >> 32;
- ft.dwHighDateTime = (DWORD)MyDate;
- return ft;
- }
- char *Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
- int GetMonthFromLiteral(LPCSTR Month)
- {
- for(int i = 0; i < 12; i++)
- {
- if (!strnicmp(Months[i], Month, 3))
- return ++i;
- }
- return 1;
- }
- BOOL IsMultiline(LPCSTR Text)
- {
- LPCSTR p = strchr(Text,'r');
- while(p && isspace(*p))
- ++p;
- return p && *p;
- }
- CString PrepereForWnd(LPCSTR Text)
- {
- CString cBuf("");
- ASSERT(AfxIsValidString(Text));
- while(*Text)
- {
- if (*Text == 0x0a)
- cBuf += "rn";
- else if (*Text != 0x0d)
- cBuf += *Text;
- ++Text;
- }
- return cBuf;
- }
- // Map the string so that sprintf( str) can be called
- CString MapStringValid(LPCSTR Text)
- {
- CString cBuf("");
- ASSERT(AfxIsValidString(Text));
- while(*Text)
- {
- if (*Text == '%')
- cBuf += '%';
- cBuf += *Text++;
- }
- return cBuf;
- }