Subversion Repositories Tewi

Rev

Rev 315 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
21 nishi 1
/* $Id: dir.c 364 2024-10-17 00:47:01Z nishi $ */
2
 
3
#include "cm_dir.h"
4
 
5
#include "cm_string.h"
6
 
7
#include <sys/stat.h>
219 nishi 8
#if !defined(_MSC_VER) && !defined(__WATCOMC__)
21 nishi 9
#include <dirent.h>
315 nishi 10
#elif defined(__NETWARE__)
11
#include <dirent.h>
261 nishi 12
#elif defined(__WATCOMC__) || defined(_MSC_VER)
219 nishi 13
#include <direct.h>
212 nishi 14
#endif
261 nishi 15
#ifdef _MSC_VER
16
#include <windows.h>
17
#endif
21 nishi 18
#include <stdlib.h>
19
#include <string.h>
20
 
22 nishi 21
int cm_sort(const void* _a, const void* _b) {
21 nishi 22
	char* a = *(char**)_a;
23
	char* b = *(char**)_b;
24
	return strcmp(a, b);
25
}
26
 
22 nishi 27
char** cm_scandir(const char* path) {
215 nishi 28
#if defined(_MSC_VER) || defined(__BORLANDC__)
255 nishi 29
	WIN32_FIND_DATA ffd;
30
	HANDLE hfind;
31
	char** r = malloc(sizeof(*r));
32
	int len;
33
	char** old;
34
	int i;
35
	char* p;
36
	r[0] = NULL;
37
 
38
	p = cm_strcat(path, "/*");
39
	hfind = FindFirstFile(p, &ffd);
40
	if(INVALID_HANDLE_VALUE == hfind) {
41
		return NULL;
42
	}
43
	do {
44
		if(strcmp(ffd.cFileName, ".") != 0 && strcmp(ffd.cFileName, "..") != 0) {
257 nishi 45
			old = r;
46
			for(i = 0; old[i] != NULL; i++)
47
				;
48
			r = malloc(sizeof(*r) * (i + 2));
49
			for(i = 0; old[i] != NULL; i++) r[i] = old[i];
50
			r[i] = cm_strcat(ffd.cFileName, (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? "/" : "");
51
			r[i + 1] = NULL;
52
			free(old);
255 nishi 53
		}
54
	} while(FindNextFile(hfind, &ffd) != 0);
55
	FindClose(hfind);
56
	free(p);
57
	for(len = 0; r[len] != NULL; len++)
58
		;
59
	qsort(r, len, sizeof(char*), cm_sort);
60
 
61
	old = r;
62
	for(i = 0; old[i] != NULL; i++)
63
		;
64
	r = malloc(sizeof(*r) * (i + 2));
65
	for(i = 0; old[i] != NULL; i++) r[i + 1] = old[i];
66
	r[0] = cm_strdup("../");
67
	r[i + 1] = NULL;
68
	free(old);
69
 
70
	return r;
212 nishi 71
#else
364 nishi 72
	char* fxpath = cm_strcat(path, "/");
73
	DIR* dir = opendir(fxpath);
22 nishi 74
	if(dir != NULL) {
21 nishi 75
		char** r = malloc(sizeof(*r));
212 nishi 76
		struct dirent* d;
292 nishi 77
		char** old;
78
		int len;
79
		int i;
21 nishi 80
		r[0] = NULL;
22 nishi 81
		while((d = readdir(dir)) != NULL) {
82
			if(strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
21 nishi 83
				struct stat s;
84
				char* p = cm_strcat3(path, "/", d->d_name);
85
				stat(p, &s);
86
				free(p);
87
 
292 nishi 88
				old = r;
22 nishi 89
				for(i = 0; old[i] != NULL; i++)
90
					;
21 nishi 91
				r = malloc(sizeof(*r) * (i + 2));
92
				for(i = 0; old[i] != NULL; i++) r[i] = old[i];
93
				r[i] = cm_strcat(d->d_name, S_ISDIR(s.st_mode) ? "/" : "");
94
				r[i + 1] = NULL;
95
				free(old);
96
			}
97
		}
22 nishi 98
		for(len = 0; r[len] != NULL; len++)
99
			;
21 nishi 100
		qsort(r, len, sizeof(char*), cm_sort);
22 nishi 101
 
292 nishi 102
		old = r;
22 nishi 103
		for(i = 0; old[i] != NULL; i++)
104
			;
105
		r = malloc(sizeof(*r) * (i + 2));
106
		for(i = 0; old[i] != NULL; i++) r[i + 1] = old[i];
107
		r[0] = cm_strdup("../");
108
		r[i + 1] = NULL;
109
		free(old);
110
 
150 nishi 111
		closedir(dir);
364 nishi 112
		free(fxpath);
150 nishi 113
 
21 nishi 114
		return r;
22 nishi 115
	} else {
364 nishi 116
		free(fxpath);
21 nishi 117
		return NULL;
118
	}
212 nishi 119
#endif
21 nishi 120
}