//This file is part of HTTPServer a Miranda IM plugin
//Copyright (C)2002 Kennet Nielsen
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "Glob.h"
static const char szXmlHeader1[] =	"\r\n"
    "\r\n"
    "\r\n";
static const char szXmlTail[] =	"";
static void ReplaceSign(char* pszSrc, int MaxLength, const char pszReplace, 
												const char * pszNew) {
	static char szBuffer[1024];
	char* pszSign = strchr(pszSrc, pszReplace);
	if (pszSign) {
		strcpy(szBuffer, pszSrc);
		do {
			strcpy(szBuffer + (pszSign - pszSrc), pszNew);
			strcpy(szBuffer + (pszSign - pszSrc) + strlen(pszNew), pszSign + 1);
			*pszSign = ' ';
		} while (pszSign = strchr(pszSrc, pszReplace));
		strncpy(pszSrc, szBuffer, MaxLength);
		pszSrc[MaxLength-1] = '\0';
	}
}
/////////////////////////////////////////////////////////////////////
// Member Function : bCreateIndexXML
// Type            : Global
// Parameters      : pszRealPath - ?
// Returns         :
// Description     :
//
// References      : -
// Remarks         : -
// Created         : 050821, 05 august 2005
// Developer       : Houdini
/////////////////////////////////////////////////////////////////////
bool bCreateIndexXML(const char * pszRealPath, const char * pszIndexPath, 
										 const char * pszSrvPath, DWORD dwRemoteIP) {
	char szMask[MAX_PATH+1];
	strcpy(szMask, pszRealPath);
	strcat(szMask, "*");
	WIN32_FIND_DATAA fdFindFileData;
	HANDLE hFind = FindFirstFile(szMask, &fdFindFileData);
	if (hFind == INVALID_HANDLE_VALUE)
		return FALSE;
	HANDLE hFile = CreateFile(pszIndexPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, 
		OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
		FindClose(hFind);
		return FALSE;
	}
	const int BUFFER_SIZE = 1000;
	char  szBuffer[BUFFER_SIZE+1];
	char* pszBuffer = szBuffer;
	char  szFileName[MAX_PATH+1] = "";
	char* pszExt;
	DWORD dwBytesWritten = 0;
	// Generate Dirname
	strcpy(szBuffer, pszSrvPath);
	char* pszTemp = strrchr(szBuffer, '/');
	if (pszTemp)
		*pszTemp = '\0';
	pszTemp = strrchr(szBuffer, '/');
	if (pszTemp)
		strcpy(szFileName, pszTemp + 1);
	// Write Header
	WriteFile(hFile, szXmlHeader1, sizeof(szXmlHeader1) - 1, &dwBytesWritten, NULL);
	// check if a index.xsl exists in the same directory otherwise use the global
	strcpy(szMask, pszRealPath);
	strcat(szMask, "index.xsl");
	HANDLE hFileExists = CreateFile(szMask, GENERIC_READ, 
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFileExists == INVALID_HANDLE_VALUE) {
		strcpy(szBuffer, "/index.xsl");
	} else {
		CloseHandle(hFileExists);
		strcpy(szBuffer, "index.xsl");
	}
	WriteFile(hFile, szBuffer, strlen(szBuffer), &dwBytesWritten, NULL);
	WriteFile(hFile, szXmlHeader2, sizeof(szXmlHeader2) - 1, &dwBytesWritten, NULL);
	// Write dirname
	ReplaceSign(szFileName, MAX_PATH, '&', "&");
	pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), 
		"  %s\r\n", szFileName);
	WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL);
	// Find files and directories
	do {
		if (strcmp(fdFindFileData.cFileName, ".") &&
		    strncmp(fdFindFileData.cFileName, "@", 1) &&
		    (strcmp(fdFindFileData.cFileName, "..") || strcmp(pszSrvPath, "/"))) { // hide .. in root
			pszBuffer = szBuffer;
			strcpy(szFileName, fdFindFileData.cFileName);
			ReplaceSign(szFileName, MAX_PATH, '&', "&");
			if (fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
				pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), 
					"  - \r\n", szFileName);
			} else {
				pszExt = strrchr(szFileName, '.');
				if (pszExt != NULL) {
					*pszExt = '\0';
					pszExt++;
				}
				pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), 
					"  \r\n");
			}
			if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
				break;
		}
	} while (FindNextFile(hFind, &fdFindFileData));
	if (hFind != 0)
		FindClose(hFind);
	// Add other shared files & directories
	for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) {
		if (!((pclCur->st.dwAllowedIP ^ dwRemoteIP) & pclCur->st.dwAllowedMask) &&  // hide inaccessible shares
		    (size_t)(pclCur->nGetSrvPathLen()) > strlen(pszSrvPath) &&
		    !strstr(pclCur->st.pszRealPath, "\\@") &&
		    !strncmp(pclCur->st.pszSrvPath, pszSrvPath, strlen(pszSrvPath))) {
			pszBuffer = szBuffer;
			strcpy(szFileName, &pclCur->st.pszSrvPath[strlen(pszSrvPath)]);
			ReplaceSign(szFileName, MAX_PATH, '&', "&");
			if (pclCur->bIsDirectory()) {
				szFileName[strlen(szFileName)-1] = '\0';
				if (!strchr(szFileName, '/')) { // only one level deeper
					pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), 
						"
- \r\n", szFileName);
					if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
						break;
				}
			} else {
				if (!strchr(szFileName, '/') &&   // only one level deeper
				    strncmp(pszRealPath, pclCur->st.pszRealPath, strlen(pszRealPath))) { // no duplicates
					pszExt = strrchr(szFileName, '.');
					if (pszExt != NULL) {
						*pszExt = '\0';
						pszExt++;
					}
					DWORD dwFileSize = 0;
					FILETIME ftFileCreateTime;
					FILETIME ftFileAccessTime;
					FILETIME ftFileModifyTime;
					HANDLE hFileS = CreateFile(pclCur->st.pszRealPath, GENERIC_READ, 
						FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
					if (hFileS != INVALID_HANDLE_VALUE) {
						dwFileSize = GetFileSize(hFileS, NULL);
						GetFileTime(hFileS, &ftFileCreateTime, &ftFileAccessTime, &ftFileModifyTime);
						CloseHandle(hFileS);
					}
					pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), 
						"  \r\n");
					if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL))
						break;
				}
			}
		}
	}
	WriteFile(hFile, szXmlTail, sizeof(szXmlTail) - 1, &dwBytesWritten, NULL);
	SetEndOfFile(hFile);
	CloseHandle(hFile);
	return TRUE;
}