dirent.c

Go to the documentation of this file.
00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include "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 (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 /* count the number of entries and get the strlen of the longest name */
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); /* extra 2 for / and NULL */
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)  /* this shouldn't happen */
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 }

Generated on Wed Aug 23 17:48:32 2006 for GRASS by  doxygen 1.4.7