/************************************************************************
 * AUTHOR: NiuJiuRu
 * FILENAME: swdir.c
 * CONTENT: 常用的目录操作接口函数
 * NOTE:
 * HISTORY:
 * 1, [2010-12-24] created by NiuJiuRu
 ************************************************************************/
#include "swapi.h"
#include "swstring.h"
#include "swfile.h"
#include "swdir.h"

/* 创建目录以及该目录前的所有父目录 */
int sw_dir_create(const char *dir)
{
	char path1[MAX_PATH_CHARS] = { 0 }, path2[MAX_PATH_CHARS] = { 0 };
	char *ptr1 = NULL, *ptr2 = NULL;
	int cnt = 0;
	
	if(!dir) return -1;
	
	strncpy(path1, dir, sizeof(path1)-1);
	path1[sizeof(path1) - 1] = '\0';
	xstrcharreplace(path1, '\\', '/');
	ptr1 = path1;
	while(ptr1 < path1+strlen(path1))
	{
		memset(path2, 0, sizeof(path2));
		ptr2 = strchr(ptr1, '/');
		if(ptr2) { memcpy(path2, path1, ptr2-path1 > 0 ? ptr2-path1 : 1); ptr1 = ptr2 + 1; }
		else { strcpy(path2, path1); ptr1 = path1+strlen(path1); }
		
		if(sw_dir_exists(path2)) continue;
		if(mkdir(path2, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) cnt++; // create a new directory success
		else break;
	}
	
	return cnt;
}

/* 删除目录以及该目录下的所有子目录和文件 */
bool sw_dir_delete(const char *dir)
{
	DIR *hDir = NULL; struct dirent *pData = NULL; struct stat statBuf = { 0 };
	char path[MAX_PATH_CHARS] = { 0 }; // full path(dir + entry name)
	bool success = true;
	
	hDir = (DIR *)sw_dir_open(dir);
	if(!hDir) return false;
	while(1)
	{
		pData = (struct dirent *)sw_dir_read(hDir);
		if(!pData) break;
		
		if(xstrcasecmp(pData->d_name, ".") == 0 || xstrcasecmp(pData->d_name, "..") == 0) continue;
		
		memset(path, 0, sizeof(path));
		strncpy(path, dir, sizeof(path)-1);
		xstrcharreplace(path, '\\', '/');
		if(strlen(path) > 0 && path[strlen(path)-1] != '/') strcat(path, "/");
		strcat(path, pData->d_name);
		
		memset(&statBuf, 0, sizeof(statBuf));
		if(lstat(path, &statBuf) == 0) // 用"lstat()"获取文件信息, 避免软链接等特殊文件导致的错误删除
		{
			if(S_ISDIR(statBuf.st_mode)) { if(!sw_dir_delete(path)) { success = false; break; } } // 目录
			else if(sw_file_delete(path) != 0) { success = false; break; } // 文件
		}
	}
	sw_dir_close(hDir);
	
	if(success && rmdir(dir) != 0) return false;
	
	return success;
}

/* 判断目录是否存在 */
bool sw_dir_exists(const char *dir)
{
	if(access(dir, 0) == 0) return true;
	else return false;
}

/* 打开目录 */
void *sw_dir_open(const char *dir)
{
	return opendir(dir);
}

/* 读目录内容, 返回NULL时表示结束 */
void *sw_dir_read(void *hDir)
{
	return readdir(hDir);
}

/* 关闭目录 */
void sw_dir_close(void *hDir)
{
	closedir(hDir);
}

/* 得到文件名 */
char *xGetPathFileName(const char *path)
{
	char *filename1 = NULL, *filename2 = NULL;
	
	filename1 = xstrcasechr(path, "right", '\\');
	filename2 = xstrcasechr(path, "right", '/');
	
	if(filename1 && filename2) return filename1 > filename2 ? filename1+1 : filename2+1;
	else if(filename1 && !filename2) return filename1+1;
	else if(!filename1 && filename2) return filename2+1;
	else return (char *)path;
}

/* 程序运行后, 得到其可执行文件所在的目录及对应文件名 */
int xGetSelfRunningInfo(char *dir, char *bin)
{
	char appModuleFile[MAX_PATH_CHARS] = { 0 };
	char *ptr = NULL;
	
	if(readlink("/proc/self/exe", appModuleFile, sizeof(appModuleFile)) < 0) return -1;
	
	ptr = xGetPathFileName(appModuleFile);
	if(dir) {
		memcpy(dir, appModuleFile, ptr-appModuleFile);
		dir[ptr-appModuleFile] = '\0';
	}
	if(bin) strcpy(bin, ptr);
	
	return 0;
}
