MISR Toolkit  1.5.1
MtkFindFileList.c
Go to the documentation of this file.
1 /*===========================================================================
2 = =
3 = MtkFindFileList =
4 = =
5 =============================================================================
6 
7  Jet Propulsion Laboratory
8  MISR
9  MISR Toolkit
10 
11  Copyright 2005, California Institute of Technology.
12  ALL RIGHTS RESERVED.
13  U.S. Government Sponsorship acknowledged.
14 
15 ============================================================================*/
16 
17 #include "MisrFileQuery.h"
18 #include "MisrError.h"
19 #include <stdio.h> /* standard input/output routines. */
20 #include <sys/stat.h> /* stat(), etc. */
21 #include <string.h> /* strstr(), etc. */
22 
23 #ifdef _WIN32
24  #include "dirent_win32.h"
25 #else
26  #include <dirent.h> /* readdir(), etc. */
27 #endif
28 
29 #ifndef _WIN32
30  #include <unistd.h> /* getcwd(), etc. */
31 #endif
32 
33 #ifndef REGEXP_WORKAROUND
34 #include <regex.h>
35 #endif
36 
37 #ifndef S_ISDIR
38 #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
39 #endif
40 
41 #ifndef REG_BASIC /* REG_BASIC is not defined in regex.h in Linux */
42 # define REG_BASIC 0
43 #endif
44 
45 #define MAX_DIR_PATH 2048 /* maximal full path we support. */
46 #define FILE_LIST_SIZE 20 /* Size to extend file list by */
47 
48 #ifndef REGEXP_WORKAROUND
49 static void findfile(const regex_t* preg, int *count, int *max, char ***file_list, MTKt_status *status);
50 #endif
51 
52 
69  const char *searchdir,
70  const char *product,
71  const char *camera,
72  const char *path,
73  const char *orbit,
74  const char *version,
75  int *filecnt,
76  char **filenames[] )
77 {
78 #ifdef REGEXP_WORKAROUND
79  return MTK_FAILURE;
80 #else // regex enabled
81  MTKt_status status; /* Return status */
82  int status_code = 1;
83  int chdir_status = 0;
84  char **temp_file_list = NULL;
85  char *curr_dir = NULL; /* current directory */
86  int max = FILE_LIST_SIZE;
87  char* dir_path; /* path to the directory. */
88  regex_t preg;
89  int count;
90 
91  int path_name_size = 1024; /* length of curr_dir */
92  struct stat dir_stat; /* used by stat(). */
93  char temp[128];
94 
95 
96  /* Check Arguments */
97  if (searchdir == NULL || product == NULL || path == NULL ||
98  orbit == NULL || version == NULL || filecnt == NULL ||
99  filenames == NULL)
101 
102  dir_path = (char *)searchdir;
103 
104  /* make sure the given path refers to a directory. */
105  if (stat(dir_path, &dir_stat) == -1) {
106  /* perror("stat:"); */
108  }
109 
110  if (!S_ISDIR(dir_stat.st_mode)) {
111  /* fprintf(stderr, "'%s' is not a directory\n", dir_path); */
113  }
114 
115  /* save current directory
116  allocate a larger buffer if needed */
117  curr_dir = (char*)malloc(path_name_size * sizeof(char));
118  while (getcwd(curr_dir,path_name_size) == NULL)
119  {
120  path_name_size += 1024;
121  curr_dir = (char*)realloc(curr_dir,path_name_size * sizeof(char));
122  }
123 
124  /* change into the given directory. */
125  if (chdir(dir_path) == -1) {
126  /*fprintf(stderr, "Cannot change to directory '%s': ", dir_path);
127  perror(""); */
129  }
130 
131  /* Create regular expression */
132  if (camera == NULL)
133  sprintf(temp,"MISR_AM1_%s_P%s_O%s_%s.hdf",product,path,
134  orbit,version);
135  else if (strlen(camera) == 0)
136  sprintf(temp,"MISR_AM1_%s_P%s_O%s_%s.hdf",product,path,
137  orbit,version);
138  else
139  sprintf(temp,"MISR_AM1_%s_P%s_O%s_%s_%s.hdf",product,path,
140  orbit,camera,version);
141 
142  regcomp(&preg,temp,REG_BASIC | REG_NOSUB);
143 
144  /* Allocated memory */
145  max = FILE_LIST_SIZE;
146  temp_file_list = (char**)calloc(max,sizeof(int*));
147  count = 0;
148 
149  /* recursively scan the directory for the given file name pattern. */
150  status = MTK_SUCCESS;
151  findfile(&preg,&count,&max,&temp_file_list,&status);
152 
153  *filecnt = count;
154  *filenames = temp_file_list;
155 
156  /* restore current directory */
157  chdir_status = chdir(curr_dir);
158  if (chdir_status) {
159  perror("chdir error: ");
160  }
161 
162  regfree(&preg);
163  free(curr_dir);
164 
165  return MTK_SUCCESS;
166 
167 ERROR_HANDLE:
168  if (temp_file_list != NULL)
169  MtkStringListFree(max, &temp_file_list);
170 
171  if (curr_dir != NULL)
172  {
173  chdir_status = chdir(curr_dir); /* restore current directory */
174  if (chdir_status) {
175  perror("chdir error: ");
176  }
177  free(curr_dir);
178  }
179 
180  return status_code;
181 #endif
182 }
183 
184 #ifndef REGEXP_WORKAROUND
185 static void findfile(const regex_t* preg, int *count, int *max, char ***file_list, MTKt_status *status)
186 {
187  DIR* dir; /* pointer to the scanned directory. */
188  struct dirent* entry; /* pointer to one directory entry. */
189  char cwd[MAX_DIR_PATH+1]; /* current working directory. */
190  struct stat dir_stat; /* used by stat(). */
191  int len;
192  char **temp_file_list;
193  int i;
194 
195  /* first, save path of current working directory */
196  if (!getcwd(cwd, MAX_DIR_PATH+1))
197  {
198  /*perror("getcwd:");*/
199  return;
200  }
201 
202  /* open the directory for reading */
203  dir = opendir(".");
204  if (!dir)
205  {
206  /*fprintf(stderr, "Cannot read directory '%s': ", cwd);
207  perror("");*/
208  return;
209  }
210 
211  /* scan the directory, traversing each sub-directory, and */
212  /* matching the pattern for each file name. */
213  while ((entry = readdir(dir)))
214  {
215  /* check if the pattern matchs. */
216  if (entry && regexec(preg, entry->d_name, 0, NULL, 0) == 0)
217  {
218  len = strlen(cwd) + strlen(entry->d_name) + 2;
219  if (*count < *max)
220  (*file_list)[*count] = (char*)malloc(len * sizeof(char));
221  else /* Extend List */
222  {
223  temp_file_list = (char**)calloc(*max + FILE_LIST_SIZE, sizeof(int*));
224  if (temp_file_list == NULL)
225  {
226  /*fprintf(stderr,"Error extending memory\n");*/
227  *status = MTK_FAILURE;
228  return;
229  }
230 
231  *max += FILE_LIST_SIZE;
232  for (i = 0; i < *count; ++i)
233  temp_file_list[i] = (*file_list)[i];
234 
235  temp_file_list[*count] = (char*)malloc(len * sizeof(char));
236  *file_list = temp_file_list;
237  }
238 
239  strcpy((*file_list)[*count],cwd);
240  strcat((*file_list)[*count],"/");
241  strcat((*file_list)[*count],entry->d_name);
242  ++*count;
243  }
244 
245  /* check if the given entry is a directory. */
246  if (stat(entry->d_name, &dir_stat) == -1)
247  {
248  /*perror("stat:");*/
249  continue;
250  }
251 
252  /* skip the "." and ".." entries, to avoid loops. */
253  if (strcmp(entry->d_name, ".") == 0)
254  continue;
255 
256  if (strcmp(entry->d_name, "..") == 0)
257  continue;
258 
259  /* is this a directory? */
260  if (S_ISDIR(dir_stat.st_mode))
261  {
262  /* Change into the new directory */
263  if (chdir(entry->d_name) == -1)
264  {
265  /*fprintf(stderr, "Cannot chdir into '%s': ", entry->d_name);
266  perror("");*/
267  continue;
268  }
269  /* check this directory */
270  findfile(preg,count,max,file_list,status);
271 
272  /* finally, restore the original working directory. */
273  if (chdir("..") == -1)
274  {
275  /*fprintf(stderr, "Cannot chdir back to '%s': ", cwd);
276  perror("");*/
277  return;
278  }
279  }
280  }
281 
282  closedir(dir);
283 }
284 #endif
#define REG_NOSUB
Definition: regex.h:134
HDFFCLIBAPI intf intf intf * count
MTKt_status MtkStringListFree(int strcnt, char **strlist[])
Free string list.
int version
Definition: jpeglib.h:901
HDFFCLIBAPI intf * len
int closedir(DIR *dirp)
Definition: dirent.c:225
#define MTK_ERR_CODE_JUMP(code)
Definition: MisrError.h:175
LIBTRE_DLL_IMPEXP void regfree(regex_t *preg)
#define FILE_LIST_SIZE
LIBTRE_DLL_IMPEXP int regcomp(regex_t *preg, const char *regex, int cflags)
#define REG_BASIC
HDFFCLIBAPI int32 float32 * max
MTKt_status MtkFindFileList(const char *searchdir, const char *product, const char *camera, const char *path, const char *orbit, const char *version, int *filecnt, char **filenames[])
Find files in a directory tree, using regular expressions.
#define MAX_DIR_PATH
static void findfile(const regex_t *preg, int *count, int *max, char ***file_list, MTKt_status *status)
struct dirent * readdir(DIR *dirp)
Definition: dirent.c:242
MTKt_status
Definition: MisrError.h:11
char d_name[MAXNAMLEN+1]
Definition: dirent_win32.h:22
DIR * opendir(char *name) const
Definition: dirent.c:78
#define S_ISDIR(x)
Definition: regex.h:100
LIBTRE_DLL_IMPEXP int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)

MISR Toolkit - Copyright © 2005 - 2020 Jet Propulsion Laboratory
Generated on Fri Jun 19 2020 22:49:51