00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00024
00025
00026
00027
00028
00029
00030 #define _GNU_SOURCE
00031
00032 #include <dirent.h>
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <sys/errno.h>
00037 #include <sys/param.h>
00038 #include <sys/stat.h>
00039 #include <unistd.h>
00040
00041 #include <libermanifest/ermanifest.h>
00042
00043 #include "contentListerLog.h"
00044 #include "metadataStoreManager.h"
00045 #include "search_files.h"
00046 #include "system.h"
00047
00048
00049
00050 int FileExist(const char* filename)
00051 {
00052 struct stat buf;
00053
00054 if(NULL==filename) return 0;
00055
00056 return ( 0==stat(filename, &buf) );
00057 }
00058
00059 static void DirDel(const char* sDir)
00060 {
00061 char* cp;
00062 char* argv[10];
00063 int argc;
00064
00065 argc = 0;
00066 argv[argc++] = "rm";
00067 argv[argc++] = "-rf";
00068
00069 cp = alloca( strlen(sDir) + 1 );
00070 g_assert(cp != NULL);
00071 strcpy(cp, sDir);
00072 argv[argc++] = cp;
00073
00074 argv[argc] = NULL;
00075 g_assert( argc < (sizeof(argv)/sizeof(argv[0])) );
00076 fork_exec(argc, argv);
00077 }
00078
00079
00080
00081 int getEndSepratorLocation(const char* sDir)
00082 {
00083 if( NULL==sDir) return -1;
00084
00085 int iLastPos=strlen(sDir)-1;
00086 if( '/' == sDir[iLastPos] )
00087 {
00088 return iLastPos;
00089 }
00090 return -1;
00091 }
00092
00093
00094 static int searchDirectory(const char* sPath, char** ssSearchTokens, const char* sResultDir)
00095 {
00096 CL_SEARCHPRINTF("entry: path [%s] token [%s] [%s] [%s] resultDir [%s]", sPath, ssSearchTokens[0], ssSearchTokens[1], ssSearchTokens[2], sResultDir);
00097
00098 DIR* dirp = opendir(sPath);
00099 if (dirp == NULL)
00100 {
00101 CL_ERRORPRINTF("Cannot open dir [%s] - %s", sPath, strerror(errno));
00102 return -1;
00103 }
00104
00105 static int recurse_level = 0;
00106 static int symlinks_num = 0;
00107
00108 if (recurse_level > SEARCH_MAX_RECURSE)
00109 {
00110 CL_ERRORPRINTF("Search level too high [%d] sPath [%s]", recurse_level, sPath);
00111 return -1;
00112 }
00113 if (recurse_level == 0)
00114 {
00115 symlinks_num = 0;
00116 }
00117 recurse_level++;
00118
00119 int i;
00120 char* cp;
00121 char** token_ptr;
00122 gboolean patternMatch;
00123 struct dirent* direntp;
00124 struct stat statBuf;
00125 char buf[ERMDS_MAX_FILENAME_SIZE];
00126 char resolvedPath[PATH_MAX];
00127 char fileName[ERMDS_MAX_FILENAME_SIZE];
00128 char* extension;
00129
00130 while ( (direntp = readdir(dirp)) != NULL)
00131 {
00132
00133 if ( direntp->d_name[0] == '.'
00134 || direntp->d_name[0] == '_' )
00135 {
00136 continue;
00137 }
00138
00139
00140 snprintf(buf, sizeof(buf), "%s/%s", sPath, direntp->d_name);
00141 cp = realpath(buf, resolvedPath);
00142 if (cp == NULL)
00143 {
00144 CL_ERRORPRINTF("Cannot resolve path [%s] - %s", buf, strerror(errno));
00145 continue;
00146 }
00147 CL_SEARCHPRINTF("resolved path [%s]", resolvedPath);
00148
00149
00150 cp = strrchr(resolvedPath, '/');
00151 g_assert(cp != NULL);
00152 snprintf(fileName, sizeof(fileName), "%s", cp + 1);
00153 CL_SEARCHPRINTF("filename [%s]", fileName);
00154
00155
00156 if (stat(resolvedPath, &statBuf) == 0)
00157 {
00158
00159 if ( S_ISREG(statBuf.st_mode) || S_ISDIR(statBuf.st_mode) )
00160 {
00161 patternMatch = FALSE;
00162 for (token_ptr = ssSearchTokens ; *token_ptr != NULL ; token_ptr++)
00163 {
00164 cp = strcasestr(fileName, *token_ptr);
00165 if (cp)
00166 {
00167 patternMatch = TRUE;
00168 }
00169 }
00170
00171 if (patternMatch)
00172 {
00173
00174 if (symlinks_num >= SEARCH_MAX_SYMLINKS)
00175 {
00176 CL_ERRORPRINTF("too many search results [%d] path [%s]", symlinks_num, resolvedPath);
00177 }
00178 else
00179 {
00180 symlinks_num++;
00181
00182
00183 snprintf(buf, sizeof(buf), "%s/%s", sResultDir, fileName);
00184 cp = strrchr(fileName, '.');
00185 if (cp)
00186 {
00187 *cp = '\0';
00188 extension = cp + 1;
00189 }
00190 else
00191 {
00192 extension = NULL;
00193 }
00194
00195 for (i = 1 ; FileExist(buf) && i <= 99 ; i++)
00196 {
00197 if (extension)
00198 {
00199 snprintf(buf, sizeof(buf), "%s/%s_%02d.%s", sResultDir, fileName, i, extension);
00200 }
00201 else
00202 {
00203 snprintf(buf, sizeof(buf), "%s/%s_%02d", sResultDir, fileName, i);
00204 }
00205 }
00206
00207
00208 if ( 0 == symlink(resolvedPath, buf) )
00209 {
00210 CL_SEARCHPRINTF("Created symlink [%s] -> [%s]", buf, resolvedPath);
00211 }
00212 else
00213 {
00214 CL_ERRORPRINTF("Cannot create symlink [%s] -> [%s] - %s", buf, resolvedPath, strerror(errno));
00215 }
00216 }
00217 }
00218 }
00219
00220
00221 if ( S_ISDIR(statBuf.st_mode) )
00222 {
00223
00224 snprintf(buf, sizeof(buf), "%s/%s", resolvedPath, MANIFEST_FILENAME);
00225 if ( !FileExist(buf) )
00226 {
00227
00228 cp = strrchr(buf, '/');
00229 g_assert(cp != NULL);
00230 *cp = '\0';
00231 searchDirectory(buf, ssSearchTokens, sResultDir);
00232 }
00233 }
00234 }
00235 }
00236 closedir(dirp);
00237
00238 --recurse_level;
00239 return 0;
00240 }
00241
00242 int execSearch(const char* sPath, const char* sPattern)
00243 {
00244 int i;
00245 char* cp;
00246
00247 CL_SEARCHPRINTF("entry: path [%s] pattern [%s]", sPath, sPattern);
00248
00249 gchar dir_searchresult[ERMDS_MAX_FILENAME_SIZE];
00250 mdsGetRootLocation(st_SearchResult, dir_searchresult, sizeof(dir_searchresult));
00251 CL_SEARCHPRINTF("dir_searchresult [%s]", dir_searchresult);
00252
00253 gchar dir_searchresult_tmp[ERMDS_MAX_FILENAME_SIZE];
00254 snprintf(dir_searchresult_tmp, sizeof(dir_searchresult_tmp), "%s_tmp", dir_searchresult);
00255 CL_SEARCHPRINTF("dir_searchresult_tmp [%s]", dir_searchresult_tmp);
00256
00257 const char* sSearchPath = NULL;
00258 int nRet = -1;
00259
00260
00261 if( 0 == strncmp(sPath, dir_searchresult, sizeof(dir_searchresult)) )
00262 {
00263
00264 rename(dir_searchresult, dir_searchresult_tmp);
00265 sSearchPath = dir_searchresult_tmp;
00266 CL_SEARCHPRINTF("search path [%s]", sSearchPath);
00267 }
00268 else
00269 {
00270
00271 DirDel(dir_searchresult);
00272 sSearchPath = sPath;
00273 CL_SEARCHPRINTF("search path [%s]", sSearchPath);
00274 }
00275 CL_SEARCHPRINTF("search path [%s]", sSearchPath);
00276
00277
00278 if( 0 != mkdir(dir_searchresult, 0755) )
00279 {
00280 CL_ERRORPRINTF("Could not create dir: [%s]",dir_searchresult);
00281 return nRet;
00282 }
00283
00284
00285
00286 char* pattern = alloca( strlen(sPattern) + 1 );
00287 g_assert(pattern != NULL);
00288 strcpy(pattern, sPattern);
00289
00290 char* tokens[MAX_TOKENS_IN_SEARCHSTRING + 1];
00291 int n_tokens = 0;
00292 cp = pattern;
00293 while (*cp)
00294 {
00295 if (*cp == ' ')
00296 {
00297
00298 cp++;
00299 }
00300 else
00301 {
00302
00303 if (n_tokens < MAX_TOKENS_IN_SEARCHSTRING)
00304 {
00305 if (*cp == '"' && *(cp+1) != '"')
00306 {
00307
00308 cp++;
00309 tokens[n_tokens++] = cp;
00310 while (*cp != '"' && *cp != '\0')
00311 {
00312
00313 cp++;
00314 }
00315 if (*cp)
00316 {
00317 *cp = '\0';
00318 cp++;
00319 }
00320 }
00321 else
00322 {
00323
00324 tokens[n_tokens++] = cp;
00325 while (*cp != ' ' && *cp != '\0')
00326 {
00327
00328 cp++;
00329 }
00330 if (*cp)
00331 {
00332 *cp = '\0';
00333 cp++;
00334 }
00335 }
00336 }
00337 }
00338 }
00339 if (n_tokens == 0)
00340 {
00341 tokens[n_tokens++] = "";
00342 }
00343 tokens[n_tokens] = NULL;
00344
00345 CL_SEARCHPRINTF("Search string [%s]", sPattern);
00346 for (i = 0 ; i <= n_tokens ; i++)
00347 {
00348 CL_SEARCHPRINTF("Search token [%d] [%s]", i, tokens[i]);
00349 }
00350
00351
00352 nRet = searchDirectory(sSearchPath, tokens, dir_searchresult);
00353
00354
00355 DirDel(dir_searchresult_tmp);
00356
00357 return nRet;
00358 }