#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libermanifest/ermanifest.h>
#include "contentListerLog.h"
#include "metadataStoreManager.h"
#include "search_files.h"
#include "system.h"
Go to the source code of this file.
Defines | |
#define | _GNU_SOURCE |
Functions | |
int | FileExist (const char *filename) |
static void | DirDel (const char *sDir) |
int | getEndSepratorLocation (const char *sDir) |
static int | searchDirectory (const char *sPath, char **ssSearchTokens, const char *sResultDir) |
int | execSearch (const char *sPath, const char *sPattern) |
Definition in file search_files.c.
#define _GNU_SOURCE |
Definition at line 30 of file search_files.c.
static void DirDel | ( | const char * | sDir | ) | [static] |
Definition at line 59 of file search_files.c.
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 }
int execSearch | ( | const char * | sPath, | |
const char * | sPattern | |||
) |
Definition at line 242 of file search_files.c.
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; // 0 = ok, -1 = error 00259 00260 // check whether we are searchig in previous search results 00261 if( 0 == strncmp(sPath, dir_searchresult, sizeof(dir_searchresult)) ) 00262 { 00263 // searching in search-results: move old results to temporary location 00264 rename(dir_searchresult, dir_searchresult_tmp); 00265 sSearchPath = dir_searchresult_tmp; 00266 CL_SEARCHPRINTF("search path [%s]", sSearchPath); 00267 } 00268 else 00269 { 00270 // searching elsewhere: discard old results 00271 DirDel(dir_searchresult); 00272 sSearchPath = sPath; 00273 CL_SEARCHPRINTF("search path [%s]", sSearchPath); 00274 } 00275 CL_SEARCHPRINTF("search path [%s]", sSearchPath); 00276 00277 // create directory to hold the search result 00278 if( 0 != mkdir(dir_searchresult, 0755) ) 00279 { 00280 CL_ERRORPRINTF("Could not create dir: [%s]",dir_searchresult); 00281 return nRet; 00282 } 00283 00284 // split search pattern into multiple tokens 00285 // make a working copy of sPattern 00286 char* pattern = alloca( strlen(sPattern) + 1 ); 00287 g_assert(pattern != NULL); 00288 strcpy(pattern, sPattern); 00289 // find tokens 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 // separator: ignore 00298 cp++; 00299 } 00300 else 00301 { 00302 // start of new token 00303 if (n_tokens < MAX_TOKENS_IN_SEARCHSTRING) 00304 { 00305 if (*cp == '"' && *(cp+1) != '"') 00306 { 00307 // token is a quoted string, e.g. "this is a string" 00308 cp++; 00309 tokens[n_tokens++] = cp; 00310 while (*cp != '"' && *cp != '\0') 00311 { 00312 // character is part of token: next character 00313 cp++; 00314 } 00315 if (*cp) 00316 { 00317 *cp = '\0'; 00318 cp++; 00319 } 00320 } 00321 else 00322 { 00323 // token is a single word, e.g. "word" 00324 tokens[n_tokens++] = cp; 00325 while (*cp != ' ' && *cp != '\0') 00326 { 00327 // character is part of token: next character 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 // now search for it 00352 nRet = searchDirectory(sSearchPath, tokens, dir_searchresult); 00353 00354 // clean-up temporary links 00355 DirDel(dir_searchresult_tmp); 00356 00357 return nRet; 00358 }
int FileExist | ( | const char * | filename | ) |
Definition at line 50 of file search_files.c.
00051 { 00052 struct stat buf; 00053 00054 if(NULL==filename) return 0; 00055 00056 return ( 0==stat(filename, &buf) ); 00057 }
int getEndSepratorLocation | ( | const char * | sDir | ) |
Definition at line 81 of file search_files.c.
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 }
static int searchDirectory | ( | const char * | sPath, | |
char ** | ssSearchTokens, | |||
const char * | sResultDir | |||
) | [static] |
Definition at line 94 of file search_files.c.
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; // error 00103 } 00104 00105 static int recurse_level = 0; // nesting level of recursive calls 00106 static int symlinks_num = 0; // number of symlinks created 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; // error 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 // skip hidden entries and current/parent directory 00133 if ( direntp->d_name[0] == '.' 00134 || direntp->d_name[0] == '_' ) 00135 { 00136 continue; 00137 } 00138 00139 // convert symlink to the file or directory behind it 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; // while 00146 } 00147 CL_SEARCHPRINTF("resolved path [%s]", resolvedPath); 00148 // 00149 // set a pointer to the filename 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 // determine what kind of directory entry this really is 00156 if (stat(resolvedPath, &statBuf) == 0) 00157 { 00158 // for file or directory check for pattern match 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 // pattern match -> create symlink 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 // symlink name is filename 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 // add a sequence number in case of duplicate filenames 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 // now create the symlink 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 // recursively search directories that have NO manifest file 00221 if ( S_ISDIR(statBuf.st_mode) ) 00222 { 00223 // check whether directory holds a manifest file 00224 snprintf(buf, sizeof(buf), "%s/%s", resolvedPath, MANIFEST_FILENAME); 00225 if ( !FileExist(buf) ) 00226 { 00227 // no manifest file -> scan recursively 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; // ok 00240 }