index.c File Reference

#include "config.h"
#include <sys/time.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <gtk/gtk.h>
#include <unistd.h>
#include <stdlib.h>
#include "log.h"
#include "filetypes.h"
#include "index_db.h"
#include "index.h"
#include "tags.h"
#include "index_ipc.h"
#include "shortcut.h"
Include dependency graph for index.c:

Go to the source code of this file.

Data Structures

struct  fs_entry_t

Typedefs

typedef unsigned long long u_int64_t

Functions

u_int64_t getCurrentTime ()
static gboolean fs_ignore_filename (const gchar *filename)
static db_entry_tcreate_db_entry (const fs_entry_t *fs_entry)
static db_entry_tget_entry (const GSList *db_model, const char *filepath, const char *filename)
static void compare_entry (GSList **db_model, fs_entry_t *fs_entry)
static gboolean ignore_dir (const char *name)
static gboolean ignore_file (const char *filename, const char *ext, gboolean is_dir)
static gboolean ignore_thumbnail_generation (db_entry_t *db_entry)
static void read_directory (const gchar *name, GSList **db_model)
static gboolean send_store_metadata (db_entry_t *db_entry)
static gboolean check_shortcut (const GSList *db_model, const char *filepath, const char *filename, char **display_name, char **author)
static gboolean handle_changes (const GSList *db_model, const char *dir, gboolean skip_thumbnails)
void store_metadata_ready ()
 Handle next documents.
gboolean index_full (gchar *dir, gboolean skip_thumbnails)

Variables

const GSList * g_iter
gchar startdir [256]
int startdirlen = 0
gchar drz_dir [256]
gchar shortcut_dir [256]
gchar ade_thumbs_dir [256]
static const char * HIDDEN_FILENAMES []

Typedef Documentation

typedef unsigned long long u_int64_t

Definition at line 63 of file index.c.


Function Documentation

static gboolean check_shortcut ( const GSList *  db_model,
const char *  filepath,
const char *  filename,
char **  display_name,
char **  author 
) [static]

Definition at line 318 of file index.c.

References shortcut_t::details, ER_OK, shortcut_t::file, get_entry(), is_shortcut_file(), LOGPRINTF, shortcut_t::name, parse_shortcut_file(), shortcut_free, SHORTCUT_TO_APPLICATION, SHORTCUT_TO_FILE, SHORTCUT_TO_FOLDER, startdirlen, and shortcut_t::type.

Referenced by handle_changes().

00323 {
00324     shortcut_t *shortcut = NULL;
00325     int ret = parse_shortcut_file(filepath, filename, &shortcut);
00326     if (ret != ER_OK) {
00327         LOGPRINTF("DENYING: %s/%s - invalid shortcut file", filepath, filename);
00328         return FALSE;
00329     }
00330     g_assert(shortcut);
00331 
00332     if (shortcut->type == SHORTCUT_TO_APPLICATION) {
00333         // dont check application shortcuts
00334         // name and author deliberatly empty, will be read from .desktop file on runtime
00335         *author = g_strdup("");
00336         *display_name = g_strdup("");
00337         goto allowed;
00338     }
00339 
00340     // only allow shortcuts to file or directory (not apps?)
00341     if (shortcut->type != SHORTCUT_TO_FILE &&
00342         shortcut->type != SHORTCUT_TO_FOLDER)
00343     {
00344         LOGPRINTF("DENYING: %s/%s - not shortcut to file/folder", filepath, filename);
00345         goto not_allowed;
00346     }
00347 
00348     // dont allow nested shortcuts
00349     if (is_shortcut_file(shortcut->details.file.filename)) {
00350         LOGPRINTF("DENYING: %s/%s - shortcut to shortcut", filepath, filename);
00351         goto not_allowed;
00352     }
00353 
00354     // check if destination exists in db
00355     if (get_entry(db_model, shortcut->details.file.directory,
00356             shortcut->details.file.filename) == NULL)
00357     {
00358         LOGPRINTF("DENYING: %s/%s - target unknown", filepath, filename);
00359         goto not_allowed;
00360     }
00361 
00362     // pass ownership to display_name
00363     *display_name = shortcut->name;
00364     shortcut->name = NULL;
00365 
00366     // pass target dir relative to startdir (= mountpoint)
00367     const char* localdir = shortcut->details.file.directory + startdirlen;
00368     if (localdir[0] == '/') {   // have subdir
00369         *author = g_strdup_printf("%s/%s", localdir+1, shortcut->details.file.filename);
00370     } else {        // no subdir
00371         *author = g_strdup(shortcut->details.file.filename);
00372     }
00373 
00374 allowed:
00375     shortcut_free(shortcut);
00376     return TRUE;
00377 not_allowed:
00378     shortcut_free(shortcut);
00379     return FALSE;
00380 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void compare_entry ( GSList **  db_model,
fs_entry_t fs_entry 
) [static]

Definition at line 138 of file index.c.

References CHANGED, create_db_entry(), fs_entry_t::date_modified, fs_entry_t::filename, fs_entry_t::filepath, fs_entry_t::filesize, db_entry_t::filesize, get_entry(), fs_entry_t::is_dir, db_entry_t::is_dir, db_entry_t::last_modified, SAME, db_entry_t::state, and UNKNOWN.

Referenced by read_directory().

00139 {
00140     db_entry_t* db_entry = get_entry(*db_model, fs_entry->filepath, fs_entry->filename);
00141     if (db_entry) {     // entry exists
00142         if (db_entry->is_dir != fs_entry->is_dir) {
00143             // add new entry, old entry will be deleted automatically
00144             db_entry_t* new_entry = create_db_entry(fs_entry);
00145             // NOTE: entry should be appended! (first delete old one, then add new one)
00146             *db_model = g_slist_append(*db_model, new_entry);
00147             return;
00148         }
00149         if (!db_entry->is_dir && db_entry->filesize != fs_entry->filesize) {
00150             db_entry->filesize = fs_entry->filesize;
00151             db_entry->state = CHANGED;
00152         }
00153         if (db_entry->last_modified != fs_entry->date_modified) {
00154             db_entry->last_modified = fs_entry->date_modified;
00155             db_entry->state = CHANGED;
00156         }
00157         if (db_entry->state == UNKNOWN) db_entry->state = SAME;
00158     } else {    // unknown entry, add to list
00159         db_entry_t* new_entry = create_db_entry(fs_entry);
00160         *db_model = g_slist_prepend(*db_model, new_entry);
00161         // NOTE: on all entries marked NEW there is memory management on strings!!
00162     }
00163 }

Here is the call graph for this function:

Here is the caller graph for this function:

static db_entry_t* create_db_entry ( const fs_entry_t fs_entry  )  [static]

Definition at line 107 of file index.c.

References fs_entry_t::date_modified, fs_entry_t::filename, db_entry_t::filename, fs_entry_t::filepath, db_entry_t::filepath, fs_entry_t::filesize, db_entry_t::filesize, fs_entry_t::is_dir, db_entry_t::is_dir, db_entry_t::last_modified, NEW, and db_entry_t::state.

Referenced by compare_entry().

00108 {
00109     db_entry_t* entry = g_malloc(sizeof(db_entry_t));
00110     memset(entry, 0, sizeof(db_entry_t));
00111     entry->filename = g_strdup(fs_entry->filename);
00112     entry->filepath = g_strdup(fs_entry->filepath);
00113     entry->is_dir = fs_entry->is_dir;
00114     entry->filesize = fs_entry->filesize;
00115     entry->last_modified = fs_entry->date_modified;
00116     entry->state = NEW;
00117     return entry;
00118 }

Here is the caller graph for this function:

static gboolean fs_ignore_filename ( const gchar *  filename  )  [static]

Definition at line 88 of file index.c.

References HIDDEN_FILENAMES.

Referenced by ignore_file().

00089 {
00090     int len = strlen(filename);
00091     if (len == 0) return TRUE;
00092 
00093     // check on hidden prefix
00094     if (filename[0] == '.' || filename[0] == '_') return TRUE;
00095 
00096     // check on hidden filename
00097     const char** cpp = NULL;
00098     for (cpp = HIDDEN_FILENAMES ; *cpp; cpp++)
00099     {
00100         if ( strcmp(filename, *cpp) == 0 ) return TRUE;
00101     }
00102 
00103     return FALSE;
00104 }

Here is the caller graph for this function:

static db_entry_t* get_entry ( const GSList *  db_model,
const char *  filepath,
const char *  filename 
) [static]

Definition at line 121 of file index.c.

References db_entry_t::filename, and db_entry_t::filepath.

Referenced by check_shortcut(), and compare_entry().

00122 {
00123 
00124     const GSList* iter = db_model;
00125     while (iter) {
00126         db_entry_t* db_entry = iter->data;
00127         if ((strcmp(db_entry->filename, filename) == 0) &&
00128             strcmp(db_entry->filepath, filepath) == 0)
00129         {
00130             return db_entry;
00131         }
00132         iter = g_slist_next(iter);
00133     }
00134     return NULL;
00135 }

Here is the caller graph for this function:

u_int64_t getCurrentTime (  ) 

Definition at line 64 of file index.c.

Referenced by index_full(), main(), on_message_timeout(), and schedule_update().

00065 {
00066     struct timespec now;
00067 
00068     clock_gettime(CLOCK_MONOTONIC, &now);
00069     u_int64_t now64 = now.tv_sec;
00070     now64 *= 1000000;
00071     now64 += (now.tv_nsec/1000);
00072     return now64;
00073 }

Here is the caller graph for this function:

static gboolean handle_changes ( const GSList *  db_model,
const char *  dir,
gboolean  skip_thumbnails 
) [static]

Definition at line 383 of file index.c.

References CHANGED, check_shortcut(), db_add_entry(), db_close(), db_delete_entry(), db_end_transaction(), db_open_global(), db_start_transaction(), db_update_entry(), db_update_shortcut_entry(), ER_OK, ERRORPRINTF, db_entry_t::file_id, db_entry_t::filename, db_entry_t::filepath, g_iter, get_tag_for_file(), ignore_thumbnail_generation(), db_entry_t::is_dir, is_shortcut_file(), LOGPRINTF, NEW, SAME, send_store_metadata(), shortcut_dir, startdir, db_entry_t::state, state2str, tag, UNKNOWN, and WARNPRINTF.

Referenced by index_full().

00384 {
00385     int removed = 0;
00386     int same = 0;
00387     int changed = 0;
00388     int new = 0;
00389 
00390     db_state_t db_state;
00391     if (db_open_global(&db_state, dir) != ER_OK) {
00392         ERRORPRINTF("error opening db");
00393         return FALSE;
00394     }
00395 
00396     int ret = db_start_transaction(&db_state);
00397     if (ret != ER_OK) {
00398         ERRORPRINTF("error starting transaction");
00399         goto error;
00400     }
00401 
00402     const GSList* iter = db_model;
00403     while (iter) {
00404         db_entry_t* db_entry = iter->data;
00405         if (db_entry->state != SAME) {
00406             LOGPRINTF(" %s  %4lld  %s", state2str(db_entry->state), db_entry->file_id, db_entry->filename);
00407         }
00408 
00409         gchar* display_name = NULL;
00410         gchar* author = NULL;
00411 
00412         gboolean is_shortcut = is_shortcut_file(db_entry->filename) && !db_entry->is_dir;
00413         // special checking for shortcuts
00414         if (is_shortcut && db_entry->state != UNKNOWN)
00415         {
00416             if (!check_shortcut(db_model, db_entry->filepath, db_entry->filename, &display_name, &author)) {
00417                 // delete from fs if it's in DIR_SHORTCUTS
00418                 if (strcmp(db_entry->filepath, shortcut_dir) == 0) {
00419                     char fullname[256];
00420                     sprintf(fullname, "%s/%s", db_entry->filepath, db_entry->filename);
00421                     LOGPRINTF("deleting %s", fullname);
00422                     int err = unlink(fullname);
00423                     if (err) {
00424                         WARNPRINTF("cannot delete %s", fullname);
00425                     }
00426                 }
00427                 switch (db_entry->state) {
00428                 case UNKNOWN:
00429                     // was in db, but now deleted, so ok
00430                     break;
00431                 case SAME:
00432                 case CHANGED:
00433                     // was in db, delete by setting to unknown
00434                     db_entry->state = UNKNOWN;
00435                     break;
00436                 case NEW:
00437                     // not yet in db, skip it
00438                     goto next;
00439                 }
00440             }
00441         }
00442 
00443         switch (db_entry->state) {
00444         case UNKNOWN:
00445             db_delete_entry(&db_state, db_entry);
00446             removed++;
00447             break;
00448         case SAME:
00449             // do nothing
00450             same++;
00451             break;
00452         case CHANGED:
00453             db_update_entry(&db_state, db_entry);
00454             if (is_shortcut) {
00455                 db_update_shortcut_entry(&db_state, db_entry, display_name, author);
00456             }
00457             changed++;
00458             break;
00459         case NEW:
00460             {
00461                 const gchar* tag = NULL;
00462                 if (!db_entry->is_dir) tag = get_tag_for_file(db_entry->filename, db_entry->filepath, startdir);
00463                 db_add_entry(&db_state, db_entry, tag, display_name, author);
00464                 new++;
00465                 break;
00466             }
00467         }
00468 next:
00469         g_free(display_name);
00470         g_free(author);
00471         iter = g_slist_next(iter);
00472     }
00473 
00474     db_end_transaction (&db_state);
00475 
00476     if (!skip_thumbnails) {
00477         // This while loop searches for the first document to store metadata and thumbnails for
00478         // The rest of the documents is handled in store_metadata_ready
00479         g_iter = db_model;
00480         while (g_iter) {
00481             db_entry_t* db_entry = g_iter->data;
00482 
00483             if (!ignore_thumbnail_generation(db_entry))
00484             {
00485                 if (send_store_metadata(db_entry))
00486                 {
00487                     gtk_main();
00488                     break;
00489                 }
00490             }
00491             g_iter = g_slist_next(g_iter);
00492         }
00493     }
00494 
00495 error:
00496     db_close(&db_state);
00497     printf("mdbindex: new %d  removed %d  same %d  changed %d\n", new, removed, same, changed);
00498 
00499     return (new + changed + removed) > 0;
00500 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean ignore_dir ( const char *  name  )  [static]

Definition at line 166 of file index.c.

References ade_thumbs_dir.

Referenced by read_directory().

00167 {
00168     if (strcmp(ade_thumbs_dir, name) == 0) return TRUE;
00169     return FALSE;
00170 }

Here is the caller graph for this function:

static gboolean ignore_file ( const char *  filename,
const char *  ext,
gboolean  is_dir 
) [static]

Definition at line 173 of file index.c.

References fs_ignore_filename(), get_viewer_from_file_extension(), and is_shortcut_file_extension().

Referenced by read_directory().

00174 {
00175     if (fs_ignore_filename(filename)) return TRUE;
00176 
00177     // if is directory, don't skip
00178     if (is_dir) return FALSE;
00179 
00180     // ignore files without extension
00181     if (ext[0] == 0) return TRUE;
00182 
00183     // don't skip shortcuts
00184     if (is_shortcut_file_extension(ext)) return FALSE;
00185 
00186     return (get_viewer_from_file_extension(ext) == NULL);
00187 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean ignore_thumbnail_generation ( db_entry_t db_entry  )  [static]

Definition at line 190 of file index.c.

References CHANGED, db_entry_t::filename, g_extension_pointer(), get_generate_thumbnail(), get_viewer_from_file_extension(), db_entry_t::is_dir, NEW, and db_entry_t::state.

Referenced by handle_changes(), and store_metadata_ready().

00191 {
00192     // Only handle changed or new files      
00193     if (db_entry->state != CHANGED && db_entry->state != NEW)
00194       return TRUE;
00195 
00196     // Ignore directories
00197     if (db_entry->is_dir)
00198       return TRUE;
00199 
00200     // Otherwise check extension
00201     const char *ext = g_extension_pointer(db_entry->filename);
00202                      
00203     // Ignore files not configured
00204     if (get_viewer_from_file_extension(ext) == NULL)
00205       return TRUE;
00206       
00207     // Ignore files where thumbnail generation was not enabled for
00208     return (!get_generate_thumbnail(ext));
00209 }

Here is the call graph for this function:

Here is the caller graph for this function:

gboolean index_full ( gchar *  dir,
gboolean  skip_thumbnails 
)

File Name : index.h Copyright (C) 2009 iRex Technologies B.V. All rights reserved.

Definition at line 525 of file index.c.

References ade_thumbs_dir, db_close(), db_get_model(), db_open_global(), DIR_ADE_THUMBS, DIR_DRZ, DIR_SHORTCUTS, drz_dir, ER_OK, ERRORPRINTF, filetypes_init(), getCurrentTime(), handle_changes(), LOGPRINTF, read_directory(), shortcut_dir, startdir, startdirlen, and WARNPRINTF.

Referenced by main().

00526 {
00527     int len = strlen(dir);
00528     // strip off trailing slash
00529     if (len>0 && dir[len-1] == '/') dir[len-1] = '\0';
00530     strncpy(startdir, dir, sizeof(startdir));
00531     startdir[sizeof(startdir)-1] = '\0';
00532     startdirlen = strlen(startdir);
00533 
00534     // check if dir exists and is dir
00535     struct stat statbuf;
00536     int res = stat(dir, &statbuf);
00537     if (res == -1 || !S_ISDIR(statbuf.st_mode)) {
00538         fprintf(stderr, "mdbindex: directory '%s' doesn't exist or is not a dir\n", dir);
00539         return FALSE;
00540     }
00541 
00542     // init static dirs with startdir pre-fix
00543     sprintf(drz_dir, "%s/%s", startdir, DIR_DRZ);
00544     sprintf(shortcut_dir, "%s/%s", startdir, DIR_SHORTCUTS);
00545     sprintf(ade_thumbs_dir, "%s/%s", startdir, DIR_ADE_THUMBS);
00546 
00547     db_state_t db_state;
00548     if (db_open_global(&db_state, dir) != ER_OK)
00549     {
00550         ERRORPRINTF("Failed to open global db");
00551         return FALSE;
00552     }
00553     db_close(&db_state);
00554     
00555     filetypes_init(FALSE);
00556 
00557     // read database model
00558     u_int64_t t1 = getCurrentTime();
00559     GSList* db_model = db_get_model(dir);
00560     if (db_model == NULL) WARNPRINTF("DB is empty");
00561     u_int64_t t2 = getCurrentTime();
00562     u_int64_t diff = t2 - t1;
00563     LOGPRINTF("DB DURATION = %lld ms", diff / 1000);
00564 
00565     // read fs and mark changes
00566     t1 = getCurrentTime();
00567     read_directory(dir, &db_model);
00568     t2 = getCurrentTime();
00569     diff = t2 - t1;
00570     LOGPRINTF("FS/COMPARE DURATION = %lld ms", diff / 1000);
00571 
00572     // update database with changed entries
00573     t1 = getCurrentTime();
00574     gboolean changed = handle_changes(db_model, dir, skip_thumbnails);
00575     t2 = getCurrentTime();
00576     diff = t2 - t1;
00577     LOGPRINTF("DB UPDATE DURATION = %lld ms", diff / 1000);
00578 
00579     // NOTE: not freeing db_model for speed
00580     return changed;
00581 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void read_directory ( const gchar *  name,
GSList **  db_model 
) [static]

Definition at line 212 of file index.c.

References compare_entry(), fs_entry_t::date_modified, drz_dir, ermetadb_close(), ERMETADB_LOCAL_DATABASE_FILE, ermetadb_local_open(), ERRORPRINTF, fs_entry_t::filename, fs_entry_t::filepath, fs_entry_t::filesize, g_extension_pointer(), ignore_dir(), ignore_file(), fs_entry_t::is_dir, is_drz_file_extension(), and LOGPRINTF.

Referenced by index_full().

00213 {
00214     DIR* dir = opendir(name);
00215     if (dir == NULL) {
00216         perror("opendir");
00217         return;
00218     }
00219     struct dirent* current = readdir(dir);
00220     while (current != 0)
00221     {
00222         if (current->d_name[0] == '.') goto next;
00223         char fullname[1024];
00224         snprintf(fullname, sizeof(fullname), "%s/%s", name, current->d_name);
00225         struct stat statbuf;
00226         stat(fullname, &statbuf);
00227 
00228         gboolean is_dir = S_ISDIR(statbuf.st_mode);
00229         gboolean is_reg = S_ISREG(statbuf.st_mode);
00230         if (!is_dir && !is_reg) goto next;
00231 
00232         // try to open and close all local db's for possible version updates
00233         if (strcmp(current->d_name, ERMETADB_LOCAL_DATABASE_FILE) == 0) {
00234             LOGPRINTF("trying to open and close %s", fullname);
00235             erMetadb local_db = ermetadb_local_open(name, TRUE);
00236             if (local_db == NULL) {
00237                 ERRORPRINTF("cannot open db %s", fullname);
00238             }
00239             ermetadb_close(local_db);
00240             goto next;
00241         }
00242 
00243         const char *ext = g_extension_pointer(current->d_name);
00244 
00245         if (is_drz_file_extension(ext))
00246         {
00247             if (strcmp(name, drz_dir) != 0) {
00248                 // create drz dir if it doesn't exist
00249                 g_mkdir_with_parents(drz_dir, 644);
00250     
00251                 // move file to drz directory
00252                 char command[256];
00253                 LOGPRINTF("force moving %s to %s/", fullname, drz_dir);
00254                 sprintf(command, "mv -f %s %s/", fullname, drz_dir);
00255                 system(command);
00256             }
00257             else
00258             {
00259                 LOGPRINTF("ignoring %s", current->d_name);
00260             }
00261             goto next;
00262         }
00263 
00264         if (ignore_file(current->d_name, ext, is_dir))
00265         {
00266             LOGPRINTF("ignoring %s", current->d_name);
00267             goto next;
00268         }
00269 
00270         if (is_dir && ignore_dir(fullname))
00271         {
00272             LOGPRINTF("ignoring %s", current->d_name);
00273             goto next;
00274         }
00275 
00276         fs_entry_t fs_entry;
00277         fs_entry.filename = current->d_name;
00278         fs_entry.filepath = name;
00279         fs_entry.is_dir = is_dir;
00280         fs_entry.filesize = is_dir ? 0 : statbuf.st_size;
00281         fs_entry.date_modified = statbuf.st_mtime;
00282         compare_entry(db_model, &fs_entry);
00283         
00284         if (is_dir)
00285         { 
00286             read_directory(fullname, db_model);
00287         }
00288 next:
00289         current = readdir(dir);
00290     }
00291     closedir(dir);
00292 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean send_store_metadata ( db_entry_t db_entry  )  [static]

Definition at line 309 of file index.c.

References db_entry_t::filename, db_entry_t::filepath, ipc_send_store_metadata(), and LOGPRINTF.

Referenced by handle_changes(), and store_metadata_ready().

00310 {
00311      LOGPRINTF("Store metadata for [%s/%s]", db_entry->filepath, db_entry->filename);
00312      ipc_send_store_metadata(db_entry->filepath, db_entry->filename);
00313      return TRUE;
00314 }

Here is the call graph for this function:

Here is the caller graph for this function:

void store_metadata_ready (  ) 

Handle next documents.

Definition at line 505 of file index.c.

References g_iter, ignore_thumbnail_generation(), and send_store_metadata().

Referenced by on_storemetadata_ready().

00506 {
00507     g_iter = g_slist_next(g_iter);
00508 
00509     while (g_iter) {
00510         db_entry_t* db_entry = g_iter->data;
00511 
00512         if (!ignore_thumbnail_generation(db_entry))
00513         {
00514             if (send_store_metadata(db_entry))
00515             {
00516                 return;
00517             }
00518         }
00519         g_iter = g_slist_next(g_iter);
00520     }
00521     gtk_main_quit();
00522 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

gchar ade_thumbs_dir[256]

Definition at line 51 of file index.c.

Referenced by ignore_dir(), and index_full().

gchar drz_dir[256]

Definition at line 49 of file index.c.

Referenced by index_full(), and read_directory().

const GSList* g_iter

Copyright (C) 2008 iRex Technologies B.V. All rights reserved.

Definition at line 46 of file index.c.

Referenced by handle_changes(), and store_metadata_ready().

const char* HIDDEN_FILENAMES[] [static]
Initial value:
{
    ERMETADB_GLOBAL_DATABASE_FILE,
    ERMETADB_LOCAL_DATABASE_FILE,
    ERMETADB_LOCAL_DATABASE_FILE "-journal",
    ERMETADB_LOCAL_DATABASE_FILE ".old",
    "autorun.inf",
    "Thumbs.db",
    NULL
}

Definition at line 76 of file index.c.

Referenced by fs_ignore_filename().

gchar shortcut_dir[256]

Definition at line 50 of file index.c.

Referenced by create_shortcut_item(), handle_changes(), and index_full().

gchar startdir[256]

Definition at line 47 of file index.c.

Referenced by handle_changes(), and index_full().

int startdirlen = 0

Definition at line 48 of file index.c.

Referenced by check_shortcut(), and index_full().

Generated by  doxygen 1.6.2-20100208