static ssize_t pi_inet_read(pi_socket_t *ps, pi_buffer_t *msg, size_t len, int flags) { int r, fl = 0; pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; fd_set ready; struct timeval t; if (pi_buffer_expect (msg, len) == NULL) { errno = ENOMEM; return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY); } if (flags == PI_MSG_PEEK) fl = MSG_PEEK; FD_ZERO(&ready); FD_SET(ps->sd, &ready); /* If timeout == 0, wait forever for packet, otherwise wait till timeout milliseconds */ if (data->timeout == 0) select(ps->sd + 1, &ready, 0, 0, 0); else { t.tv_sec = data->timeout / 1000; t.tv_usec = (data->timeout % 1000) * 1000; if (select(ps->sd + 1, &ready, 0, 0, &t) == 0) return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); } /* If data is available in time, read it */ if (FD_ISSET(ps->sd, &ready)) { r = recv(ps->sd, msg->data + msg->used, len, fl); if (r < 0) { if (errno == EPIPE || errno == EBADF) { ps->state = PI_SOCK_CONN_BREAK; return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); } return pi_set_error(ps->sd, PI_ERR_SOCK_IO); } data->rx_bytes += r; msg->used += r; LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV RX Inet Bytes: %d\n", r)); return r; } /* otherwise throw out any current packet and return */ LOG((PI_DBG_DEV, PI_DBG_LVL_WARN, "DEV RX Inet timeout\n")); data->rx_errors++; return 0; }
/*********************************************************************** * * Function: u_read_buf * * Summary: read buffer * * Parameters: pi_socket_t*, char* to buffer, length of buffer * * Returns: number of bytes read * ***********************************************************************/ static int u_read_buf (pi_socket_t *ps, pi_buffer_t *buf, size_t len, int flags) { struct pi_usb_data *data = (struct pi_usb_data *)ps->device->data; size_t rbuf = data->buf_size; if (rbuf > len) rbuf = len; if (pi_buffer_append (buf, data->buf, rbuf) == NULL) { errno = ENOMEM; return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY); } if (flags != PI_MSG_PEEK) { data->buf_size -= rbuf; if (data->buf_size > 0) memmove(data->buf, &data->buf[rbuf], data->buf_size); } LOG((PI_DBG_DEV, PI_DBG_LVL_DEBUG, "DEV RX linuxusb read %d bytes from read-ahead buffer\n", rbuf)); return rbuf; }
/*********************************************************************** * * Function: u_poll * * Summary: Poll the open socket/file descriptor * * Parameters: None * * Returns: 1 on success, PI_ERR_SOCK_TIMEOUT on timeout * ***********************************************************************/ static int u_poll(pi_socket_t *ps, int timeout) { struct timeval t; fd_set ready; FD_ZERO(&ready); FD_SET(ps->sd, &ready); /* If timeout == 0, wait forever for packet, otherwise wait till timeout milliseconds */ if (timeout == 0) select(ps->sd + 1, &ready, 0, 0, 0); else { t.tv_sec = timeout / 1000; t.tv_usec = (timeout % 1000) * 1000; select(ps->sd + 1, &ready, 0, 0, &t); } if (!FD_ISSET(ps->sd, &ready)) { /* otherwise throw out any current packet and return */ LOG((PI_DBG_DEV, PI_DBG_LVL_WARN, "DEV POLL linuxusb timeout\n")); errno = ETIMEDOUT; return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); } LOG((PI_DBG_DEV, PI_DBG_LVL_DEBUG, "DEV POLL linuxusb found data on fd: %d\n", ps->sd)); return 1; }
static ssize_t pi_inet_write(pi_socket_t *ps, const unsigned char *msg, size_t len, int flags) { int total, nwrote; pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; struct timeval t; fd_set ready; FD_ZERO(&ready); FD_SET(ps->sd, &ready); total = len; while (total > 0) { if (data->timeout == 0) { if (select(ps->sd + 1, 0, &ready, 0, 0) < 0 && errno == EINTR) continue; } else { t.tv_sec = data->timeout / 1000; t.tv_usec = (data->timeout % 1000) * 1000; if (select(ps->sd + 1, 0, &ready, 0, &t) == 0) return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); } if (!FD_ISSET(ps->sd, &ready)) { ps->state = PI_SOCK_CONN_BREAK; return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); } nwrote = write(ps->sd, msg, len); if (nwrote < 0) { /* test errno to properly set the socket error */ if (errno == EPIPE || errno == EBADF) { ps->state = PI_SOCK_CONN_BREAK; return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); } return pi_set_error(ps->sd, PI_ERR_SOCK_IO); } total -= nwrote; } data->tx_bytes += len; LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV TX Inet Bytes: %d\n", len)); return len; }
/*********************************************************************** * * Function: u_write * * Summary: Write to the open socket/file descriptor * * Parameters: None * * Returns: Nothing * ***********************************************************************/ static int u_write(pi_socket_t *ps, unsigned char *buf, size_t len, int flags) { int total, nwrote; struct pi_usb_data *data = (struct pi_usb_data *)ps->device->data; struct timeval t; fd_set ready; FD_ZERO(&ready); FD_SET(ps->sd, &ready); total = len; while (total > 0) { if (data->timeout == 0) select(ps->sd + 1, 0, &ready, 0, 0); else { t.tv_sec = data->timeout / 1000; t.tv_usec = (data->timeout % 1000) * 1000; if (select(ps->sd + 1, 0, &ready, 0, &t)) return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); } if (!FD_ISSET(ps->sd, &ready)) { ps->state = PI_SOCK_CONN_BREAK; return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); } nwrote = write(ps->sd, buf, len); if (nwrote < 0) { ps->state = PI_SOCK_CONN_BREAK; return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); } total -= nwrote; } LOG((PI_DBG_DEV, PI_DBG_LVL_DEBUG, "DEV TX linuxusb wrote %d bytes\n", len)); return len; }
static GnomePilotRecord local_record_to_pilot_record (EMemoLocalRecord *local, EMemoConduitContext *ctxt) { GnomePilotRecord p; #ifdef PILOT_LINK_0_12 pi_buffer_t * buffer; #else static char record[0xffff]; #endif memset(&p, 0, sizeof (p)); g_assert (local->comp != NULL); g_assert (local->memo != NULL ); LOG (g_message ( "local_record_to_pilot_record\n" )); memset (&p, 0, sizeof (GnomePilotRecord)); p.ID = local->local.ID; p.category = local->local.category; p.attr = local->local.attr; p.archived = local->local.archived; p.secret = local->local.secret; /* Generate pilot record structure */ #ifdef PILOT_LINK_0_12 buffer = pi_buffer_new(DLP_BUF_SIZE); if(buffer == NULL){ pi_set_error(ctxt->dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); return p; } pack_Memo (local->memo, buffer, memo_v1); p.record = g_new0(unsigned char, buffer->used); p.length = buffer->used; memcpy(p.record, buffer->data, buffer->used); pi_buffer_free(buffer); #else p.record = (unsigned char *)record; p.length = pack_Memo (local->memo, p.record, 0xffff); #endif return p; }
static int pi_inet_setsockopt(pi_socket_t *ps, int level, int option_name, const void *option_value, size_t *option_len) { pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; switch (option_name) { case PI_DEV_TIMEOUT: if (*option_len != sizeof (data->timeout)) { errno = EINVAL; return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT); } memcpy (&data->timeout, option_value, sizeof (data->timeout)); break; } return 0; }
static void local_record_from_ecard (EAddrLocalRecord *local, EContact *contact, EAddrConduitContext *ctxt) { EContactAddress *address = NULL; int phone = entryPhone1; EContactField field; gboolean syncable; int i; g_return_if_fail (local != NULL); g_return_if_fail (contact != NULL); local->contact = g_object_ref (contact); local->local.ID = e_pilot_map_lookup_pid (ctxt->map, e_contact_get_const (contact, E_CONTACT_UID), TRUE); compute_status (ctxt, local, e_contact_get_const (contact, E_CONTACT_UID)); local->addr = g_new0 (struct Address, 1); /* Handle the fields and category we don't sync by making sure * we don't overwrite them */ if (local->local.ID != 0) { struct Address addr; int cat = 0; #ifdef PILOT_LINK_0_12 pi_buffer_t * record; record = pi_buffer_new(DLP_BUF_SIZE); if(record == NULL){ pi_set_error(ctxt->dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); return; } #else char record[0xffff]; #endif if (dlp_ReadRecordById (ctxt->dbi->pilot_socket, ctxt->dbi->db_handle, #ifdef PILOT_LINK_0_12 local->local.ID, record, NULL, NULL, &cat) > 0) { #else local->local.ID, &record, NULL, NULL, NULL, &cat) > 0) { #endif local->local.category = cat; memset (&addr, 0, sizeof (struct Address)); #ifdef PILOT_LINK_0_12 unpack_Address (&addr, record, address_v1); #else unpack_Address (&addr, (unsigned char *)record, 0xffff); #endif for (i = 0; i < 5; i++) { if (addr.entry[entryPhone1 + i]) local->addr->entry[entryPhone1 + i] = strdup (addr.entry[entryPhone1 + i]); local->addr->phoneLabel[i] = addr.phoneLabel[i]; } local->addr->showPhone = addr.showPhone; for (i = 0; i < 4; i++) { if (addr.entry[entryCustom1 + i]) local->addr->entry[entryCustom1 + i] = strdup (addr.entry[entryCustom1 + i]); } free_Address (&addr); } #ifdef PILOT_LINK_0_12 pi_buffer_free (record); #endif } local->addr->entry[entryFirstname] = e_pilot_utf8_to_pchar (e_contact_get_const (contact, E_CONTACT_GIVEN_NAME)); local->addr->entry[entryLastname] = e_pilot_utf8_to_pchar (e_contact_get_const (contact, E_CONTACT_FAMILY_NAME)); local->addr->entry[entryCompany] = e_pilot_utf8_to_pchar (e_contact_get_const (contact, E_CONTACT_ORG)); local->addr->entry[entryTitle] = e_pilot_utf8_to_pchar (e_contact_get_const (contact, E_CONTACT_TITLE)); /* See if the default has something in it */ if ((address = e_contact_get (contact, ctxt->cfg->default_address))) { field = ctxt->cfg->default_address; } else { /* Try to find a non-empty address field */ for (field = E_CONTACT_FIRST_ADDRESS_ID; field <= E_CONTACT_LAST_ADDRESS_ID; field++) { if ((address = e_contact_get (contact, field))) break; } } if (address) { char *add; /* If the address has 2 lines, make sure both get added */ if (address->ext != NULL && strlen (address->ext) > 0) { add = g_strconcat (address->street, "\n", address->ext, NULL); LOG (g_warning ("Address has two lines: [%s]\n", add)); } else { add = g_strdup (address->street); LOG (g_warning ("Address has only one line: [%s]\n", add)); } local->addr->entry[entryAddress] = e_pilot_utf8_to_pchar (add); g_free (add); local->addr->entry[entryCity] = e_pilot_utf8_to_pchar (address->locality); local->addr->entry[entryState] = e_pilot_utf8_to_pchar (address->region); local->addr->entry[entryZip] = e_pilot_utf8_to_pchar (address->code); local->addr->entry[entryCountry] = e_pilot_utf8_to_pchar (address->country); e_contact_address_free (address); } /* Phone numbers */ /* See if everything is syncable */ syncable = is_syncable (ctxt, local); if (syncable) { INFO ("Syncable"); /* Sync by priority */ for (i = 0, phone = entryPhone1; priority[i] != E_CONTACT_FIELD_LAST && phone <= entryPhone5; i++) { const char *phone_str; phone_str = e_contact_get_const (contact, priority[i]); if (phone_str && *phone_str) { clear_entry_text (*local->addr, phone); local->addr->entry[phone] = e_pilot_utf8_to_pchar (phone_str); local->addr->phoneLabel[phone - entryPhone1] = priority_label[i]; phone++; } } for ( ; phone <= entryPhone5; phone++) local->addr->phoneLabel[phone - entryPhone1] = phone - entryPhone1; local->addr->showPhone = 0; } else { EContactField next_mail, next_home, next_work, next_fax; EContactField next_other, next_main, next_pager, next_mobile; INFO ("Not Syncable"); get_next_init (&next_mail, &next_home, &next_work, &next_fax, &next_other, &next_main, &next_pager, &next_mobile); /* Not completely syncable, so do the best we can */ for (i = entryPhone1; i <= entryPhone5; i++) { int phonelabel = local->addr->phoneLabel[i - entryPhone1]; const char *phone_str = NULL; if (phonelabel == LABEL_EMAIL && !is_next_done (next_mail)) { phone_str = e_contact_get_const (contact, next_mail); next_mail = get_next_mail (&next_mail); } else if (phonelabel == LABEL_HOME && !is_next_done (next_home)) { phone_str = e_contact_get_const (contact, next_home); next_home = get_next_home (&next_home); } else if (phonelabel == LABEL_WORK && !is_next_done (next_work)) { phone_str = e_contact_get_const (contact, next_work); next_work = get_next_work (&next_work); } else if (phonelabel == LABEL_FAX && !is_next_done (next_fax)) { phone_str = e_contact_get_const (contact, next_fax); next_fax = get_next_fax (&next_fax); } else if (phonelabel == LABEL_OTHER && !is_next_done (next_other)) { phone_str = e_contact_get_const (contact, next_other); next_other = get_next_other (&next_other); } else if (phonelabel == LABEL_MAIN && !is_next_done (next_main)) { phone_str = e_contact_get_const (contact, next_main); next_main = get_next_main (&next_main); } else if (phonelabel == LABEL_PAGER && !is_next_done (next_pager)) { phone_str = e_contact_get_const (contact, next_pager); next_pager = get_next_pager (&next_pager); } else if (phonelabel == LABEL_MOBILE && !is_next_done (next_mobile)) { phone_str = e_contact_get_const (contact, next_mobile); next_mobile = get_next_mobile (&next_mobile); } if (phone_str && *phone_str) { clear_entry_text (*local->addr, i); local->addr->entry[i] = e_pilot_utf8_to_pchar (phone_str); } } } /* Note */ local->addr->entry[entryNote] = e_pilot_utf8_to_pchar (e_contact_get_const (contact, E_CONTACT_NOTE)); }
/* Pilot syncing callbacks */ static gint pre_sync (GnomePilotConduit *conduit, GnomePilotDBInfo *dbi, EAddrConduitContext *ctxt) { GnomePilotConduitSyncAbs *abs_conduit; EBookQuery *query; GList *l; int len; char *filename; char *change_id; char *auth; gint num_records, add_records = 0, mod_records = 0, del_records = 0; #ifdef PILOT_LINK_0_12 pi_buffer_t *buffer; #else unsigned char *buf; #endif abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit); LOG (g_message ( "---------------------------------------------------------\n" )); LOG (g_message ( "pre_sync: Addressbook Conduit v.%s", CONDUIT_VERSION )); /* g_message ("Addressbook Conduit v.%s", CONDUIT_VERSION); */ ctxt->dbi = dbi; if (ctxt->cfg->source) { ctxt->ebook = e_book_new (ctxt->cfg->source, NULL); } else { ctxt->ebook = e_book_new_default_addressbook (NULL); } auth = (gchar *)e_source_get_property (ctxt->cfg->source, "auth"); if (auth) { LOG (g_message ("contacts needs authentication\n")); g_signal_connect (ctxt->ebook, "auth_required", G_CALLBACK (addressbook_authenticate), ctxt->cfg->source); } if (!ctxt->ebook || !e_book_open (ctxt->ebook, TRUE, NULL)) { WARN(_("Could not load addressbook")); gnome_pilot_conduit_error (conduit, _("Could not load addressbook")); return -1; } /* Load the uid <--> pilot id mappings */ filename = map_name (ctxt); e_pilot_map_read (filename, &ctxt->map); g_free (filename); /* Get a list of all contacts */ if (!(query = e_book_query_any_field_contains (""))) { LOG (g_warning ("Failed to get EBookQuery")); return -1; } if (!e_book_get_contacts (ctxt->ebook, query, &ctxt->cards, NULL)) { LOG (g_warning ("Failed to get Contacts")); e_book_query_unref (query); return -1; } e_book_query_unref (query); /* Count and hash the changes */ change_id = g_strdup_printf ("pilot-sync-evolution-addressbook-%d", ctxt->cfg->pilot_id); if (!e_book_get_changes (ctxt->ebook, change_id, &ctxt->changed, NULL)) return -1; ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal); g_free (change_id); for (l = ctxt->changed; l != NULL; l = l->next) { EBookChange *ebc = l->data; const char *uid; uid = e_contact_get_const (ebc->contact, E_CONTACT_UID); if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) { g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ebc); switch (ebc->change_type) { case E_BOOK_CHANGE_CARD_ADDED: add_records++; break; case E_BOOK_CHANGE_CARD_MODIFIED: mod_records++; break; case E_BOOK_CHANGE_CARD_DELETED: del_records++; break; } } else if (ebc->change_type == E_BOOK_CHANGE_CARD_DELETED) { e_pilot_map_remove_by_uid (ctxt->map, uid); } } /* Set the count information */ num_records = g_list_length (ctxt->cards); gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records); gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records); gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records); gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records); #ifdef PILOT_LINK_0_12 buffer = pi_buffer_new(DLP_BUF_SIZE); if(buffer == NULL){ return pi_set_error(dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); } len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0, DLP_BUF_SIZE, buffer); #else buf = (unsigned char*)g_malloc (0xffff); len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0, (unsigned char *)buf, 0xffff); #endif if (len < 0) { WARN (_("Could not read pilot's Address application block")); WARN ("dlp_ReadAppBlock(...) = %d", len); gnome_pilot_conduit_error (conduit, _("Could not read pilot's Address application block")); return -1; } #ifdef PILOT_LINK_0_12 unpack_AddressAppInfo (&(ctxt->ai), buffer->data, len); pi_buffer_free (buffer); #else unpack_AddressAppInfo (&(ctxt->ai), buf, len); g_free (buf); #endif check_for_slow_setting (conduit, ctxt); if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot) ctxt->map->write_touched_only = TRUE; return 0; }
static EContact * ecard_from_remote_record(EAddrConduitContext *ctxt, GnomePilotRecord *remote, EContact *in_contact) { struct Address address; EContact *contact; EContactName *name; EContactAddress *eaddress; EContactField mailing_address; char *txt, *find, *full_name; EContactField next_mail, next_home, next_work, next_fax; EContactField next_other, next_main, next_pager, next_mobile; int i; #ifdef PILOT_LINK_0_12 pi_buffer_t * buffer; #endif g_return_val_if_fail(remote!=NULL,NULL); memset (&address, 0, sizeof (struct Address)); #ifdef PILOT_LINK_0_12 buffer = pi_buffer_new(DLP_BUF_SIZE); if(buffer == NULL){ pi_set_error(ctxt->dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); return NULL; } if(pi_buffer_append(buffer, remote->record, remote->length)==NULL){ pi_set_error(ctxt->dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); return NULL; } unpack_Address (&address, buffer, address_v1); pi_buffer_free(buffer); #else unpack_Address (&address, remote->record, remote->length); #endif if (in_contact == NULL) contact = e_contact_new (); else contact = e_contact_duplicate (in_contact); /* Name */ name = e_contact_name_new (); name->given = get_entry_text (address, entryFirstname); name->family = get_entry_text (address, entryLastname); full_name = e_contact_name_to_string (name); e_contact_set (contact, E_CONTACT_FULL_NAME, full_name); e_contact_name_free (name); /* File As */ if (!full_name || !*full_name) set_contact_text (contact, E_CONTACT_FILE_AS, address, entryCompany); g_free (full_name); /* Title and Company */ set_contact_text (contact, E_CONTACT_TITLE, address, entryTitle); set_contact_text (contact, E_CONTACT_ORG, address, entryCompany); /* Address */ mailing_address = -1; if ((eaddress = e_contact_get (contact, ctxt->cfg->default_address))) { mailing_address = ctxt->cfg->default_address; e_contact_address_free (eaddress); } else { for (i = E_CONTACT_FIRST_ADDRESS_ID; i <= E_CONTACT_LAST_ADDRESS_ID; i++) { if ((eaddress = e_contact_get (contact, i))) { e_contact_address_free (eaddress); mailing_address = i; break; } } } if (mailing_address == -1) mailing_address = ctxt->cfg->default_address; eaddress = g_new0 (EContactAddress, 1); txt = get_entry_text (address, entryAddress); if (txt && (find = strchr (txt, '\n')) != NULL) { *find = '\0'; find++; } else { find = NULL; } eaddress->street = txt; eaddress->ext = find != NULL ? g_strdup (find) : g_strdup (""); eaddress->locality = get_entry_text (address, entryCity); eaddress->region = get_entry_text (address, entryState); eaddress->country = get_entry_text (address, entryCountry); eaddress->code = get_entry_text (address, entryZip); e_contact_set (contact, mailing_address, eaddress); e_contact_address_free (eaddress); /* Phone numbers */ get_next_init (&next_mail, &next_home, &next_work, &next_fax, &next_other, &next_main, &next_pager, &next_mobile); for (i = entryPhone1; i <= entryPhone5; i++) { int phonelabel = address.phoneLabel[i - entryPhone1]; char *phonenum = get_entry_text (address, i); if (phonelabel == LABEL_EMAIL && !is_next_done (next_mail)) { e_contact_set (contact, next_mail, phonenum); next_mail = get_next_mail (&next_mail); } else if (phonelabel == LABEL_HOME && !is_next_done (next_home)) { e_contact_set (contact, next_home, phonenum); next_home = get_next_home (&next_home); } else if (phonelabel == LABEL_WORK && !is_next_done (next_work)) { e_contact_set (contact, next_work, phonenum); next_work = get_next_work (&next_work); } else if (phonelabel == LABEL_FAX && !is_next_done (next_fax)) { e_contact_set (contact, next_fax, phonenum); next_fax = get_next_fax (&next_fax); } else if (phonelabel == LABEL_OTHER && !is_next_done (next_other)) { e_contact_set (contact, next_other, phonenum); next_other = get_next_other (&next_other); } else if (phonelabel == LABEL_MAIN && !is_next_done (next_main)) { e_contact_set (contact, next_main, phonenum); next_main = get_next_main (&next_main); } else if (phonelabel == LABEL_PAGER && !is_next_done (next_pager)) { e_contact_set (contact, next_pager, phonenum); next_pager = get_next_pager (&next_pager); } else if (phonelabel == LABEL_MOBILE && !is_next_done (next_mobile)) { e_contact_set (contact, next_mobile, phonenum); next_mobile = get_next_mobile (&next_mobile); } g_free (phonenum); } /* Note */ set_contact_text (contact, E_CONTACT_NOTE, address, entryNote); free_Address(&address); return contact; }
/* Pilot syncing callbacks */ static gint pre_sync (GnomePilotConduit *conduit, GnomePilotDBInfo *dbi, EMemoConduitContext *ctxt) { GnomePilotConduitSyncAbs *abs_conduit; GList *l; int len; unsigned char *buf; char *filename, *change_id; icalcomponent *icalcomp; gint num_records, add_records = 0, mod_records = 0, del_records = 0; #ifdef PILOT_LINK_0_12 pi_buffer_t * buffer; #endif abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit); LOG (g_message ( "---------------------------------------------------------\n" )); LOG (g_message ( "pre_sync: Memo Conduit v.%s", CONDUIT_VERSION )); g_message ("Memo Conduit v.%s", CONDUIT_VERSION); ctxt->dbi = dbi; ctxt->client = NULL; if (start_calendar_server (ctxt) != 0) { WARN(_("Could not start evolution-data-server")); gnome_pilot_conduit_error (conduit, _("Could not start evolution-data-server")); return -1; } /* Get the timezone */ ctxt->timezone = get_default_timezone (); if (ctxt->timezone == NULL) return -1; LOG (g_message ( " Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) )); /* Set the default timezone on the backend. */ if (ctxt->timezone && !e_cal_set_default_timezone (ctxt->client, ctxt->timezone, NULL)) return -1; /* Get the default component */ if (!e_cal_get_default_object (ctxt->client, &icalcomp, NULL)) return -1; ctxt->default_comp = e_cal_component_new (); if (!e_cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) { g_object_unref (ctxt->default_comp); icalcomponent_free (icalcomp); return -1; } /* Load the uid <--> pilot id map */ filename = map_name (ctxt); e_pilot_map_read (filename, &ctxt->map); g_free (filename); /* Get the local database */ if (!e_cal_get_object_list_as_comp (ctxt->client, "#t", &ctxt->comps, NULL)) return -1; /* Count and hash the changes */ change_id = g_strdup_printf ("pilot-sync-evolution-memo-%d", ctxt->cfg->pilot_id); if (!e_cal_get_changes (ctxt->client, change_id, &ctxt->changed, NULL)) return -1; ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal); g_free (change_id); for (l = ctxt->changed; l != NULL; l = l->next) { ECalChange *ccc = l->data; const char *uid; e_cal_component_get_uid (ccc->comp, &uid); if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) { g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc); switch (ccc->type) { case E_CAL_CHANGE_ADDED: add_records++; break; case E_CAL_CHANGE_MODIFIED: mod_records++; break; case E_CAL_CHANGE_DELETED: del_records++; break; } } else if (ccc->type == E_CAL_CHANGE_DELETED) { e_pilot_map_remove_by_uid (ctxt->map, uid); } } /* Set the count information */ num_records = g_list_length (ctxt->comps); gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records); gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records); gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records); gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records); g_message("num_records: %d\nadd_records: %d\nmod_records: %d\ndel_records: %d\n", num_records, add_records, mod_records, del_records); #ifdef PILOT_LINK_0_12 buffer = pi_buffer_new(DLP_BUF_SIZE); if(buffer == NULL){ pi_set_error(dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); return -1; } len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0, DLP_BUF_SIZE, buffer); #else buf = (unsigned char*)g_malloc (0xffff); len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0, (unsigned char *)buf, 0xffff); #endif if (len < 0) { WARN (_("Could not read pilot's Memo application block")); WARN ("dlp_ReadAppBlock(...) = %d", len); gnome_pilot_conduit_error (conduit, _("Could not read pilot's Memo application block")); return -1; } #ifdef PILOT_LINK_0_12 buf = g_new0 (unsigned char,buffer->used); memcpy(buf, buffer->data, buffer->used); unpack_MemoAppInfo (&(ctxt->ai), buf, len); pi_buffer_free(buffer); #else unpack_MemoAppInfo (&(ctxt->ai), buf, len); #endif g_free (buf); lastDesktopUniqueID = 128; check_for_slow_setting (conduit, ctxt); if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot) ctxt->map->write_touched_only = TRUE; return 0; }
/* * converts a ECalComponent object to a EMemoLocalRecord */ static void local_record_from_comp (EMemoLocalRecord *local, ECalComponent *comp, EMemoConduitContext *ctxt) { const char *uid; GSList *d_list = NULL; ECalComponentText *description; ECalComponentClassification classif; LOG (g_message ( "local_record_from_comp\n" )); g_return_if_fail (local != NULL); g_return_if_fail (comp != NULL); local->comp = comp; g_object_ref (comp); LOG(fprintf(stderr, "local_record_from_comp: calling e_cal_component_get_uid\n")); e_cal_component_get_uid (local->comp, &uid); LOG(fprintf(stderr, "local_record_from_comp: got UID - %s, calling e_pilot_map_lookup_pid\n", uid)); local->local.ID = e_pilot_map_lookup_pid (ctxt->map, uid, TRUE); LOG(fprintf(stderr, "local_record_from_comp: local->local.ID == %lu\n", local->local.ID)); compute_status (ctxt, local, uid); LOG(fprintf(stderr, "local_record_from_comp: local->local.attr: %d\n", local->local.attr)); local->memo = g_new0 (struct Memo,1); /* Don't overwrite the category */ if (local->local.ID != 0) { #ifdef PILOT_LINK_0_12 struct Memo memo; pi_buffer_t * record; #else char record[0xffff]; #endif int cat = 0; #ifdef PILOT_LINK_0_12 record = pi_buffer_new(DLP_BUF_SIZE); if(record == NULL){ pi_set_error(ctxt->dbi->pilot_socket, PI_ERR_GENERIC_MEMORY); return; } #endif LOG(fprintf(stderr, "local_record_from_comp: calling dlp_ReadRecordById\n")); if (dlp_ReadRecordById (ctxt->dbi->pilot_socket, ctxt->dbi->db_handle, #ifdef PILOT_LINK_0_12 local->local.ID, record, NULL, NULL, &cat) > 0) { local->local.category = cat; memset (&memo, 0, sizeof (struct Memo)); unpack_Memo (&memo, record, memo_v1); local->memo->text = strdup (memo.text); free_Memo (&memo); } pi_buffer_free (record); #else local->local.ID, &record, NULL, NULL, NULL, &cat) > 0) { local->local.category = cat; } #endif LOG(fprintf(stderr, "local_record_from_comp: done calling dlp_ReadRecordById\n")); } /*Category support*/ e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category)); /* STOP: don't replace these with g_strdup, since free_Memo uses free to deallocate */ e_cal_component_get_description_list (comp, &d_list); if (d_list) { description = (ECalComponentText *) d_list->data; if (description && description->value){ local->memo->text = e_pilot_utf8_to_pchar (description->value); } else{ local->memo->text = NULL; } } else { local->memo->text = NULL; } e_cal_component_get_classification (comp, &classif); if (classif == E_CAL_COMPONENT_CLASS_PRIVATE) local->local.secret = 1; else local->local.secret = 0; local->local.archived = 0; }
static int pi_inet_accept(pi_socket_t *ps, struct sockaddr *addr, size_t *addrlen) { int sd, err, split = 0, chunksize = 0; size_t len, size; pl_socklen_t l = 0; unsigned char cmp_flags; if (addrlen) l = *addrlen; sd = accept(ps->sd, addr, &l); if (addrlen) *addrlen = l; if (sd < 0) { pi_set_error(ps->sd, sd); err = PI_ERR_GENERIC_SYSTEM; goto fail; } pi_socket_setsd(ps, sd); pi_socket_init(ps); switch (ps->cmd) { case PI_CMD_CMP: if ((err = cmp_rx_handshake(ps, 57600, 0)) < 0) goto fail; /* propagate the long packet format flag to both command and non-command stacks */ size = sizeof(cmp_flags); pi_getsockopt(ps->sd, PI_LEVEL_CMP, PI_CMP_FLAGS, &cmp_flags, &size); if (cmp_flags & CMP_FL_LONG_PACKET_SUPPORT) { int use_long_format = 1; size = sizeof(int); pi_setsockopt(ps->sd, PI_LEVEL_PADP, PI_PADP_USE_LONG_FORMAT, &use_long_format, &size); ps->command ^= 1; pi_setsockopt(ps->sd, PI_LEVEL_PADP, PI_PADP_USE_LONG_FORMAT, &use_long_format, &size); ps->command ^= 1; } break; case PI_CMD_NET: /* network: make sure we don't split writes. set socket option * on both the command and non-command instances of the protocol */ len = sizeof (split); pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_SPLIT_WRITES, &split, &len); len = sizeof (chunksize); pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_WRITE_CHUNKSIZE, &chunksize, &len); ps->command ^= 1; len = sizeof (split); pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_SPLIT_WRITES, &split, &len); len = sizeof (chunksize); pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_WRITE_CHUNKSIZE, &chunksize, &len); ps->command ^= 1; if ((err = net_rx_handshake(ps)) < 0) goto fail; break; } ps->state = PI_SOCK_CONN_ACCEPT; ps->command = 0; ps->dlprecord = 0; LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV INET ACCEPT accepted\n")); return ps->sd; fail: return err; }
static int pi_inet_connect(pi_socket_t *ps, struct sockaddr *addr, size_t addrlen) { int sd, err; struct pi_sockaddr *paddr = (struct pi_sockaddr *) addr; struct sockaddr_in serv_addr; char *device = paddr->pi_device; /* Figure out the addresses to allow */ memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (strlen(device) > 1) { serv_addr.sin_addr.s_addr = inet_addr(device); if (serv_addr.sin_addr.s_addr == (in_addr_t)-1) { struct hostent *hostent = gethostbyname(device); if (!hostent) { LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, "DEV CONNECT Inet: Unable" " to determine host\n")); return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); } memcpy((char *) &serv_addr.sin_addr.s_addr, hostent->h_addr, (size_t)hostent->h_length); } } else { serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); } serv_addr.sin_port = htons(14238); sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) { LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, "DEV CONNECT Inet: Unable to create socket\n")); return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); } if ((err = pi_socket_setsd (ps, sd)) < 0) return err; if (connect (ps->sd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, "DEV CONNECT Inet: Unable to connect\n")); return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); } ps->raddr = malloc(addrlen); memcpy(ps->raddr, addr, addrlen); ps->raddrlen = addrlen; ps->laddr = malloc(addrlen); memcpy(ps->laddr, addr, addrlen); ps->laddrlen = addrlen; switch (ps->cmd) { case PI_CMD_CMP: if ((err = cmp_tx_handshake(ps)) < 0) goto fail; break; case PI_CMD_NET: if ((err = net_tx_handshake(ps)) < 0) goto fail; break; } ps->state = PI_SOCK_CONN_INIT; ps->command = 0; LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV CONNECT Inet: Connected\n")); return 0; fail: return err; }
static int pi_inet_bind(pi_socket_t *ps, struct sockaddr *addr, size_t addrlen) { int opt, sd, err; size_t optlen; struct pi_sockaddr *paddr = (struct pi_sockaddr *) addr; struct sockaddr_in serv_addr; char *device = paddr->pi_device, *port = NULL; /* Figure out the addresses to allow */ memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (strlen(device) > 1 && strncmp(device, "any", 3)) { serv_addr.sin_addr.s_addr = inet_addr(device); if (serv_addr.sin_addr.s_addr == (in_addr_t)-1) { struct hostent *hostent = gethostbyname(device); if (!hostent) return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); memcpy((char *) &serv_addr.sin_addr.s_addr, hostent->h_addr, (size_t)hostent->h_length); } } else { serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); } if ((port = strchr(device, ':')) != NULL) { serv_addr.sin_port = htons(atoi(++port)); } else { serv_addr.sin_port = htons(14238); } sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) { LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, "DEV BIND Inet: Unable to create socket\n")); return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); } if ((err = pi_socket_setsd (ps, sd)) < 0) return err; opt = 1; optlen = sizeof(opt); if (setsockopt(ps->sd, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, (int)optlen) < 0) { return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); } if (bind(ps->sd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV BIND Inet Bound to %s\n", device)); ps->raddr = malloc(addrlen); memcpy(ps->raddr, addr, addrlen); ps->raddrlen = addrlen; ps->laddr = malloc(addrlen); memcpy(ps->laddr, addr, addrlen); ps->laddrlen = addrlen; return 0; }
/*********************************************************************** * * Function: u_read * * Summary: Read incoming data from the socket/file descriptor * * Parameters: pi_socket_t*, char* to buffer, buffer length, flags * * Returns: number of bytes read or negative otherwise * ***********************************************************************/ static int u_read(pi_socket_t *ps, pi_buffer_t *buf, size_t len, int flags) { ssize_t rbuf = 0, bytes; struct pi_usb_data *data = (struct pi_usb_data *)ps->device->data; struct timeval t; fd_set ready; /* check whether we have at least partial data in store */ if (data->buf_size) { rbuf = u_read_buf(ps, buf, len, flags); if (rbuf < 0) return rbuf; len -= rbuf; if (len == 0) return rbuf; } /* If timeout == 0, wait forever for packet, otherwise wait till timeout milliseconds */ FD_ZERO(&ready); FD_SET(ps->sd, &ready); if (data->timeout == 0) select(ps->sd + 1, &ready, 0, 0, 0); else { t.tv_sec = data->timeout / 1000; t.tv_usec = (data->timeout % 1000) * 1000; if (select(ps->sd + 1, &ready, 0, 0, &t) == 0) { LOG((PI_DBG_DEV, PI_DBG_LVL_WARN, "DEV RX linuxusb timeout\n")); errno = ETIMEDOUT; return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); } } /* If data is available in time, read it */ if (FD_ISSET(ps->sd, &ready)) { if (flags == PI_MSG_PEEK && len > 256) len = 256; if (pi_buffer_expect (buf, len) == NULL) { errno = ENOMEM; return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY); } bytes = read(ps->sd, buf->data + buf->used, len); if (bytes > 0) { if (flags == PI_MSG_PEEK) { memcpy(data->buf + data->buf_size, buf->data + buf->used, bytes); data->buf_size += bytes; } buf->used += bytes; rbuf += bytes; LOG((PI_DBG_DEV, PI_DBG_LVL_DEBUG, "DEV RX linuxusb read %d bytes\n", bytes)); } } else { LOG((PI_DBG_DEV, PI_DBG_LVL_WARN, "DEV RX linuxusb timeout\n")); errno = ETIMEDOUT; return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); } return rbuf; }