pcshareMgr/src/sharethread.c File Reference

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#include <mntent.h>
#include <dirent.h>
#include <errno.h>
#include <linux/limits.h>
#include <config.h>
#include <gtk/gtk.h>
#include <liberdm/display.h>
#include <liberregxml/erregapi.h>
#include "control.h"
#include "logging.h"
#include "displayUpdate.h"
#include "systemcalls.h"
#include "view.h"
#include "sharethread.h"
#include "languages.h"
#include "main.h"
#include "settings.h"

Go to the source code of this file.

Defines

#define OUTBOX_NAME   "outbox"
#define INBOX_NAME   "inbox"
#define INBOX_NAME_TEMP   "inbox.tmp"
#define SHARE_MOUNT_TYPE   "cifs"
#define ILIAD_DOCUMENTS   "documents"
#define ILIAD_NEWSPAPERS   "newspapers"
#define ILIAD_BOOKS   "books"
#define ILIAD_NOTES   "notes"
#define PC_STORAGE_INTERNAL   "Internal"
#define PC_STORAGE_CF   "CF"
#define PC_STORAGE_USB   "USB"
#define PC_STORAGE_MMC   "MMC"
#define ILIAD_STORAGE_INTERNAL   "/mnt/free"
#define ILIAD_STORAGE_CF   "/media/cf"
#define ILIAD_STORAGE_USB   "/mnt/usb"
#define ILIAD_STORAGE_MMC   "/media/card"
#define MANIFEST_FILENAME   "manifest.xml"
#define ARRAY_LEN(x)   (sizeof(x) / sizeof ((x) [0]))

Functions

static void report_error (const gchar *msg)
static void DisplayMessage (shareMgr_t *theShareMgr, gchar *szMessageProblem, gchar *szMessageSolution)
static int shareDoUpload (void)
static int shareDoDownload (void)
static int recursiveFilesDownload (const char *sPath, const char *sResultDir)
static gboolean isPartitionMounted (const char *partition, const char *type)
void shareThreadErrorConfirmed (void)
static gboolean g_progress_callback (gpointer data)
static gpointer shareThread (gpointer arg)
gboolean shareThread_start (shareMgr_t *share_parms)
gboolean shareThread_stop ()
gboolean shareThread_wait (int timeout_sec)

Variables

static shareMgr_ttheStaticShareMgr = NULL
static char szShareRootDir [MAX_PATH]
static char szShareOutbox [MAX_PATH]
static char szShareInbox [MAX_PATH]
static char szShareInboxTmp [MAX_PATH]
static gboolean g_error_confirmed = FALSE
static int g_notRemovedFiles = 0
static int g_filesDownloaded = 0
static int g_filesUploaded = 0
static int g_transferError = 0
static pcShareCfg_tthePCShareSettings = NULL
static const char * outbox_locations []
static volatile GThread * g_share_thread = NULL
static volatile gboolean g_share_abort = FALSE


Define Documentation

#define ARRAY_LEN (  )     (sizeof(x) / sizeof ((x) [0]))

Definition at line 102 of file sharethread.c.

#define ILIAD_BOOKS   "books"

Definition at line 66 of file sharethread.c.

#define ILIAD_DOCUMENTS   "documents"

Definition at line 64 of file sharethread.c.

#define ILIAD_NEWSPAPERS   "newspapers"

Definition at line 65 of file sharethread.c.

#define ILIAD_NOTES   "notes"

Definition at line 67 of file sharethread.c.

#define ILIAD_STORAGE_CF   "/media/cf"

Definition at line 74 of file sharethread.c.

#define ILIAD_STORAGE_INTERNAL   "/mnt/free"

Definition at line 73 of file sharethread.c.

#define ILIAD_STORAGE_MMC   "/media/card"

Definition at line 76 of file sharethread.c.

#define ILIAD_STORAGE_USB   "/mnt/usb"

Definition at line 75 of file sharethread.c.

#define INBOX_NAME   "inbox"

Definition at line 60 of file sharethread.c.

#define INBOX_NAME_TEMP   "inbox.tmp"

Definition at line 61 of file sharethread.c.

#define MANIFEST_FILENAME   "manifest.xml"

Definition at line 78 of file sharethread.c.

#define OUTBOX_NAME   "outbox"

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

Definition at line 59 of file sharethread.c.

#define PC_STORAGE_CF   "CF"

Definition at line 70 of file sharethread.c.

#define PC_STORAGE_INTERNAL   "Internal"

Definition at line 69 of file sharethread.c.

#define PC_STORAGE_MMC   "MMC"

Definition at line 72 of file sharethread.c.

#define PC_STORAGE_USB   "USB"

Definition at line 71 of file sharethread.c.

#define SHARE_MOUNT_TYPE   "cifs"

Definition at line 62 of file sharethread.c.


Function Documentation

void DisplayMessage ( shareMgr_t theShareMgr,
gchar *  szMessageProblem,
gchar *  szMessageSolution 
) [static]

Definition at line 796 of file sharethread.c.

00797 {
00798     gchar   szMessage[VIEW_MAX_INF0_STRING_SIZE];
00799 
00800     g_snprintf(szMessage, VIEW_MAX_INF0_STRING_SIZE, " %s %s", szMessageProblem, szMessageSolution);
00801     
00802     if (!main_get_background())
00803     {
00804         gdk_threads_enter();
00805         viewShowInfo(szMessage);
00806         viewHideProgress();
00807         gdk_threads_leave();
00808     }
00809     else
00810     {
00811         DL_MSGPRINTF("%s", szMessage);
00812     }
00813 }

Here is the call graph for this function:

static gboolean g_progress_callback ( gpointer  data  )  [static]

Definition at line 815 of file sharethread.c.

00816 {
00817     if (!main_get_background())
00818     {
00819         gdk_threads_enter();
00820         viewShowProgress();
00821         gdk_threads_leave();
00822         
00823         return TRUE;
00824     }
00825     else
00826     {
00827         // No need for progress indication when in background
00828         return FALSE;
00829     }
00830 }

Here is the call graph for this function:

static gboolean isPartitionMounted ( const char *  partition,
const char *  type 
) [static]

Definition at line 317 of file sharethread.c.

00318 {
00319     gboolean found = FALSE;
00320     FILE *fp = setmntent("/proc/mounts", "r");
00321     struct mntent* mt = NULL;
00322     while ((mt = getmntent(fp)))
00323     {
00324 //        DL_LOGPRINTF("Partition: %s: %s %s", mt->mnt_fsname, mt->mnt_dir, mt->mnt_type);
00325         if (strcasecmp(mt->mnt_dir, partition) == 0)
00326         {
00327             DL_LOGPRINTF("Found mounted partition: %s [%s]", mt->mnt_fsname, mt->mnt_type);
00328             if ( (type == NULL) || (strcasecmp(mt->mnt_type, type) == 0) )
00329             {
00330                 found = TRUE;
00331             }
00332             else
00333             {
00334                 found = FALSE;
00335             }
00336         }
00337     }
00338     endmntent(fp);
00339 
00340     return found;
00341 }

static int recursiveFilesDownload ( const char *  sPath,
const char *  sResultDir 
) [static]

Definition at line 603 of file sharethread.c.

00604 {
00605     DL_LOGPRINTF("entry: path [%s] resultDir [%s]", sPath, sResultDir);
00606 
00607     DIR* dirp = opendir(sPath);
00608     if (dirp == NULL)
00609     {
00610         DL_ERRORPRINTF("Cannot open dir [%s] - %s", sPath, strerror(errno));
00611         return -1;  // error
00612     }
00613 
00614     char*           cp;
00615     struct dirent*  direntp;
00616     struct stat     statBuf;
00617     char            buf[MAX_FILENAME_SIZE];
00618     char            resolvedPath[PATH_MAX];
00619     char            fileName[MAX_FILENAME_SIZE];
00620     char            fname[MAX_FILENAME_SIZE];
00621     char            newResultDir[PATH_MAX];
00622     char*           newFile;
00623 
00624 
00625     // TODO: we need to make sure recursion ends. The realpath() call seems to ensure we cannot
00626     // get into an endless loop, but we might want to limit the amount of subdirs to something
00627     // more workable than the maximum directory depth of a FAT32 filesystem.
00628 
00629     while ( (direntp = readdir(dirp)) != NULL  &&  !g_share_abort)
00630     {
00631         // skip hidden entries and current/parent directory
00632         // do copy files starting with a '_'
00633         if ( direntp->d_name[0] == '.' )
00634         {
00635             continue;
00636         }
00637 
00638         // convert symlink to the file or directory behind it
00639         snprintf(buf, sizeof(buf), "%s/%s", sPath, direntp->d_name);
00640         cp = realpath(buf, resolvedPath);
00641         if (cp == NULL)
00642         {
00643             DL_ERRORPRINTF("Cannot resolve path [%s] - %s", buf, strerror(errno));
00644             continue;  // while
00645         }
00646         DL_LOGPRINTF("resolved path [%s]", resolvedPath);
00647 
00648         // set a pointer to the filename
00649         cp = strrchr(resolvedPath, '/');
00650         g_assert(cp != NULL);
00651         snprintf(fileName, sizeof(fileName), "%s", cp + 1);
00652         DL_LOGPRINTF("filename [%s]", fileName);
00653 
00654         // determine what kind of directory entry this really is
00655         if (stat(resolvedPath, &statBuf) == 0)
00656         {
00657             // Handle file that is not in manifest dir
00658             if ( S_ISREG(statBuf.st_mode) )
00659             {
00660                 // Copy the file, if destination exists, rewrite filename
00661                 DisplayMessage(theStaticShareMgr, _("Downloading from PC:"), fileName);
00662 
00663                 if (thePCShareSettings->overwrite)
00664                 {
00665                     // Make sure file with same name does not exist in the result dir
00666                     char buf[MAX_PATH];
00667                     snprintf( buf, sizeof(buf), "%s/%s", sResultDir, fileName);
00668                     delDir(buf);
00669                 }
00670 
00671                 if ((newFile = fileCopy(resolvedPath, sResultDir, g_progress_callback)) != NULL)
00672                 {
00673                     createDownloadHistoryEntry(newFile);
00674                     free(newFile);
00675                     DL_LOGPRINTF("unlink('%s');", resolvedPath);
00676                     if (unlink(resolvedPath) == -1)
00677                     {
00678                         g_notRemovedFiles++;
00679                         DL_ERRORPRINTF("Unable to delete file '%s' on PC: %s", resolvedPath, strerror(errno));
00680                     }
00681                     g_filesDownloaded++;
00682                 }
00683                 else
00684                 {
00685                     DL_ERRORPRINTF("Unable to copy [%s]", fileName);
00686                     g_transferError++;
00687                 }
00688             }
00689             else if ( S_ISDIR(statBuf.st_mode) )
00690             {
00691                 // TODO: parse manifest file to see if it is really a container or just a manifest dir
00692                 // Check whether directory holds a manifest file
00693                 snprintf(buf, sizeof(buf), "%s/%s", resolvedPath, MANIFEST_FILENAME);
00694                 if ( fileExists(buf) )
00695                 {
00696                     // We have a manifest file, recursively copy this dir
00697                     DL_LOGPRINTF("Found a manifest file, copy container: [cp -r '%s' %s]", resolvedPath, sResultDir);
00698                     DisplayMessage(theStaticShareMgr, _("Downloading from PC:"), fileName);
00699 
00700                     if (thePCShareSettings->overwrite)
00701                     {
00702                         // Make sure file with same name does not exist in the result dir
00703                         char buf[MAX_PATH];
00704                         snprintf( buf, sizeof(buf), "%s/%s", sResultDir, fileName);
00705                         delDir(buf);
00706                     }
00707  
00708                     if ((newFile = dirCopy(resolvedPath, sResultDir, g_progress_callback)))
00709                     {
00710                         createDownloadHistoryEntry(newFile);
00711                         free(newFile);
00712                         DL_LOGPRINTF("delDir('%s');", resolvedPath);
00713                         if (delDir(resolvedPath) == -1)
00714                         {
00715                             g_notRemovedFiles++;
00716                             DL_ERRORPRINTF("Unable to delete file '%s' on PC: %s", resolvedPath, strerror(errno));
00717                         }
00718                         g_filesDownloaded++;
00719                     }
00720                     else
00721                     {
00722                         DL_ERRORPRINTF("Unable to copy manifest dir %s to %s", resolvedPath, sResultDir);
00723                         g_transferError++;
00724                     }
00725                 }
00726                 else
00727                 {
00728                     // A plain dir:
00729                     // - Check if the strtolower() version exists, if so use that one
00730                     // - Otherwise use the original name (with upper and lowercase)
00731                     // - Create this folder in sResultDir (only if not exists)
00732                     // - Recursively call myself to copy its contents
00733                     cp = strrchr(buf, '/');
00734                     g_assert(cp != NULL);
00735                     *cp = '\0';
00736                     strcpy(fname, fileName);
00737                     strtolower(fname);
00738                     snprintf(newResultDir, sizeof(newResultDir), "%s/%s", sResultDir, fname);
00739                     if (!fileExists(newResultDir))
00740                     {
00741                         // Make the dir as requested, not all in lowercase
00742                         snprintf(newResultDir, sizeof(newResultDir), "%s/%s", sResultDir, fileName);
00743                         DL_LOGPRINTF("mkdir(%s)", newResultDir);
00744                         mkdir(newResultDir, 0755);
00745                     }
00746                     else
00747                     {
00748                         // Use the existing dir, all in lowercase
00749                         DL_LOGPRINTF("Dir %s exists, using that one", newResultDir);
00750                     }
00751                     recursiveFilesDownload(buf, newResultDir);
00752                 }
00753             }
00754         }
00755     }
00756     closedir(dirp);
00757 
00758     return 0;  // ok
00759 }

Here is the call graph for this function:

static void report_error ( const gchar *  msg  )  [static]

Definition at line 761 of file sharethread.c.

00762 {
00763     assert(g_error_confirmed == FALSE);
00764 
00765     if ( !main_get_background() )
00766     {
00767         // trigger error-confirmation and show error message
00768         gdk_threads_enter();
00769         view_callback_on_error_confirmed(shareThreadErrorConfirmed);
00770         viewShowError(msg);
00771         gdk_threads_leave();
00772 
00773         // wait for confirmation,
00774         // polling wait allowed because shareThread has nothing else to do now
00775         while (g_error_confirmed == FALSE)
00776         {
00777             g_usleep(500*1000L);
00778         }
00779         g_error_confirmed = FALSE;
00780         
00781         // disable callback, hide error message
00782         gdk_threads_enter();
00783         view_callback_on_error_confirmed(NULL);
00784         viewHideError();
00785         gdk_threads_leave();
00786     }
00787 
00788     DL_ERRORPRINTF("%s", msg);
00789 }

Here is the call graph for this function:

static int shareDoDownload ( void   )  [static]

Definition at line 510 of file sharethread.c.

00511 {
00512     DIR *dir;
00513     struct dirent *entry;
00514     char szComputerLocation[MAX_PATH];
00515     char *sziLiadLocation = NULL;
00516 
00517     // Check abort status, exit if aborted
00518     if (g_share_abort)
00519     {
00520         return 0;
00521     }
00522 
00523     g_filesDownloaded = 0;
00524     
00525     // Open PC outbox
00526     if ((dir = opendir(szShareOutbox)) != NULL)
00527     {
00528         // Read all files in dir
00529         while ((entry = readdir(dir)) != NULL  &&  !g_share_abort)
00530         {
00531             if (strcasecmp(entry->d_name, PC_STORAGE_INTERNAL) == 0)
00532             {
00533                 sziLiadLocation = strdup(ILIAD_STORAGE_INTERNAL);
00534             }
00535             else if (strcasecmp(entry->d_name, PC_STORAGE_CF) == 0)
00536             {
00537                 sziLiadLocation = strdup(ILIAD_STORAGE_CF);
00538             }
00539             else if (strcasecmp(entry->d_name, PC_STORAGE_USB) == 0)
00540             {
00541                 sziLiadLocation = strdup(ILIAD_STORAGE_USB);
00542             }
00543             else if (strcasecmp(entry->d_name, PC_STORAGE_MMC) == 0)
00544             {
00545                 sziLiadLocation = strdup(ILIAD_STORAGE_MMC);
00546             }
00547             else
00548             {
00549                 // Ignore
00550                 sziLiadLocation = NULL;
00551             }
00552             
00553             if ( sziLiadLocation )
00554             {
00555                 // First; we need to see if sziLiadLocation is a mounted filesystem
00556                 // otherwise we skip it
00557                 if (isPartitionMounted(sziLiadLocation, NULL))
00558                 {
00559                     // Recursively copy all manifest directories inside sziLiadLocation
00560                     // All copied manifest dirs need an entry in the download history
00561                     snprintf(szComputerLocation, MAX_PATH, "%s/%s", szShareOutbox, entry->d_name);
00562                     recursiveFilesDownload(szComputerLocation, sziLiadLocation);
00563                 }
00564                 else
00565                 {
00566                     DL_WARNPRINTF("Skipping [%s] because it is not mounted", sziLiadLocation);
00567                 }
00568             }
00569         }
00570     }
00571     else
00572     {
00573         DL_WARNPRINTF("No PC outbox found, nothing to download. Creating the structure on the PC.");
00574         // Create the structure on the PC
00575         if (mkdir(szShareOutbox, 0755) == 0)
00576         {
00577             // Make all appropriate dirs
00578             snprintf(szComputerLocation, MAX_PATH, "%s/%s",    szShareOutbox, PC_STORAGE_INTERNAL);
00579             mkdir(szComputerLocation, 0755);
00580             snprintf(szComputerLocation, MAX_PATH, "%s/%s/%s", szShareOutbox, PC_STORAGE_INTERNAL, ILIAD_DOCUMENTS);
00581             mkdir(szComputerLocation, 0755);
00582             snprintf(szComputerLocation, MAX_PATH, "%s/%s/%s", szShareOutbox, PC_STORAGE_INTERNAL, ILIAD_NEWSPAPERS);
00583             mkdir(szComputerLocation, 0755);
00584             snprintf(szComputerLocation, MAX_PATH, "%s/%s/%s", szShareOutbox, PC_STORAGE_INTERNAL, ILIAD_BOOKS);
00585             mkdir(szComputerLocation, 0755);
00586             snprintf(szComputerLocation, MAX_PATH, "%s/%s/%s", szShareOutbox, PC_STORAGE_INTERNAL, ILIAD_NOTES);
00587             mkdir(szComputerLocation, 0755);
00588             snprintf(szComputerLocation, MAX_PATH, "%s/%s",    szShareOutbox, PC_STORAGE_MMC);
00589             mkdir(szComputerLocation, 0755);
00590             snprintf(szComputerLocation, MAX_PATH, "%s/%s",    szShareOutbox, PC_STORAGE_CF);
00591             mkdir(szComputerLocation, 0755);
00592             snprintf(szComputerLocation, MAX_PATH, "%s/%s",    szShareOutbox, PC_STORAGE_USB);
00593             mkdir(szComputerLocation, 0755);
00594         }
00595     }
00596     
00597     if (sziLiadLocation != NULL)
00598     {
00599         free(sziLiadLocation);
00600     }
00601 }

Here is the call graph for this function:

static int shareDoUpload ( void   )  [static]

Definition at line 343 of file sharethread.c.

00344 {
00345     int i, ret;
00346     DIR *dir;
00347     struct dirent *entry;
00348     struct stat d;
00349     char *filename;
00350     int copied = 0;
00351     char msg[512];
00352     char szDestination[MAX_PATH];
00353     char szTempDestination[MAX_PATH];
00354     
00355     // Check abort status, exit if aborted
00356     if (g_share_abort)
00357     {
00358         return 0;
00359     }
00360 
00361     filename = (char *) malloc(sizeof(char) * MAX_PATH);
00362     
00363     // Check if Inbox exists, otherwise create it
00364     if (!fileExists(szShareInbox))
00365     {
00366         DL_LOGPRINTF("Create PC Inbox");
00367         if (mkdir(szShareInbox, 0755) != 0)
00368         {
00369             DL_ERRORPRINTF("Unable to create PC inbox: [%d] %s", errno, strerror(errno));
00370             snprintf(msg, sizeof(msg), _("Unable to upload files to PC: cannot create inbox folder.\nFile upload has been cancelled."));
00371             report_error(msg);
00372             // Stop uploading files
00373             return 0;
00374         }
00375     }
00376 
00377     delDir(szShareInboxTmp);
00378     DL_LOGPRINTF("Create PC Inbox Temp");
00379     if (mkdir(szShareInboxTmp, 0755) != 0)
00380     {
00381         DL_ERRORPRINTF("Unable to create PC inbox tmp: [%d] %s", errno, strerror(errno));
00382         snprintf(msg, sizeof(msg), _("Unable to upload files to PC: cannot create temporary inbox folder.\nFile upload has been cancelled."));
00383         report_error(msg);
00384         // Stop uploading files
00385         return 0;
00386     }
00387 
00388     // Traverse all outboxes
00389     for(i = 0; i < ARRAY_LEN(outbox_locations) && !g_share_abort; i++)
00390     {
00391         // Check if the outbox exists
00392         if ((dir = opendir(outbox_locations[i])) != NULL)
00393         {
00394             // Yes: this is a dir, process it
00395             DL_LOGPRINTF("Processing Outbox: %s", outbox_locations[i]);
00396 
00397             // Read all files in dir
00398             while ((entry = readdir(dir)) != NULL  &&  !g_share_abort)
00399             {
00400                 // Ignore '.' and '..'
00401                 if (!((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)))
00402                 {
00403                     filename[0] = '\0';
00404                     strncat(filename, outbox_locations[i], MAX_PATH);
00405                     strncat(filename, "/", MAX_PATH);
00406                     strncat(filename, entry->d_name, MAX_PATH);
00407 
00408                     // Check if this entry is a dir or a normal file
00409                     if ((stat(filename, &d) == 0) && (S_ISDIR(d.st_mode) || S_ISREG(d.st_mode)))
00410                     {
00411                         // Copy the file to the Inbox of the PC
00412                         // TODO: Take title from manifest.xml 
00413                         DL_LOGPRINTF("Copy command: cp -r %s %s", filename, szShareInboxTmp);
00414                         DisplayMessage(theStaticShareMgr, _("Uploading to PC:"), entry->d_name);
00415 
00416                         // Put ShareInbox plus name into a variable, so we can check if the destination path
00417                         // exists. We need to call recursive_dircopy with the full destination path, because
00418                         // it also deletes the destination path on failure
00419                         // We create both the temporary destination and the ultimate destination path here, to
00420                         // make sure both do not already exist.
00421                         snprintf(szTempDestination, sizeof(szTempDestination), "%s/%s", szShareInboxTmp, entry->d_name);
00422                         snprintf(szDestination, sizeof(szDestination), "%s/%s", szShareInbox, entry->d_name);
00423 
00424                         DL_ERRORPRINTF("szTempDestination = %s", szTempDestination);
00425                         if (fileExists(szTempDestination))
00426                         {
00427                             // It might not be a dir, but delDir uses 'rm -rf' so it should be fine for a file as well
00428                             DL_LOGPRINTF("Remove %s because it exists", szTempDestination);
00429                             delDir(szTempDestination);
00430                         }
00431                         
00432                         DL_ERRORPRINTF("szDestination = %s", szDestination);
00433                         if (fileExists(szDestination))
00434                         {
00435                             // It might not be a dir, but delDir uses 'rm -rf' so it should be fine for a file as well
00436                             DL_LOGPRINTF("Remove %s because it exists", szDestination);
00437                             delDir(szDestination);
00438                         }
00439 
00440                         DL_ERRORPRINTF("recursive_dircopy(%s, %s)", filename, szTempDestination);
00441                         ret = recursive_dircopy(filename, szTempDestination, g_progress_callback);
00442                         if (ret != 0)
00443                         {
00444                             if (copied == 0)
00445                             {
00446                                 // First upload failed, probably all others as well.
00447                                 DL_ERRORPRINTF("Error while uploading %s to PC: %s (%d) [STOPPING UPLOAD]", entry->d_name, strerror(ret), ret);
00448                                 if ( !g_share_abort )
00449                                 {
00450                                     snprintf( msg, sizeof(msg),
00451                                               _("Error while uploading %s to PC. File upload has been cancelled.\nError: %s (%d)"),
00452                                               entry->d_name, strerror(ret), ret );
00453                                     report_error(msg);
00454                                 }
00455                                 return 0;  // Abort upload
00456                             }
00457                             else
00458                             {
00459                                 DL_ERRORPRINTF("Error while uploading %s to PC: %s (%d)", entry->d_name, strerror(ret), ret);
00460                                 g_transferError++;
00461                             }
00462                         }
00463                         else
00464                         {
00465                             // Transfer is OK. We need to move the file from szShareInboxTmp to szShareInbox
00466                             DL_LOGPRINTF("Moving %s to %s...", szTempDestination, szDestination);
00467                             if (rename(szTempDestination, szDestination) != 0)
00468                             {
00469                                 // Rename failed. Delete file from szShareInboxTmp, don't delete it on the iLiad
00470                                 DL_ERRORPRINTF("Error: unable to move file to %s, deleting %s", szDestination, szTempDestination);
00471                                 delDir(szTempDestination);
00472                                 g_transferError++;
00473                             }
00474                             else
00475                             {
00476                                 // Delete the uploaded file from the iLiad Outbox
00477                                 if (delDir(filename) == -1)
00478                                 {
00479                                     g_notRemovedFiles++;
00480                                     DL_ERRORPRINTF("Unable to delete file '%s' on iLiad: %s", filename, strerror(errno));
00481                                 }
00482                                 copied++;
00483                             }
00484                         }
00485                     }
00486                     else
00487                     {
00488                         // Strange file type, skip it
00489                         DL_WARNPRINTF("Skipping %s of type %d", filename, d.st_mode);
00490                     }
00491                 }
00492             }
00493         }
00494         else
00495         {
00496             DL_LOGPRINTF("No outbox found at %s", outbox_locations[i]);
00497         }
00498     }
00499 
00500     g_filesUploaded = copied;
00501 
00502     // Clear and delete szShareInboxTmp
00503     delDir(szShareInboxTmp);
00504     
00505     free(filename);
00506 
00507     return copied;
00508 }

Here is the call graph for this function:

static gpointer shareThread ( gpointer  arg  )  [static]

Definition at line 114 of file sharethread.c.

00115 {
00116     shareMgr_t *theShareMgr = (shareMgr_t *) arg;
00117     regContentCategory_t *regCc = NULL;
00118     int rc;
00119     char msg[512];
00120 
00121     theStaticShareMgr = theShareMgr;
00122 
00123     DL_LOGPRINTF("enter");
00124     DisplayMessage(theShareMgr, _("Connecting to PC share..."), "");
00125     
00126     regCc = erRegGetContentCategory(DOWNLOAD_HISTORY);
00127     if (regCc == NULL)
00128     {
00129         DL_ERRORPRINTF("Could not access info for download history location");
00130         // Display a sensible message
00131         report_error( _("Cannot find download history location") );
00132         theShareMgr->returnVal = DOWNLOAD_HISTORY_LOCATION_ERROR;
00133         goto EXIT_THREAD;
00134     }
00135 
00136     if (regCc->location)
00137     {
00138         DL_LOGPRINTF("Download History Location: %s", regCc->location);
00139         setDownloadHistory(regCc->location);
00140     }
00141     else
00142     {
00143         DL_ERRORPRINTF("Failed to retrieve download history location");
00144         report_error( _("Cannot find download history location") );
00145         theShareMgr->returnVal = DOWNLOAD_HISTORY_LOCATION_ERROR;
00146         goto EXIT_THREAD;
00147     }
00148 
00149     // The location of the CIFS mount
00150     sprintf(szShareRootDir, SHARE_MOUNT_POINT);
00151 
00152     if (isPartitionMounted(szShareRootDir, SHARE_MOUNT_TYPE) == FALSE)
00153     {
00154         DL_ERRORPRINTF("Cannot find the shared folder on the PC");
00155         report_error( _("Cannot find the shared folder on the PC") );
00156         theShareMgr->returnVal = SHARE_NOT_MOUNTED;
00157         goto EXIT_THREAD;
00158     }
00159 
00160     thePCShareSettings = get_pc_share_settings();
00161 
00162     DL_LOGPRINTF("thePCShareSettings->overwrite = %d", thePCShareSettings->overwrite);
00163     
00164     // Outbox / Inbox locations on the server
00165     sprintf(szShareOutbox, "%s/%s", szShareRootDir, OUTBOX_NAME);
00166     sprintf(szShareInbox, "%s/%s", szShareRootDir, INBOX_NAME);
00167     sprintf(szShareInboxTmp, "%s/%s", szShareRootDir, INBOX_NAME_TEMP);
00168 
00169     // Do upload of all files in outboxes
00170     rc = shareDoUpload();
00171     DL_MSGPRINTF("Upload finished, uploaded %d items", rc);
00172     
00173     scFlushFileBuffers();
00174 
00175     // Do recursive download of all files in PC outbox to iLiad
00176     shareDoDownload();
00177     DL_MSGPRINTF("Download finished, downloaded %d items", g_filesDownloaded);
00178     
00179     scFlushFileBuffers();
00180     
00181     if (g_share_abort)
00182     {
00183         // If aborted, immediately exit
00184         theShareMgr->returnVal = SHARE_THREAD_ABORTED;
00185         goto EXIT_THREAD;
00186     }
00187 
00188     if (g_filesDownloaded || g_filesUploaded)
00189     {
00190         DisplayMessage(theShareMgr, _("--- Transfer Complete ---"), "");
00191     }
00192     else
00193     {
00194         DisplayMessage(theShareMgr, _("--- Nothing to Transfer ---"), "");
00195     }
00196     
00197     if (g_filesDownloaded)
00198     {
00199         main_report_new_content();
00200     }
00201 
00202     if (g_transferError != 0)
00203     {
00204         snprintf(msg, sizeof(msg),
00205                 _("There were errors during the transfer of %d items. "
00206                   "Please make sure the destination location "
00207                   "on your iLiad has enough free space "
00208                   "and the PC share has both read and write permissions."),
00209                   g_transferError);
00210         report_error(msg);
00211     }
00212     else
00213     {
00214         sleep(5);
00215     }
00216     
00217   EXIT_THREAD:
00218     // Tell GTK thread we are done ...
00219     g_share_thread = NULL;
00220     gdk_threads_enter();
00221     {
00222         if (gtk_main_level() == 0)
00223         {
00224             DL_WARNPRINTF("    -- oops, gtk_main has quit!");
00225         }
00226         else
00227         {
00228             g_signal_emit_by_name(theShareMgr->topLevelWindow, "destroy");
00229         }
00230     }
00231     gdk_threads_leave();
00232     // ... and quit
00233     DL_LOGPRINTF("leave");
00234     return NULL;
00235 }

Here is the call graph for this function:

gboolean shareThread_start ( shareMgr_t share_parms  ) 

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

Definition at line 237 of file sharethread.c.

00238 {
00239     GThread* thread = NULL;
00240     GError*  error = NULL;
00241 
00242     DL_LOGPRINTF("entry");
00243     if (g_share_thread)
00244     {
00245         DL_ERRORPRINTF("share thread already running");
00246         return FALSE;
00247     }
00248 
00249     // create the share thread
00250     g_share_abort = FALSE;
00251     thread = g_thread_create(shareThread, share_parms, FALSE, &error);
00252     if (error != NULL)
00253     {
00254         DL_ERRORPRINTF("Failed to create share thread - %s [%d]", error->message, error->code);
00255         g_free(error);
00256         error = NULL;
00257     }
00258     else
00259     {
00260         g_share_thread = thread;
00261     }
00262 
00263     return TRUE;
00264 }

Here is the call graph for this function:

gboolean shareThread_stop ( void   ) 

Definition at line 266 of file sharethread.c.

00267 {
00268     DL_LOGPRINTF("entry");
00269 
00270     if (g_share_thread)
00271     {
00272         // stop the share thread
00273         g_share_abort = TRUE;
00274 
00275         // stop any process spawned by shareThread
00276         pid_t pid = get_forkexec_child_pid();
00277         if (pid > 0)
00278         {
00279             kill(pid, SIGTERM);
00280         }
00281 
00282         // stop fileCopy that might be running on shareThread
00283         fileCopy_abort();
00284 
00285         return TRUE;
00286     }
00287     else
00288     {
00289         DL_ERRORPRINTF("share thread not running");
00290         return FALSE;
00291     }
00292 }

Here is the call graph for this function:

gboolean shareThread_wait ( int  timeout_sec  ) 

Definition at line 294 of file sharethread.c.

00295 {
00296     int max_ticks = 2 * timeout_sec;
00297 
00298     DL_LOGPRINTF("entry");
00299 
00300     if (g_share_thread)
00301     {
00302         // sorry don't like busy-wait, but g_thread_join has no timeout option
00303         while (g_share_thread  &&  --max_ticks >= 0)
00304         {
00305             g_usleep(500*1000L);
00306         }
00307         return TRUE;
00308     }
00309     else
00310     {
00311         DL_ERRORPRINTF("share thread not running");
00312         return FALSE;
00313     }
00314 }

void shareThreadErrorConfirmed ( void   ) 

Definition at line 791 of file sharethread.c.

00792 {
00793     g_error_confirmed = TRUE;
00794 }


Variable Documentation

gboolean g_error_confirmed = FALSE [static]

Definition at line 86 of file sharethread.c.

int g_filesDownloaded = 0 [static]

Definition at line 88 of file sharethread.c.

int g_filesUploaded = 0 [static]

Definition at line 89 of file sharethread.c.

int g_notRemovedFiles = 0 [static]

Definition at line 87 of file sharethread.c.

volatile gboolean g_share_abort = FALSE [static]

Definition at line 112 of file sharethread.c.

volatile GThread* g_share_thread = NULL [static]

Definition at line 111 of file sharethread.c.

int g_transferError = 0 [static]

Definition at line 90 of file sharethread.c.

const char* outbox_locations[] [static]

Initial value:

 
{
    "/mnt/free/outbox",
    "/mnt/usb/outbox",
    "/mnt/cf/outbox",
    "/mnt/card/outbox",
}

Definition at line 103 of file sharethread.c.

char szShareInbox[MAX_PATH] [static]

Definition at line 83 of file sharethread.c.

char szShareInboxTmp[MAX_PATH] [static]

Definition at line 84 of file sharethread.c.

char szShareOutbox[MAX_PATH] [static]

Definition at line 82 of file sharethread.c.

char szShareRootDir[MAX_PATH] [static]

Definition at line 81 of file sharethread.c.

pcShareCfg_t* thePCShareSettings = NULL [static]

Definition at line 91 of file sharethread.c.

shareMgr_t* theStaticShareMgr = NULL [static]

Definition at line 80 of file sharethread.c.


Generated on Sun Dec 14 17:16:52 2008 by  doxygen 1.5.6