00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <grass/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 (char *dirname, int *n)
00036
00037 {
00038 DIR *dp;
00039 dir_entry *entry;
00040 dbDirent *dirent;
00041 int i, count;
00042 char *path;
00043 int len, max;
00044
00045 db_clear_error();
00046
00047 *n = 0;
00048 dp = opendir(dirname);
00049 if (dp == NULL)
00050 {
00051 db_syserror(dirname);
00052 return (dbDirent *) NULL;
00053 }
00054
00055
00056
00057 count = 0;
00058 max = 0;
00059 while (entry = readdir(dp))
00060 {
00061 count++;
00062 len = strlen (entry->d_name);
00063 if (len > max) max = len;
00064 }
00065 rewinddir(dp);
00066
00067 path = db_malloc (strlen(dirname) + max + 2);
00068 if (path == NULL)
00069 {
00070 closedir(dp);
00071 return (dbDirent *) NULL;
00072 }
00073 dirent = db_alloc_dirent_array (count);
00074 if (dirent == NULL)
00075 {
00076 closedir(dp);
00077 return (dbDirent *) NULL;
00078 }
00079 *n = count;
00080 for (i = 0; i < count; i++)
00081 {
00082 entry = readdir(dp);
00083 if (entry == NULL)
00084 break;
00085
00086 if(DB_OK != db_set_string (&dirent[i].name, entry->d_name))
00087 break;
00088 sprintf (path, "%s/%s", dirname, entry->d_name);
00089 dirent[i].perm = get_perm(path);
00090 dirent[i].isdir = (db_isdir(path) == DB_OK);
00091 }
00092 closedir(dp);
00093 free (path);
00094
00095 sort_dirent(dirent, *n);
00096
00097 return dirent;
00098 }
00099
00106 void
00107 db_free_dirent_array (dbDirent *dirent, int count)
00108
00109 {
00110 int i;
00111
00112 if (dirent)
00113 {
00114 for (i = 0; i < count; i++)
00115 db_free_string(&dirent[i].name);
00116 free(dirent);
00117 }
00118 }
00119
00120 static int
00121 get_perm (char *path)
00122
00123 {
00124 int perm;
00125
00126 perm = 0;
00127
00128 if (access(path,R_OK) == 0)
00129 perm |= DB_PERM_R;
00130 if (access(path,W_OK) == 0)
00131 perm |= DB_PERM_W;
00132 if (access(path,X_OK) == 0)
00133 perm |= DB_PERM_X;
00134
00135 return perm;
00136 }
00137
00138 static int
00139 cmp_dirent (const void *aa, const void *bb)
00140
00141 {
00142 const dbDirent *a = aa;
00143 const dbDirent *b = bb;
00144 return strcmp (db_get_string(&a->name), db_get_string(&b->name));
00145 }
00146
00147 static void
00148 sort_dirent (dbDirent *a, int n)
00149
00150 {
00151 qsort (a, n, sizeof(dbDirent), cmp_dirent);
00152 }
00153
00160 dbDirent *
00161 db_alloc_dirent_array (int count)
00162
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 }