static void init_commands(void) { attr_init(); bmap_init(); fadvise_init(); file_init(); freeze_init(); fsync_init(); getrusage_init(); help_init(); imap_init(); inject_init(); madvise_init(); mincore_init(); mmap_init(); open_init(); parent_init(); pread_init(); prealloc_init(); fiemap_init(); pwrite_init(); quit_init(); resblks_init(); sendfile_init(); shutdown_init(); truncate_init(); }
static void test_imap_receive_multiple_lines(void **state) { struct imap_connection *imap = malloc(sizeof(struct imap_connection)); imap_init(imap); imap->mode = RECV_LINE; const char *buffer = "a001 FOOBAR\r\na002 FOOBAZ\r\n"; expect_string(__wrap_hashtable_get, key, "FOOBAR"); will_return(__wrap_hashtable_get, test_handler); expect_string(__wrap_hashtable_get, key, "FOOBAZ"); will_return(__wrap_hashtable_get, test_handler); set_ab_recv_result((void *)buffer, strlen(buffer)); will_return(__wrap_ab_recv, strlen(buffer)); will_return(__wrap_poll, 0); imap->poll[0].revents = POLLIN; imap_receive(imap); assert_int_equal(handler_called, 2); imap_close(imap); }
/*********************************************************************** * * imap_do() * * This function is registered as 'curl_do' function. It decodes the path * parts etc as a wrapper to the actual DO function (imap_perform). * * The input argument is already checked for validity. */ static CURLcode imap_do(struct connectdata *conn, bool *done) { CURLcode retcode = CURLE_OK; *done = FALSE; /* default to false */ /* Since connections can be re-used between SessionHandles, this might be a connection already existing but on a fresh SessionHandle struct so we must make sure we have a good 'struct IMAP' to play with. For new connections, the struct IMAP is allocated and setup in the imap_connect() function. */ Curl_reset_reqproto(conn); retcode = imap_init(conn); if(retcode) return retcode; /* Parse the URL path */ retcode = imap_parse_url_path(conn); if(retcode) return retcode; retcode = imap_regular_transfer(conn, done); return retcode; }
/*********************************************************************** * * imap_connect() should do everything that is to be considered a part of * the connection phase. * * The variable 'done' points to will be TRUE if the protocol-layer connect * phase is done when this function returns, or FALSE is not. When called as * a part of the easy interface, it will always be TRUE. */ static CURLcode imap_connect(struct connectdata *conn, bool *done) /* see description above */ { CURLcode result; struct imap_conn *imapc = &conn->proto.imapc; struct SessionHandle *data=conn->data; struct pingpong *pp = &imapc->pp; *done = FALSE; /* default to not done yet */ /* If there already is a protocol-specific struct allocated for this sessionhandle, deal with it */ Curl_reset_reqproto(conn); result = imap_init(conn); if(CURLE_OK != result) return result; /* We always support persistent connections on imap */ conn->bits.close = FALSE; pp->response_time = RESP_TIMEOUT; /* set default response time-out */ pp->statemach_act = imap_statemach_act; pp->endofresp = imap_endofresp; pp->conn = conn; if((conn->handler->flags & PROTOPT_SSL) && data->state.used_interface != Curl_if_multi) { /* IMAPS is simply imap with SSL for the control channel */ /* so perform the SSL initialization for this socket */ result = Curl_ssl_connect(conn, FIRSTSOCKET); if(result) return result; } /* Initialise the response reader stuff */ Curl_pp_init(pp); /* Start off waiting for the server greeting response */ state(conn, IMAP_SERVERGREET); /* Start off with an id of '*' */ imapc->idstr = "*"; if(data->state.used_interface == Curl_if_multi) result = imap_multi_statemach(conn, done); else { result = imap_easy_statemach(conn); if(!result) *done = TRUE; } return result; }
static void test_imap_receive_full_buffer(void **state) { struct imap_connection *imap = malloc(sizeof(struct imap_connection)); imap_init(imap); imap->mode = RECV_LINE; char buffer[4096]; memset(buffer, 'a', 4096); const char *cmd_1 = "a001 FOOBAR "; memcpy(buffer, cmd_1, strlen(cmd_1)); const char *cmd_2 = "\r\na002 FOOBAZ "; memcpy(buffer + 2048 + 128, cmd_2, strlen(cmd_2)); buffer[4094] = '\r'; buffer[4095] = '\n'; will_return(__wrap_poll, 0); will_return(__wrap_poll, 0); will_return(__wrap_poll, 0); will_return(__wrap_poll, 0); imap->poll[0].revents = POLLIN; set_ab_recv_result((void *)buffer, 1024); will_return(__wrap_ab_recv, 1024); imap_receive(imap); // First command (incomplete) set_ab_recv_result((void *)(buffer + 1024), 1024); will_return(__wrap_ab_recv, 1024); imap_receive(imap); // First command (incomplete) expect_string(__wrap_hashtable_get, key, "FOOBAR"); will_return(__wrap_hashtable_get, test_handler); set_ab_recv_result((void *)(buffer + 2048), 1024); will_return(__wrap_ab_recv, 1024); imap_receive(imap); // First command (complete), second command (incomplete) assert_int_equal(handler_called, 1); expect_string(__wrap_hashtable_get, key, "FOOBAZ"); will_return(__wrap_hashtable_get, test_handler); set_ab_recv_result((void *)(buffer + 2048), 1024); will_return(__wrap_ab_recv, 1024); imap_receive(imap); // Second command (complete) assert_int_equal(handler_called, 2); imap_close(imap); }
static void test_handle_line_known_handler(void **state) { int _; struct imap_connection *imap = malloc(sizeof(struct imap_connection)); imap_init(imap); imap_arg_t *arg = malloc(sizeof(imap_arg_t)); imap_parse_args("a001 FOOBAR", arg, &_); expect_string(__wrap_hashtable_get, key, "FOOBAR"); will_return(__wrap_hashtable_get, test_handler); handle_line(imap, arg); assert_int_equal(handler_called, 1); free(arg); imap_close(imap); }
/* * imap_connect() should do everything that is to be considered a part of * the connection phase. * * The variable 'done' points to will be TRUE if the protocol-layer connect * phase is done when this function returns, or FALSE is not. When called as * a part of the easy interface, it will always be TRUE. */ static CURLcode imap_connect(struct connectdata *conn, bool *done) /* see description above */ { CURLcode result; struct imap_conn *imapc = &conn->proto.imapc; struct SessionHandle *data=conn->data; struct pingpong *pp = &imapc->pp; *done = FALSE; /* default to not done yet */ /* If there already is a protocol-specific struct allocated for this sessionhandle, deal with it */ Curl_reset_reqproto(conn); result = imap_init(conn); if(CURLE_OK != result) return result; /* We always support persistant connections on imap */ conn->bits.close = FALSE; pp->response_time = RESP_TIMEOUT; /* set default response time-out */ pp->statemach_act = imap_statemach_act; pp->endofresp = imap_endofresp; pp->conn = conn; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { /* for IMAP over HTTP proxy */ struct HTTP http_proxy; struct FTP *imap_save; /* BLOCKING */ /* We want "seamless" IMAP operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member * conn->proto.http; we want IMAP through HTTP and we have to change the * member temporarily for connecting to the HTTP proxy. After * Curl_proxyCONNECT we have to set back the member to the original struct * IMAP pointer */ imap_save = data->state.proto.imap; memset(&http_proxy, 0, sizeof(http_proxy)); data->state.proto.http = &http_proxy; result = Curl_proxyCONNECT(conn, FIRSTSOCKET, conn->host.name, conn->remote_port); data->state.proto.imap = imap_save; if(CURLE_OK != result) return result; } #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */ if(conn->protocol & PROT_IMAPS) { /* BLOCKING */ /* IMAPS is simply imap with SSL for the control channel */ /* now, perform the SSL initialization for this socket */ result = Curl_ssl_connect(conn, FIRSTSOCKET); if(result) return result; } Curl_pp_init(pp); /* init generic pingpong data */ /* When we connect, we start in the state where we await the server greeting response */ state(conn, IMAP_SERVERGREET); imapc->idstr = "*"; /* we start off waiting for a '*' response */ if(data->state.used_interface == Curl_if_multi) result = imap_multi_statemach(conn, done); else { result = imap_easy_statemach(conn); if(!result) *done = TRUE; } return result; }
//gcc -o imap imap.c -DIMAP_TEST -DTEST_INS -DHAVE_PTHREAD -lpthread && ./imap int main() { IMAP *imap = NULL; int i = 0, j = 0, n = 0, total = 0, no = 0, stat[MASK], stat2[MASK]; int32_t val = 0, from = 0, to = 0, *res = NULL; int32_t inputs[256], nos[256], last[256]; int32_t all = 0; time_t stime = 0, etime = 0; void *timer = NULL; if((imap = imap_init("/tmp/1.idx"))) { res = (int32_t *)calloc(60000000, sizeof(int32_t)); TIMER_INIT(timer); #ifdef TEST_INS //fprintf(stdout, "sizeof(stat):%d\n", sizeof(stat)); memset(stat, 0, sizeof(stat)); memset(stat2, 0, sizeof(stat2)); srand(time(NULL)); n = 256; for(i = 0; i < n; i++) { no = (rand()%MASK); nos[i] = no; if((i % 3) == 0) inputs[i] = no * -1; else inputs[i] = no; } TIMER_RESET(timer); for(i = 1; i < 20000000; i++) { j = (rand()%n); val = inputs[j]; no = nos[j]; stat[no]++; imap_set(imap, i, val); last[j] = i; } TIMER_SAMPLE(timer); fprintf(stdout, "set() 40000000 data, time used:%lld\n", PT_LU_USEC(timer)); TIMER_RESET(timer); for(i = 0; i < n; i++) { imap_del(imap, last[i]); } TIMER_SAMPLE(timer); fprintf(stdout, "del() time used:%lld\n", PT_LU_USEC(timer)); TIMER_RESET(timer); for(i = 0; i < n; i++) { val = inputs[i]; no = nos[i]; stat2[no] = imap_in(imap, val, res); } TIMER_SAMPLE(timer); fprintf(stdout, "in() time used:%lld\n", PT_LU_USEC(timer)); TIMER_RESET(timer); total = imap_ins(imap, inputs, n, NULL); TIMER_SAMPLE(timer); fprintf(stdout, "ins(keys, NULL) total:%d time used:%lld\n", total, PT_LU_USEC(timer)); TIMER_RESET(timer); total = imap_ins(imap, inputs, n, res); TIMER_SAMPLE(timer); fprintf(stdout, "ins(keys, res:%p) total:%d time used:%lld\n", res, total, PT_LU_USEC(timer)); for(i = 0; i < n; i++) { j = nos[i]; if(stat[j] != stat2[j]) fprintf(stdout, "%d:%d/%d::%d\n", j, stat[j], stat2[j], inputs[i]); } #ifdef OUT_ALL for(i = 0; i < total; i++) { fprintf(stdout, "%d:%d\n", i, res[i]); } #endif #endif /* for(i = 0; i < imap->state->count; i++) { fprintf(stdout, "%d:{min:%d max:%d}(%d)\n", i, imap->slots[i].min, imap->slots[i].max, imap->slots[i].count); } */ #ifdef TEST_RANGEFILTER imap_set(imap, 1, 1234567); imap_set(imap, 2, 1567890); fprintf(stdout, "rangefrom():%d\n", imap_rangefrom(imap, 1569000, NULL)); fprintf(stdout, "rangeto():%d\n", imap_rangeto(imap, 1111111, NULL)); fprintf(stdout, "range():%d\n", imap_range(imap, 1111111, 1600000, NULL)); #endif #ifdef TEST_RANGE srand(time(NULL)); TIMER_RESET(timer); for(i = 1; i < 40000000; i++) { val = 1356969600 + (rand()%31536000); imap_set(imap, i, val); } TIMER_SAMPLE(timer); fprintf(stdout, "set() 40000000 timestamps, time used:%lld\n", PT_LU_USEC(timer)); fflush(stdout); srand(time(NULL)); TIMER_RESET(timer); all = 0; for(i = 0; i < 1000; i++) { val = 1356969600 + (rand()%31536000); all += imap_rangefrom(imap, val, res); } TIMER_SAMPLE(timer); fprintf(stdout, "rangefrom() 1000 times total:%lld, time used:%lld\n", (long long int)all, PT_LU_USEC(timer)); fflush(stdout); srand(time(NULL)); TIMER_RESET(timer); all = 0; for(i = 0; i < 1000; i++) { val = 1356969600 + (rand()%31536000); all += imap_rangeto(imap, val, res); } TIMER_SAMPLE(timer); fprintf(stdout, "rangeto() 1000 times total:%lld, time used:%lld\n", (long long int)all, PT_LU_USEC(timer)); fflush(stdout); srand(time(NULL)); TIMER_RESET(timer); all = 0; for(i = 0; i < 1000; i++) { from = 1356969600 + (rand()%31536000); to = from + rand()%31536000; all += imap_range(imap, from, to, res); } TIMER_SAMPLE(timer); fprintf(stdout, "range(%p) 1000 times total:%lld, time used:%lld\n", res, (long long int)all, PT_LU_USEC(timer)); fflush(stdout); srand(time(NULL)); TIMER_RESET(timer); all = 0; for(i = 0; i < 1000; i++) { from = 1356969600 + (rand()%31536000); to = from + rand()%31536000; all += imap_range(imap, from, to, NULL); } TIMER_SAMPLE(timer); fprintf(stdout, "range(null) 1000 times total:%lld, time used:%lld\n", (long long int)all, PT_LU_USEC(timer)); fflush(stdout); #endif imap_close(imap); TIMER_CLEAN(timer); free(res); } }