static void startup(void) { const char *algorithm = "sha256"; const char *key = NULL; char **argv = sol_argv(); int i, argc = sol_argc(); size_t chunk_size = -1; if (argc < 2) { fprintf(stderr, "Usage:\n\t%s [-a <algorithm>] [-c chunk_size] [-k key] <file1> .. <fileN>\n", argv[0]); sol_quit_with_code(EXIT_FAILURE); return; } for (i = 1; i < argc; i++) { struct feed_ctx *ctx; struct sol_message_digest_config cfg = { SOL_SET_API_VERSION(.api_version = SOL_MESSAGE_DIGEST_CONFIG_API_VERSION, ) .algorithm = algorithm, .on_feed_done = on_feed_done, .on_digest_ready = on_digest_ready, }; struct sol_file_reader *fr; struct sol_blob *blob; struct sol_message_digest *mdh; int r; if (argv[i][0] == '-') { if (argv[i][1] == 'a') { if (i + 1 < argc) { algorithm = argv[i + 1]; i++; continue; } else fputs("ERROR: argument -a missing value.\n", stderr); } else if (argv[i][1] == 'k') { if (i + 1 < argc) { key = argv[i + 1]; i++; continue; } else fputs("ERROR: argument -a missing value.\n", stderr); } else if (argv[i][1] == 'c') { if (i + 1 < argc) { chunk_size = atoi(argv[i + 1]); i++; continue; } else fputs("ERROR: argument -c missing value.\n", stderr); } else fprintf(stderr, "ERROR: unknown option %s\n", argv[i]); sol_quit_with_code(EXIT_FAILURE); return; } fr = sol_file_reader_open(argv[i]); if (!fr) { fprintf(stderr, "ERROR: could not open file '%s': %s\n", argv[i], sol_util_strerrora(errno)); continue; } blob = sol_file_reader_to_blob(fr); if (!blob) { fprintf(stderr, "ERROR: could not create blob for file '%s'\n", argv[i]); continue; } cfg.data = ctx = calloc(1, sizeof(struct feed_ctx)); if (!ctx) { fprintf(stderr, "ERROR: could not allocate context memory " "to process file '%s'\n", argv[i]); sol_blob_unref(blob); continue; } ctx->file = argv[i]; ctx->start = sol_util_timespec_get_current(); ctx->done = 0; ctx->chunk_size = chunk_size; if (key) cfg.key = sol_str_slice_from_str(key); mdh = sol_message_digest_new(&cfg); if (!mdh) { fprintf(stderr, "ERROR: could not create message digest for " " algorithm \"%s\": %s\n", algorithm, sol_util_strerrora(errno)); sol_blob_unref(blob); free(ctx); continue; } if (chunk_size <= 0) { r = sol_message_digest_feed(mdh, blob, true); if (r < 0) { fprintf(stderr, "ERROR: could not feed message for " " algorithm \"%s\": %s\n", algorithm, sol_util_strerrora(-r)); sol_blob_unref(blob); sol_message_digest_del(mdh); free(ctx); continue; } } else { size_t offset = 0; while (offset < blob->size) { size_t remaining = blob->size - offset; size_t clen = remaining > chunk_size ? chunk_size : remaining; uint8_t *cmem = (uint8_t *)blob->mem + offset; bool is_last = offset + clen == blob->size; struct sol_blob *chunk = sol_blob_new(&SOL_BLOB_TYPE_NO_FREE_DATA, blob, cmem, clen); if (!chunk) { fprintf(stderr, "ERROR: could not create chunk blob at " "mem %p, size=%zd\n", cmem, clen); sol_blob_unref(blob); sol_message_digest_del(mdh); free(ctx); continue; } r = sol_message_digest_feed(mdh, chunk, is_last); if (r < 0) { fprintf(stderr, "ERROR: could not feed chunk for " " algorithm \"%s\": %s\n", algorithm, sol_util_strerrora(-r)); sol_blob_unref(blob); sol_blob_unref(chunk); sol_message_digest_del(mdh); free(ctx); continue; } sol_blob_unref(chunk); offset += clen; } } sol_blob_unref(blob); pending++; }
static void test_set_slice_at(void) { struct sol_buffer buf; struct sol_str_slice slice; int err; sol_buffer_init(&buf); slice = sol_str_slice_from_str("World"); err = sol_buffer_set_slice_at(&buf, 0, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("World")); ASSERT_STR_EQ(buf.data, "World"); slice = sol_str_slice_from_str("Hello"); err = sol_buffer_set_slice_at(&buf, 0, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("Hello")); ASSERT_STR_EQ(buf.data, "Hello"); slice = sol_str_slice_from_str("World"); err = sol_buffer_set_slice_at(&buf, strlen("Hello"), slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("HelloWorld")); ASSERT_STR_EQ(buf.data, "HelloWorld"); slice = sol_str_slice_from_str(" -*- "); err = sol_buffer_set_slice_at(&buf, 2, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("He -*- rld")); ASSERT_STR_EQ(buf.data, "He -*- rld"); //overlapping slice = SOL_STR_SLICE_STR((char *)buf.data + 3, 3); err = sol_buffer_set_slice_at(&buf, 7, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("He -*- -*-")); ASSERT_STR_EQ(buf.data, "He -*- -*-"); slice = sol_str_slice_from_str("whatever"); err = sol_buffer_set_slice_at(&buf, 222, slice); ASSERT_INT_EQ(err, -EINVAL); sol_buffer_fini(&buf); sol_buffer_init(&buf); slice = sol_str_slice_from_str("abcd"); err = sol_buffer_set_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcd")); ASSERT_STR_EQ(buf.data, "abcd"); slice = sol_str_slice_from_str("XY"); err = sol_buffer_set_slice_at(&buf, 4, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcdXY")); ASSERT_STR_EQ(buf.data, "abcdXY"); sol_buffer_fini(&buf); sol_buffer_init(&buf); slice = sol_str_slice_from_str("abcd"); err = sol_buffer_set_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcd")); ASSERT_STR_EQ(buf.data, "abcd"); slice = sol_str_slice_from_str("XY"); err = sol_buffer_set_slice_at(&buf, 3, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcXY")); ASSERT_STR_EQ(buf.data, "abcXY"); sol_buffer_fini(&buf); sol_buffer_init(&buf); slice = sol_str_slice_from_str("abcd"); err = sol_buffer_set_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcd")); ASSERT_STR_EQ(buf.data, "abcd"); slice = sol_str_slice_from_str("XY"); err = sol_buffer_set_slice_at(&buf, 2, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abXY")); ASSERT_STR_EQ(buf.data, "abXY"); sol_buffer_fini(&buf); sol_buffer_init(&buf); slice = sol_str_slice_from_str("abcd"); err = sol_buffer_set_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcd")); ASSERT_STR_EQ(buf.data, "abcd"); slice = sol_str_slice_from_str("XY"); err = sol_buffer_set_slice_at(&buf, 1, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("aXYd")); ASSERT_STR_EQ(buf.data, "aXYd"); sol_buffer_fini(&buf); sol_buffer_init(&buf); slice = sol_str_slice_from_str("abcd"); err = sol_buffer_set_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("abcd")); ASSERT_STR_EQ(buf.data, "abcd"); slice = sol_str_slice_from_str("XY"); err = sol_buffer_set_slice_at(&buf, 0, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("XYcd")); ASSERT_STR_EQ(buf.data, "XYcd"); sol_buffer_fini(&buf); }
int main(int argc, char *argv[]) { struct sol_coap_server *server; struct sol_str_slice *path; struct sol_network_link_addr cliaddr = { }; struct sol_coap_packet *req; uint8_t observe = 0; int i, r; struct sol_network_link_addr servaddr = { .family = SOL_NETWORK_FAMILY_INET6, .port = 0 }; uint8_t token[4] = { 0x41, 0x42, 0x43, 0x44 }; sol_init(); if (argc < 3) { printf("Usage: %s <address> <path> [path]\n", argv[0]); return 0; } server = sol_coap_server_new(&servaddr); if (!server) { SOL_WRN("Could not create a coap server."); return -1; } req = sol_coap_packet_request_new(SOL_COAP_METHOD_GET, SOL_COAP_TYPE_CON); if (!req) { SOL_WRN("Could not make a GET request to resource %s", argv[2]); return -1; } r = sol_coap_header_set_token(req, token, sizeof(token)); if (r < 0) { SOL_WRN("Could not set coap header token."); return -1; } path = calloc(argc - 1, sizeof(*path)); if (!path) { sol_coap_packet_unref(req); return -1; } for (i = 2; i < argc; i++) { path[i - 2] = sol_str_slice_from_str(argv[i]); } sol_coap_add_option(req, SOL_COAP_OPTION_OBSERVE, &observe, sizeof(observe)); for (i = 0; path[i].data; i++) sol_coap_add_option(req, SOL_COAP_OPTION_URI_PATH, path[i].data, path[i].len); cliaddr.family = SOL_NETWORK_FAMILY_INET6; if (!sol_network_link_addr_from_str(&cliaddr, argv[1])) { SOL_WRN("%s is an invalid IPv6 address", argv[1]); free(path); sol_coap_packet_unref(req); return -1; } cliaddr.port = DEFAULT_UDP_PORT; /* Takes the ownership of 'req'. */ sol_coap_send_packet_with_reply(server, req, &cliaddr, reply_cb, path); sol_run(); sol_coap_server_unref(server); free(path); return 0; }