/* XXX - really, this should be refactored into a "buffered writer" object */ static int write_dir_list(struct vsf_session* p_sess, struct mystr_list* p_dir_list, enum EVSFRWTarget target) { /* This function writes out a list of strings to the client, over the * data socket. We now coalesce the strings into fewer write() syscalls, * which saved 33% CPU time writing a large directory. */ int retval = 0; unsigned int dir_index_max = str_list_get_length(p_dir_list); unsigned int dir_index; struct mystr buf_str = INIT_MYSTR; str_reserve(&buf_str, VSFTP_DIR_BUFSIZE); for (dir_index = 0; dir_index < dir_index_max; dir_index++) { str_append_str(&buf_str, str_list_get_pstr(p_dir_list, dir_index)); if (dir_index == dir_index_max - 1 || str_getlen(&buf_str) + str_getlen(str_list_get_pstr(p_dir_list, dir_index + 1)) > VSFTP_DIR_BUFSIZE) { /* Writeout needed - we're either at the end, or we filled the buffer */ int writeret = ftp_write_str(p_sess, &buf_str, target); if (writeret != 0) { retval = 1; break; } str_empty(&buf_str); } } str_free(&buf_str); return retval; }
void str_copy_cstr(str_t* dest, const char* src, size_t n) { str_reserve(dest, n + 1); memcpy(dest->s, src, n); dest->s[n] = '\0'; dest->n = n; }
static int ssl_cert_digest(SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str) { X509* p_cert = SSL_get_peer_certificate(p_ssl); unsigned int num_bytes = 0; if (p_cert == NULL) { return 0; } str_reserve(p_str, EVP_MAX_MD_SIZE); str_empty(p_str); str_rpad(p_str, EVP_MAX_MD_SIZE); if (!X509_digest(p_cert, EVP_sha256(), (unsigned char*) str_getbuf(p_str), &num_bytes)) { die("X509_digest failed"); } X509_free(p_cert); if (tunable_debug_ssl) { unsigned int i; str_alloc_text(&debug_str, "Cert digest:"); for (i = 0; i < num_bytes; ++i) { str_append_char(&debug_str, ' '); str_append_ulong( &debug_str, (unsigned long) (unsigned char) str_get_char_at(p_str, i)); } vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str); } str_trunc(p_str, num_bytes); return 1; }
pstr STDCALL os_dirgetcur( pstr name ) { #ifdef LINUX return str_setlen( name,getcwd( str_ptr( name), 512 )); #else return str_setlen( name, GetCurrentDirectory( 512,str_ptr( str_reserve( name, 512 )))); #endif }
void str_copy(str_t* dest, const str_t* src) { str_reserve(dest, src->n + 1); if (src->s == NULL) dest->s[0] = '\0'; else memcpy(dest->s, src->s, src->n); dest->n = src->n; dest->s[dest->n] = '\0'; }
pstr STDCALL os_tempdir( pstr name ) { #ifdef LINUX pstr stemp = os_gettemp(); uint uLenTempStr = str_len(stemp); str_copy(name,stemp); #else str_setlen( name, GetTempPath( 1024, str_reserve( name, 1024 )->data )); #endif return str_trim( name, SLASH, TRIM_ONE | TRIM_RIGHT ); }
pstr STDCALL getmodulename( pstr name ) { #ifdef WINDOWS uint i; str_reserve( name, 512 ); i = GetModuleFileName( 0, str_ptr( name ), 511 ); str_setlen( name, i ); #endif return name; }
void _reserve(str_t* str, size_t new_len) { size_t allocated = str->allocated; if (allocated == 0) allocated = START_SIZE; while (new_len >= allocated) allocated *= 2; str_reserve(str, allocated); }
int str_netfd_read(struct mystr* p_str, int fd, unsigned int len) { int retval; str_reserve(p_str, len); str_trunc(p_str, len); retval = str_read_loop(p_str, fd); if (vsf_sysutil_retval_is_error(retval) || (unsigned int) retval != len) { return -1; } return retval; }
static void seqenc_decode_seq(seqenc_t* E, short_read_t* x, size_t n) { if (n == 0) return; str_reserve(&x->seq, n + 1); kmer_t uv, u, v; uint32_t ctx = 0; size_t i; for (i = 0; i < n - 1 && i / 2 < prefix_len;) { uv = cond_dist16_decode(E->ac, &E->cs0[i/2], ctx); u = uv >> 2; v = uv & 0x3; x->seq.s[i++] = kmertochar[u]; x->seq.s[i++] = kmertochar[v]; ctx = ((ctx << 4) | uv) & E->ctx_mask; } while (i < n - 1) { uv = cond_dist16_decode(E->ac, &E->cs, ctx); u = uv >> 2; v = uv & 0x3; x->seq.s[i++] = kmertochar[u]; x->seq.s[i++] = kmertochar[v]; ctx = ((ctx << 4) | uv) & E->ctx_mask; } if (i == n - 1) { uv = cond_dist16_decode(E->ac, &E->cs, ctx); v = uv & 0x3; x->seq.s[i] = kmertochar[v]; } /* decode N mask */ reserve_nmask(E, n); for (i = 0; i < n; ++i) { if (dist2_decode(E->ac, &E->d_nmask[i])) x->seq.s[i] = 'N'; } x->seq.s[n] = '\0'; x->seq.n = n; }
static void seqenc_decode_alignment(seqenc_t* E, short_read_t* x, size_t qlen) { str_reserve(&x->seq, qlen + 1); memset(x->seq.s, '\0', qlen + 1); /* decode N mask */ size_t i; reserve_nmask(E, qlen); for (i = 0; i < qlen; ++i) { if (dist2_decode(E->ac, &E->d_nmask[i])) x->seq.s[i] = 'N'; } uint8_t strand = dist2_decode(E->ac, &E->d_aln_strand); uint32_t spos = uint32_enc_decode(E->ac, &E->d_contig_off); size_t slen = E->supercontig_motif.n; assert(spos < slen); kmer_t u; if (strand) { for (i = 0; i < qlen; ++i) { if (x->seq.s[i] == 'N') continue; u = cond_dist4_decode(E->ac, &E->supercontig_motif, slen - (spos + i) - 1); x->seq.s[i] = kmertochar[kmer_comp1(u)]; } } else { for (i = 0; i < qlen; ++i) { if (x->seq.s[i] == 'N') continue; u = cond_dist4_decode(E->ac, &E->supercontig_motif, spos + i); x->seq.s[i] = kmertochar[u]; } } x->seq.s[qlen] = '\0'; x->seq.n = qlen; }
void str_memcpy(str_t* dest, const uint8_t* src, size_t n) { str_reserve(dest, n); memcpy(dest->s, src, n); dest->n = n; }
static void seqenc_decode_reference_alignment(seqenc_t* E, short_read_t* r, size_t seqlen) { const twobit_t* refseq = seqmap_get(E->ref, (const char*) r->seqname.s); if (refseq == NULL) { quip_error( "A read was aligned to sequence %s, which was not found in the reference.", r->seqname.s); } str_reserve(&r->seq, seqlen + 1); r->seq.n = 0; /* decode N mask */ size_t i; reserve_nmask(E, seqlen); memset(r->seq.s, '\0', seqlen + 1); for (i = 0; i < seqlen; ++i) { if (dist2_decode(E->ac, &E->d_nmask[i])) r->seq.s[i] = 'N'; } uint32_t ref_pos = r->pos; uint32_t read_pos = 0; i = 0; /* cigar operation */ size_t j; /* position within the cigar op */ kmer_t y; /* reference nucleotide */ for (i = 0; i < r->cigar.n; ++i) { switch (r->cigar.ops[i]) { case BAM_CEQUAL: case BAM_CDIFF: case BAM_CMATCH: for (j = 0; j < r->cigar.lens[i]; ++j, ++read_pos, ++ref_pos) { if (r->seq.s[read_pos] == 'N') continue; if (dist2_decode(E->ac, &E->d_ref_match) == SEQENC_REF_MATCH) { y = twobit_get(refseq, ref_pos); r->seq.s[read_pos] = kmertochar[y]; } else { r->seq.s[read_pos] = kmertochar[dist4_decode(E->ac, &E->d_ref_ins_nuc)]; } } break; case BAM_CINS: for (j = 0; j < r->cigar.lens[i]; ++j, ++read_pos) { if (r->seq.s[read_pos] == 'N') continue; r->seq.s[read_pos] = kmertochar[dist4_decode(E->ac, &E->d_ref_ins_nuc)]; } break; case BAM_CDEL: ref_pos += r->cigar.lens[i]; break; case BAM_CREF_SKIP: ref_pos += r->cigar.lens[i]; break; case BAM_CSOFT_CLIP: for (j = 0; j < r->cigar.lens[i]; ++j, ++read_pos) { if (r->seq.s[read_pos] == 'N') continue; r->seq.s[read_pos] = kmertochar[dist4_decode(E->ac, &E->d_ref_ins_nuc)]; } break; case BAM_CHARD_CLIP: ref_pos += r->cigar.lens[i]; break; case BAM_CPAD: quip_error("Unsupported cigar operation."); break; } } r->seq.s[seqlen] = '\0'; r->seq.n = seqlen; if (read_pos != seqlen) { quip_error("Cigar operations do not account for full read length."); } if (r->strand) str_revcomp(r->seq.s, r->seq.n); }
int test_str(void) { STR_DEFINE( s3, 10 ); Str *s4, *s5; STR_DEFINE(s6, 10); STR_DEFINE(s7, 10); dump_str( s1, "s1" ); dump_str( s2, "s2" ); dump_str( s3, "s3" ); /* check static strings keep their value */ mu_assert_str( static_str(4), ==, "4" ); mu_assert_str( static_str(-1), ==, "4" ); mu_assert_str( static_str(-1), ==, "4" ); mu_assert_str( static_str(7), ==, "7" ); mu_assert_str( static_str(-1), ==, "7" ); mu_assert_str( static_str(-1), ==, "7" ); T_STR(s4, s4 = str_new(6)); /* alloc, keep memory leak */ T_STR(s5, s5 = str_new(6)); /* expand */ T_STR(s3, str_clear(s3)); T_STR(s3, str_reserve(s3, 9)); T_STR(s3, str_reserve(s3, 10)); T_STR(s3, str_reserve(s3, 11)); T_STR(s3, str_clear(s3)); /* char */ T_STR(s4, str_set(s4, "xxxx")); T_STR(s4, str_set_char(s4, 0)); T_STR(s4, str_append_char(s4, 1)); T_STR(s4, str_append_char(s4, 2)); T_STR(s4, str_append_char(s4, 3)); T_STR(s4, str_append_char(s4, 4)); T_STR(s4, str_append_char(s4, 5)); T_STR(s4, str_append_char(s4, 6)); T_STR(s4, str_append_char(s4, 7)); T_STR(s4, str_append_char(s4, 8)); T_STR(s4, str_append_char(s4, 9)); T_STR(s4, str_append_char(s4, 10)); T_STR(s4, str_clear(s4)); /* string */ T_STR(s5, str_set(s5, "1234")); T_STR(s5, str_append(s5, "56789")); T_STR(s5, str_append(s5, "0")); T_STR(s5, str_clear(s5)); /* substring */ T_STR(s5, str_set_n(s5, "1234xx", 4)); T_STR(s5, str_append_n(s5, "56789xx", 5)); T_STR(s5, str_append_n(s5, "01234567890xx", 11)); T_STR(s5, str_clear(s5)); /* bytes */ T_STR(s5, str_set_bytes(s5, "\0\1\2\3x", 3)); T_STR(s5, str_append_bytes(s5, "\4\5\6x", 3)); T_STR(s5, str_clear(s5)); /* sprintf - test repeated call to vsprintf when buffer grows, needs va_copy in MacOS */ T_STR(s6, str_set(s6, "xxxx")); T_STR(s6, str_sprintf(s6, "%s %d", "hello", 123)); T_STR(s6, str_sprintf(s6, "%s %d", "hello", 1234)); T_STR(s6, str_append_sprintf(s6, "%s %d", "hello", 12345)); T_STR(s6, str_clear(s6)); /* vsprintf - test repeated call to vsprintf when buffer grows, needs va_copy in MacOS */ T_STR(s7, str_set(s7, "xxxx")); T_STR(s7, call_vsprintf(s7, "%s %d", "hello", 123)); T_STR(s7, call_vsprintf(s7, "%s %d", "hello", 1234)); T_STR(s7, call_append_vsprintf(s7, "%s %d", "hello", 12345)); T_STR(s7, str_clear(s7)); str_delete(s5); mu_assert_ptr_null(s5); STR_DELETE(s3); mu_assert_ptr_null(s3); STR_DELETE(s6); mu_assert_ptr_null(s6); STR_DELETE(s7); mu_assert_ptr_null(s7); return MU_PASS; }
pstr STDCALL os_filefullname( pstr filename, pstr result ) { pubyte ptr; #ifdef LINUX //ubyte exename[512]; //ubyte proname[ 512 ]; pstr p_drive,p_path,p_fname,p_fext,p_slesh; ubyte ffn_drive[FILENAME_MAX+1]; ubyte ffn_path[PATH_MAX+1]; ubyte ffn_fname[FILENAME_MAX+1]; ubyte ffn_fext[FILENAME_MAX+1]; os_splitpath(str_ptr(filename),ffn_drive,ffn_path,ffn_fname,ffn_fext); p_slesh = str_new((pubyte)"/"); if (strlen(ffn_path)==0) { char cur[512]; getcwd( cur, 512 ); p_path = str_new(cur); str_add(p_path,p_slesh); } else p_path = str_new(ffn_path); p_fname = str_new(ffn_fname); p_fext = str_new(ffn_fext); str_add(result,p_path); str_add(result,p_fname); str_add(result,p_fext); str_destroy(p_path); str_destroy(p_slesh); str_destroy(p_fname); str_destroy(p_fext); /* char cur[512]; if ( filename[0] != '/' ) { getcwd( cur, 512 ); chdir( filename ); basename( filename ); getcwd( str_ptr( ( pstr )buf ), 512 ); str_setlen( ( pstr )buf, strlen( str_ptr( ( pstr )buf ) ) ); str_appendb( buf, '/' ); str_appendp( buf, filename ); chdir( cur ); } else { //Ìîæåò ðàáîòàòü íåêîððåêòíî åñëè â àáñîëþòíîì ïóòè âñòðå÷àþòñÿ '.' '..' str_appendp( buf, filename ); } */ #else uint len; str_reserve( result, 512 ); len = GetFullPathName(str_ptr(filename), 512, str_ptr(result), &ptr ); // äëÿ Windows str_setlen(result, len); #endif return result; }
void ssl_slave(struct vsf_session* p_sess) { struct mystr data_str = INIT_MYSTR; str_reserve(&data_str, VSFTP_DATA_BUFSIZE); /* Before becoming the slave, clear the alarm for the FTP protocol. */ vsf_sysutil_clear_alarm(); /* No need for any further communications with the privileged parent. */ priv_sock_set_parent_context(p_sess); if (tunable_setproctitle_enable) { vsf_sysutil_setproctitle("SSL handler"); } while (1) { char cmd = priv_sock_get_cmd(p_sess->ssl_slave_fd); int ret; if (cmd == PRIV_SOCK_GET_USER_CMD) { ret = ftp_getline(p_sess, &p_sess->ftp_cmd_str, p_sess->p_control_line_buf); priv_sock_send_int(p_sess->ssl_slave_fd, ret); if (ret >= 0) { priv_sock_send_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str); } } else if (cmd == PRIV_SOCK_WRITE_USER_RESP) { priv_sock_get_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str); ret = ftp_write_str(p_sess, &p_sess->ftp_cmd_str, kVSFRWControl); priv_sock_send_int(p_sess->ssl_slave_fd, ret); } else if (cmd == PRIV_SOCK_DO_SSL_HANDSHAKE) { char result = PRIV_SOCK_RESULT_BAD; if (p_sess->data_fd != -1 || p_sess->p_data_ssl != 0) { bug("state not clean"); } p_sess->data_fd = priv_sock_recv_fd(p_sess->ssl_slave_fd); ret = ssl_accept(p_sess, p_sess->data_fd); if (ret == 1) { result = PRIV_SOCK_RESULT_OK; } else { vsf_sysutil_close(p_sess->data_fd); p_sess->data_fd = -1; } priv_sock_send_result(p_sess->ssl_slave_fd, result); } else if (cmd == PRIV_SOCK_DO_SSL_READ) { str_trunc(&data_str, VSFTP_DATA_BUFSIZE); ret = ssl_read_into_str(p_sess, p_sess->p_data_ssl, &data_str); priv_sock_send_int(p_sess->ssl_slave_fd, ret); priv_sock_send_str(p_sess->ssl_slave_fd, &data_str); } else if (cmd == PRIV_SOCK_DO_SSL_WRITE) { priv_sock_get_str(p_sess->ssl_slave_fd, &data_str); ret = ssl_write(p_sess->p_data_ssl, str_getbuf(&data_str), str_getlen(&data_str)); priv_sock_send_int(p_sess->ssl_slave_fd, ret); } else if (cmd == PRIV_SOCK_DO_SSL_CLOSE) { char result = PRIV_SOCK_RESULT_BAD; if (p_sess->data_fd == -1 && p_sess->p_data_ssl == 0) { result = PRIV_SOCK_RESULT_OK; } else { ret = ssl_data_close(p_sess); if (ret == 1) { result = PRIV_SOCK_RESULT_OK; } vsf_sysutil_close(p_sess->data_fd); p_sess->data_fd = -1; } priv_sock_send_result(p_sess->ssl_slave_fd, result); } else { die("bad request in process_ssl_slave_req"); } } }