contentLister/src/search_files.c File Reference

search - eReader search implementation. More...

#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)


Detailed Description

search - eReader search implementation.

Definition in file search_files.c.


Define Documentation

#define _GNU_SOURCE

Definition at line 30 of file search_files.c.


Function Documentation

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:


Generated on Sun Dec 14 17:13:41 2008 by  doxygen 1.5.6