dirent.c

Go to the documentation of this file.
00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <grass/dbmi.h>
00005 /* NOTE: these should come from <unistd.h> or from <sys/file.h> */
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 /* read directory and build an array of dbDirent's */
00033 /* append one entry with name = NULL to mark end of array */
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 /* count the number of entries and get the strlen of the longest name */
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); /* extra 2 for / and NULL */
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)  /* this shouldn't happen */
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 }

Generated on Sun Apr 6 17:31:38 2008 for GRASS by  doxygen 1.5.5