00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include "dbmi.h"
00005
00006 #define R_OK 4
00007 #define W_OK 2
00008 #define X_OK 1
00009
00010 #include <sys/types.h>
00011 #ifdef USE_DIRECT
00012 # include <sys/dir.h>
00013 typedef struct direct dir_entry;
00014 #else
00015 # include <dirent.h>
00016 typedef struct dirent dir_entry;
00017 #endif
00018
00019 extern DIR *opendir();
00020 extern dir_entry *readdir();
00021
00022 static int get_perm();
00023 static void sort_dirent();
00024
00025
00032
00033
00034 dbDirent *
00035 db_dirent (dirname, n)
00036 char *dirname;
00037 int *n;
00038 {
00039 DIR *dp;
00040 dir_entry *entry;
00041 dbDirent *dirent;
00042 int i, count;
00043 char *path;
00044 int len, max;
00045
00046 db_clear_error();
00047
00048 *n = 0;
00049 dp = opendir(dirname);
00050 if (dp == NULL)
00051 {
00052 db_syserror(dirname);
00053 return (dbDirent *) NULL;
00054 }
00055
00056
00057
00058 count = 0;
00059 max = 0;
00060 while (entry = readdir(dp))
00061 {
00062 count++;
00063 len = strlen (entry->d_name);
00064 if (len > max) max = len;
00065 }
00066 rewinddir(dp);
00067
00068 path = db_malloc (strlen(dirname) + max + 2);
00069 if (path == NULL)
00070 {
00071 closedir(dp);
00072 return (dbDirent *) NULL;
00073 }
00074 dirent = db_alloc_dirent_array (count);
00075 if (dirent == NULL)
00076 {
00077 closedir(dp);
00078 return (dbDirent *) NULL;
00079 }
00080 *n = count;
00081 for (i = 0; i < count; i++)
00082 {
00083 entry = readdir(dp);
00084 if (entry == NULL)
00085 break;
00086
00087 if(DB_OK != db_set_string (&dirent[i].name, entry->d_name))
00088 break;
00089 sprintf (path, "%s/%s", dirname, entry->d_name);
00090 dirent[i].perm = get_perm(path);
00091 dirent[i].isdir = (db_isdir(path) == DB_OK);
00092 }
00093 closedir(dp);
00094 free (path);
00095
00096 sort_dirent(dirent, *n);
00097
00098 return dirent;
00099 }
00100
00107 void
00108 db_free_dirent_array (dirent, count)
00109 dbDirent *dirent;
00110 {
00111 int i;
00112
00113 if (dirent)
00114 {
00115 for (i = 0; i < count; i++)
00116 db_free_string(&dirent[i].name);
00117 free(dirent);
00118 }
00119 }
00120
00121 static int
00122 get_perm (path)
00123 char *path;
00124 {
00125 int perm;
00126
00127 perm = 0;
00128
00129 if (access(path,R_OK) == 0)
00130 perm |= DB_PERM_R;
00131 if (access(path,W_OK) == 0)
00132 perm |= DB_PERM_W;
00133 if (access(path,X_OK) == 0)
00134 perm |= DB_PERM_X;
00135
00136 return perm;
00137 }
00138
00139 static int
00140 cmp_dirent (a, b)
00141 dbDirent *a, *b;
00142 {
00143 return strcmp (db_get_string(&a->name), db_get_string(&b->name));
00144 }
00145
00146 static void
00147 sort_dirent (a, n)
00148 dbDirent *a;
00149 int n;
00150 {
00151 qsort (a, n, sizeof(dbDirent), cmp_dirent);
00152 }
00153
00160 dbDirent *
00161 db_alloc_dirent_array (count)
00162 int count;
00163 {
00164 int i;
00165 dbDirent *dirent;
00166
00167 dirent = (dbDirent *) db_calloc (count, sizeof(dbDirent));
00168 if (dirent == NULL)
00169 return dirent;
00170
00171 for (i = 0; i < count; i++)
00172 db_init_string(&dirent[i].name);
00173
00174 return dirent;
00175 }