#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <linux/limits.h>
#include <sys/vfs.h>
#include <glib/gprintf.h>
#include <gtk/gtk.h>
#include <libermanifest/ermanifest.h>
#include "contentListerLog.h"
#include "erConnect.h"
#include "system.h"
#include "gtkPincodeScreen.h"
#include "control.h"
#include "erMdsContent.h"
#include "languages.h"
#include "metadataStoreManager.h"
Go to the source code of this file.
Classes | |
struct | trusted_device_t |
Defines | |
#define | MOBIPOCKET_CHECK1_OFFSET 0x3C |
#define | MOBIPOCKET_FIRST_RECORD 0x4E |
#define | MOBIPOCKET_CHECK2_OFFSET 0x10 |
#define | MOBIPOCKET_ENCODING_OFFSET 0x1C |
#define | MOBIPOCKET_CHECK3_OFFSET 0x24 |
#define | MOBIPOCKET_TITLE_RECORD_OFFSET 0x54 |
#define | MOBIPOCKET_TITLE_LENGTH_OFFSET 0x58 |
#define | MOBIPOCKET_PDB_TITLE_OFFSET 0x00 |
#define | MOBIPOCKET_PDB_TITLE_LENGTH 0x20 |
#define | MOBIPOCKET_ENCODING_UTF8 0xFDE9 |
#define | MOBIPOCKET_ENCODING_WIN1252 0x04E4 |
Functions | |
static int | erClGetFileType (const char *szPath) |
static int | erClGetSymlinkInfo (const char *szRealpath, mdsFsItemType_e *pFit) |
static void | mdsContentPreSort (GArray *contentItemArray, mdsSortStruct_t *sort) |
static void | mdsContentPostSort (GArray *contentItemArray) |
static gint | mdsFieldFsNameComparison (gconstpointer a, gconstpointer b, gpointer user_data) |
static gint | mdsFieldGenericComparison (gconstpointer a, gconstpointer b, gpointer user_data) |
static int | datecmp (const char *dateA, const char *dateB) |
static int | sizecmp (const char *sizeA, const char *sizeB) |
static void | mdsFetchField (mdsFsItem_t *pFsItem, mdsSortStruct_t *sort, char *szField) |
static void | mdsFetchFieldOfFile (mdsFsItem_t *pFsItem, mdsSortStruct_t *sort, char *szField) |
static void | mdsFetchFieldOfFolder (mdsFsItem_t *pFsItem, mdsSortStruct_t *sort, char *szField) |
static void | mdsFetchFieldOfContainer (mdsFsItem_t *pFsItem, mdsSortStruct_t *sort, char *szField) |
static void | mdsFetchFieldOfSymlink (mdsFsItem_t *pFsItem, mdsSortStruct_t *sort, char *szField) |
static void | getFakeTitle (const char *szPath, char *szTitle) |
static int | getSize (const char *pathName) |
static void | getDate (const char *szPath, char *szDate) |
static void | getExtName (const char *szPath, char *szExt) |
static gboolean | getMobipocketTitle (const char *szPath, char *szTitle) |
static gboolean | is_mobipocket_folder (const char *szPath, const int len) |
static void | displayItemSetDefault (clDisplayItem_t *displayItem) |
static void | containerGetDisplayItem (mdsFsItem_t *pFsItem, clDisplayItem_t *displayItem) |
static void | symlinkGetDisplayItem (mdsFsItem_t *pFsItem, clDisplayItem_t *displayItem) |
static void | fileGetDisplayItem (mdsFsItem_t *pFsItem, clDisplayItem_t *displayItem) |
static void | folderGetDisplayItem (mdsFsItem_t *pFsItem, clDisplayItem_t *displayItem) |
static gboolean | extensionIsMobipocket (char *pExt) |
const gchar * | ctrl_is_trusted_path (const char *path) |
int | erMdsContentScan (GArray *dirArray, GArray **contentItemArray) |
int | erMdsContentSort (GArray *contentItemArray, mdsSortStruct_t *sort) |
int | erClGetDisplayItems (GArray *contentItemArray, int nBegin, int *nChunk, clDisplayItem_t *displayItemArray) |
Variables | |
static trusted_device_t | g_trusted_devices [] |
#define MOBIPOCKET_CHECK1_OFFSET 0x3C |
static void containerGetDisplayItem | ( | mdsFsItem_t * | pFsItem, | |
clDisplayItem_t * | displayItem | |||
) | [static] |
Definition at line 1614 of file erMdsFs.c.
01615 { 01616 char* cp = NULL; 01617 char szFilename[ERMDS_MAX_FILENAME_SIZE]; 01618 char szRealpath[PATH_MAX]; 01619 char szManifestPath[ERMDS_MAX_FILENAME_SIZE]; 01620 char storageDirName[ERMDS_MAX_FILENAME_SIZE]; 01621 int nPathLength; 01622 int ret; 01623 struct stat statbuf; 01624 struct statfs statfsbuf; 01625 st_ContentType_e storageType; 01626 mdsFsItem_t fsItemSymlink; 01627 01628 static int nSymlinkChain = 0; 01629 01630 if (NULL == pFsItem || pFsItem->fit != mdsFitContainer || NULL == displayItem) 01631 { 01632 CL_ERRORPRINTF("invalid arguments"); 01633 return; 01634 } 01635 01636 // Convert symlinks into the real path 01637 // Note: also needed for symlinks in directory path, e.g. /opt/content/books/... 01638 cp = realpath(pFsItem->szFilename, szRealpath); 01639 if (cp != NULL) 01640 { 01641 CL_LOGPRINTF("entry %s", szRealpath); 01642 snprintf(szFilename, sizeof(szFilename), "%s", szRealpath); 01643 } 01644 else 01645 { 01646 CL_LOGPRINTF("entry %s", pFsItem->szFilename); 01647 strcpy(szFilename, pFsItem->szFilename); 01648 } 01649 01650 // fit = filesystem item type 01651 displayItem->fit = pFsItem->fit; 01652 01653 // A container is a directory containing a manifest file 01654 nPathLength = g_snprintf(szManifestPath, ERMDS_MAX_FILENAME_SIZE, "%s/" MANIFEST_FILENAME, szFilename); 01655 if ( stat(szManifestPath, &statbuf) == 0 01656 && S_ISREG(statbuf.st_mode) ) 01657 { 01658 // Store Manifest file 01659 strcpy(displayItem->szManifest, szManifestPath); 01660 01661 // Manifest file exists: parse the manifest file 01662 // Note: function erClXmlParseManifest() may change displayItem->fit and ->szManifest 01663 ret = erClXmlParseManifest(szFilename, displayItem); 01664 01665 if (ret == 0) 01666 { 01667 switch (displayItem->fit) 01668 { 01669 case mdsFitContainer: 01670 // normal container: determine the file extension (of the start page) 01671 getExtName(displayItem->szFilename, displayItem->szFileExt); 01672 if (0 == strlen(displayItem->szFileExt)) 01673 { 01674 CL_WARNPRINTF("%s does not have a file extension", szFilename); 01675 } 01676 if (displayItem->size <= 0) 01677 { 01678 // write the size of container to manifest.xml 01679 displayItem->size = getSize(szFilename); 01680 erClXmlSetFieldSize(szFilename, displayItem->size); 01681 } 01682 break; 01683 01684 case mdsFitStorage: 01685 // storage device: get free space when possible 01686 storageType = ctrl_get_storageType(displayItem->szExtID); 01687 if ( stackIsStorage(storageType) 01688 && storageIsMounted(storageType) 01689 && mdsGetRootLocation(storageType, storageDirName, sizeof(storageDirName)) > 0 ) 01690 { 01691 if (statfs(storageDirName, &statfsbuf) == 0) 01692 { 01693 displayItem->size = statfsbuf.f_bavail * statfsbuf.f_bsize / 1024; 01694 } 01695 } 01696 break; 01697 01698 case mdsFitManifestSymlinkLocale: 01699 // Use locale-specific directory, if present. 01700 snprintf( szFilename, sizeof(szFilename), 01701 "%s/.%s", 01702 displayItem->szFilename, 01703 languagesGetLocale() ); 01704 if ( stat(szFilename, &statbuf) == 0 ) 01705 { 01706 strcpy(displayItem->szFilename, szFilename); 01707 } 01708 else 01709 { 01710 snprintf( szFilename, sizeof(szFilename), 01711 "%s/.%s", 01712 displayItem->szFilename, 01713 DEFAULT_LOCALE ); 01714 if ( stat(szFilename, &statbuf) == 0 ) 01715 { 01716 strcpy(displayItem->szFilename, szFilename); 01717 } 01718 else 01719 { 01720 CL_WARNPRINTF("not found [%s]", szFilename); 01721 // downgrade to folder item 01722 fsItemSymlink = *pFsItem; 01723 fsItemSymlink.fit = mdsFitFolder; 01724 strcpy(fsItemSymlink.szFilename, displayItem->szFilename); 01725 folderGetDisplayItem(&fsItemSymlink, displayItem); 01726 break; // exit switch, NO FALLTHROUGH 01727 } 01728 } 01729 // FALLTHROUGH to case mdsFitManifestSymlink 01730 01731 case mdsFitManifestSymlink: 01732 if (nSymlinkChain < ERMDS_MAX_SYMLINK_CHAIN) 01733 { 01734 nSymlinkChain++; 01735 // simulate an FsItem for a symbolic link at filesystem level 01736 fsItemSymlink = *pFsItem; 01737 fsItemSymlink.fit = mdsFitSymlink; 01738 strcpy(fsItemSymlink.szFilename, displayItem->szFilename); 01739 // get details for symlink, or leave displayItem unchanged 01740 symlinkGetDisplayItem(&fsItemSymlink, displayItem); 01741 nSymlinkChain--; 01742 } 01743 else 01744 { 01745 CL_ERRORPRINTF("Symlink chain too long for [%s]", displayItem->szFilename); 01746 ret = -1; 01747 } 01748 break; 01749 01750 default: 01751 if (displayItem->iconID == clUnknownIcon) 01752 { 01753 displayItem->iconID = clFolderIcon; 01754 } 01755 } 01756 } 01757 else 01758 { 01759 CL_ERRORPRINTF("Failure to parse %s", szManifestPath); 01760 CL_ERRORPRINTF("Downgrading %s to folder", szFilename); 01761 // szFilename 01762 strcpy(displayItem->szFilename, szFilename); 01763 // Changing 'fit' to folder 01764 displayItem->fit = mdsFitFolder; 01765 // Determine Icon 01766 displayItem->iconID = clFolderIcon; 01767 // Determine title 01768 getFakeTitle(szFilename, displayItem->szTitle); 01769 } 01770 } 01771 else 01772 { 01773 // Normally this branch will not be taken. 01774 CL_ERRORPRINTF("%s is missing. Illegal branch", szManifestPath); 01775 } 01776 }
const gchar* ctrl_is_trusted_path | ( | const char * | path | ) |
Definition at line 123 of file erMdsFs.c.
00124 { 00125 const gchar* ret = NULL; // return value 00126 trusted_device_t* pDevice; 00127 00128 static gboolean first_time = TRUE; 00129 static char* download_history = NULL; // name of the download history directory 00130 static int download_history_len = 0; 00131 00132 00133 // do first-time initialisations 00134 if (first_time) 00135 { 00136 char dirname[ERMDS_MAX_FILENAME_SIZE]; 00137 00138 // determine length for pathnames of trusted devices 00139 for (pDevice = (trusted_device_t*)&g_trusted_devices[0] ; pDevice->path != NULL ; pDevice++) 00140 { 00141 pDevice->len = strlen(pDevice->path); 00142 } 00143 00144 // determine location of download history 00145 if (mdsGetRootLocation(st_DownloadHistory, dirname, sizeof(dirname)) > 0) 00146 { 00147 download_history = strdup(dirname); 00148 download_history_len = strlen(download_history); 00149 } 00150 00151 // first time happens only once ;-) 00152 first_time = FALSE; 00153 } 00154 00155 // check path in trusted devices 00156 for (pDevice = &g_trusted_devices[0] ; pDevice->path != NULL && ret == NULL ; pDevice++) 00157 { 00158 if (strncmp(path, pDevice->path, pDevice->len) == 0) 00159 { 00160 // found 00161 ret = pDevice->path; 00162 } 00163 } 00164 00165 // if not found, check for download history 00166 if (ret == NULL && download_history) 00167 { 00168 if (strncmp(path, download_history, download_history_len) == 0) 00169 { 00170 // found 00171 ret = download_history; 00172 } 00173 } 00174 00175 // return what we found 00176 return ret; 00177 }
static int datecmp | ( | const char * | dateA, | |
const char * | dateB | |||
) | [static] |
Definition at line 592 of file erMdsFs.c.
00593 { 00594 struct tm tmA, tmB; 00595 time_t timeA, timeB; 00596 double diff = 0; 00597 char *string = NULL; 00598 00599 CL_LOGPRINTF("entry"); 00600 00601 if (NULL == dateA || NULL == dateB) 00602 { 00603 CL_ERRORPRINTF("invalid arguments"); 00604 return diff; 00605 } 00606 00607 string = strptime(dateA, "%Y-%m-%dT%H:%M:%S", &tmA); 00608 string = strptime(dateB, "%Y-%m-%dT%H:%M:%S", &tmB); 00609 timeA = mktime(&tmA); 00610 timeB = mktime(&tmB); 00611 diff = difftime(timeA, timeB); 00612 00613 return (int)diff; 00614 }
static void displayItemSetDefault | ( | clDisplayItem_t * | displayItem | ) | [static] |
Definition at line 1508 of file erMdsFs.c.
01509 { 01510 if (NULL == displayItem) 01511 { 01512 return; 01513 } 01514 displayItem->iconID = clUnknownIcon; 01515 strcpy(displayItem->clIconURL, ""); 01516 strcpy(displayItem->szFileExt, ""); 01517 strcpy(displayItem->szTitle, ""); 01518 strcpy(displayItem->szSubTitle, ""); 01519 strcpy(displayItem->szDate, ""); 01520 strcpy(displayItem->szDescription, ""); 01521 strcpy(displayItem->szFilename, ""); 01522 strcpy(displayItem->szManifest, ""); 01523 displayItem->size = ERCL_INVALID_SIZE; 01524 displayItem->fit = mdsFitUndefined; 01525 displayItem->modifyEnable.bDefault = TRUE; 01526 displayItem->modifyEnable.bDelete = TRUE; 01527 displayItem->modifyEnable.bScribble = TRUE; 01528 displayItem->modifyEnable.bTagging = TRUE; 01529 }
int erClGetDisplayItems | ( | GArray * | contentItemArray, | |
int | nBegin, | |||
int * | nChunk, | |||
clDisplayItem_t * | displayItemArray | |||
) |
Definition at line 1449 of file erMdsFs.c.
01450 { 01451 int nEnd = 0; 01452 int i; 01453 int j; 01454 mdsFsItem_t* pFsItem; 01455 01456 // Validate parameters 01457 if (nBegin < 0 || nBegin >= contentItemArray->len) 01458 { 01459 return ERCL_INVALID_ARGS; 01460 } 01461 else if (*nChunk < 0) 01462 { 01463 return ERCL_INVALID_ARGS; 01464 } 01465 01466 nEnd = (contentItemArray->len - 1 <= nBegin + *nChunk - 1) ? contentItemArray->len - 1 : nBegin + *nChunk - 1; 01467 *nChunk = nEnd - nBegin + 1; 01468 01469 // i counts displayItemArray items 01470 // j counts contentItemArray items 01471 for (i = 0, j = nBegin; i < *nChunk; i++, j++) 01472 { 01473 pFsItem = &g_array_index(contentItemArray, mdsFsItem_t, j); 01474 01475 // set default value of displayItem 01476 displayItemSetDefault(&displayItemArray[i]); 01477 01478 // Get information to be displayed 01479 switch (pFsItem->fit) 01480 { 01481 case mdsFitFile: 01482 fileGetDisplayItem(pFsItem, &displayItemArray[i]); 01483 break; 01484 01485 case mdsFitContainer: 01486 containerGetDisplayItem(pFsItem, &displayItemArray[i]); 01487 break; 01488 01489 case mdsFitFolder: 01490 folderGetDisplayItem(pFsItem, &displayItemArray[i]); 01491 break; 01492 01493 case mdsFitSymlink: 01494 symlinkGetDisplayItem(pFsItem, &displayItemArray[i]); 01495 break; 01496 01497 case mdsFitStorage: 01498 case mdsFitApplication: 01499 case mdsFitManifestDirectory: 01500 default: 01501 CL_LOGPRINTF("No action required."); // No action required. 01502 } 01503 } 01504 01505 return ERCL_OK; 01506 }
static int erClGetFileType | ( | const char * | szPath | ) | [static] |
Definition at line 1363 of file erMdsFs.c.
01364 { 01365 struct stat statBuf; 01366 char * ext; 01367 01368 // TODO ---- TODO ---- TODO ---- TODO 01369 // Check file extension to see if we have to ignore it 01370 // We should create a nice function and get values 01371 // from the registry. Now this is hardcoded for Mobipocket. 01372 // PLEASE FIX ME!!! 01373 ext = strrchr(szPath, '.'); 01374 if (ext && strcasecmp(++ext, "mbp") == 0) 01375 { 01376 CL_LOGPRINTF("Ignoring [%s] because it has extension [%s]", szPath, ext); 01377 return GFT_IGNORE; 01378 } 01379 01380 if (lstat(szPath, &statBuf) == -1) 01381 { 01382 CL_ERRORPRINTF("lstat(%s) returned with error [%s]", szPath, strerror(errno)); 01383 return GFT_NOSUCHFILE; 01384 } 01385 else 01386 { 01387 if (S_ISLNK(statBuf.st_mode)) 01388 { 01389 return GFT_SYMLINK; 01390 } 01391 else if (S_ISDIR(statBuf.st_mode)) 01392 { 01393 return GFT_DIR; 01394 } 01395 else 01396 { 01397 return GFT_FILE; 01398 } 01399 } 01400 }
static int erClGetSymlinkInfo | ( | const char * | szRealpath, | |
mdsFsItemType_e * | pFit | |||
) | [static] |
Definition at line 1402 of file erMdsFs.c.
01403 { 01404 int n; 01405 char szManifestPath[ERMDS_MAX_FILENAME_SIZE]; 01406 struct stat statbuf; 01407 int filetype; 01408 int ret; 01409 01410 // Default return: error 01411 ret = ERCL_NOMATCH; 01412 *pFit = mdsFitUndefined; 01413 g_assert(szRealpath != NULL); 01414 01415 // Determine the fit and filename for symlinks 01416 filetype = erClGetFileType(szRealpath); 01417 switch (filetype) 01418 { 01419 case GFT_FILE: 01420 *pFit = mdsFitFile; 01421 ret = ERCL_OK; 01422 break; 01423 01424 case GFT_DIR: 01425 *pFit = mdsFitFolder; 01426 ret = ERCL_OK; 01427 01428 // If the directory contains a manifest file we have a container 01429 n = g_snprintf(szManifestPath, ERMDS_MAX_FILENAME_SIZE, "%s/" MANIFEST_FILENAME, szRealpath); 01430 if (n < ERMDS_MAX_FILENAME_SIZE) 01431 { 01432 // Does the manifest file exist? 01433 if ( stat(szManifestPath, &statbuf) == 0 01434 && S_ISREG(statbuf.st_mode) ) 01435 { 01436 *pFit = mdsFitContainer; 01437 } 01438 } 01439 break; 01440 01441 default: 01442 CL_ERRORPRINTF("unexpected filetype [%d] for [%s]", filetype, szRealpath); 01443 ; // ignore 01444 } 01445 01446 return ret; 01447 }
int erMdsContentScan | ( | GArray * | dirArray, | |
GArray ** | contentItemArray | |||
) |
Scan an array of directories for content items that match search criteria.
dirArray | An array of directories that will be scanned | |
contentItemArray | Will contain retrieved content items. Pass NULL when you want the function to allocate memory |
Definition at line 183 of file erMdsFs.c.
00184 { 00185 gint nDir; 00186 guint initialArraySize = ERMDS_INITIAL_CONTENT_SCAN_ARRAY_SIZE; 00187 DIR *dirp; 00188 struct dirent *direntp; 00189 mdsFsItem_t fsItem; 00190 int ret = ERMDS_CONTENT_SCAN_OK; 00191 00192 CL_LOGPRINTF("entry"); 00193 00194 // Only create a new array when necessary: 00195 if (*contentItemArray == NULL) 00196 { 00197 CL_LOGPRINTF("Creating a new contentItemArray"); 00198 // Create a new array for initialArraySize items to store mdsFsItem_t values. 00199 // Don't zero-terminate or clear to 0's. 00200 *contentItemArray = g_array_sized_new(FALSE, FALSE, sizeof(mdsFsItem_t), initialArraySize); 00201 } 00202 00203 CL_LOGPRINTF("dirArray->len = %d", dirArray->len); 00204 00205 // Loop over all directories 00206 for (nDir = 0; nDir < dirArray->len; nDir++) 00207 { 00208 // This works because mdsDirectory_t contains the filename as first member 00209 char *szDir = (char *) &g_array_index(dirArray, mdsDirectory_t, nDir); 00210 00211 if ((dirp = opendir(szDir)) == NULL) 00212 { 00213 // This is not an error condition 00214 CL_WARNPRINTF("Could not open directory %s (error %s).", szDir, strerror(errno)); 00215 } 00216 else 00217 { 00218 while ((direntp = readdir(dirp)) != NULL) 00219 { 00220 // Hide '.' and '..' entries and names starting with a dot 00221 // Hide file/dir names starting with an underscore 00222 // Hide 'manifest.xml' files 00223 if ((direntp->d_name[0] != (int) '.') && (direntp->d_name[0] != (int) '_') 00224 && (strcasecmp(MANIFEST_FILENAME, direntp->d_name) != 0)) 00225 { 00226 gint nPathLength; 00227 00228 CL_LOGPRINTF("%s", direntp->d_name); 00229 00230 // Check on buffer overflow 00231 nPathLength = 00232 g_snprintf(fsItem.szFilename, ERMDS_MAX_FILENAME_SIZE, "%s/%s", szDir, direntp->d_name); 00233 fsItem.sortField = NULL; 00234 fsItem.priority = 0; 00235 00236 if (nPathLength < ERMDS_MAX_FILENAME_SIZE) 00237 { 00238 // Determine the file item type: File / Container / Folder 00239 // fprintf(stderr, "(%d)", nPathLength); 00240 int gft = erClGetFileType(fsItem.szFilename); 00241 switch (gft) 00242 { 00243 case GFT_FILE: 00244 fsItem.fit = mdsFitFile; 00245 break; 00246 00247 case GFT_DIR: 00248 { 00249 char szManifestPath[ERMDS_MAX_FILENAME_SIZE]; 00250 struct stat statbuf; 00251 00252 // If the directory contains a manifest file we have a container 00253 g_snprintf( szManifestPath, sizeof(szManifestPath), 00254 "%s/" MANIFEST_FILENAME, 00255 fsItem.szFilename ); 00256 // Does the manifest file exist? 00257 if (stat(szManifestPath, &statbuf) == 0) 00258 { 00259 if (S_ISREG(statbuf.st_mode) != 0) 00260 { 00261 fsItem.fit = mdsFitContainer; 00262 } 00263 else 00264 { 00265 CL_WARNPRINTF("%s is not a regular file, default to folder type", 00266 szManifestPath); 00267 fsItem.fit = mdsFitFolder; 00268 } 00269 } 00270 else 00271 { 00272 fsItem.fit = mdsFitFolder; 00273 } 00274 00275 // Mobipocket HACK, sort it always on top 00276 if (is_mobipocket_folder(fsItem.szFilename, nPathLength)) 00277 { 00278 CL_LOGPRINTF("Found Mobipocket: %s", fsItem.szFilename); 00279 fsItem.priority = MOBIPOCKET_FOLDER_SORT_PRIORITY; 00280 } 00281 } 00282 break; 00283 00284 case GFT_SYMLINK: 00285 fsItem.fit = mdsFitSymlink; 00286 break; 00287 00288 case GFT_NOSUCHFILE: 00289 case GFT_IGNORE: 00290 default: 00291 continue; // while ((direntp = readdir(dirp)) != NULL) 00292 } 00293 00294 if ((*contentItemArray)->len < ERMDS_MAX_CONTENT_SCAN_ARRAY_SIZE) 00295 { 00296 g_array_append_val(*contentItemArray, fsItem); 00297 } 00298 else 00299 { 00300 ret = ERMDS_CONTENT_SCAN_TOO_MANY_ITEMS; 00301 break; 00302 } 00303 } 00304 else 00305 { 00306 CL_ERRORPRINTF("Filename %s/%s too long. (nPathLength (%d) > %d)", szDir, direntp->d_name, 00307 nPathLength, ERMDS_MAX_FILENAME_SIZE); 00308 } 00309 } 00310 } // while ((direntp = readdir(dirp)) != NULL) 00311 closedir(dirp); 00312 } 00313 if (ret == ERMDS_CONTENT_SCAN_TOO_MANY_ITEMS) 00314 { 00315 return ret; 00316 } 00317 } // for (nDir = 0; nDir < dirArray->len; nDir++) 00318 return ret; 00319 }
int erMdsContentSort | ( | GArray * | contentItemArray, | |
mdsSortStruct_t * | sort | |||
) |
Sort the array passed as an argument according to the sort criterium.
contentItemArray | - Contain items to be sorted | |
sort | - |
Definition at line 323 of file erMdsFs.c.
00324 { 00325 int ret; 00326 00327 CL_LOGPRINTF("entry"); 00328 00329 switch (sort->ft) 00330 { 00331 case mdsFieldFsName: 00332 g_array_sort_with_data(contentItemArray, mdsFieldFsNameComparison, (gpointer) sort); 00333 ret = ERMDS_CONTENT_SORT_OK; 00334 break; 00335 00336 case mdsFieldAuthor: 00337 case mdsFieldDate: 00338 case mdsFieldDescription: 00339 case mdsFieldFile: 00340 case mdsFieldTitle: 00341 case mdsFieldExtName: 00342 case mdsFieldSize: 00343 mdsContentPreSort(contentItemArray, sort); 00344 g_array_sort_with_data(contentItemArray, mdsFieldGenericComparison, (gpointer) sort); 00345 mdsContentPostSort(contentItemArray); 00346 ret = ERMDS_CONTENT_SORT_OK; 00347 break; 00348 00349 default: 00350 CL_ERRORPRINTF("No support for sorting of type %d", (int) sort->ft); 00351 ret = ERMDS_CONTENT_SORT_NOT_IMPLEMENTED; 00352 } 00353 return ret; 00354 }
static gboolean extensionIsMobipocket | ( | char * | pExt | ) | [inline, static] |
static void fileGetDisplayItem | ( | mdsFsItem_t * | pFsItem, | |
clDisplayItem_t * | displayItem | |||
) | [static] |
Definition at line 1531 of file erMdsFs.c.
01532 { 01533 char* cp = NULL; 01534 char szFilename[ERMDS_MAX_FILENAME_SIZE]; 01535 char szRealpath[ERMDS_MAX_FILENAME_SIZE]; 01536 01537 // check whether arguments valid or not 01538 if (NULL == pFsItem || pFsItem->fit != mdsFitFile || NULL == displayItem) 01539 { 01540 CL_ERRORPRINTF("invalid arguments"); 01541 return; 01542 } 01543 // Convert symlinks into the real path 01544 // Note: also needed for symlinks in directory path, e.g. /opt/content/books/... 01545 cp = realpath(pFsItem->szFilename, szRealpath); 01546 if (cp != NULL) 01547 { 01548 CL_LOGPRINTF("entry %s", szRealpath); 01549 snprintf(szFilename, sizeof(szFilename), "%s", szRealpath); 01550 } 01551 else 01552 { 01553 CL_ERRORPRINTF("entry %s", pFsItem->szFilename); 01554 strcpy(szFilename, pFsItem->szFilename); 01555 } 01556 01557 // szFilename 01558 strcpy(displayItem->szFilename, szFilename); 01559 // fit 01560 displayItem->fit = pFsItem->fit; 01561 // sztitle 01562 getFakeTitle(szFilename, displayItem->szTitle); 01563 // szFileExt 01564 getExtName(szFilename, displayItem->szFileExt); 01565 if (0 == strlen(displayItem->szFileExt)) 01566 { 01567 CL_WARNPRINTF("%s does not have a file extension", szFilename); 01568 } 01569 // szDate 01570 getDate(szFilename, displayItem->szDate); 01571 // size 01572 displayItem->size = getSize(szFilename); 01573 }
static void folderGetDisplayItem | ( | mdsFsItem_t * | pFsItem, | |
clDisplayItem_t * | displayItem | |||
) | [static] |
Definition at line 1575 of file erMdsFs.c.
01576 { 01577 char* cp = NULL; 01578 char szFilename[ERMDS_MAX_FILENAME_SIZE]; 01579 char szRealpath[PATH_MAX]; 01580 01581 if (pFsItem == NULL || pFsItem->fit != mdsFitFolder || displayItem == NULL) 01582 { 01583 CL_ERRORPRINTF("invalid arguments"); 01584 return; 01585 } 01586 // Convert symlinks into the real path 01587 // Note: also needed for symlinks in directory path, e.g. /opt/content/books/... 01588 cp = realpath(pFsItem->szFilename, szRealpath); 01589 if (cp != NULL) 01590 { 01591 CL_LOGPRINTF("entry %s", szRealpath); 01592 snprintf(szFilename, sizeof(szFilename), "%s", szRealpath); 01593 } 01594 else 01595 { 01596 CL_ERRORPRINTF("entry %s", pFsItem->szFilename); 01597 strcpy(szFilename, pFsItem->szFilename); 01598 } 01599 // szFilename 01600 strcpy(displayItem->szFilename, szFilename); 01601 // fit 01602 displayItem->fit = pFsItem->fit; 01603 // Determine Title 01604 getFakeTitle(szFilename, displayItem->szTitle); 01605 // Determine Icon 01606 displayItem->iconID = clFolderIcon; 01607 // Determine date 01608 getDate(szFilename, displayItem->szDate); 01609 // determinte size 01610 // int size = getSize(pFsItem->szFilename); 01611 // g_snprintf(szField, ERMDS_MAX_FILENAME_SIZE, "%d", size); 01612 }
static void getDate | ( | const char * | szPath, | |
char * | szDate | |||
) | [static] |
Definition at line 1248 of file erMdsFs.c.
01249 { 01250 struct stat statBuf; 01251 01252 if (NULL == szPath || NULL == szDate) 01253 { 01254 CL_ERRORPRINTF("invalid arguments"); 01255 return; 01256 } 01257 01258 strcpy(szDate, ""); 01259 01260 if (strlen(szPath)) 01261 { 01262 if (stat(szPath, &statBuf) == 0) 01263 { 01264 if (S_ISREG(statBuf.st_mode) != 0 || S_ISDIR(statBuf.st_mode)) 01265 { 01266 // What is date? 01267 struct tm localTime; 01268 01269 localtime_r(&statBuf.st_mtime, &localTime); 01270 strftime(szDate, ERCL_MAX_SUBTITLE_SIZE, "%Y-%m-%dT%H:%M:%S", &localTime); 01271 CL_LOGPRINTF("Time of %s: %s", szPath, szDate); 01272 } 01273 else if (S_ISLNK(statBuf.st_mode)) 01274 { 01275 CL_WARNPRINTF("getDate of S_ISLNK not implemented yet."); 01276 } 01277 else 01278 { 01279 CL_WARNPRINTF("%s is not a regular file or directory", szPath); 01280 } 01281 } 01282 } 01283 else 01284 { 01285 CL_WARNPRINTF("Can't determinte the date of %s", szPath); 01286 } 01287 }
static void getExtName | ( | const char * | szPath, | |
char * | szExt | |||
) | [static] |
Definition at line 1289 of file erMdsFs.c.
01290 { 01291 struct stat statbuf; 01292 char *pChar = NULL; 01293 char *pTmp = NULL; 01294 01295 if (NULL == szPath || NULL == szExt) 01296 { 01297 CL_ERRORPRINTF("invalid arguments"); 01298 return; 01299 } 01300 01301 strcpy(szExt, ""); 01302 01303 if (strlen(szPath)) 01304 { 01305 01306 if (0 != stat(szPath, &statbuf)) 01307 { 01308 CL_WARNPRINTF("entry"); 01309 // dummy.bmp doesn't exsits, do something special for it 01310 if (strstr(szPath, "dummy.bmp")) 01311 { 01312 strcpy(szExt, "bmp"); 01313 } 01314 } 01315 else 01316 { 01317 if (S_ISREG(statbuf.st_mode)) 01318 { 01319 pChar = strrchr(szPath, (int) '.'); 01320 pTmp = strrchr(szPath, (int) '/'); 01321 // It is only an extension if it is part of the filename 01322 // Check this by comparing the position of the last '/' 01323 // to the position of the last '.' 01324 // A path will always contain one '/', but we check for a 01325 // NULL pointer anyway. 01326 if (pChar != NULL && (pTmp == NULL || pTmp < pChar)) 01327 { 01328 strcpy(szExt, ++pChar); 01329 CL_LOGPRINTF("the extname of %s is %s", szPath, szExt); 01330 } 01331 else 01332 { 01333 CL_WARNPRINTF("%s does not have a file extension", szPath); 01334 } 01335 } 01336 else if(S_ISDIR(statbuf.st_mode)) 01337 { 01338 CL_WARNPRINTF("%s is a directory", szPath); 01339 } 01340 else if(S_ISLNK(statbuf.st_mode)) 01341 { 01342 CL_WARNPRINTF("%s is a symbollink", szPath); 01343 } 01344 else 01345 { 01346 CL_WARNPRINTF("entry"); 01347 } 01348 } 01349 } 01350 else 01351 { 01352 CL_WARNPRINTF("%s does not have a file extension", szPath); 01353 } 01354 01355 // report extension always as lower case 01356 for (pChar = szExt ; *pChar ; pChar++) 01357 { 01358 *pChar = tolower(*pChar); 01359 } 01360 }
static void getFakeTitle | ( | const char * | szPath, | |
char * | szTitle | |||
) | [static] |
Definition at line 883 of file erMdsFs.c.
00884 { 00885 char *pChar = NULL; 00886 00887 if (NULL == szPath || NULL == szTitle) 00888 { 00889 CL_ERRORPRINTF("invalid arguments"); 00890 return; 00891 } 00892 00893 strcpy(szTitle, ""); 00894 00895 if (strlen(szPath)) 00896 { 00897 // Mobipocket files are different 00898 // We need to try to get the title from the file itself 00899 pChar = strrchr(szPath, (int) '.'); 00900 if (pChar != NULL) 00901 { 00902 pChar++; 00903 if (extensionIsMobipocket(pChar)) 00904 { 00905 if (getMobipocketTitle(szPath, szTitle)) 00906 { 00907 return; 00908 } 00909 } 00910 } 00911 00912 // Use filename as title 00913 pChar = strrchr(szPath, (int) '/'); 00914 if (pChar != NULL) 00915 { 00916 strcpy(szTitle, ++pChar); 00917 } 00918 else 00919 { 00920 CL_WARNPRINTF("Can not determine title of %s", szPath); 00921 } 00922 } 00923 else 00924 { 00925 CL_WARNPRINTF("Can not determine title of %s", szPath); 00926 } 00927 CL_LOGPRINTF("the title of %s is %s", szPath, szTitle); 00928 }
static gboolean getMobipocketTitle | ( | const char * | szPath, | |
char * | szTitle | |||
) | [static] |
Definition at line 933 of file erMdsFs.c.
00934 { 00935 GIOChannel *io; 00936 guint32 firstRecordIndex = 0; 00937 guint32 titleEncoding = 0; 00938 guint32 titleOffset = 0; 00939 guint32 titleLength = 0; 00940 guint32 check3Value = 0; 00941 int i; 00942 gchar *encoding = NULL; 00943 gchar *p; 00944 GString *tmpTitle; 00945 gunichar uniChar = 0; 00946 GIOStatus st; 00947 00948 gchar buf[9]; 00949 memset(buf, '\0', sizeof(buf)); 00950 00951 CL_LOGPRINTF("entry: [%s]", szPath); 00952 00953 io = g_io_channel_new_file(szPath, "r", NULL); 00954 if (io != NULL) 00955 { 00956 g_io_channel_set_encoding(io, NULL, NULL); // Binary data 00957 00958 // First check: make sure this is a Mobipocket document 00959 st = g_io_channel_seek_position(io, MOBIPOCKET_CHECK1_OFFSET, G_SEEK_SET, NULL); 00960 if (st != G_IO_STATUS_NORMAL) 00961 { 00962 CL_ERRORPRINTF("Unable to seek to 0x%x", MOBIPOCKET_CHECK1_OFFSET); 00963 goto return_false; 00964 } 00965 g_io_channel_read_chars(io, buf, 8, NULL, NULL); 00966 buf[8] = '\0'; 00967 if (strcmp(buf, "BOOKMOBI") != 0) 00968 { 00969 CL_ERRORPRINTF("Identifier 'BOOKMOBI' not found"); 00970 if (strcmp(buf, "TEXtREAd") == 0) 00971 { 00972 CL_WARNPRINTF("Identifier 'TEXtREAd' found; Assuming PDB title is valid."); 00973 // Assume UTF-8 encoding and read title from location 0 (PDB mode) 00974 // This skips all other tests 00975 firstRecordIndex = 0; 00976 titleOffset = MOBIPOCKET_PDB_TITLE_OFFSET; 00977 titleLength = MOBIPOCKET_PDB_TITLE_LENGTH; 00978 encoding = g_strdup("UTF-8"); 00979 goto read_title; 00980 } 00981 else 00982 { 00983 goto return_false; 00984 } 00985 } 00986 memset(buf, '\0', sizeof(buf)); 00987 00988 // Get firstRecordIndex 00989 st = g_io_channel_seek_position(io, MOBIPOCKET_FIRST_RECORD, G_SEEK_SET, NULL); 00990 if (st != G_IO_STATUS_NORMAL) 00991 { 00992 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex); 00993 goto return_false; 00994 } 00995 g_io_channel_read_chars(io, buf, 4, NULL, NULL); 00996 for (i = 0; i < 4; i++) 00997 { 00998 firstRecordIndex = firstRecordIndex << 8; 00999 firstRecordIndex = firstRecordIndex + buf[i]; 01000 } 01001 memset(buf, '\0', sizeof(buf)); 01002 01003 CL_LOGPRINTF("firstRecordIndex = 0x%x", firstRecordIndex); 01004 01005 // Second check: make sure this is a Mobipocket document 01006 st = g_io_channel_seek_position(io, firstRecordIndex + MOBIPOCKET_CHECK2_OFFSET, G_SEEK_SET, NULL); 01007 if (st != G_IO_STATUS_NORMAL) 01008 { 01009 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex + MOBIPOCKET_CHECK2_OFFSET); 01010 goto return_false; 01011 } 01012 g_io_channel_read_chars(io, buf, 4, NULL, NULL); 01013 buf[4] = '\0'; 01014 if (strcmp(buf, "MOBI") != 0) 01015 { 01016 CL_ERRORPRINTF("Identifier 'MOBI' not found"); 01017 goto return_false; 01018 } 01019 memset(buf, '\0', sizeof(buf)); 01020 01021 // Get encoding of the title 01022 st = g_io_channel_seek_position(io, firstRecordIndex + MOBIPOCKET_ENCODING_OFFSET, G_SEEK_SET, NULL); 01023 if (st != G_IO_STATUS_NORMAL) 01024 { 01025 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex + MOBIPOCKET_ENCODING_OFFSET); 01026 goto return_false; 01027 } 01028 g_io_channel_read_chars(io, buf, 4, NULL, NULL); 01029 for (i = 0; i < 4; i++) 01030 { 01031 titleEncoding = titleEncoding << 8; 01032 titleEncoding = titleEncoding + buf[i]; 01033 } 01034 if (titleEncoding == MOBIPOCKET_ENCODING_UTF8) 01035 { 01036 encoding = g_strdup("UTF-8"); 01037 } 01038 else if (titleEncoding == MOBIPOCKET_ENCODING_WIN1252) 01039 { 01040 encoding = g_strdup("WINDOWS-1252"); 01041 } 01042 else 01043 { 01044 CL_ERRORPRINTF("Unknown encoding 0x%x", titleEncoding); 01045 goto return_false; 01046 } 01047 memset(buf, '\0', sizeof(buf)); 01048 01049 // Check 3: Make sure this is a Mobipocket document (value must be >= 2) 01050 st = g_io_channel_seek_position(io, firstRecordIndex + MOBIPOCKET_CHECK3_OFFSET, G_SEEK_SET, NULL); 01051 if (st != G_IO_STATUS_NORMAL) 01052 { 01053 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex + MOBIPOCKET_CHECK3_OFFSET); 01054 goto return_false; 01055 } 01056 g_io_channel_read_chars(io, buf, 4, NULL, NULL); 01057 for (i = 0; i < 4; i++) 01058 { 01059 check3Value = check3Value << 8; 01060 check3Value = check3Value + buf[i]; 01061 } 01062 memset(buf, '\0', sizeof(buf)); 01063 01064 if (check3Value < 2) 01065 { 01066 // PDB title mode: title is in first 32 bytes of the file 01067 CL_WARNPRINTF("Check 3: value < 2 ; fallback to PDB mode"); 01068 firstRecordIndex = 0; 01069 titleOffset = MOBIPOCKET_PDB_TITLE_OFFSET; 01070 titleLength = MOBIPOCKET_PDB_TITLE_LENGTH; 01071 } 01072 else 01073 { 01074 // Normal Mobipocket document: get the title offset 01075 01076 // Get title offset (big endian int) 01077 st = g_io_channel_seek_position(io, firstRecordIndex + MOBIPOCKET_TITLE_RECORD_OFFSET, G_SEEK_SET, NULL); 01078 if (st != G_IO_STATUS_NORMAL) 01079 { 01080 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex + MOBIPOCKET_TITLE_RECORD_OFFSET); 01081 goto return_false; 01082 } 01083 g_io_channel_read_chars(io, buf, 4, NULL, NULL); 01084 for (i = 0; i < 4; i++) 01085 { 01086 titleOffset = titleOffset << 8; 01087 titleOffset = titleOffset + buf[i]; 01088 } 01089 memset(buf, '\0', sizeof(buf)); 01090 01091 // Get title length (big endian int) 01092 st = g_io_channel_seek_position(io, firstRecordIndex + MOBIPOCKET_TITLE_LENGTH_OFFSET, G_SEEK_SET, NULL); 01093 if (st != G_IO_STATUS_NORMAL) 01094 { 01095 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex + MOBIPOCKET_TITLE_LENGTH_OFFSET); 01096 goto return_false; 01097 } 01098 g_io_channel_read_chars(io, buf, 4, NULL, NULL); 01099 for (i = 0; i < 4; i++) 01100 { 01101 titleLength = titleLength << 8; 01102 titleLength = titleLength + buf[i]; 01103 } 01104 memset(buf, '\0', sizeof(buf)); 01105 01106 // Check length and truncate if needed 01107 if (titleLength >= ERMDS_MAX_FILENAME_SIZE) 01108 { 01109 CL_ERRORPRINTF("titleLength %d >= %d; truncating...", titleLength, ERMDS_MAX_FILENAME_SIZE); 01110 titleLength = ERMDS_MAX_FILENAME_SIZE - 1; 01111 } 01112 else if (titleLength == 0) 01113 { 01114 // When the titleLength == 0, we fallback to PDB title mode 01115 // and get the title from the first 32 bytes of the file 01116 CL_WARNPRINTF("titleLength == 0"); 01117 firstRecordIndex = 0; 01118 titleOffset = MOBIPOCKET_PDB_TITLE_OFFSET; 01119 titleLength = MOBIPOCKET_PDB_TITLE_LENGTH; 01120 } 01121 01122 } // if check3Value < 2 01123 01124 read_title: 01125 01126 CL_LOGPRINTF("titleLength = %d, titleOffset = 0x%x", titleLength, titleOffset); 01127 01128 // Get the title at titleOffset, read titleLength bytes 01129 st = g_io_channel_seek_position(io, firstRecordIndex + titleOffset, G_SEEK_SET, NULL); 01130 if (st != G_IO_STATUS_NORMAL) 01131 { 01132 CL_ERRORPRINTF("Unable to seek to 0x%x", firstRecordIndex + titleOffset); 01133 goto return_false; 01134 } 01135 // Set the source encoding for the string to be read 01136 // Strings are automatically converted to unicode when read 01137 st = g_io_channel_set_encoding(io, encoding, NULL); 01138 if (st != G_IO_STATUS_NORMAL) 01139 { 01140 CL_ERRORPRINTF("Unable to change channel encoding to %s", encoding); 01141 goto return_false; 01142 } 01143 01144 CL_LOGPRINTF("Channel encoding changed to %s", encoding); 01145 01146 // Read titleLength chars, not bytes (because some chars might be multibyte) 01147 tmpTitle = g_string_sized_new(titleLength); 01148 for (i = 0; i < titleLength; i++) 01149 { 01150 st = g_io_channel_read_unichar(io, &uniChar, NULL); 01151 if (st != G_IO_STATUS_NORMAL) 01152 { 01153 CL_ERRORPRINTF("Unable to read char from pos %d", i); 01154 goto return_false; 01155 } 01156 g_string_append_unichar(tmpTitle, uniChar); 01157 } 01158 strcpy(szTitle, tmpTitle->str); 01159 g_string_free(tmpTitle, TRUE); // free the string including character data 01160 01161 // Replace all '&' references in szTitle with only '&' 01162 while ((p = strstr(szTitle, "&")) != NULL) 01163 { 01164 strcpy(p + 1, p + 5); 01165 } 01166 01167 CL_LOGPRINTF("Found title [%s]", szTitle); 01168 } 01169 else 01170 { 01171 CL_ERRORPRINTF("Unable to open file [%s]", szPath); 01172 goto return_false; 01173 } 01174 01175 // All OK, free stuff and close filepointer 01176 if (encoding) g_free(encoding); 01177 g_io_channel_shutdown(io, FALSE, NULL); 01178 g_io_channel_unref(io); 01179 CL_LOGPRINTF("leave"); 01180 return TRUE; 01181 01182 return_false: 01183 if (encoding) g_free(encoding); 01184 if (io) 01185 { 01186 g_io_channel_shutdown(io, FALSE, NULL); 01187 g_io_channel_unref(io); 01188 } 01189 01190 CL_WARNPRINTF("Not a valid Mobipocket file [%s]", szPath); 01191 return FALSE; 01192 }
static int getSize | ( | const char * | pathName | ) | [static] |
Definition at line 1194 of file erMdsFs.c.
01195 { 01196 struct stat statbuf; 01197 01198 // Determin file size 01199 if (0 != stat(pathName, &statbuf)) 01200 { 01201 return ERCL_INVALID_SIZE; 01202 } 01203 01204 if (S_ISREG(statbuf.st_mode)) 01205 { 01206 int size = 0; 01207 size = statbuf.st_blocks * 512; 01208 CL_LOGPRINTF("the title of %s is %d", pathName, size); 01209 return statbuf.st_blocks * 512; // Use blocks here to show size on disk 01210 } 01211 01212 if (S_ISDIR(statbuf.st_mode)) 01213 { 01214 // visit dir and accumulate 01215 DIR * dir = opendir(pathName); 01216 struct dirent *entry; 01217 int size = 0, item = 0; 01218 if (NULL == dir) 01219 { 01220 CL_WARNPRINTF("Open dir returns NULL"); 01221 return size; 01222 } 01223 while ((entry = readdir(dir)) != NULL) 01224 { 01225 if (strcmp(".", entry->d_name) && strcmp("..", entry->d_name)) 01226 { 01227 char path[ERMDS_MAX_FILENAME_SIZE] ={0}; 01228 snprintf(path, ERMDS_MAX_FILENAME_SIZE, "%s/%s", 01229 pathName, entry->d_name); 01230 item = getSize(path); 01231 CL_LOGPRINTF("name: %s", path); 01232 if (ERCL_INVALID_SIZE != item) 01233 { 01234 size += item; 01235 } 01236 } 01237 } 01238 closedir(dir); 01239 CL_LOGPRINTF("the title of %s is %d", pathName, size); 01240 return size; 01241 } 01242 return ERCL_INVALID_SIZE; 01243 }
static gboolean is_mobipocket_folder | ( | const char * | szPath, | |
const int | len | |||
) | [inline, static] |
Definition at line 437 of file erMdsFs.c.
00438 { 00439 const char *cp = &szPath[0]; 00440 00441 if (len > MOBIPOCKET_FOLDER_LENGTH) 00442 { 00443 cp += (len - MOBIPOCKET_FOLDER_LENGTH); 00444 } 00445 else 00446 { 00447 return FALSE; 00448 } 00449 00450 if (strcmp(cp, MOBIPOCKET_FOLDER) == 0) 00451 { 00452 return TRUE; 00453 } 00454 else 00455 { 00456 return FALSE; 00457 } 00458 }
static void mdsContentPostSort | ( | GArray * | contentItemArray | ) | [static] |
Definition at line 402 of file erMdsFs.c.
00403 { 00404 mdsFsItem_t *pFsItem; 00405 int i, total; 00406 00407 CL_LOGPRINTF("entry"); 00408 00409 if (contentItemArray) 00410 { 00411 total = contentItemArray->len; 00412 for (i = 0; i < total; i++) 00413 { 00414 pFsItem = &g_array_index(contentItemArray, mdsFsItem_t, i); 00415 if (pFsItem) 00416 { 00417 if (pFsItem->sortField) 00418 { 00419 free(pFsItem->sortField); 00420 pFsItem->sortField = NULL; 00421 } 00422 } 00423 else 00424 { 00425 CL_ERRORPRINTF("Can't get the (%d)th pFsItem.", i); 00426 } 00427 } 00428 } 00429 }
static void mdsContentPreSort | ( | GArray * | contentItemArray, | |
mdsSortStruct_t * | sort | |||
) | [static] |
Definition at line 357 of file erMdsFs.c.
00358 { 00359 mdsFsItem_t *pFsItem; 00360 int i, total; 00361 char szField[ERMDS_MAX_FILENAME_SIZE]; 00362 int len; 00363 00364 CL_LOGPRINTF("entry"); 00365 00366 if (contentItemArray && sort) 00367 { 00368 total = contentItemArray->len; 00369 for (i = 0; i < total; i++) 00370 { 00371 pFsItem = &g_array_index(contentItemArray, mdsFsItem_t, i); 00372 if (pFsItem) 00373 { 00374 // Free the old ones. 00375 if (pFsItem->sortField) 00376 { 00377 free(pFsItem->sortField); 00378 pFsItem->sortField = NULL; 00379 } 00380 // Fetch the string on which to compare. 00381 mdsFetchField(pFsItem, sort, szField); 00382 len = strlen(szField) + 1; 00383 pFsItem->sortField = (char *)malloc(len); 00384 if (pFsItem->sortField) 00385 { 00386 strcpy(pFsItem->sortField, szField); 00387 } 00388 else 00389 { 00390 CL_ERRORPRINTF("Can't malloc memory for pFsItem->sortField."); 00391 } 00392 } 00393 else 00394 { 00395 CL_ERRORPRINTF("Can't get the (%d)th pFsItem.", i); 00396 } 00397 }// for 00398 } 00399 }
static void mdsFetchField | ( | mdsFsItem_t * | pFsItem, | |
mdsSortStruct_t * | sort, | |||
char * | szField | |||
) | [static] |
Definition at line 642 of file erMdsFs.c.
00643 { 00644 if (NULL == pFsItem || NULL == sort || NULL == szField) 00645 { 00646 CL_ERRORPRINTF("invalid arguments"); 00647 return; 00648 } 00649 00650 switch (pFsItem->fit) 00651 { 00652 case mdsFitFile: 00653 mdsFetchFieldOfFile(pFsItem, sort, szField); 00654 break; 00655 case mdsFitFolder: 00656 mdsFetchFieldOfFolder(pFsItem, sort, szField); 00657 break; 00658 case mdsFitSymlink: 00659 mdsFetchFieldOfSymlink(pFsItem, sort, szField); 00660 break; 00661 case mdsFitContainer: 00662 mdsFetchFieldOfContainer(pFsItem, sort, szField); 00663 break; 00664 default: 00665 CL_ERRORPRINTF("fit %d is not defined", pFsItem->fit); 00666 strcpy(szField, ""); 00667 } 00668 }
static void mdsFetchFieldOfContainer | ( | mdsFsItem_t * | pFsItem, | |
mdsSortStruct_t * | sort, | |||
char * | szField | |||
) | [static] |
Definition at line 758 of file erMdsFs.c.
00759 { 00760 CL_LOGPRINTF("entry"); 00761 00762 char szManifestPath[ERMDS_MAX_FILENAME_SIZE]; 00763 00764 if (NULL == pFsItem || NULL == sort || NULL == szField) 00765 { 00766 CL_ERRORPRINTF("invalid arguments"); 00767 return; 00768 } 00769 if (mdsFitContainer != pFsItem->fit) 00770 { 00771 CL_ERRORPRINTF("invalid arguments"); 00772 return; 00773 } 00774 00775 // get the field from manifest 00776 if (mdsFieldDate == sort->ft || mdsFieldDescription == sort->ft 00777 || mdsFieldFile == sort->ft || mdsFieldTitle == sort->ft 00778 || mdsFieldSize == sort->ft) 00779 { 00780 // we assume the manifest file exists: no checks 00781 g_snprintf(szManifestPath, ERMDS_MAX_FILENAME_SIZE, "%s/" MANIFEST_FILENAME, pFsItem->szFilename); 00782 CL_LOGPRINTF("Calling erClXmlFetchField: %s, %d, ...", szManifestPath, (int) sort->ft); 00783 erClXmlFetchField(szManifestPath, sort->ft, szField); 00784 } 00785 else if (mdsFieldExtName == sort->ft) 00786 { 00787 char szStartPage[ERMDS_MAX_FILENAME_SIZE+1]; 00788 char szStartPagePath[ERMDS_MAX_FILENAME_SIZE+1]; 00789 // we assume the manifest file exists: no checks 00790 g_snprintf(szManifestPath, ERMDS_MAX_FILENAME_SIZE, "%s/" MANIFEST_FILENAME, pFsItem->szFilename); 00791 CL_LOGPRINTF("Calling erClXmlFetchField: %s, %d, ...", szManifestPath, (int) mdsFieldFile); 00792 erClXmlFetchField(szManifestPath, mdsFieldFile, szStartPage); 00793 g_snprintf(szStartPagePath, ERMDS_MAX_FILENAME_SIZE, "%s/%s", pFsItem->szFilename, szStartPage); 00794 getExtName(szStartPagePath, szField); 00795 } 00796 else 00797 { 00798 CL_LOGPRINTF("Field(%d) never be found in manifest.", (int)sort->ft); 00799 strcpy(szField, ""); 00800 } 00801 // deal with the scenario we can't get the field value from manifest 00802 if (0 == strlen(szField)) 00803 { 00804 switch (sort->ft) 00805 { 00806 case mdsFieldFsName: 00807 strcpy(szField, pFsItem->szFilename); 00808 break; 00809 case mdsFieldDate: 00810 getDate(pFsItem->szFilename, szField); 00811 break; 00812 case mdsFieldTitle: 00813 getFakeTitle(pFsItem->szFilename, szField); 00814 break; 00815 case mdsFieldSize: 00816 { 00817 int size = 0; 00818 size = getSize(pFsItem->szFilename); 00819 g_snprintf(szField, ERMDS_MAX_FILENAME_SIZE, "%d", size); 00820 // write the size of container to manifest.xml 00821 erClXmlSetFieldSize(pFsItem->szFilename, size); 00822 } 00823 break; 00824 default: 00825 CL_ERRORPRINTF("can't get the field value"); 00826 } 00827 } 00828 CL_LOGPRINTF("Time of %s: %s", pFsItem->szFilename, szField); 00829 }
static void mdsFetchFieldOfFile | ( | mdsFsItem_t * | pFsItem, | |
mdsSortStruct_t * | sort, | |||
char * | szField | |||
) | [static] |
Definition at line 670 of file erMdsFs.c.
00671 { 00672 CL_LOGPRINTF("entry"); 00673 00674 int size = 0; 00675 00676 if (NULL == pFsItem || NULL == sort || NULL == szField) 00677 { 00678 CL_ERRORPRINTF("invalid arguments"); 00679 return; 00680 } 00681 if (mdsFitFile != pFsItem->fit) 00682 { 00683 CL_ERRORPRINTF("invalid arguments"); 00684 return; 00685 } 00686 00687 switch (sort->ft) 00688 { 00689 case mdsFieldFsName: 00690 strcpy(szField, pFsItem->szFilename); 00691 break; 00692 case mdsFieldTitle: 00693 getFakeTitle(pFsItem->szFilename, szField); 00694 break; 00695 case mdsFieldDate: 00696 getDate(pFsItem->szFilename, szField); 00697 break; 00698 case mdsFieldSize: 00699 size = getSize(pFsItem->szFilename); 00700 g_snprintf(szField, ERMDS_MAX_FILENAME_SIZE, "%d", size); 00701 break; 00702 case mdsFieldExtName: 00703 getExtName(pFsItem->szFilename, szField); 00704 break; 00705 case mdsFieldAuthor: 00706 case mdsFieldDescription: 00707 case mdsFieldFile: 00708 default: 00709 strcpy(szField, ""); 00710 } 00711 CL_LOGPRINTF("%s", szField); 00712 }
static void mdsFetchFieldOfFolder | ( | mdsFsItem_t * | pFsItem, | |
mdsSortStruct_t * | sort, | |||
char * | szField | |||
) | [static] |
Definition at line 714 of file erMdsFs.c.
00715 { 00716 CL_LOGPRINTF("entry"); 00717 00718 if (NULL == pFsItem || NULL == sort || NULL == szField) 00719 { 00720 CL_ERRORPRINTF("invalid arguments"); 00721 return; 00722 } 00723 if (pFsItem->fit != mdsFitFolder) 00724 { 00725 CL_ERRORPRINTF("invalid arguments"); 00726 return; 00727 } 00728 00729 switch (sort->ft) 00730 { 00731 case mdsFieldFsName: 00732 strcpy(szField, pFsItem->szFilename); 00733 break; 00734 case mdsFieldTitle: 00735 getFakeTitle(pFsItem->szFilename, szField); 00736 break; 00737 case mdsFieldDate: 00738 getDate(pFsItem->szFilename, szField); 00739 break; 00740 case mdsFieldSize: 00741 { 00742 // if it's a folder, we treat its size to be zero, otherwise it'll be slow 00743 // int size = getSize(pFsItem->szFilename); 00744 int size = 0; 00745 g_snprintf(szField, ERMDS_MAX_FILENAME_SIZE, "%d", size); 00746 } 00747 break; 00748 case mdsFieldExtName: 00749 case mdsFieldAuthor: 00750 case mdsFieldDescription: 00751 case mdsFieldFile: 00752 default: 00753 strcpy(szField, ""); 00754 } 00755 CL_LOGPRINTF("%s", szField); 00756 }
static void mdsFetchFieldOfSymlink | ( | mdsFsItem_t * | pFsItem, | |
mdsSortStruct_t * | sort, | |||
char * | szField | |||
) | [static] |
Definition at line 832 of file erMdsFs.c.
00833 { 00834 CL_LOGPRINTF("entry"); 00835 00836 char* cp = NULL; 00837 char szFilename[ERMDS_MAX_FILENAME_SIZE]; 00838 char szRealpath[PATH_MAX]; 00839 mdsFsItemType_e fit; 00840 mdsFsItem_t fsItem; 00841 00842 if (NULL == pFsItem || NULL == sort || NULL == szField) 00843 { 00844 CL_ERRORPRINTF("invalid arguments"); 00845 return; 00846 } 00847 if (mdsFitSymlink != pFsItem->fit) 00848 { 00849 CL_ERRORPRINTF("invalid arguments"); 00850 return; 00851 } 00852 00853 strcpy(szField, ""); 00854 // Convert symlinks into the real path 00855 // Note: also needed for symlinks in directory path, e.g. /opt/content/books/... 00856 cp = realpath(pFsItem->szFilename, szRealpath); 00857 if (cp != NULL) 00858 { 00859 snprintf(szFilename, sizeof(szFilename), "%s", szRealpath); 00860 // Determine the fit and filename for symlinks 00861 erClGetSymlinkInfo(szFilename, &fit); 00862 00863 if (mdsFitFile == fit || mdsFitFolder == fit || mdsFitContainer == fit) 00864 { 00865 // the realpath is a file or a folder or a container 00866 fsItem.fit = fit; 00867 strcpy(fsItem.szFilename, szFilename); 00868 mdsFetchField(&fsItem, sort, szField); 00869 } 00870 else 00871 { 00872 CL_ERRORPRINTF("entry"); 00873 } 00874 } 00875 else 00876 { 00877 CL_ERRORPRINTF("entry"); 00878 } 00879 00880 CL_LOGPRINTF("entry"); 00881 }
static gint mdsFieldFsNameComparison | ( | gconstpointer | a, | |
gconstpointer | b, | |||
gpointer | user_data | |||
) | [static] |
Definition at line 461 of file erMdsFs.c.
00462 { 00463 mdsFsItem_t *pFsItemA = (mdsFsItem_t *) a; 00464 mdsFsItem_t *pFsItemB = (mdsFsItem_t *) b; 00465 mdsSortStruct_t *sort = (mdsSortStruct_t *) user_data; 00466 int ret; 00467 00468 // Check to see if one of the files is the Mobipocket special folder 00469 // The Mobipocket special folder always sorts on top 00470 00471 // If equal priorities, check name 00472 if (pFsItemA->priority == pFsItemB->priority) 00473 { 00474 if (sort->ascending == 1) 00475 { 00476 ret = strcasecmp(pFsItemA->szFilename, pFsItemB->szFilename); 00477 } 00478 else 00479 { 00480 ret = strcasecmp(pFsItemB->szFilename, pFsItemA->szFilename); 00481 } 00482 } 00483 else if (pFsItemA->priority < pFsItemB->priority) 00484 { 00485 ret = 1; 00486 } 00487 else 00488 { 00489 ret = -1; 00490 } 00491 00492 return ret; 00493 }
static gint mdsFieldGenericComparison | ( | gconstpointer | a, | |
gconstpointer | b, | |||
gpointer | user_data | |||
) | [static] |
Definition at line 495 of file erMdsFs.c.
00496 { 00497 mdsFsItem_t *pFsItemA; 00498 mdsFsItem_t *pFsItemB; 00499 mdsSortStruct_t *sort; 00500 char *szFieldA = NULL; 00501 char *szFieldB = NULL; 00502 int ret = 0; 00503 00504 pFsItemA = (mdsFsItem_t *) a; 00505 pFsItemB = (mdsFsItem_t *) b; 00506 sort = (mdsSortStruct_t *) user_data; 00507 00508 // Check to see if one of the files is the Mobipocket special folder 00509 // The Mobipocket special folder always sorts on top 00510 00511 // Handle priorities, if priorities are not equal we don't have to do fancy checks 00512 if (pFsItemA->priority != pFsItemB->priority) 00513 { 00514 if (pFsItemA->priority < pFsItemB->priority) 00515 { 00516 return 1; 00517 } 00518 else 00519 { 00520 return -1; 00521 } 00522 } 00523 00524 szFieldA = pFsItemA->sortField; 00525 szFieldB = pFsItemB->sortField; 00526 00527 if (szFieldA && szFieldB) 00528 { 00529 // comparing 00530 if (mdsFieldDate == sort->ft) 00531 { 00532 ret = datecmp(szFieldA, szFieldB); 00533 } 00534 else if (mdsFieldSize == sort->ft) 00535 { 00536 ret = sizecmp(szFieldA, szFieldB); 00537 } 00538 else 00539 { 00540 ret = strcasecmp(szFieldA, szFieldB); 00541 } 00542 } 00543 else if (szFieldA && NULL == szFieldB) 00544 { 00545 ret = 1; 00546 CL_LOGPRINTF("szFieldA && szFieldB == NULL"); 00547 } 00548 else if (NULL == szFieldA && szFieldB) 00549 { 00550 ret = -1; 00551 CL_LOGPRINTF("szFieldA == NULL && szFieldB"); 00552 } 00553 else 00554 { 00555 ret = 0; 00556 CL_LOGPRINTF("szFieldA == szFieldB == NULL"); 00557 } 00558 /* 00559 // if equals, we using title to be sorting criteria 00560 if (0 == ret && mdsFieldTitle != sort->ft && mdsFieldFsName != sort->ft) 00561 { 00562 CL_LOGPRINTF("using sorting type: title"); 00563 00564 mdsSortStruct_t localSort; 00565 char fieldA[ERMDS_MAX_FILENAME_SIZE]; 00566 char fieldB[ERMDS_MAX_FILENAME_SIZE]; 00567 00568 localSort.ft = mdsFieldTitle; 00569 localSort.ascending = sort->ascending; 00570 00571 mdsFetchField(pFsItemA, &localSort, fieldA); 00572 mdsFetchField(pFsItemB, &localSort, fieldB); 00573 ret = strcasecmp(fieldA, fieldB); 00574 } 00575 */ 00576 // if equals, we using filename to be sorting criteria 00577 if (0 == ret && mdsFieldTitle != sort->ft && mdsFieldFsName != sort->ft) 00578 { 00579 CL_LOGPRINTF("using default sorting type: Filename"); 00580 ret = strcasecmp(pFsItemA->szFilename, pFsItemB->szFilename); 00581 } 00582 // sort ording 00583 if (sort->ascending == 0) 00584 { 00585 ret = 0 - ret; 00586 } 00587 CL_LOGPRINTF("ret = %d", ret); 00588 return ret; 00589 }
static int sizecmp | ( | const char * | sizeA, | |
const char * | sizeB | |||
) | [static] |
Definition at line 617 of file erMdsFs.c.
00618 { 00619 int nSizeA, nSizeB; 00620 int diff = 0; 00621 00622 CL_LOGPRINTF("entry"); 00623 00624 if (NULL == sizeA || NULL == sizeB) 00625 { 00626 CL_ERRORPRINTF("invalid arguments"); 00627 return diff; 00628 } 00629 00630 nSizeA = atoi(sizeA); 00631 nSizeB = atoi(sizeB); 00632 diff = nSizeA - nSizeB; 00633 00634 return diff; 00635 }
static void symlinkGetDisplayItem | ( | mdsFsItem_t * | pFsItem, | |
clDisplayItem_t * | displayItem | |||
) | [static] |
Definition at line 1778 of file erMdsFs.c.
01779 { 01780 char* cp = NULL; 01781 char szFilename[ERMDS_MAX_FILENAME_SIZE]; 01782 char szRealpath[PATH_MAX]; 01783 mdsFsItem_t fsItem; 01784 mdsFsItemType_e fit; 01785 01786 if (NULL == pFsItem || pFsItem->fit != mdsFitSymlink || NULL == displayItem) 01787 { 01788 CL_ERRORPRINTF("invalid arguments"); 01789 return; 01790 } 01791 01792 // Convert symlinks into the real path 01793 // Note: also needed for symlinks in directory path, e.g. /opt/content/books/... 01794 cp = realpath(pFsItem->szFilename, szRealpath); 01795 if (cp != NULL) 01796 { 01797 // Determine the fit and filename for symlinks 01798 snprintf(szFilename, sizeof(szFilename), "%s", szRealpath); 01799 erClGetSymlinkInfo(szFilename, &fit); 01800 displayItem->fit = fit; 01801 01802 fsItem.fit = fit; 01803 strcpy(fsItem.szFilename, szFilename); 01804 switch (fit) 01805 { 01806 case mdsFitContainer: 01807 containerGetDisplayItem(&fsItem, displayItem); 01808 break; 01809 case mdsFitFile: 01810 fileGetDisplayItem(&fsItem, displayItem); 01811 break; 01812 case mdsFitFolder: 01813 folderGetDisplayItem(&fsItem, displayItem); 01814 break; 01815 default: 01816 CL_ERRORPRINTF("entry"); 01817 break; 01818 } 01819 } 01820 else 01821 { 01822 CL_ERRORPRINTF("realpath error on [%s]", pFsItem->szFilename); 01823 } 01824 }
trusted_device_t g_trusted_devices[] [static] |