SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
			      SilcBool waitable)
{
#ifdef SILC_THREADS
  SilcSymbianThread *tc;
  RThread *thread;
  TInt ret;
  char tmp[24];
  SilcUInt16 wname[24];

  SILC_LOG_DEBUG(("Creating new thread"));

  tc = (SilcSymbianThread *)silc_calloc(1, sizeof(*tc));
  if (!tc)
    return NULL;
  tc->start_func = start_func;
  tc->context = context;
  tc->waitable = waitable;

  /* Allocate thread */
  thread = new RThread;
  if (!thread) {
    silc_free(tc);
    return NULL;
  }

  /* Create the thread */
  silc_snprintf(tmp, sizeof(tmp), "thread-%p", tc);
  silc_utf8_c2w((const unsigned char *)tmp, strlen(tmp), wname,
		sizeof(wname) / sizeof(wname[0]));
  TBuf<24> name((unsigned short *)wname);
  name.PtrZ();
  ret = thread->Create(name, silc_thread_start, 8192, NULL, tc);
  if (ret != KErrNone) {
    SILC_LOG_ERROR(("Could not create new thread, error %d", ret));
    delete thread;
    silc_free(tc);
    return NULL;
  }

  /* Start the thread */
  thread->Resume();

  /* Close our instance to the thread */
  thread->Close();

  return (SilcThread)thread;
#else
  /* Call thread callback immediately */
  (*start_func)(context);
  return NULL;
#endif
}
Example #2
0
void silc_mime_set_multipart(SilcMime mime, const char *type,
                             const char *boundary)
{
    char tmp[1024];

    if (!mime || !type || !boundary)
        return;

    memset(tmp, 0, sizeof(tmp));
    silc_snprintf(tmp, sizeof(tmp) - 1, "multipart/%s; boundary=%s", type, boundary);
    silc_mime_add_field(mime, "Content-Type", tmp);
    silc_free(mime->boundary);
    mime->boundary = strdup(boundary);

    if (mime->multiparts)
        return;
    mime->multiparts = silc_dlist_init();
}
Example #3
0
static void silc_client_ftp_open_handle(SilcSFTP sftp,
					SilcSFTPStatus status,
					SilcSFTPHandle handle,
					void *context)
{
  SilcClientFtpSession session = (SilcClientFtpSession)context;
  char path[512];

  SILC_LOG_DEBUG(("Start"));

  if (status != SILC_SFTP_STATUS_OK) {
    /* Call monitor callback */
    if (session->monitor)
      (*session->monitor)(session->client, session->conn,
			  SILC_CLIENT_FILE_MONITOR_ERROR,
			  (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
			   SILC_CLIENT_FILE_NO_SUCH_FILE :
			   status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
			   SILC_CLIENT_FILE_PERMISSION_DENIED :
			   SILC_CLIENT_FILE_ERROR), 0, 0,
			  session->client_entry, session->session_id,
			  session->filepath, session->monitor_context);
    return;
  }

  /* Open the actual local file */
  memset(path, 0, sizeof(path));
  silc_snprintf(path, sizeof(path) - 1, "%s%s", session->path ?
		session->path : "", session->filepath);
  session->fd = silc_file_open(path, O_RDWR | O_CREAT | O_EXCL);
  if (session->fd < 0) {
    /* Call monitor callback */
    session->client->internal->ops->say(session->client, session->conn,
					SILC_CLIENT_MESSAGE_ERROR,
					"File `%s' open failed: %s",
					session->filepath,
					strerror(errno));

    if (session->monitor)
      (*session->monitor)(session->client, session->conn,
			  SILC_CLIENT_FILE_MONITOR_ERROR,
			  SILC_CLIENT_FILE_PERMISSION_DENIED, 0, 0,
			  session->client_entry, session->session_id,
			  session->filepath, session->monitor_context);
    return;
  }

  session->read_handle = handle;

  /* Now, start reading the file */
  silc_sftp_read(sftp, session->read_handle, session->read_offset,
                 SILC_PACKET_MAX_LEN - 1024,
		 silc_client_ftp_data, session);

  /* Call monitor callback */
  if (session->monitor)
    (*session->monitor)(session->client, session->conn,
			SILC_CLIENT_FILE_MONITOR_RECEIVE,
			SILC_CLIENT_FILE_OK,
			session->read_offset, session->filesize,
			session->client_entry, session->session_id,
			session->filepath, session->monitor_context);
}
Example #4
0
SilcDList silc_mime_encode_partial(SilcMime mime, int max_size)
{
    unsigned char *buf, *tmp;
    SilcUInt32 buf_len, len, tmp_len, off;
    SilcDList list;
    SilcBuffer buffer;
    SilcMime partial;
    char type[128], id[64];
    int num;

    SILC_LOG_DEBUG(("Fragmenting MIME message"));

    /* Encode as normal */
    buf = silc_mime_encode(mime, &buf_len);
    if (!buf)
        return NULL;

    list = silc_dlist_init();

    /* Fragment if it is too large */
    if (buf_len > max_size) {
        memset(id, 0, sizeof(id));
        memset(type, 0, sizeof(type));
        gethostname(type, sizeof(type) - 1);
        srand((time(NULL) + buf_len) ^ rand());
        silc_snprintf(id, sizeof(id) - 1, "%X%X%X%s",
                      (unsigned int)rand(), (unsigned int)time(NULL),
                      (unsigned int)buf_len, type);

        SILC_LOG_DEBUG(("Fragment ID %s", id));

        partial = silc_mime_alloc();
        if (!partial)
            return NULL;

        silc_mime_add_field(partial, "MIME-Version", "1.0");
        memset(type, 0, sizeof(type));
        silc_snprintf(type, sizeof(type) - 1,
                      "message/partial; id=\"%s\"; number=1", id);
        silc_mime_add_field(partial, "Content-Type", type);
        silc_mime_add_data(partial, buf, max_size);

        tmp = silc_mime_encode(partial, &tmp_len);
        if (!tmp)
            return NULL;
        silc_mime_free(partial);

        /* Add to list */
        buffer = silc_buffer_alloc_size(tmp_len);
        if (!buffer)
            return NULL;
        silc_buffer_put(buffer, tmp, tmp_len);
        silc_dlist_add(list, buffer);
        silc_free(tmp);

        len = buf_len - max_size;
        off = max_size;
        num = 2;
        while (len > 0) {
            partial = silc_mime_alloc();
            if (!partial)
                return NULL;

            memset(type, 0, sizeof(type));
            silc_mime_add_field(partial, "MIME-Version", "1.0");

            if (len > max_size) {
                silc_snprintf(type, sizeof(type) - 1,
                              "message/partial; id=\"%s\"; number=%d",
                              id, num++);
                silc_mime_add_data(partial, buf + off, max_size);
                off += max_size;
                len -= max_size;
            } else {
                silc_snprintf(type, sizeof(type) - 1,
                              "message/partial; id=\"%s\"; number=%d; total=%d",
                              id, num, num);
                silc_mime_add_data(partial, buf + off, len);
                len = 0;
            }

            silc_mime_add_field(partial, "Content-Type", type);

            tmp = silc_mime_encode(partial, &tmp_len);
            if (!tmp)
                return NULL;
            silc_mime_free(partial);

            /* Add to list */
            buffer = silc_buffer_alloc_size(tmp_len);
            if (!buffer)
                return NULL;
            silc_buffer_put(buffer, tmp, tmp_len);
            silc_dlist_add(list, buffer);
            silc_free(tmp);
        }
    } else {
        /* No need to fragment */
        buffer = silc_buffer_alloc_size(buf_len);
        if (!buffer)
            return NULL;
        silc_buffer_put(buffer, buf, buf_len);
        silc_dlist_add(list, buffer);
    }

    silc_free(buf);

    return list;
}
Example #5
0
unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len)
{
    SilcMime part;
    SilcHashTableList htl;
    SilcBufferStruct buf;
    SilcBuffer buffer;
    char *field, *value, tmp[1024], tmp2[4];
    unsigned char *ret;
    int i;

    SILC_LOG_DEBUG(("Encoding MIME message"));

    if (!mime)
        return NULL;

    memset(&buf, 0, sizeof(buf));

    /* Encode the headers. Order doesn't matter */
    i = 0;
    silc_hash_table_list(mime->fields, &htl);
    while (silc_hash_table_get(&htl, (void *)&field, (void *)&value)) {
        memset(tmp, 0, sizeof(tmp));
        SILC_LOG_DEBUG(("Header %s: %s", field, value));
        silc_snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value);
        silc_buffer_strformat(&buf, tmp, SILC_STRFMT_END);
        i++;
    }
    silc_hash_table_list_reset(&htl);
    if (i)
        silc_buffer_strformat(&buf, "\r\n", SILC_STRFMT_END);

    /* Assemble the whole buffer */
    buffer = silc_buffer_alloc_size(mime->data_len + silc_buffer_len(&buf));
    if (!buffer)
        return NULL;

    /* Add headers */
    if (silc_buffer_len(&buf)) {
        silc_buffer_put(buffer, buf.head, silc_buffer_len(&buf));
        silc_buffer_pull(buffer, silc_buffer_len(&buf));
        silc_buffer_purge(&buf);
    }

    /* Add data */
    if (mime->data) {
        SILC_LOG_DEBUG(("Data len %d", mime->data_len));
        silc_buffer_put(buffer, mime->data, mime->data_len);
    }

    /* Add multiparts */
    if (mime->multiparts) {
        SILC_LOG_DEBUG(("Encoding multiparts"));

        silc_dlist_start(mime->multiparts);
        i = 0;
        while ((part = silc_dlist_get(mime->multiparts)) != SILC_LIST_END) {
            unsigned char *pd;
            SilcUInt32 pd_len;

            /* Recursive encoding */
            pd = silc_mime_encode(part, &pd_len);
            if (!pd)
                return NULL;

            memset(tmp, 0, sizeof(tmp));
            memset(tmp2, 0, sizeof(tmp2));

            /* If fields are not present, add extra CRLF */
            if (!silc_hash_table_count(part->fields))
                silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n");
            silc_snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s",
                          i != 0 ? "\r\n" : "", mime->boundary, tmp2);
            i = 1;

            buffer = silc_buffer_realloc(buffer, silc_buffer_truelen(buffer) +
                                         pd_len + strlen(tmp));
            if (!buffer)
                return NULL;
            silc_buffer_put_tail(buffer, tmp, strlen(tmp));
            silc_buffer_pull_tail(buffer, strlen(tmp));
            silc_buffer_put_tail(buffer, pd, pd_len);
            silc_buffer_pull_tail(buffer, pd_len);
            silc_free(pd);
        }

        memset(tmp, 0, sizeof(tmp));
        silc_snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary);
        buffer = silc_buffer_realloc(buffer, silc_buffer_truelen(buffer) +
                                     strlen(tmp));
        if (!buffer)
            return NULL;
        silc_buffer_put_tail(buffer, tmp, strlen(tmp));
        silc_buffer_pull_tail(buffer, strlen(tmp));
    }

    ret = silc_buffer_steal(buffer, encoded_len);
    silc_buffer_free(buffer);

    return ret;
}
Example #6
0
SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
                          SilcUInt32 data_len)
{
    SilcMime m = NULL;
    int i, k;
    char *tmp, *field, *value, *line;

    SILC_LOG_DEBUG(("Parsing MIME message"));

    if (!data)
        return NULL;

    if (!mime) {
        mime = silc_mime_alloc();
        if (!mime)
            return NULL;
        m = mime;
    }

    /* Parse the fields */
    line = tmp = (char *)data;
    for (i = 0; i < data_len; i++) {
        /* Get field line */
        if (data_len - i >= 2 && tmp[i] == '\r' && tmp[i + 1] == '\n') {
            /* Get field */
            field = strchr(line, ':');
            if (!field)
                goto err;
            field = silc_memdup(line, field - line);
            if (!field)
                goto err;

            /* Get value. Remove whitespaces too. */
            value = strchr(line, ':');
            if ((tmp + i) - value < 2)
                goto err;
            value++;
            for (k = 0; k < (tmp + i) - value; k++) {
                if (value[k] == '\r')
                    goto err;
                if (value[k] != ' ' && value[k] != '\t')
                    break;
            }
            value += k;
            if ((tmp + i) - value < 1)
                goto err;
            value = silc_memdup(value, (tmp + i) - value);
            if (!value)
                goto err;

            SILC_LOG_DEBUG(("Header '%s' '%s'", field, value));

            /* Add field and value */
            silc_mime_add_field(mime, field, value);
            silc_free(field);
            silc_free(value);

            /* Mark start of next line */
            line = (tmp + i) + 2;
            i += 2;

            /* Break if this is last header */
            if (data_len - i >= 2 &&
                    tmp[i] == '\r' && tmp[i + 1] == '\n') {
                i += 2;
                break;
            }
        }
    }

    /* Parse multiparts if present */
    field = (char *)silc_mime_get_field(mime, "Content-Type");
    if (field && strstr(field, "multipart")) {
        char b[1024];
        SilcMime p;
        unsigned int len;

        mime->multiparts = silc_dlist_init();
        if (!mime->multiparts)
            goto err;

        /* Get multipart type */
        value = strchr(field, '/');
        if (!value)
            goto err;
        value++;
        if (strchr(field, '"'))
            value++;
        if (!strchr(field, ';'))
            goto err;
        memset(b, 0, sizeof(b));
        len = (unsigned int)(strchr(field, ';') - value);
        if (len > sizeof(b) - 1)
            goto err;
        strncpy(b, value, len);
        if (strchr(b, '"'))
            *strchr(b, '"') = '\0';
        mime->multitype = silc_memdup(b, strlen(b));

        /* Get boundary */
        value = strrchr(field, '=');
        if (value && strlen(value) > 1) {
            value++;

            SILC_LOG_DEBUG(("Boundary '%s'", value));

            memset(b, 0, sizeof(b));
            line = strdup(value);
            if (strrchr(line, '"')) {
                *strrchr(line, '"') = '\0';
                silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1);
                mime->boundary = strdup(line + 1);
            } else {
                silc_snprintf(b, sizeof(b) - 1, "--%s", line);
                mime->boundary = strdup(line);
            }
            silc_free(line);

            for (i = i; i < data_len; i++) {
                /* Get boundary data */
                if (data_len - i >= strlen(b) &&
                        tmp[i] == '-' && tmp[i + 1] == '-') {
                    if (memcmp(tmp + i, b, strlen(b)))
                        continue;

                    i += strlen(b);

                    if (data_len - i >= 4 &&
                            tmp[i    ] == '\r' && tmp[i + 1] == '\n' &&
                            tmp[i + 2] == '\r' && tmp[i + 3] == '\n')
                        i += 4;
                    else if (data_len - i >= 2 &&
                             tmp[i] == '\r' && tmp[i + 1] == '\n')
                        i += 2;
                    else if (data_len - i >= 2 &&
                             tmp[i] == '-' && tmp[i + 1] == '-')
                        break;

                    line = tmp + i;

                    /* Find end of boundary */
                    for (k = i; k < data_len; k++)
                        if (data_len - k >= strlen(b) &&
                                tmp[k] == '-' && tmp[k + 1] == '-')
                            if (!memcmp(tmp + k, b, strlen(b)))
                                break;
                    if (k >= data_len)
                        goto err;

                    /* Remove preceding CRLF */
                    k -= 2;

                    /* Parse the part */
                    p = silc_mime_decode(NULL, line, k - i);
                    if (!p)
                        goto err;

                    silc_dlist_add(mime->multiparts, p);
                    i += (k - i);
                }
            }
        }
    } else {
        /* Get data area.  If we are at the end and we have fields present
           there is no data area present, but, if fields are not present we
           only have data area. */
        if (i >= data_len && !silc_hash_table_count(mime->fields))
            i = 0;
        SILC_LOG_DEBUG(("Data len %d", data_len - i));
        if (data_len - i)
            silc_mime_add_data(mime, tmp + i, data_len - i);
    }

    return mime;

err:
    if (m)
        silc_mime_free(m);
    return NULL;
}
Example #7
0
int main(int argc, char **argv)
{
  SilcBool success = FALSE;
  unsigned char *s1, *s2, *s3, *s4;
  unsigned char t[16];
  char h[32 + 1], str[40];
  int l, opt, i;
  SilcUInt32 len;

  while ((opt = getopt(argc, argv, "hVd:")) != EOF) {
      switch(opt) {
        case 'h':
          printf("usage: test_silcstrutil\n");
	  exit(0);
          break;
        case 'V':
          printf("Secure Internet Live Conferencing\n");
          exit(0);
          break;
        case 'd':
          silc_log_debug(TRUE);
	  silc_log_debug_hexdump(TRUE);
	  silc_log_quick(TRUE);
          if (optarg)
            silc_log_set_debug_string(optarg);
	  else
	    silc_log_set_debug_string("*strutil*,*errno*");
          break;
	default:
	  exit(1);
	  break;
      }
  }

  /* Failure tests */
  utf8failc(1);  utf8failc(2);
  utf8failc(3);  utf8failc(4);
  utf8failc(5);  utf8failc(6);
  utf8failc(7);  utf8failc(8);
  utf8failc(9);  utf8failc(10);
  utf8failc(11);  utf8failc(12);
  utf8failc(13);  utf8failc(14);
  utf8failc(15);  utf8failc(16);
  utf8failc(17);  utf8failc(18);
  utf8failc(19);  utf8failc(20);
  utf8failc(21);  utf8failc(22);
  utf8failc(23);  utf8failc(24);
  utf8failc(25);  utf8failc(26);
  utf8failc(27);  utf8failc(28);
  utf8failc(29);  utf8failc(30);

  /* LDAP DN simple test */
  s1 = "#&?*Pekka, \\Riikonen, <*****@*****.**>\xc4\x8d\\ ";
  SILC_LOG_DEBUG(("s1 = %s", s1));

  /* To LDAP DN */
  l = silc_utf8_decoded_len(s1, strlen(s1), SILC_STRING_LDAP_DN);
  if (!l)
    goto err;
  s3 = silc_calloc(l + 1, sizeof(*s3));
  silc_utf8_decode(s1, strlen(s1), SILC_STRING_LDAP_DN, s3, l);
  SILC_LOG_DEBUG(("ldapdn = %s", s3));

  /* To UTF-8 */
  l = silc_utf8_encoded_len(s3, strlen(s3), SILC_STRING_LDAP_DN);
  if (!l)
    goto err;
  s4 = silc_calloc(l + 1, sizeof(*s4));
  silc_utf8_encode(s3, strlen(s3), SILC_STRING_LDAP_DN, s4, l);
  SILC_LOG_DEBUG(("utf8 = %s", s4));

  if (memcmp(s4, s1, strlen(s4))) {
    SILC_LOG_DEBUG(("UTF-8 mismatch"));
    goto err;
  }
  silc_free(s3);
  silc_free(s4);

  /* UTF-8 strcasecmp test */
  SILC_LOG_DEBUG(("silc_utf8_strcasecmp test"));
  s1 = "Päivää vuan Yrjö";
  s2 = "PÄIVÄÄ VUAN YRJÖ";
  l = silc_utf8_encoded_len(s1, strlen(s1), SILC_STRING_LOCALE);
  if (!l)
    goto err;
  s3 = silc_calloc(l + 1, sizeof(*s3));
  silc_utf8_encode(s1, strlen(s1), SILC_STRING_LOCALE, s3, l);

  l = silc_utf8_encoded_len(s2, strlen(s2), SILC_STRING_LOCALE);
  if (!l)
    goto err;
  s4 = silc_calloc(l + 1, sizeof(*s4));
  silc_utf8_encode(s2, strlen(s2), SILC_STRING_LOCALE, s4, l);

  SILC_LOG_DEBUG(("%s == %s", s3, s4));
  if (!silc_utf8_strcasecmp(s3, s4)) {
    SILC_LOG_DEBUG(("mismatch"));
    goto err;
  }
  SILC_LOG_DEBUG(("match"));

  silc_free(s3);
  silc_free(s4);

  /* Regex test */
  SILC_LOG_DEBUG(("Simple regex test"));
  s1 = "foo,bar,silc,com";
  SILC_LOG_DEBUG(("Find 'silc' from %s", s1));
  if (!silc_string_match(s1, "silc"))
    goto err;
  SILC_LOG_DEBUG(("Regex match"));
  SILC_LOG_DEBUG(("Find 'foobar' from %s", s1));
  if (silc_string_match(s1, "foobar"))
    goto err;
  SILC_LOG_DEBUG(("Regex not found (Ok)"));

  /* HEX to data, data to HEX tests */
  for (i = 0; i < sizeof(t); i++)
    t[i] = i;
  silc_data2hex(t, sizeof(t), h, sizeof(h));
  silc_hex2data(h, t, sizeof(t), &len);
  silc_snprintf(h, sizeof(h), "010203ffabdef9ab");
  silc_hex2data(h, t, sizeof(t), &len);
  silc_data2hex(t, sizeof(t), h, sizeof(h));

  /* snprintf test */
  silc_snprintf(str, sizeof(str), "This is %@ rendered\n",
		render, "automatically");
  SILC_LOG_DEBUG((str));
  SILC_LOG_DEBUG(("This too %@ rendered", render, "is automatically"));

  success = TRUE;

 err:
  SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
  fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");

  return !success;
}