コード例 #1
0
/**
 * Encode and send password on a socket
 */
bool synce_password_send(
		SynceSocket* socket,
		const char* asciiPassword,
		unsigned char key)
{
	bool success = false;
	unsigned char* encoded_password = NULL;
	size_t size = 0;
	uint16_t size_le = 0;
	
	if (!synce_password_encode(asciiPassword, key, &encoded_password, &size))
	{
		synce_error("failed to encode password");
	}

	size_le = htole16((uint16_t)size);

	if ( !synce_socket_write(socket, &size_le, sizeof(uint16_t)) )
	{
		synce_error("failed to write buffer size to socket");
		goto exit;
	}

	if ( !synce_socket_write(socket, encoded_password, size) )
	{
		synce_error("failed to write encoded password to socket");
		goto exit;
	}

	success = true;

exit:
	synce_password_free(encoded_password);
	return success;
}
コード例 #2
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_add_simple_propval(Generator* self, const char* name, CEPROPVAL* propval)/*{{{*/
{
  bool success = false;
  
  if (STATE_IDLE != self->state)
  {
    synce_error("Missing call to generator_end_line()");
    return false;
  }

  switch (propval->propid & 0xffff)
  {
    case CEVT_LPWSTR:
      /* do not add empty strings */
      if (propval->val.lpwstr[0])
      {
        strbuf_append(self->buffer, name);
        strbuf_append_c(self->buffer, ':');
        generator_append_escaped_wstr(self, propval->val.lpwstr);
        strbuf_append_crlf(self->buffer);
      }
      success = true;
      break;

    default:
      synce_error("Data type not handled");
      break;
  }
  
  return success;
}/*}}}*/
コード例 #3
0
static SynceInfo* synce_info_from_midasyncd(const char* path)
{
  bool success = false;
  SynceInfo* result = calloc(1, sizeof(SynceInfo));
  DBusConnection* connection = NULL;
  DBusError error;
  char** device_names = NULL;
  int device_count = 0;
  DBusMessage* properties = NULL;

  dbus_error_init(&error);

  /* Connect to D-BUS */
  connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
  if (dbus_error_is_set (&error))
  {
    synce_error("%s error '%s'", error.name, error.message);
    dbus_error_free(&error);
    goto exit;
  }

  if (!connection) {
    synce_error("Failed to connect to the D-BUS daemon");
    goto exit;
  }

  if (!path)
  {
    if (!get_all_devices(connection, &device_names, &device_count))
      goto exit;

    if (device_count < 1)
      goto exit;

    path = device_names[0];
  }

  if (!get_all_properties(connection, path, &properties))
    goto exit;

  if (!properties_to_info(properties, result))
    goto exit;

  success = true;

exit:
  /* TODO: clean up D-BUS connection */
  if (device_names)
    dbus_free_string_array(device_names);

  if (success)
    return result;
  else
  {
    synce_info_destroy(result);
    return NULL;
  }
}
コード例 #4
0
static bool get_all_devices(DBusConnection* connection, char*** pDeviceNames, int* pDeviceCount)/*{{{*/
{
  bool success = false;
  DBusError error;
  DBusMessage *message = NULL;
  DBusMessage *reply = NULL;
  DBusMessageIter iter;

  dbus_error_init(&error);

  /* Create and send method call */
  message = dbus_message_new_method_call(
      MIDASYNC_SERVICE,
      MANAGER_PATH,
      MANAGER_INTERFACE,
      "GetAllDevices");
  if (message == NULL)
  {
    synce_error("Couldn't allocate D-BUS message");
    goto exit;
  }

  reply = dbus_connection_send_with_reply_and_block(
      connection,
      message, -1,
      &error);
  if (dbus_error_is_set (&error))
  {
    synce_error("%s error '%s'", error.name, error.message);
    goto exit;
  }

  if (!reply)
    goto exit;

  /* Handle reply */
  dbus_message_iter_init(reply, &iter);
  if (!dbus_message_iter_get_string_array(
        &iter,
        pDeviceNames,
        pDeviceCount))
  {
    synce_error("Invalid reply from midasyncd.");
    return NULL;
  }

  synce_debug("Found %i devices registered by midasyncd", *pDeviceCount);

  success = true;

exit:
  if (message)
    dbus_message_unref(message);
  if (reply)
    dbus_message_unref(reply);

  return success;
}/*}}}*/
コード例 #5
0
ファイル: recurrence.c プロジェクト: asmblur/SynCE
bool recurrence_generate_rrule_ical(
    Generator* g, 
    CEPROPVAL* propval,
    RRA_Timezone *tzi)
{
  bool success = false;
  RRA_RecurrencePattern* pattern = NULL;

  if ((propval->propid & 0xffff) != CEVT_BLOB)
  {
    synce_error("CEPROPVAL is not a BLOB");
    goto exit;
  }
  
  pattern = rra_recurrence_pattern_from_buffer(propval->val.blob.lpb, propval->val.blob.dwCount, tzi);

  if (!pattern)
  {
    synce_error("Failed to decode recurrence pattern");
    goto exit;
  }

  switch (pattern->recurrence_type)
  {
    case olRecursDaily:
      success = recurrence_generate_daily_rrule_ical(g, pattern);
      break;
    case olRecursWeekly:
      success = recurrence_generate_weekly_rrule_ical(g, pattern);
      break;
    case olRecursMonthly:
      success = recurrence_generate_monthly_rrule_ical(g, pattern);
      break;
    case olRecursMonthNth:
      success = recurrence_generate_monthnth_rrule_ical(g, pattern);
      break;
    default:
      goto exit;
  }

  if (!success)
  {
    synce_error("Failed to generate RRULE for recurrence type %i",
      pattern->recurrence_type);
    goto exit;
  }

  success = recurrence_generate_exceptions(g, pattern->exceptions);

exit:
  rra_recurrence_pattern_destroy(pattern);
  return success;
}
コード例 #6
0
static bool get_all_properties(DBusConnection* connection, const char* path, DBusMessage** reply)
{
  bool success = false;
  DBusError error;
  DBusMessage *message = NULL;

  *reply = NULL;

  dbus_error_init(&error);

  /* Create and send method call */
  message = dbus_message_new_method_call(
      MIDASYNC_SERVICE,
      path,
      DEVICE_INTERFACE,
      "GetAllProperties");
  if (message == NULL)
  {
    synce_error("Couldn't allocate D-BUS message");
    goto exit;
  }

  *reply = dbus_connection_send_with_reply_and_block(
      connection,
      message, -1,
      &error);
  if (dbus_error_is_set (&error))
  {
    synce_error("%s error '%s'", error.name, error.message);
    goto exit;
  }

  if (!*reply)
    goto exit;

  success = true;

exit:
  if (message)
    dbus_message_unref(message);
  if (!success && *reply)
  {
    dbus_message_unref(*reply);
    *reply = NULL;
  }

  return success;
}
コード例 #7
0
/**
 * Encode a password with a key
 */
static bool synce_password_encode(
		const char *asciiPassword,
		unsigned char key,
		unsigned char **encodedPassword,
		size_t *encodedPasswordSize)
{	
	int length;
	unsigned i;
	
	*encodedPassword = NULL;
	
	if (!asciiPassword)
	{
		synce_error("password parameter is NULL");
		goto error;
	}

	length = strlen(asciiPassword);

	*encodedPassword      = (unsigned char*)wstr_from_ascii(asciiPassword);
	*encodedPasswordSize  = 2 * (length + 1);

	for (i = 0; i < *encodedPasswordSize; i++)
	{
		(*encodedPassword)[i] ^= key;
	}

	return true;

error:
	synce_password_free(*encodedPassword);
	*encodedPassword = NULL;
	return false;
}
コード例 #8
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_set_data(Generator* self, const uint8_t* data, size_t data_size)/*{{{*/
{
  bool success = false;

  if (!data)
  {
    synce_error("RRA Calendar data is NULL");
    goto exit;
  }

  if (data_size < 8)
  {
    synce_error("Invalid data size for RRA calendar data");
    goto exit;
  }

  self->propval_count = letoh32(*(uint32_t*)(data + 0));
  synce_trace("RRA calendar data field count: %i", self->propval_count);

  if (0 == self->propval_count)
  {
    synce_error("No fields in RRA calendar record!");
    goto exit;
  } 
	
  if (self->propval_count > MAX_PROPVAL_COUNT)
  {
    synce_error("Too many fields in RRA calendar record");
    goto exit;
  }

  self->propvals = (CEPROPVAL*)malloc(sizeof(CEPROPVAL) * self->propval_count);

  if (!dbstream_to_propvals(data + 8, self->propval_count, self->propvals))
  {
    synce_error("Failed to convert RRA calendar database stream");
    goto exit;
  }

  success = true;

exit:
  return success;
}/*}}}*/
コード例 #9
0
ファイル: recurrence.c プロジェクト: asmblur/SynCE
static bool recurrence_initialize_rrule_ical(const char* str, RRule* rrule)
{
  int i;
  char** strv = strsplit(str, ';');

  rrule->interval = 1;

  for (i = 0; strv[i]; i++)
  {
    char** pair = strsplit(strv[i], '=');
    if (!pair[0] || !pair[1])
    {
      synce_warning("Invalid rrule part: '%s'", strv[i]);
      continue;
    }

    synce_trace("RRULE part: key=%s, value=%s", 
        pair[0], pair[1]);

    if (STR_EQUAL(pair[0], "BYDAY"))
      replace_string_with_copy(&rrule->byday, pair[1]);
    else if (STR_EQUAL(pair[0], "BYMONTH"))
      rrule->bymonth = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "BYMONTHDAY"))
      rrule->bymonthday = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "BYSETPOS"))
      rrule->bysetpos = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "COUNT"))
      rrule->count = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "FREQ"))
      {
	if (STR_EQUAL(pair[1], "DAILY"))
	  rrule->freq = RRuleDaily;
	else if (STR_EQUAL(pair[1], "WEEKLY"))
	  rrule->freq = RRuleWeekly;
	else if (STR_EQUAL(pair[1], "MONTHLY"))
	  rrule->freq = RRuleMonthly;
	else if (STR_EQUAL(pair[1], "YEARLY"))
	  rrule->freq = RRuleYearly;
	else
	  synce_error("Unexpected frequencey in RRULE '%s'", str);
      }
    else if (STR_EQUAL(pair[0], "INTERVAL"))
      rrule->interval = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "UNTIL"))
      replace_string_with_copy(&rrule->until, pair[1]);
    else
      synce_warning("Unhandled part of RRULE: '%s'", strv[i]);

    strv_free(pair);
  }
  
  strv_free(strv);
  return true;
}
コード例 #10
0
bool synce_password_recv_reply(
		SynceSocket* socket,
		size_t size,
		bool* passwordCorrect)
{
	bool success = false;
	union
	{
		uint8_t   byte;
		uint16_t  word;
	} reply;

	if (size < 1 || size > 2)
	{
		synce_error("invalid size");
		goto exit;	
	}

	if (!synce_socket_read(socket, &reply, size))
	{
		synce_error("failed to read password reply");
		goto exit;	
	}

	if (size == 1)
	{
		/*synce_trace("password reply = 0x%02x (%i)", reply.byte, reply.byte);*/
		*passwordCorrect = reply.byte;
	}
	else /* size == 2 */
	{
		reply.word = letoh16(reply.word);
		/*synce_trace("password reply = 0x%04x (%i)", reply.word, reply.word);*/
		*passwordCorrect = reply.word;
	}

	/*synce_trace("Password was %s", *passwordCorrect ? "correct!" : "incorrect :-(");*/
	success = true;

exit:
	return success;
}
コード例 #11
0
static SynceInfo* synce_info_from_file(const char* filename)
{
  SynceInfo* result = calloc(1, sizeof(SynceInfo));
  bool success = false;
  char* connection_filename;
 	struct configFile* config = NULL;

  if (filename)
    connection_filename = strdup(filename);
  else
    synce_get_connection_filename(&connection_filename);

	config = readConfigFile(connection_filename);
	if (!config)
	{
		synce_error("unable to open file: %s", connection_filename);
		goto exit;
	}

  result->dccm_pid        = getConfigInt(config, "dccm",   "pid");

  result->key             = getConfigInt(config, "device", "key");
  result->os_version      = getConfigInt(config, "device", "os_version");
  result->build_number    = getConfigInt(config, "device", "build_number");
  result->processor_type  = getConfigInt(config, "device", "processor_type");
  result->partner_id_1    = getConfigInt(config, "device", "partner_id_1");
  result->partner_id_2    = getConfigInt(config, "device", "partner_id_2");

  result->ip        = STRDUP(getConfigString(config, "device", "ip"));
  result->password  = STRDUP(getConfigString(config, "device", "password"));
  result->name      = STRDUP(getConfigString(config, "device", "name"));
  result->os_name   = STRDUP(getConfigString(config, "device", "os_name"));
  result->model     = STRDUP(getConfigString(config, "device", "model"));

  result->transport = STRDUP(getConfigString(config, "connection", "transport"));

  success = true;

exit:
  FREE(connection_filename);

  if (config)
    unloadConfigFile(config);

  if (success)
    return result;
  else
  {
    synce_info_destroy(result);
    return NULL;
  }
}
コード例 #12
0
ファイル: recurrence.c プロジェクト: asmblur/SynCE
static void recurrence_append_byday_ical(
    char* buffer, 
    size_t size,
    RRA_RecurrencePattern* pattern)
{
  int i;
  bool first = true;
  
 
  for (i = 0; i < 7; i++)
  {
    if (pattern->days_of_week_mask & masks_and_names[i].mask)
    {
      if (first)
      {
        snprintf(buffer, size, ";BYDAY=");
        first = false;
      }
      else
        snprintf(buffer, size, ",");

      size -= strlen(buffer);
      buffer += strlen(buffer);

#if 0
      switch (pattern->instance)
      {
        case 1:
        case 2:
        case 3:
        case 4:
          snprintf(buffer, size, "%i%s", pattern->instance, masks_and_names[i].name);
          break;
        case 5:
          snprintf(buffer, size, "-1%s", masks_and_names[i].name);
          break;
        case 0:
#endif
          snprintf(buffer, size, "%s", masks_and_names[i].name);
#if 0
          break;
        default:
          synce_error("Invalid instance: %08x", pattern->instance);
          break;
      }
#endif

      size -= strlen(buffer);
      buffer += strlen(buffer);
    }
  }
}
コード例 #13
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_begin_line(Generator* self, const char* name)/*{{{*/
{
  if (STATE_IDLE != self->state)
  {
    synce_error("Missing call to generator_end_line()");
    return false;
  }

  self->state = STATE_PARAM_OR_VALUE;
  
  strbuf_append(self->buffer, name);
  return true;
}/*}}}*/
コード例 #14
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_end_line(Generator* self)/*{{{*/
{
  if (STATE_VALUE != self->state)
  {
    synce_error("Invalid state: %i", self->state);
    return false;
  }

  self->state = STATE_IDLE;

  strbuf_append_crlf(self->buffer);
  return true;
}/*}}}*/
コード例 #15
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_add_simple_unescaped(Generator* self, const char* name, const char* value)/*{{{*/
{
  if (STATE_IDLE != self->state)
  {
    synce_error("Missing call to generator_end_line()");
    return false;
  }

  strbuf_append(self->buffer, name);
  strbuf_append_c(self->buffer, ':');
  strbuf_append(self->buffer, value);
  strbuf_append_crlf(self->buffer);
  return true;
}/*}}}*/
コード例 #16
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_begin_parameter(Generator* self, const char* name)/*{{{*/
{
  if (STATE_PARAM_OR_VALUE != self->state)
  {
    synce_error("Invalid state: %i", self->state);
    return false;
  }

  self->state = STATE_FIRST_PARAM;

  strbuf_append_c(self->buffer, ';');
  strbuf_append(self->buffer, name);
  strbuf_append_c(self->buffer, '=');
  
  return true;
}/*}}}*/
コード例 #17
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_end_parameter(Generator* self)/*{{{*/
{
  if (STATE_FIRST_PARAM == self->state)
  {
    synce_warning("Empty parameter");
  }
  else if (STATE_NEXT_PARAM != self->state)
  {
    synce_error("Invalid state: %i", self->state);
    return false;
  }

  self->state = STATE_PARAM_OR_VALUE;

  return true;
}/*}}}*/
コード例 #18
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_add_with_type(Generator* self, const char* name, /*{{{*/
    const char* type, const char* value)
{
  if (STATE_IDLE != self->state)
  {
    synce_error("Missing call to generator_end_line()");
    return false;
  }

  strbuf_append(self->buffer, name);
  strbuf_append(self->buffer, ";VALUE=");
  strbuf_append(self->buffer, type);
  strbuf_append_c(self->buffer, ':');
  generator_append_escaped(self, value);
  strbuf_append_crlf(self->buffer);
  return true;
}/*}}}*/
コード例 #19
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_add_parameter_value(Generator* self, const char* value)/*{{{*/
{
  if (STATE_NEXT_PARAM == self->state)
  {
    strbuf_append_c(self->buffer, ',');
  }
  else if (STATE_FIRST_PARAM != self->state)
  {
    synce_error("Invalid state: %i", self->state);
    return false;
  }

  self->state = STATE_NEXT_PARAM;

  /* XXX: escape string?  */
  strbuf_append(self->buffer, value);

  return true;
}/*}}}*/
コード例 #20
0
ファイル: generator.c プロジェクト: asmblur/SynCE
bool generator_add_value(Generator* self, const char* value)/*{{{*/
{
  if (STATE_PARAM_OR_VALUE == self->state)
  {
    strbuf_append_c(self->buffer, ':');
  }
  else if (STATE_VALUE == self->state)
  {
    strbuf_append_c(self->buffer, ',');
  }
  else
  {
    synce_error("Invalid state: %i", self->state);
    return false;
  }

  self->state = STATE_VALUE;

  generator_append_escaped(self, value);
  return true;
}/*}}}*/
コード例 #21
0
ファイル: recurrence.c プロジェクト: asmblur/SynCE
static bool recurrence_initialize_rrule_vcal(const char* str, RRule* rrule)
{
  int i;

  /** TODO - check for other whitespace, and multiple whitespace */
  char** strv = strsplit(str, ' ');

  rrule->interval = 1;

  if (strv[0][0] == 'D')
  {
    rrule->freq = RRuleDaily;
    rrule->interval = atoi(strv[0]+1);
    if (strv[1])
    {
      if (strv[1][0] == '#')
	rrule->count = atoi(strv[1]+1);
      else
	replace_string_with_copy(&rrule->until, strv[1]);
    }
  }
  else if (strv[0][0] == 'W')
  {
    rrule->freq = RRuleWeekly;
    rrule->interval = atoi(strv[0]+1);

    StrBuf *days_list = strbuf_new(NULL);
    for (i = 1; strv[i]; i++)
    {
      if (strv[i][0] == '#')
      {
	rrule->count = atoi(strv[i]+1);
	break;
      }
      else if (isdigit(strv[i][0]))
      {
	replace_string_with_copy(&rrule->until, strv[i]);
	break;
      }
      else
      {
	if (days_list->length > 0)
	  days_list = strbuf_append(days_list,",");
	days_list = strbuf_append(days_list,strv[i]);
      }
    }
    if (days_list->length > 0)
      replace_string_with_copy(&rrule->byday, days_list->buffer);
    strbuf_destroy(days_list,1);
  }
  else if (strv[0][0] == 'M')
  {
    rrule->freq = RRuleMonthly;
    if (strv[0][1] == 'D') /* by day in month, ie date */
    {
      rrule->interval = atoi(strv[0]+2);

      int days_found = 0;
      for (i = 1; strv[i]; i++)
      {
	if (strv[i][0] == '#')
	{
	  rrule->count = atoi(strv[i]+1);
	  break;
	}
	else if (isdigit(strv[i][0]) || STR_EQUAL(strv[i],"LD"))
	{
	  if (strlen(strv[i]) > 2)
	  {
	    replace_string_with_copy(&rrule->until, strv[i]);
	    break;
	  }

	  if (days_found == 0)
	  {
	    if (STR_EQUAL(strv[i],"LD"))
	      rrule->bymonthday = -1;
	    else
	      rrule->bymonthday = atoi(strv[i]);
	  }
	  days_found++;
	}
      }

      if (days_found > 1)
	synce_warning("Monthly by Day (MD) can only handle one day in RRA format, in RRULE '%s'", str);
    }
    else if (strv[0][1] == 'P') /* by position, ie the complicated one */
    {
      rrule->interval = atoi(strv[0]+2);

      StrBuf *days_list = strbuf_new(NULL);
      int occurence = 0;
      for (i = 1; strv[i]; i++)
      {
	if (strv[i][0] == '#')
	{
	  rrule->count = atoi(strv[i]+1);
	  break;
	}
	else if (isdigit(strv[i][0]) && strlen(strv[i]) > 2)
	{
	  replace_string_with_copy(&rrule->until, strv[i]);
	  break;
	}
	else if (isdigit(strv[i][0]))
	{
	  if (occurence != 0)
	    /* Any days following this shoukd be bound by this subsequent
	       occurence modifier, but cant be. We'll allow them to go with
	       the first occurrence modifier for now, but maybe we should
	       drop them entirely */
	    synce_info("Multiple occurence values cannot be represented by RRA in Monthly by Position recurrence");
	  else
	    occurence = atoi(strv[i]);
	}
	else
	{
	  if (days_list->length > 0)
	    days_list = strbuf_append(days_list,",");
	  days_list = strbuf_append(days_list,strv[i]);
	}
      }
      rrule->bysetpos = occurence;

      if (days_list->length > 0)
	replace_string_with_copy(&rrule->byday, days_list->buffer);
      strbuf_destroy(days_list,1);
    }
    else
      synce_error("Unexpected frequency in RRULE '%s'", str);
  }
  else if (strv[0][0] == 'Y')
  {
    rrule->freq = RRuleYearly;
    rrule->interval = atoi(strv[0]+2);

    if (strv[0][1] == 'M') /* by month number */
    {
      int months_found = 0;
      for (i = 1; strv[i]; i++)
      {
	if (strv[i][0] == '#')
	{
	  rrule->count = atoi(strv[i]+1);
	  break;
	}
	else if (isdigit(strv[i][0]))
	{
	  if (strlen(strv[i]) > 2)
	  {
	    replace_string_with_copy(&rrule->until, strv[i]);
	    break;
	  }

	  if (months_found == 0)
	  {
	    rrule->bymonth = atoi(strv[i]);
	  }
	  months_found++;
	}
      }

    }
    else if (strv[0][1] == 'D') /* by day in year */
    {
      int days_found = 0;
      for (i = 1; strv[i]; i++)
      {
	if (strv[i][0] == '#')
	{
	  rrule->count = atoi(strv[i]+1);
	  break;
	}
	else if (isdigit(strv[i][0]))
	{
	  if (strlen(strv[i]) > 2)
	  {
	    replace_string_with_copy(&rrule->until, strv[i]);
	    break;
	  }

	  if (days_found == 0)
	  {
	    rrule->bymonthday = atoi(strv[i]);
	  }
	  days_found++;
	}
      }

      if (days_found > 1)
	synce_warning("Yearly by Day (YD) (converted to monthly) can only handle one day in RRA format, in RRULE '%s'", str);

    }
    else
      synce_error("Unexpected frequency in RRULE '%s'", str);
  }
  else
  {
    synce_error("Unexpected frequency in RRULE '%s'", str);
  }
  
  strv_free(strv);
  return true;
}
コード例 #22
0
ファイル: recurrence.c プロジェクト: asmblur/SynCE
bool recurrence_parse_rrule(
    struct _Parser* p, 
    mdir_line* mdir_dtstart,
    mdir_line* mdir_dtend,
    mdir_line* mdir_rrule, 
    RRA_MdirLineVector* exdates,
    RRA_Timezone *tzi)
{
  bool success = false;
  RRule rrule;
  RRA_RecurrencePattern* pattern = rra_recurrence_pattern_new();

  if (!recurrence_set_dates(pattern, mdir_dtstart, mdir_dtend))
  {
    synce_error("Failed to set dates");
    goto exit;
  }

  memset(&rrule, 0, sizeof(RRule));

  bool rrule_init_result;
  if (strstr(mdir_rrule->values[0],"FREQ"))
    rrule_init_result = recurrence_initialize_rrule_ical(mdir_rrule->values[0], &rrule);
  else
    rrule_init_result = recurrence_initialize_rrule_vcal(mdir_rrule->values[0], &rrule);

  if (!rrule_init_result)
  {
    synce_error("Failed to parse RRULE '%s'", mdir_rrule->values[0]);
    goto exit;
  }

  if (rrule.freq == RRuleFreqUnknown)
  {
    synce_error("No FREQ part in RRULE '%s'", mdir_rrule->values[0]);
    goto exit;
  }

  if (rrule.freq == RRuleDaily)
  {
    pattern->recurrence_type = olRecursDaily;
    /* Convert to Daily with 24*60 times the interval (days->minutes) */
    synce_trace("Converting Interval to minutes");
    rrule.interval *= MINUTES_PER_DAY;
  }
  else if (rrule.freq == RRuleWeekly)
  {
    pattern->recurrence_type = olRecursWeekly;
    recurrence_set_days_of_week_mask(pattern, &rrule);
  }
  else if (rrule.freq == RRuleMonthly)
  {
    if (rrule.bymonthday)
    {
      pattern->recurrence_type = olRecursMonthly;
      pattern->day_of_month = rrule.bymonthday;
    }
    else if (rrule.bysetpos)
    {
      pattern->recurrence_type = olRecursMonthNth;
      pattern->instance = rrule.bysetpos;
      recurrence_set_days_of_week_mask(pattern, &rrule);
    }
    else
    {
      synce_error("Missing information for monthly recurrence in RRULE '%s'", 
          mdir_rrule->values[0]);
      goto exit;
    }
  }
  else if (rrule.freq == RRuleYearly)
  {
    /* Convert to Monthly with 12 times the interval */
    pattern->recurrence_type = olRecursMonthly;
    rrule.interval *= 12;

    if (rrule.bymonthday)
    {
      pattern->day_of_month = rrule.bymonthday;
    }
    else if (rrule.bysetpos || rrule.bymonth)
    {
      synce_error("Don't know how to handle BYSETPOS or BYMONTH in RRULE '%s'", 
          mdir_rrule->values[0]);
      goto exit;
    }
    else
    {
      /* Get BYMONTHDAY from start date */
      struct tm start_date = rra_minutes_to_struct(pattern->pattern_start_date);
      pattern->day_of_month = start_date.tm_mday;
    }
  }
  else
  {
    synce_error("Unexpected frequencey in RRULE '%s'", mdir_rrule->values[0]);
    goto exit;
  }

  pattern->interval = rrule.interval;

  if (rrule.count)
  {
    pattern->occurrences = rrule.count;
    pattern->flags |= RecurrenceEndsAfterXOccurrences;

    /* XXX calculate pattern->pattern_end_date */
    /* CE requires an explicit end date */
    /* XXX Could be problematic with leap years */
    switch (pattern->recurrence_type)
    {
      case olRecursDaily:
        synce_trace("Calculating Pattern end date for daily recursion");
        pattern->pattern_end_date = pattern->pattern_start_date + (rrule.count-1) * rrule.interval;
        break;
      case olRecursWeekly:
        /* XXX Only works for interval=1 at the moment */
        synce_trace("Calculating Pattern end date for weekly recursion");
        uint32_t count_in_mask=0;
        int i;
        for (i=0; i<7; i++)
	  if (pattern->days_of_week_mask &  (1 << i)) count_in_mask++;

        uint32_t days_to_add=((rrule.count-1)/count_in_mask)*7;
        uint32_t rest=(rrule.count-1)%count_in_mask;
	
        struct tm start_date = rra_minutes_to_struct(pattern->pattern_start_date);
        /* rotate the bitmask */
        uint32_t biased_mask = (pattern->days_of_week_mask | ((pattern->days_of_week_mask & ((1<<start_date.tm_wday)-1)) << 7))>>(start_date.tm_wday+1);
        while (rest)
	{
	  rest--;
          while (biased_mask%2==0)
	  {
            if (biased_mask==0) {synce_error("Calculation of Pattern end date failed"); goto failed;}
	    days_to_add++;
	    biased_mask>>=1;
	  }
          days_to_add++;
          biased_mask>>=1;
	}
	
	pattern->pattern_end_date = pattern->pattern_start_date + days_to_add * MINUTES_PER_DAY;

        break;
      default:
      failed:
        synce_trace("FIXME: Have to calculate Pattern end date");
    pattern->pattern_end_date = RRA_DoesNotEndDate;
  }
  }
コード例 #23
0
ファイル: rapi_context.c プロジェクト: asmblur/SynCE
HRESULT rapi_context_connect(RapiContext* context)
{
    HRESULT result = E_FAIL;
    SynceInfo* info = NULL;

    if (context->is_initialized)
    {
        /* Fail immediately */
            return CERAPI_E_ALREADYINITIALIZED;
    }

    if (context->info)
        info = context->info;
    else
        info = synce_info_new(NULL);
    if (!info)
    {
        synce_error("Failed to get connection info");
        goto fail;
    }

    const char *transport = synce_info_get_transport(info);
    /*
     *  original dccm or vdccm, sanity checking
     */
    if (transport == NULL || ( strcmp(transport, "odccm") != 0 && strcmp(transport, "udev") != 0 ) ) {
        pid_t dccm_pid = 0;
        if (!(dccm_pid = synce_info_get_dccm_pid(info)))
        {
            synce_error("DCCM PID entry not found for current connection");
            goto fail;
        }

        if (kill(dccm_pid, 0) < 0)
        {
            if (errno != EPERM)
            {
                synce_error("DCCM not running with pid %i", synce_info_get_dccm_pid(info));
                goto fail;
            }
        }

        if (!synce_info_get_device_ip(info))
        {
            synce_error("IP entry not found for current connection");
            goto fail;
        }
    }

    /*
     *  original dccm or vdccm
     */
    if (transport == NULL || strncmp(transport,  "ppp", 3) == 0) {
        /*
         *  original dccm or vdccm
         */
        if ( !synce_socket_connect(context->socket, synce_info_get_device_ip(info), RAPI_PORT) )
        {
            synce_error("failed to connect to %s", synce_info_get_device_ip(info));
            goto fail;
        }

        const char *password = synce_info_get_password(info);
        if (password && strlen(password))
        {
            bool password_correct = false;

            if (!synce_password_send(context->socket, password, (unsigned char)synce_info_get_key(info)))
            {
                synce_error("failed to send password");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!synce_password_recv_reply(context->socket, 1, &password_correct))
            {
                synce_error("failed to get password reply");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!password_correct)
            {
                synce_error("invalid password");
                result = E_ACCESSDENIED;
                goto fail;
            }
        }
        context->rapi_ops = &rapi_ops;
    } else {
        /*
         *  odccm, udev, or proxy ?
         */
#if ENABLE_ODCCM_SUPPORT
        if (strcmp(transport, "odccm") == 0) {
	  int fd = -1;
	  HRESULT fd_result = get_connection_from_udev_or_odccm(info, &fd);
	  if (fd_result != S_OK)
	  {
	    synce_error("failed to get context fd from odccm: %08x: %s", fd_result, synce_strerror(HRESULT_CODE(fd_result)));
	    result = fd_result;
	    goto fail;
	  }
	  synce_socket_take_descriptor(context->socket, fd);
        }
        else
#endif
#if ENABLE_UDEV_SUPPORT
        if (strcmp(transport, "udev") == 0) {
	  int fd = -1;
	  HRESULT fd_result = get_connection_from_udev_or_odccm(info, &fd);
	  if (fd_result != S_OK)
	  {
	    synce_error("failed to get context fd from udev: %08x: %s", fd_result, synce_strerror(HRESULT_CODE(fd_result)));
	    result = fd_result;
	    goto fail;
	  }
	  synce_socket_take_descriptor(context->socket, fd);
        }
        else
#endif
	if ( !synce_socket_connect_proxy(context->socket, synce_info_get_device_ip(info)) )
        {
            synce_error("failed to connect to proxy for %s", synce_info_get_device_ip(info));
            goto fail;
        }

	/* rapi 2 seems to be used on devices with OS version of 5.1 or greater */

        unsigned int os_major = 0, os_minor = 0;
        synce_info_get_os_version(info, &os_major, &os_minor);
	if ((os_major > 4) && (os_minor > 0))
	  context->rapi_ops = &rapi2_ops;
	else
	  context->rapi_ops = &rapi_ops;
    }

    if (!context->info)
    {
      context->info = info;
      context->own_info = true;
    }

    context->is_initialized = true;
    result = S_OK;

fail:
    if (!context->info)
        synce_info_destroy(info);
    return result;
}
コード例 #24
0
HRESULT rapi_context_connect(RapiContext* context)
{
	HRESULT result = E_FAIL;
  SynceInfo* info = NULL;

	if (context->is_initialized)
	{
		/* Fail immediately */
		return CERAPI_E_ALREADYINITIALIZED;
	}

  if (context->info)
    info = context->info;
  else
    info = synce_info_new(NULL);
  if (!info)
	{
		synce_error("Failed to get connection info");
		goto fail;
	}

	if (!info->dccm_pid)
	{
		synce_error("DCCM PID entry not found for current connection");
		goto fail;
	}

	if (kill(info->dccm_pid, 0) < 0)
	{
		if (errno != EPERM)
		{
			synce_error("DCCM not running with pid %i", info->dccm_pid);
			goto fail;
		}
	}

	if (!info->ip)
	{
		synce_error("IP entry not found for current connection");
		goto fail;
	}

    if (info->transport == NULL || strncmp(info->transport,  "ppp", 3) == 0) {
        if ( !synce_socket_connect(context->socket, info->ip, RAPI_PORT) )
        {
            synce_error("failed to connect to %s", info->ip);
		  goto fail;
        }

        if (info->password && strlen(info->password))
        {
            bool password_correct = false;

            if (!synce_password_send(context->socket, info->password, info->key))
            {
                synce_error("failed to send password");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!synce_password_recv_reply(context->socket, 1, &password_correct))
            {
                synce_error("failed to get password reply");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!password_correct)
            {
                synce_error("invalid password");
                result = E_ACCESSDENIED;
                goto fail;
            }
        }
        context->rapi_ops = &rapi_ops;
    } else {
        if ( !synce_socket_connect_proxy(context->socket, info->ip) )
        {
            synce_error("failed to connect to proxy for %s", info->ip);
            goto fail;
        }
        context->rapi_ops = &rapi2_ops;
    }

	context->is_initialized = true;
	result = S_OK;

fail:
  if (!context->info)
    synce_info_destroy(info);
	return result;
}