00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <gimp-print/gimp-print.h>
00024 #include "gimp-print-internal.h"
00025 #include <gimp-print/gimp-print-intl-internal.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <errno.h>
00030 #include <dirent.h>
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033 #include <unistd.h>
00034
00035 static int stpi_path_check(const struct dirent *module);
00036 static char *stpi_path_merge(const char *path,
00037 const char *file);
00038 static int stpi_scandir (const char *dir,
00039 struct dirent ***namelist,
00040 int (*sel) (const struct dirent *),
00041 int (*cmp) (const void *, const void *));
00042
00043
00044 static const char *path_check_path;
00045 static const char *path_check_suffix;
00046
00047
00048 static int
00049 dirent_sort(const void *a,
00050 const void *b)
00051 {
00052 return strcoll ((*(const struct dirent **) a)->d_name,
00053 (*(const struct dirent **) b)->d_name);
00054 }
00055
00056
00057
00058
00059
00060 stp_list_t *
00061 stp_path_search(stp_list_t *dirlist,
00062 const char *suffix)
00063 {
00064 stp_list_t *findlist;
00065 stp_list_item_t *diritem;
00066 struct dirent** module_dir;
00067 char *module_name;
00068 int n;
00069
00070 if (!dirlist)
00071 return NULL;
00072
00073 path_check_suffix = suffix;
00074
00075 findlist = stp_list_create();
00076 if (!findlist)
00077 return NULL;
00078 stp_list_set_freefunc(findlist, stp_list_node_free_data);
00079
00080 diritem = stp_list_get_start(dirlist);
00081 while (diritem)
00082 {
00083 path_check_path = (const char *) stp_list_item_get_data(diritem);
00084 stp_deprintf(STP_DBG_PATH, "stp-path: directory: %s\n",
00085 (const char *) stp_list_item_get_data(diritem));
00086 n = stpi_scandir ((const char *) stp_list_item_get_data(diritem),
00087 &module_dir, stpi_path_check, dirent_sort);
00088 if (n >= 0)
00089 {
00090 int idx;
00091 for (idx = 0; idx < n; ++idx)
00092 {
00093 module_name = stpi_path_merge((const char *) stp_list_item_get_data(diritem),
00094 module_dir[idx]->d_name);
00095 stp_list_item_create(findlist, NULL, module_name);
00096 free (module_dir[idx]);
00097 }
00098 free (module_dir);
00099 }
00100 diritem = stp_list_item_next(diritem);
00101 }
00102 return findlist;
00103 }
00104
00105
00106
00107
00108
00109
00110 static int
00111 stpi_path_check(const struct dirent *module)
00112 {
00113 int namelen;
00114 int status = 0;
00115 int savederr;
00116 char *filename;
00117 struct stat modstat;
00118
00119 savederr = errno;
00120
00121
00122 filename = stpi_path_merge(path_check_path, module->d_name);
00123
00124 namelen = strlen(filename);
00125
00126
00127 if (namelen >= strlen(path_check_suffix) + 1)
00128 {
00129 if (!stat (filename, &modstat))
00130 {
00131
00132 if (S_ISREG(modstat.st_mode))
00133 status = 1;
00134 if (strncmp(filename + (namelen - strlen(path_check_suffix)),
00135 path_check_suffix,
00136 strlen(path_check_suffix)))
00137 {
00138 status = 0;
00139 }
00140 }
00141 }
00142
00143 if (status)
00144 stp_deprintf(STP_DBG_PATH, "stp-path: file: `%s'\n", filename);
00145
00146 stp_free(filename);
00147 filename = NULL;
00148
00149 errno = savederr;
00150 return status;
00151 }
00152
00153
00154
00155
00156
00157 static char *
00158 stpi_path_merge(const char *path,
00159 const char *file)
00160 {
00161 char *filename;
00162 int namelen = strlen(path) + strlen(file) + 2;
00163 filename = (char *) stp_malloc(namelen * sizeof(char));
00164 strcpy (filename, path);
00165 strcat (filename, "/");
00166 strcat (filename, file);
00167 filename[namelen - 1] = '\0';
00168 return filename;
00169 }
00170
00171
00172
00173
00174
00175
00176 void
00177 stp_path_split(stp_list_t *list,
00178 const char *path)
00179 {
00180 const char *start = path;
00181 const char *end = NULL;
00182 char *dir = NULL;
00183 int len;
00184
00185 while (start)
00186 {
00187 end = (const char *) strchr(start, ':');
00188 if (!end)
00189 len = strlen(start) + 1;
00190 else
00191 len = (end - start);
00192
00193 if (len && !(len == 1 && !end))
00194 {
00195 dir = (char *) stp_malloc(len + 1);
00196 strncpy(dir, start, len);
00197 dir[len] = '\0';
00198 stp_list_item_create(list, NULL, dir);
00199 }
00200 if (!end)
00201 {
00202 start = NULL;
00203 break;
00204 }
00205 start = end + 1;
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 #ifdef _DIRENT_HAVE_D_NAMLEN
00225 # ifndef _D_EXACT_NAMLEN
00226 # define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
00227 # endif
00228 # ifndef _D_ALLOC_NAMLEN
00229 # define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1)
00230 # endif
00231 #else
00232 # ifndef _D_EXACT_NAMLEN
00233 # define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name))
00234 # endif
00235 # ifndef _D_ALLOC_NAMLEN
00236 # ifdef _DIRENT_HAVE_D_RECLEN
00237 # define _D_ALLOC_NAMLEN(d) (((char *) (d) + (d)->d_reclen) - &(d)->d_name[0])
00238 # else
00239 # define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \
00240 _D_EXACT_NAMLEN (d) + 1)
00241 # endif
00242 # endif
00243 #endif
00244
00245
00246
00247
00248 static int
00249 stpi_scandir (const char *dir,
00250 struct dirent ***namelist,
00251 int (*sel) (const struct dirent *),
00252 int (*cmp) (const void *, const void *))
00253 {
00254 DIR *dp = opendir (dir);
00255 struct dirent **v = NULL;
00256 size_t vsize = 0, i;
00257 struct dirent *d;
00258 int save;
00259
00260 if (dp == NULL)
00261 return -1;
00262
00263 save = errno;
00264 errno = 0;
00265
00266 i = 0;
00267 while ((d = readdir (dp)) != NULL)
00268 if (sel == NULL || (*sel) (d))
00269 {
00270 struct dirent *vnew;
00271 size_t dsize;
00272
00273
00274 errno = 0;
00275
00276 if (i == vsize)
00277 {
00278 struct dirent **new;
00279 if (vsize == 0)
00280 vsize = 10;
00281 else
00282 vsize *= 2;
00283 new = (struct dirent **) realloc (v, vsize * sizeof (*v));
00284 if (new == NULL)
00285 break;
00286 v = new;
00287 }
00288
00289 dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
00290 vnew = (struct dirent *) malloc (dsize);
00291 if (vnew == NULL)
00292 break;
00293
00294 v[i++] = (struct dirent *) memcpy (vnew, d, dsize);
00295 }
00296
00297 if (errno != 0)
00298 {
00299 save = errno;
00300
00301 while (i > 0)
00302 free (v[--i]);
00303 free (v);
00304
00305 i = -1;
00306 }
00307 else
00308 {
00309
00310 if (cmp != NULL)
00311 qsort (v, i, sizeof (*v), cmp);
00312
00313 *namelist = v;
00314 }
00315
00316 (void) closedir (dp);
00317 errno = save;
00318
00319 return i;
00320 }