aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/calendar-pilot-sync.c
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnu.org>1999-07-28 16:41:12 +0800
committerArturo Espinosa <unammx@src.gnome.org>1999-07-28 16:41:12 +0800
commite49e9cc1755266dade86ce33662ceff466f5ca07 (patch)
tree9c26f2dea9902aef6d691d70ddeee07293cba176 /calendar/calendar-pilot-sync.c
parent81207158058c5f5e4315e3b66f92a46aec64e5ae (diff)
downloadgsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.gz
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.bz2
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.lz
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.xz
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.tar.zst
gsoc2013-evolution-e49e9cc1755266dade86ce33662ceff466f5ca07.zip
New file. Implements PalmPilot syncronization with the Gnome Calendar.
1999-07-28 Miguel de Icaza <miguel@gnu.org> * calendar-pilot-sync.c: New file. Implements PalmPilot syncronization with the Gnome Calendar. 1999-07-27 Miguel de Icaza <miguel@gnu.org> * calobj.c (ical_object_new_from_string): New function. Creates an iCalObject from a vCalendar string that is supposed to contain only one vEvent. * calendar.c: (calendar_save): Split this routine in two. * gnome-cal.c (gnome_calendar_new): Create the corba server here. * main.c: Include gnorba.h, and corba-cal-factory.h here (close_cmd): Kill the calendar server on shutdown. * calobj.c (load_recur_yearly_day): Added a fixme comment. WE need to handle intervals in the years. * calendar.c (calendar_object_find_in_list, calendar_object_find, calendar_object_find_todo, calendar_object_find_event): New functions for looking up information. * main.c (gnome_calendar_locate): New function. * corba-cal.c (calendar_create_object): New file. Implements the corba server. * calendar.c (calendar_object_changed): Flag pilot-status as changed. * calobj.c (ical_object_to_vobject): Save pilot information for syncing. (ical_object_create_from_vobject): Load syncing information for pilot. Do it in a way compatible with KOrganizer. 1999-07-26 Miguel de Icaza <miguel@gnu.org> * calobj.c (ical_object_create_from_vobject): Generate unique IDs on Vevents we load that lack it. WE need this for the old gnome calendar generated files (ie, before now :-). svn path=/trunk/; revision=1038
Diffstat (limited to 'calendar/calendar-pilot-sync.c')
-rw-r--r--calendar/calendar-pilot-sync.c360
1 files changed, 360 insertions, 0 deletions
diff --git a/calendar/calendar-pilot-sync.c b/calendar/calendar-pilot-sync.c
new file mode 100644
index 0000000000..6ed92d540a
--- /dev/null
+++ b/calendar/calendar-pilot-sync.c
@@ -0,0 +1,360 @@
+/*
+ * calendar-pilot-sync.c:
+ *
+ * (C) 1999 International GNOME Support
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnome-support.com)
+ *
+ */
+#include <config.h>
+#include <gnome.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgnorba/gnome-factory.h>
+#include <libgnorba/gnorba.h>
+#include "calobj.h"
+#include "calendar.h"
+#include "timeutil.h"
+#include "GnomeCal.h"
+#include "pi-source.h"
+#include "pi-socket.h"
+#include "pi-datebook.h"
+#include "pi-dlp.h"
+
+/* the CORBA ORB */
+CORBA_ORB orb;
+
+/* The default port to communicate with */
+char *pilot_port = "/dev/pilot";
+
+CORBA_Environment ev;
+
+struct pi_sockaddr addr;
+
+const struct poptOption calendar_sync_options [] = {
+ { "pilot", 0, POPT_ARG_STRING, &pilot_port, 0,
+ N_("Specifies the port on which the Pilot is"), N_("PORT") },
+ { NULL, '\0', 0, NULL, 0 }
+};
+
+static int
+setup_connection (void)
+{
+ int socket;
+ int ret, news;
+
+ if (!(socket = pi_socket(PI_AF_SLP, PI_SOCK_STREAM, PI_PF_PADP)))
+ g_error (_("Can not create Pilot socket\n"));
+
+ addr.pi_family = PI_AF_SLP;
+ strncpy ((void *) &addr.pi_device, pilot_port, sizeof (addr.pi_device));
+
+ ret = pi_bind (socket, (struct sockaddr *)&addr, sizeof (addr));
+ if (ret == -1)
+ g_error (_("Can not bind to device %s\n"), pilot_port);
+
+ if (pi_listen (socket, 1) == -1)
+ g_error (_("Failed to get a connection from the Pilot device"));
+
+ if ((news = pi_accept (socket, 0, 0)) == -1)
+ g_error (_("pi_accept failed"));
+
+ return news;
+}
+
+static GNOME_Calendar_Repository
+locate_calendar_server (void)
+{
+ GNOME_Calendar_Repository repo;
+ GNOME_stringlist list;
+
+ repo = goad_server_activate_with_id (
+ NULL, "IDL:GNOME:Calendar:Repository:1.0",
+ 0, NULL);
+
+ if (repo == CORBA_OBJECT_NIL)
+ g_error ("Can not communicate with GnomeCalendar server");
+
+ if (ev._major != CORBA_NO_EXCEPTION){
+ printf ("Exception: %s\n", CORBA_exception_id (&ev));
+ abort ();
+ }
+
+ return repo;
+}
+
+static void
+delete_record (GNOME_Calendar_Repository repo, int id)
+{
+ char *uid;
+
+ uid = GNOME_Calendar_Repository_get_id_from_pilot_id (repo, id, &ev);
+
+ /* The record was already deleted */
+ if (ev._major != CORBA_NO_EXCEPTION)
+ return;
+
+ GNOME_Calendar_Repository_delete_object (repo, uid, &ev);
+ CORBA_free (uid);
+}
+
+static void
+update_record (GNOME_Calendar_Repository repo, int id, struct Appointment *a, int attr)
+{
+ char *vcal_string;
+ iCalObject *obj;
+ int i;
+ char *str;
+
+ obj = ical_new (a->note ? a->note : "",
+ g_get_user_name (),
+ a->description ? a->description : "");
+
+ vcal_string = GNOME_Calendar_Repository_get_object_by_pilot_id (repo, id, &ev);
+
+ if (ev._major == CORBA_USER_EXCEPTION){
+ time_t now = time (NULL);
+
+ obj->created = now;
+ obj->last_mod = now;
+ obj->priority = 0;
+ obj->transp = 0;
+ obj->related = NULL;
+ obj->pilot_id = id;
+ obj->pilot_status = ICAL_PILOT_SYNC_NONE;
+ printf (_("Object did not exist, creating a new one"));
+ } else
+ obj = ical_object_new_from_string (vcal_string);
+
+ if (obj->pilot_status == ICAL_PILOT_SYNC_MOD){
+ printf (_("Object has been modified on desktop and on the pilot, desktop takes precedence"));
+ ical_object_destroy (obj);
+ return;
+ }
+
+ /*
+ * Begin and end
+ */
+ obj->dtstart = mktime (&a->begin);
+ obj->dtend = mktime (&a->end);
+
+ /* Special case: daily repetitions are converted to a multi-day event */
+ if (a->repeatType == repeatDaily){
+ time_t newt = time_add_day (obj->dtend, a->repeatFrequency);
+
+ obj->dtend = newt;
+ }
+
+ /*
+ * Alarm
+ */
+ if (a->alarm){
+ obj->aalarm.type = ALARM_AUDIO;
+ obj->aalarm.enabled = 1;
+ obj->aalarm.count = a->advance;
+
+ switch (a->advanceUnits){
+ case advMinutes:
+ obj->aalarm.units = ALARM_MINUTES;
+ break;
+
+ case advHours:
+ obj->aalarm.units = ALARM_HOURS;
+ break;
+
+ case advDays:
+ obj->aalarm.units = ALARM_DAYS;
+ break;
+ default:
+ }
+ }
+
+ /*
+ * Recurrence
+ */
+ if (a->repeatFrequency && a->repeatType != repeatDaily){
+ obj->recur = g_new0 (Recurrence, 1);
+
+ switch (a->repeatType){
+ case repeatDaily:
+ /*
+ * In the Pilot daily repetitions are actually
+ * multi-day events
+ */
+ g_warning ("Should not have got here");
+ break;
+
+ case repeatMonthlyByDate:
+ obj->recur->type = RECUR_MONTHLY_BY_DAY;
+ obj->recur->u.month_day = a->repeatFrequency;
+ break;
+
+ case repeatWeekly:
+ {
+ int wd;
+
+ obj->recur->type = RECUR_WEEKLY;
+ for (wd = 0; wd < 7; wd++)
+ if (a->repeatDays [wd])
+ obj->recur->weekday |= 1 << wd;
+
+ if (obj->recur->weekday == 0){
+ struct tm *tm = localtime (&obj->dtstart);
+
+ obj->recur->weekday = 1 << tm->tm_wday;
+ }
+ break;
+ }
+
+ case repeatMonthlyByDay:
+ obj->recur->type = RECUR_MONTHLY_BY_POS;
+ obj->recur->u.month_pos = a->repeatFrequency;
+ obj->recur->weekday = (a->repeatDay / 7);
+ break;
+
+ case repeatYearly:
+ obj->recur->type = RECUR_YEARLY_BY_DAY;
+ break;
+
+ default:
+ g_warning ("Unhandled repeate case");
+ }
+
+ if (a->repeatForever)
+ obj->recur->duration = 0;
+ else
+ obj->recur->_enddate = mktime (&a->repeatEnd);
+ }
+
+ /*
+ * Load exception dates
+ */
+ obj->exdate = NULL;
+ for (i = 0; i < a->exceptions; i++){
+ time_t *t = g_new (time_t, 1);
+
+ *t = mktime (&(a->exception [i]));
+ obj->exdate = g_list_prepend (obj->exdate, t);
+ }
+
+ g_free (obj->class);
+
+ if (attr & dlpRecAttrSecret)
+ obj->class = g_strdup ("PRIVATE");
+ else
+ obj->class = g_strdup ("PUBLIC");
+
+ /*
+ * Now, convert the in memory iCalObject to a full vCalendar we can send
+ */
+ str = calendar_string_from_object (obj);
+
+ GNOME_Calendar_Repository_update_object (repo, obj->uid, str, &ev);
+
+ free (str);
+
+ /*
+ * Shutdown
+ */
+ ical_object_destroy (obj);
+}
+
+static void
+sync_pilot (GNOME_Calendar_Repository repo, int pilot_fd)
+{
+ struct PilotUser user_info;
+ int db,record;
+ unsigned char buffer [65536];
+
+ printf (_("Syncing with the pilot..."));
+ dlp_ReadUserInfo (pilot_fd, &user_info);
+
+ /* This informs the user of the progress on the Pilot */
+ dlp_OpenConduit (pilot_fd);
+
+ if (dlp_OpenDB (pilot_fd, 0, 0x80 | 0x40, "DatebookDB", &db) < 0){
+ g_warning (_("Could not open DatebookDB on the Pilot"));
+ dlp_AddSyncLogEntry (pilot_fd, _("Unable to open DatebookDB"));
+ pi_close (pilot_fd);
+ exit (1);
+ }
+
+ /*
+ * 1. Pull all the records from the Pilot, and make any updates
+ * required on the desktop side
+ */
+ for (record = 0;; record++){
+ struct Appointment a;
+ int rec_len, attr, size;
+ recordid_t id;
+
+ rec_len = dlp_ReadRecordByIndex (pilot_fd, db, record, buffer, &id, &size, &attr, 0);
+
+ if (rec_len < 0)
+ break;
+
+ printf ("processing record %d\n", record);
+ unpack_Appointment (&a, buffer, rec_len);
+
+ /* If the object was deleted, remove it from the database */
+ if (attr & dlpRecAttrDeleted){
+ delete_record (repo, id);
+ continue;
+ }
+
+ if (attr & dlpRecAttrDirty){
+ printf ("updating record\n");
+ update_record (repo, id, &a, attr);
+ }
+
+ free_Appointment (&a);
+ }
+ /*
+ * 2. Pull all the records from the Calendar, and move any new items
+ * to the pilot
+ */
+ dlp_CloseDB (pilot_fd, db);
+ dlp_AddSyncLogEntry (pilot_fd, _("Synced DateBook from Pilot to GnomeCal"));
+ pi_close (pilot_fd);
+}
+
+int
+main (int argc, char *argv [])
+{
+ int link;
+ GNOME_Calendar_Repository repository;
+
+ CORBA_exception_init (&ev);
+ orb = gnome_CORBA_init_with_popt_table (
+ "calendar-pilot-sync", VERSION, &argc, argv,
+ calendar_sync_options, 0, NULL, 0, &ev);
+
+ printf ("Please, press HotSync button on the palm...");
+ fflush (stdout);
+ link = setup_connection ();
+ printf ("Connected\n");
+
+ printf ("Launching GnomeCal...");
+ fflush (stdout);
+ repository = locate_calendar_server ();
+ printf ("Done\n");
+
+ printf ("Syncing...\n");
+ sync_pilot (repository, link);
+ printf ("Done Syncing\n");
+
+ GNOME_Calendar_Repository_done (repository, &ev);
+
+ CORBA_exception_free (&ev);
+
+ return 0;
+}
+
+/* Just a stub to link with */
+void
+calendar_notify (time_t time, CalendarAlarm *which, void *data)
+{
+}
+