Revision: 2018
          http://gtkpod.svn.sourceforge.net/gtkpod/?rev=2018&view=rev
Author:   teuf
Date:     2008-06-24 11:39:38 -0700 (Tue, 24 Jun 2008)

Log Message:
-----------
* src/itdb_device.c: rework timezone handling: handle timezones as
stored on 5g ipods (hopefully) and fallback to using the computer
timezone if we can't figure out the ipod timezone
* tests/get-timezone.c: use functions from libgpod to get the
timezone instead of duplicating some itdb_device code

Modified Paths:
--------------
    libgpod/trunk/ChangeLog
    libgpod/trunk/src/itdb_device.c
    libgpod/trunk/tests/get-timezone.c

Modified: libgpod/trunk/ChangeLog
===================================================================
--- libgpod/trunk/ChangeLog     2008-06-14 22:30:36 UTC (rev 2017)
+++ libgpod/trunk/ChangeLog     2008-06-24 18:39:38 UTC (rev 2018)
@@ -1,3 +1,11 @@
+2008-06-24  Christophe Fergeau  <[EMAIL PROTECTED]>
+
+       * src/itdb_device.c: rework timezone handling: handle timezones as
+       stored on 5g ipods (hopefully) and fallback to using the computer
+       timezone if we can't figure out the ipod timezone
+       * tests/get-timezone.c: use functions from libgpod to get the
+       timezone instead of duplicating some itdb_device code
+
 2008-06-15  Christophe Fergeau  <[EMAIL PROTECTED]>
 
        * src/itdb_device.c: oops, forgot a ','

Modified: libgpod/trunk/src/itdb_device.c
===================================================================
--- libgpod/trunk/src/itdb_device.c     2008-06-14 22:30:36 UTC (rev 2017)
+++ libgpod/trunk/src/itdb_device.c     2008-06-24 18:39:38 UTC (rev 2018)
@@ -38,10 +38,12 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <time.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
 
 static const Itdb_IpodInfo ipod_info_table [] = {
     /* Handle idiots who hose their iPod file system, or lucky people
@@ -1182,75 +1184,172 @@
     return (itdb_device_get_artwork_formats (device, ARTWORK_TYPE_PHOTO) != 
NULL);
 }
 
+static char *
+get_preferences_path (const Itdb_Device *device)
+{
 
-/* This function reads the timezone information from the iPod and sets it in
- * the Itdb_Device structure. If an error occurs, the function returns silently
- * and the timezone shift is set to 0
- */
-static void itdb_device_set_timezone_info (Itdb_Device *device)
-{
     const gchar *p_preferences[] = {"Preferences", NULL};
     char *dev_path;
     char *prefs_filename;
-    FILE *f;
-    gint32 timezone;
-    const int GMT_OFFSET = 0x19;
-    int result;
 
-    device->timezone_shift = 0;
-
     if (device->mountpoint == NULL) {
-        /* Assumes the iPod is in the UTC timezone for those cases */
-        return;
+        return NULL;
     }
 
     dev_path = itdb_get_device_dir (device->mountpoint);
 
     if (dev_path == NULL) {
-        return ;
+        return NULL;
     }
 
     prefs_filename = itdb_resolve_path (dev_path, p_preferences);
     g_free (dev_path);
 
-    f = fopen (prefs_filename, "r");
+    return prefs_filename;
+}
+
+static gboolean itdb_device_read_raw_timezone (const char *prefs_path,
+                                               glong offset,
+                                               gint16 *timezone)
+{
+    FILE *f;
+    int result;
+
+    if (timezone == NULL) {
+        return FALSE;
+    }
+
+    f = fopen (prefs_path, "r");
     if (f == NULL) {
-        g_free (prefs_filename);
-        return;
+        return FALSE;
     }
 
-    result = fseek (f, 0xB10, SEEK_SET);
+    result = fseek (f, offset, SEEK_SET);
     if (result != 0) {
         fclose (f);
-        g_free (prefs_filename);
-        return;
+        return FALSE;
     }
 
-    result = fread (&timezone, sizeof (timezone), 1, f);
+    result = fread (timezone, sizeof (*timezone), 1, f);
     if (result != 1) {
         fclose (f);
-        g_free (prefs_filename);
-        return;
+        return FALSE;
     }
 
     fclose (f);
-    g_free (prefs_filename);
 
-    timezone = GINT32_FROM_LE (timezone);
-    if ((timezone < 0) || (timezone > (2*12) << 1)) {
+    *timezone = GINT16_FROM_LE (*timezone);
+
+    return TRUE;
+}
+
+static gboolean raw_timezone_to_utc_shift_4g (gint16 raw_timezone,
+                                              gint *utc_shift)
+{
+    const int GMT_OFFSET = 0x19;
+
+    if (utc_shift == NULL) {
+        return FALSE;
+    }
+
+    if ((raw_timezone < 0) || (raw_timezone > (2*12) << 1)) {
         /* invalid timezone */
-        return;
+        return FALSE;
     }
 
-    timezone -= GMT_OFFSET;
+    raw_timezone -= GMT_OFFSET;
 
-    device->timezone_shift = (timezone >> 1) * 3600;
-    if (timezone & 1) {
+    *utc_shift = (raw_timezone >> 1) * 3600;
+    if (raw_timezone & 1) {
         /* Adjust for DST */
-        device->timezone_shift += 3600;
+        *utc_shift += 3600;
     }
+
+    return TRUE;
 }
 
+static gboolean raw_timezone_to_utc_shift_5g (gint16 raw_timezone,
+                                              gint *utc_shift)
+{
+    const int TZ_SHIFT = 8;
+
+    if (utc_shift == NULL) {
+        return FALSE;
+    }
+    /* The iPod stores the timezone information as a number of minutes
+     * from Tokyo timezone which increases when going eastward (ie
+     * going from Tokyo to LA and then to Europe).
+     * The calculation below shifts the origin so that 0 corresponds
+     * to UTC-12 and the max is 24*60 and corresponds to UTC+12
+     * Finally, we substract 12*60 to that value to get a signed number
+     * giving the timezone relative to UTC.
+     */
+    *utc_shift = raw_timezone*60 - TZ_SHIFT*3600;
+
+    return TRUE;
+}
+
+static gint get_local_timezone (void)
+{
+    return timezone; /* global variable defined by time.h, see man tzset */
+}
+
+/* This function reads the timezone information from the iPod and sets it in
+ * the Itdb_Device structure. If an error occurs, the function returns silently
+ * and the timezone shift is set to 0
+ */
+static void itdb_device_set_timezone_info (Itdb_Device *device)
+{
+    gint16 raw_timezone;
+    gint timezone = 0;
+    gboolean result;
+    struct stat stat_buf;
+    int status;
+    char *prefs_path;
+
+    device->timezone_shift = get_local_timezone ();
+
+    prefs_path = get_preferences_path (device);
+    status = g_stat (prefs_path, &stat_buf);
+    if (status != 0) {
+       g_free (prefs_path);
+       return;
+    }
+    switch (stat_buf.st_size) {
+       case 2892:
+           result = itdb_device_read_raw_timezone (prefs_path, 0xb10, 
+                                                   &raw_timezone);
+           g_free (prefs_path);
+           if (!result) {
+                return;
+           }
+           result = raw_timezone_to_utc_shift_4g (raw_timezone, &timezone);
+           break;
+       case 2924:
+            result = itdb_device_read_raw_timezone (prefs_path, 0xb22, 
+                                                   &raw_timezone);
+           g_free (prefs_path);
+           if (!result) {
+                return;
+           }
+           result = raw_timezone_to_utc_shift_5g (raw_timezone, &timezone);
+           break;
+       case 2952:
+           /* ipod classic, not implemented yet */
+       default:
+           /* We don't know how to get the timezone of this ipod model,
+            * assume the computer timezone and the ipod timezone match
+            */
+           return; 
+    }
+
+    if ((timezone < -12*3600) || (timezone > 12 * 3600)) {
+        return;
+    }
+
+    device->timezone_shift = timezone;
+}
+
 /**
  * itdb_device_get_firewire_id
  * @device: an #Itdb_Device

Modified: libgpod/trunk/tests/get-timezone.c
===================================================================
--- libgpod/trunk/tests/get-timezone.c  2008-06-14 22:30:36 UTC (rev 2017)
+++ libgpod/trunk/tests/get-timezone.c  2008-06-24 18:39:38 UTC (rev 2018)
@@ -16,16 +16,12 @@
 #include <errno.h>
 #include <stdio.h>
 #include <itdb.h>
+#include <itdb_device.h>
 
 int main (int argc, char **argv)
 {
     char *mountpoint;
-    char *device_dir;
-    char *prefs_filename;
-    FILE *f;
-    int result;
-    gint32 timezone;
-    const int GMT_OFFSET = 0x19;
+    Itdb_Device *device;
 
     if (argc >= 2) {
         mountpoint = argv[1];
@@ -34,49 +30,10 @@
         return -1;
     }
 
-    device_dir = itdb_get_device_dir (mountpoint);
-    if (device_dir == NULL) {
-        g_print ("No iPod mounted at %s\n", mountpoint);
-        return -1;
-    }
-    prefs_filename = itdb_get_path (device_dir, "Preferences");
-    g_free (device_dir);
+    device = itdb_device_new ();
+    itdb_device_set_mountpoint (device, mountpoint);
 
-    f = fopen (prefs_filename, "r");
-    if (f == NULL) {
-        g_print ("Couldn't open %s: %s\n", prefs_filename, g_strerror (errno));
-        g_free (prefs_filename);
-        return -1;
-    }
+    g_print ("Timezone: UTC%+d\n", device->timezone_shift/3600);
 
-    result = fseek (f, 0xB10, SEEK_SET);
-    if (result != 0) {
-        g_print ("Couldn't seek in %s: %s\n", prefs_filename,
-                 g_strerror (errno));
-        fclose (f);
-        g_free (prefs_filename);
-        return -1;
-    }
-
-    result = fread (&timezone, sizeof (timezone), 1, f);
-    if (result != 1) {
-        g_print ("Couldn't read from %s: %s\n", prefs_filename,
-                 g_strerror (errno));
-        fclose (f);
-        g_free (prefs_filename);
-    }
-
-    fclose (f);
-    g_free (prefs_filename);
-
-    timezone = GINT32_FROM_LE (timezone);
-    timezone -= GMT_OFFSET;
-
-    g_print ("Timezone: UTC%+d", timezone >> 1);
-    if (timezone & 1) {
-        g_print (" DST");
-    }
-    g_print ("\n");
-
     return 0;
 }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to