static pj_bool_t rt_on_rx_response(pjsip_rx_data *rdata) { if (!pj_strncmp(&rdata->msg_info.cid->id, &rt_call_id, rt_call_id.slen)) { char *pos = pj_strchr(&rdata->msg_info.cid->id, '/')+1; int thread_id = (*pos - '0'); pj_timestamp recv_time; pj_mutex_lock(rt_test_data[thread_id].mutex); /* Stop timer. */ pjsip_endpt_cancel_timer(endpt, &rt_test_data[thread_id].timeout_timer); /* Update counter and end-time. */ rt_test_data[thread_id].recv_response_count++; pj_get_timestamp(&recv_time); pj_sub_timestamp(&recv_time, &rt_test_data[thread_id].send_time); pj_add_timestamp(&rt_test_data[thread_id].total_rt_time, &recv_time); if (!rt_stop) { pj_time_val tx_delay = { 0, 0 }; pj_assert(rt_test_data[thread_id].tx_timer.user_data == NULL); rt_test_data[thread_id].tx_timer.user_data = (void*)1; pjsip_endpt_schedule_timer(endpt, &rt_test_data[thread_id].tx_timer, &tx_delay); } pj_mutex_unlock(rt_test_data[thread_id].mutex); return PJ_TRUE; } return PJ_FALSE; }
void vnat_stun_detect_nat_type(v_ice_trans_t *ice_tran, pj_str_t stun_srv) { pj_status_t status; printf("[DEBUG] %s, %d adress: %s \n", __func__, __LINE__, stun_srv.ptr); /* Command line option may contain port number */ char *pos; if ((pos=pj_strchr(&stun_srv, ':')) != NULL) { printf("[DEBUG] %s, %d \n", __func__, __LINE__); server.ptr = stun_srv.ptr; server.slen = (pos - stun_srv.ptr); port = (pj_uint16_t)atoi(pos+1) + 1; } else { printf("[DEBUG] %s, %d \n", __func__, __LINE__); server = stun_srv; port = PJ_STUN_PORT; } printf("[DEBUG] %s, %d \n", __func__, __LINE__); pj_sockaddr_in_init(&addr_in, &server, port); status = pj_stun_detect_nat_type(&addr_in, &ice_tran->ice_cfg.stun_cfg, NULL, &nat_detect_cb); }
PJ_DEF(pj_str_t) pj_str_unescape( pj_pool_t *pool, const pj_str_t *src_str) { char *src = src_str->ptr; char *end = src + src_str->slen; pj_str_t dst_str; char *dst; if (pj_strchr(src_str, '%')==NULL) return *src_str; dst = dst_str.ptr = (char*) pj_pool_alloc(pool, src_str->slen); while (src != end) { if (*src == '%' && src < end-2 && pj_isxdigit(*(src+1)) && pj_isxdigit(*(src+2))) { *dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(src+1)) << 4) + pj_hex_digit_to_val(*(src+2))); ++dst; src += 3; } else { *dst++ = *src++; } } dst_str.slen = dst - dst_str.ptr; return dst_str; }
static void set_redirecting_id(pjsip_name_addr *name_addr, struct ast_party_id *data, struct ast_set_party_id *update) { pjsip_sip_uri *uri = pjsip_uri_get_uri(name_addr->uri); char *semi; pj_str_t uri_user; uri_user = uri->user; /* Always truncate redirecting number at a semicolon. */ semi = pj_strchr(&uri_user, ';'); if (semi) { /* * We need to be able to handle URI's looking like * "sip:1235557890;[email protected];user=phone" * * Where the uri->user field will result in: * "1235557890;phone-context=national" * * People don't care about anything after the semicolon * showing up on their displays even though the RFC * allows the semicolon. */ pj_strset(&uri_user, (char *) pj_strbuf(&uri_user), semi - pj_strbuf(&uri_user)); } if (pj_strlen(&uri_user)) { update->number = 1; data->number.valid = 1; set_redirecting_value(&data->number.str, &uri_user); } if (pj_strlen(&name_addr->display)) { update->name = 1; data->name.valid = 1; set_redirecting_value(&data->name.str, &name_addr->display); } }
/* * Parse address */ PJ_DEF(pj_status_t) pj_sockaddr_parse2(int af, unsigned options, const pj_str_t *str, pj_str_t *p_hostpart, pj_uint16_t *p_port, int *raf) { const char *end = str->ptr + str->slen; const char *last_colon_pos = NULL; unsigned colon_cnt = 0; const char *p; PJ_ASSERT_RETURN((af==PJ_AF_INET || af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) && options==0 && str!=NULL, PJ_EINVAL); /* Special handling for empty input */ if (str->slen==0 || str->ptr==NULL) { if (p_hostpart) p_hostpart->slen = 0; if (p_port) *p_port = 0; if (raf) *raf = PJ_AF_INET; return PJ_SUCCESS; } /* Count the colon and get the last colon */ for (p=str->ptr; p!=end; ++p) { if (*p == ':') { ++colon_cnt; last_colon_pos = p; } } /* Deduce address family if it's not given */ if (af == PJ_AF_UNSPEC) { if (colon_cnt > 1) af = PJ_AF_INET6; else af = PJ_AF_INET; } else if (af == PJ_AF_INET && colon_cnt > 1) return PJ_EINVAL; if (raf) *raf = af; if (af == PJ_AF_INET) { /* Parse as IPv4. Supported formats: * - "10.0.0.1:80" * - "10.0.0.1" * - "10.0.0.1:" * - ":80" * - ":" */ pj_str_t hostpart; unsigned long port; hostpart.ptr = (char*)str->ptr; if (last_colon_pos) { pj_str_t port_part; int i; hostpart.slen = last_colon_pos - str->ptr; port_part.ptr = (char*)last_colon_pos + 1; port_part.slen = end - port_part.ptr; /* Make sure port number is valid */ for (i=0; i<port_part.slen; ++i) { if (!pj_isdigit(port_part.ptr[i])) return PJ_EINVAL; } port = pj_strtoul(&port_part); if (port > 65535) return PJ_EINVAL; } else { hostpart.slen = str->slen; port = 0; } if (p_hostpart) *p_hostpart = hostpart; if (p_port) *p_port = (pj_uint16_t)port; return PJ_SUCCESS; } else if (af == PJ_AF_INET6) { /* Parse as IPv6. Supported formats: * - "fe::01:80" ==> note: port number is zero in this case, not 80! * - "[fe::01]:80" * - "fe::01" * - "fe::01:" * - "[fe::01]" * - "[fe::01]:" * - "[::]:80" * - ":::80" * - "[::]" * - "[::]:" * - ":::" * - "::" */ pj_str_t hostpart, port_part; if (*str->ptr == '[') { char *end_bracket; int i; unsigned long port; if (last_colon_pos == NULL) return PJ_EINVAL; end_bracket = pj_strchr(str, ']'); if (end_bracket == NULL) return PJ_EINVAL; hostpart.ptr = (char*)str->ptr + 1; hostpart.slen = end_bracket - hostpart.ptr; if (last_colon_pos < end_bracket) { port_part.ptr = NULL; port_part.slen = 0; } else { port_part.ptr = (char*)last_colon_pos + 1; port_part.slen = end - port_part.ptr; } /* Make sure port number is valid */ for (i=0; i<port_part.slen; ++i) { if (!pj_isdigit(port_part.ptr[i])) return PJ_EINVAL; } port = pj_strtoul(&port_part); if (port > 65535) return PJ_EINVAL; if (p_hostpart) *p_hostpart = hostpart; if (p_port) *p_port = (pj_uint16_t)port; return PJ_SUCCESS; } else { /* Treat everything as part of the IPv6 IP address */ if (p_hostpart) *p_hostpart = *str; if (p_port) *p_port = 0; return PJ_SUCCESS; } } else { return PJ_EAFNOTSUP; } }
/* Return 0 if success or the index of the invalid char in the string */ static unsigned parse_quoted_string(struct parse_state *st, pj_str_t *output) { pj_str_t token; char *op, *ip, *iend; pj_scan_get_quote(&st->scanner, '"', '"', &token); /* Remove the quote characters */ token.ptr++; token.slen-=2; if (pj_strchr(&token, '\\') == NULL) { *output = token; return 0; } output->ptr = op = pj_pool_alloc(st->pool, token.slen); ip = token.ptr; iend = token.ptr + token.slen; while (ip != iend) { if (*ip == '\\') { ++ip; if (ip==iend) { goto on_error; } if (*ip == 'u') { ip++; if (iend - ip < 4) { ip = iend -1; goto on_error; } /* Only use the last two hext digits because we're on * ASCII */ *op++ = (char)(pj_hex_digit_to_val(ip[2]) * 16 + pj_hex_digit_to_val(ip[3])); ip += 4; } else if (*ip=='"' || *ip=='\\' || *ip=='/') { *op++ = *ip++; } else if (*ip=='b') { *op++ = '\b'; ip++; } else if (*ip=='f') { *op++ = '\f'; ip++; } else if (*ip=='n') { *op++ = '\n'; ip++; } else if (*ip=='r') { *op++ = '\r'; ip++; } else if (*ip=='t') { *op++ = '\t'; ip++; } else { goto on_error; } } else { *op++ = *ip++; } } output->slen = op - output->ptr; return 0; on_error: output->slen = op - output->ptr; return (unsigned)(ip - token.ptr); }
PJ_END_DECL /* Get Symbian phone model info, returning length of model info */ unsigned pj_symbianos_get_model_info(char *buf, unsigned buf_size) { pj_str_t model_name; /* Get machine UID */ TInt hal_val; HAL::Get(HAL::EMachineUid, hal_val); pj_ansi_snprintf(buf, buf_size, "0x%08X", hal_val); pj_strset2(&model_name, buf); /* Get model name */ const pj_str_t st_copyright = {"(C)", 3}; const pj_str_t st_nokia = {"Nokia", 5}; char tmp_buf[64]; pj_str_t tmp_str; _LIT(KModelFilename,"Z:\\resource\\versions\\model.txt"); RFile file; RFs fs; TInt err; fs.Connect(1); err = file.Open(fs, KModelFilename, EFileRead); if (err == KErrNone) { TFileText text; text.Set(file); TBuf16<64> ModelName16; err = text.Read(ModelName16); if (err == KErrNone) { TPtr8 ptr8((TUint8*)tmp_buf, sizeof(tmp_buf)); ptr8.Copy(ModelName16); pj_strset(&tmp_str, tmp_buf, ptr8.Length()); pj_strtrim(&tmp_str); } file.Close(); } fs.Close(); if (err != KErrNone) goto on_return; /* The retrieved model name is usually in long format, e.g: * "© Nokia N95 (01.01)", "(C) Nokia E52". As we need only * the short version, let's clean it up. */ /* Remove preceding non-ASCII chars, e.g: "©" */ char *p = tmp_str.ptr; while (!pj_isascii(*p)) { p++; } pj_strset(&tmp_str, p, tmp_str.slen - (p - tmp_str.ptr)); /* Remove "(C)" */ p = pj_stristr(&tmp_str, &st_copyright); if (p) { p += st_copyright.slen; pj_strset(&tmp_str, p, tmp_str.slen - (p - tmp_str.ptr)); } /* Remove "Nokia" */ p = pj_stristr(&tmp_str, &st_nokia); if (p) { p += st_nokia.slen; pj_strset(&tmp_str, p, tmp_str.slen - (p - tmp_str.ptr)); } /* Remove language version, e.g: "(01.01)" */ p = pj_strchr(&tmp_str, '('); if (p) { tmp_str.slen = p - tmp_str.ptr; } pj_strtrim(&tmp_str); if (tmp_str.slen == 0) goto on_return; if ((unsigned)tmp_str.slen > buf_size - model_name.slen - 3) tmp_str.slen = buf_size - model_name.slen - 3; pj_strcat2(&model_name, "("); pj_strcat(&model_name, &tmp_str); pj_strcat2(&model_name, ")"); /* Zero terminate */ buf[model_name.slen] = '\0'; on_return: return model_name.slen; }
// // Find a character in the string. // char *strchr(int chr) { return pj_strchr(this, chr); }
/* * Send PUBLISH request. */ pj_status_t SIPPresence::send_publish(SIPPresence * pres) { pjsip_tx_data *tdata; pj_status_t status; DEBUG("Send PUBLISH (%s).", pres->getAccount()->getAccountID().c_str()); SIPAccount * acc = pres->getAccount(); std::string contactWithAngles = acc->getFromUri(); contactWithAngles.erase(contactWithAngles.find('>')); int semicolon = contactWithAngles.find_first_of(":"); std::string contactWithoutAngles = contactWithAngles.substr(semicolon + 1); // pj_str_t contact = pj_str(strdup(contactWithoutAngles.c_str())); // pj_memcpy(&status_data.info[0].contact, &contt, sizeof(pj_str_t));; /* Create PUBLISH request */ char *bpos; pj_str_t entity; status = pjsip_publishc_publish(pres->publish_sess_, PJ_TRUE, &tdata); pj_str_t from = pj_strdup3(pres->pool_, acc->getFromUri().c_str()); if (status != PJ_SUCCESS) { ERROR("Error creating PUBLISH request", status); goto on_error; } if ((bpos = pj_strchr(&from, '<')) != NULL) { char *epos = pj_strchr(&from, '>'); if (epos - bpos < 2) { pj_assert(!"Unexpected invalid URI"); status = PJSIP_EINVALIDURI; goto on_error; } entity.ptr = bpos + 1; entity.slen = epos - bpos - 1; } else { entity = from; } /* Create and add PIDF message body */ status = pjsip_pres_create_pidf(tdata->pool, pres->getStatus(), &entity, &tdata->msg->body); pres_msg_data msg_data; if (status != PJ_SUCCESS) { ERROR("Error creating PIDF for PUBLISH request"); pjsip_tx_data_dec_ref(tdata); goto on_error; } pj_bzero(&msg_data, sizeof(msg_data)); pj_list_init(&msg_data.hdr_list); pjsip_media_type_init(&msg_data.multipart_ctype, NULL, NULL); pj_list_init(&msg_data.multipart_parts); pres->fillDoc(tdata, &msg_data); /* Send the PUBLISH request */ status = pjsip_publishc_send(pres->publish_sess_, tdata); if (status == PJ_EPENDING) { WARN("Previous request is in progress, "); } else if (status != PJ_SUCCESS) { ERROR("Error sending PUBLISH request"); goto on_error; } return PJ_SUCCESS; on_error: if (pres->publish_sess_) { pjsip_publishc_destroy(pres->publish_sess_); pres->publish_sess_ = NULL; } return status; }
/* * Send PUBLISH request. */ static pj_status_t send_publish(int acc_id, pj_bool_t active) { pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; pjsua_acc *acc = &pjsua_var.acc[acc_id]; pjsip_pres_status pres_status; pjsip_tx_data *tdata; pj_status_t status; /* Create PUBLISH request */ if (active) { char *bpos; pj_str_t entity; status = pjsip_publishc_publish(acc->publish_sess, PJ_TRUE, &tdata); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error creating PUBLISH request", status); goto on_error; } /* Set our online status: */ pj_bzero(&pres_status, sizeof(pres_status)); pres_status.info_cnt = 1; pres_status.info[0].basic_open = acc->online_status; pres_status.info[0].id = acc->cfg.pidf_tuple_id; /* .. including RPID information */ pj_memcpy(&pres_status.info[0].rpid, &acc->rpid, sizeof(pjrpid_element)); /* Be careful not to send PIDF with presence entity ID containing * "<" character. */ if ((bpos=pj_strchr(&acc_cfg->id, '<')) != NULL) { char *epos = pj_strchr(&acc_cfg->id, '>'); if (epos - bpos < 2) { pj_assert(!"Unexpected invalid URI"); status = PJSIP_EINVALIDURI; goto on_error; } entity.ptr = bpos+1; entity.slen = epos - bpos - 1; } else { entity = acc_cfg->id; } /* Create and add PIDF message body */ status = pjsip_pres_create_pidf(tdata->pool, &pres_status, &entity, &tdata->msg->body); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error creating PIDF for PUBLISH request", status); pjsip_tx_data_dec_ref(tdata); goto on_error; } } else { status = pjsip_publishc_unpublish(acc->publish_sess, &tdata); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error creating PUBLISH request", status); goto on_error; } } /* Add headers etc */ pjsua_process_msg_data(tdata, NULL); /* Send the PUBLISH request */ status = pjsip_publishc_send(acc->publish_sess, tdata); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error sending PUBLISH request", status); goto on_error; } acc->publish_state = acc->online_status; return PJ_SUCCESS; on_error: if (acc->publish_sess) { pjsip_publishc_destroy(acc->publish_sess); acc->publish_sess = NULL; } return status; }
pj_status_t natclient_init(ice_trans_t *icetrans, ice_option_t opt) { pj_status_t status; /* Initialize the libraries before anything else */ CHECK( pj_init(), icetrans ); CHECK( pjlib_util_init(), icetrans ); CHECK( pjnath_init(), icetrans ); #if 0 //FIXME: consider if we need to log if (natclient.opt.log_file) { icetrans->log_fhnd = fopen(natclient.opt.log_file, "a"); pj_log_set_log_func(&log_func); } #endif pj_caching_pool_init(&icetrans->cp, NULL, 0); /* Init our ICE settings with null values */ pj_ice_strans_cfg_default(&icetrans->ice_cfg); icetrans->ice_cfg.stun_cfg.pf = &icetrans->cp.factory; /* Create application memory pool */ icetrans->pool = pj_pool_create(&icetrans->cp.factory, "natclient", 512, 512, NULL); /* Create timer heap for timer stuff */ CHECK( pj_timer_heap_create(icetrans->pool, 100, &icetrans->ice_cfg.stun_cfg.timer_heap), icetrans ); /* and create ioqueue for network I/O stuff */ CHECK( pj_ioqueue_create(icetrans->pool, 16, &icetrans->ice_cfg.stun_cfg.ioqueue), icetrans ); /* something must poll the timer heap and ioqueue, * unless we're on Symbian where the timer heap and ioqueue run * on themselves. */ CHECK( pj_thread_create(icetrans->pool, "natclient", &natclient_worker_thread, icetrans, 0, 0, &icetrans->thread), icetrans ); icetrans->ice_cfg.af = pj_AF_INET(); /* Create DNS resolver if nameserver is set */ if (opt.ns.slen) { CHECK( pj_dns_resolver_create(&icetrans->cp.factory, "resolver", 0, icetrans->ice_cfg.stun_cfg.timer_heap, icetrans->ice_cfg.stun_cfg.ioqueue, &icetrans->ice_cfg.resolver), icetrans ); CHECK( pj_dns_resolver_set_ns(icetrans->ice_cfg.resolver, 1, &opt.ns, NULL) , icetrans); } /* -= Start initializing ICE stream transport config =- */ /* Maximum number of host candidates */ if (opt.max_host != -1) icetrans->ice_cfg.stun.max_host_cands = opt.max_host; /* Nomination strategy */ if (opt.regular) icetrans->ice_cfg.opt.aggressive = PJ_FALSE; else icetrans->ice_cfg.opt.aggressive = PJ_TRUE; /* Configure STUN/srflx candidate resolution */ if (opt.stun_srv.slen) { char *pos; /* Command line option may contain port number */ if ((pos=pj_strchr(&opt.stun_srv, ':')) != NULL) { icetrans->ice_cfg.stun.server.ptr = opt.stun_srv.ptr; icetrans->ice_cfg.stun.server.slen = (pos - opt.stun_srv.ptr); icetrans->ice_cfg.stun.port = (pj_uint16_t)atoi(pos+1); } else { icetrans->ice_cfg.stun.server = opt.stun_srv; icetrans->ice_cfg.stun.port = PJ_STUN_PORT; } /* For this demo app, configure longer STUN keep-alive time * so that it does't clutter the screen output. */ icetrans->ice_cfg.stun.cfg.ka_interval = KA_INTERVAL; } /* Configure TURN candidate */ if (opt.turn_srv.slen) { char *pos; /* Command line option may contain port number */ if ((pos=pj_strchr(&opt.turn_srv, ':')) != NULL) { icetrans->ice_cfg.turn.server.ptr = opt.turn_srv.ptr; icetrans->ice_cfg.turn.server.slen = (pos - opt.turn_srv.ptr); icetrans->ice_cfg.turn.port = (pj_uint16_t)atoi(pos+1); } else { icetrans->ice_cfg.turn.server = opt.turn_srv; icetrans->ice_cfg.turn.port = PJ_STUN_PORT; } /* TURN credential */ icetrans->ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC; icetrans->ice_cfg.turn.auth_cred.data.static_cred.username = opt.turn_username; icetrans->ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; icetrans->ice_cfg.turn.auth_cred.data.static_cred.data = opt.turn_password; /* Connection type to TURN server */ if (opt.turn_tcp) icetrans->ice_cfg.turn.conn_type = PJ_TURN_TP_TCP; else icetrans->ice_cfg.turn.conn_type = PJ_TURN_TP_UDP; /* For this demo app, configure longer keep-alive time * so that it does't clutter the screen output. */ icetrans->ice_cfg.turn.alloc_param.ka_interval = KA_INTERVAL; } /* -= That's it for now, initialization is complete =- */ return PJ_SUCCESS; }
int string_test(void) { const pj_str_t hello_world = { HELLO_WORLD, HELLO_WORLD_LEN }; const pj_str_t just_hello = { JUST_HELLO, JUST_HELLO_LEN }; pj_str_t s1, s2, s3, s4, s5; enum { RCOUNT = 10, RLEN = 16 }; pj_str_t random[RCOUNT]; pj_pool_t *pool; int i; pool = pj_pool_create(mem, SNULL, 4096, 0, SNULL); if (!pool) return -5; /* * pj_str(), pj_strcmp(), pj_stricmp(), pj_strlen(), * pj_strncmp(), pj_strchr() */ s1 = pj_str(HELLO_WORLD); if (pj_strcmp(&s1, &hello_world) != 0) return -10; if (pj_stricmp(&s1, &hello_world) != 0) return -20; if (pj_strcmp(&s1, &just_hello) <= 0) return -30; if (pj_stricmp(&s1, &just_hello) <= 0) return -40; if (pj_strlen(&s1) != strlen(HELLO_WORLD)) return -50; if (pj_strncmp(&s1, &hello_world, 5) != 0) return -60; if (pj_strnicmp(&s1, &hello_world, 5) != 0) return -70; if (pj_strchr(&s1, HELLO_WORLD[1]) != s1.ptr+1) return -80; /* * pj_strdup() */ if (!pj_strdup(pool, &s2, &s1)) return -100; if (pj_strcmp(&s1, &s2) != 0) return -110; /* * pj_strcpy(), pj_strcat() */ s3.ptr = (char*) pj_pool_alloc(pool, 256); if (!s3.ptr) return -200; pj_strcpy(&s3, &s2); pj_strcat(&s3, &just_hello); if (pj_strcmp2(&s3, HELLO_WORLD JUST_HELLO) != 0) return -210; /* * pj_strdup2(), pj_strtrim(). */ pj_strdup2(pool, &s4, " " HELLO_WORLD "\t "); pj_strtrim(&s4); if (pj_strcmp2(&s4, HELLO_WORLD) != 0) return -250; /* * pj_utoa() */ s5.ptr = (char*) pj_pool_alloc(pool, 16); if (!s5.ptr) return -270; s5.slen = pj_utoa(UL_VALUE, s5.ptr); /* * pj_strtoul() */ if (pj_strtoul(&s5) != UL_VALUE) return -280; /* * pj_strtoul2() */ s5 = pj_str("123456"); pj_strtoul2(&s5, SNULL, 10); /* Crash test */ if (pj_strtoul2(&s5, &s4, 10) != 123456UL) return -290; if (s4.slen != 0) return -291; if (pj_strtoul2(&s5, &s4, 16) != 0x123456UL) return -292; s5 = pj_str("0123ABCD"); if (pj_strtoul2(&s5, &s4, 10) != 123) return -293; if (s4.slen != 4) return -294; if (s4.ptr == SNULL || *s4.ptr != 'A') return -295; if (pj_strtoul2(&s5, &s4, 16) != 0x123ABCDUL) return -296; if (s4.slen != 0) return -297; /* * pj_create_random_string() * Check that no duplicate strings are returned. */ for (i=0; i<RCOUNT; ++i) { int j; random[i].ptr = (char*) pj_pool_alloc(pool, RLEN); if (!random[i].ptr) return -320; random[i].slen = RLEN; pj_create_random_string(random[i].ptr, RLEN); for (j=0; j<i; ++j) { if (pj_strcmp(&random[i], &random[j])==0) return -330; } } /* Done. */ pj_pool_release(pool); /* Case sensitive comparison test. */ i = strcmp_test(); if (i != 0) return i; /* Caseless comparison test. */ i = stricmp_test(); if (i != 0) return i; return 0; }