main(int argc, char **argv) { TDSSOCKET *tds; TDSLOGIN login; TDSRESULTINFO *resinfo; tds = tds_listen(atoi(argv[1])); /* get_incoming(tds->s); */ tds_read_login(tds, &login); dump_login(&login); if (!strcmp(login.user_name, "guest") && !strcmp(login.password, "sybase")) { tds->out_flag = 4; tds_env_change(tds, 1, "master", "pubs2"); tds_send_msg(tds, 5701, 2, 10, "Changed database context to 'pubs2'.", "JDBC", "ZZZZZ", 1); if (!login.suppress_language) { tds_env_change(tds, 2, NULL, "us_english"); tds_send_msg(tds, 5703, 1, 10, "Changed language setting to 'us_english'.", "JDBC", "ZZZZZ", 1); } tds_env_change(tds, 4, NULL, "512"); tds_send_login_ack(tds, "sql server"); tds_send_capabilities_token(tds); tds_send_253_token(tds, 0, 1); } else { /* send nack before exiting */ exit(1); } tds_flush_packet(tds); /* printf("incoming packet %d\n", tds_read_packet(tds)); */ printf("query : %s\n", tds_get_query(tds)); tds->out_flag = 4; resinfo = tds_alloc_results(1); resinfo->columns[0]->column_type = SYBVARCHAR; resinfo->columns[0]->column_size = 30; strcpy(resinfo->columns[0]->column_name, "name"); resinfo->columns[0]->column_namelen = 4; resinfo->current_row = "pubs2"; tds_send_result(tds, resinfo); tds_send_174_token(tds, 1); tds_send_row(tds, resinfo); tds_send_253_token(tds, 16, 1); tds_flush_packet(tds); sleep(30); }
/** * Initialize BCP information. * Query structure of the table to server. * \tds * \param bcpinfo BCP information to initialize. Structure should be allocate * and table name and direction should be already set. */ TDSRET tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) { TDSRESULTINFO *resinfo; TDSRESULTINFO *bindinfo = NULL; TDSCOLUMN *curcol; TDS_INT result_type; int i; TDSRET rc; const char *fmt; /* FIXME don't leave state in processing state */ /* TODO quote tablename if needed */ if (bcpinfo->direction != TDS_BCP_QUERYOUT) fmt = "SET FMTONLY ON select * from %s SET FMTONLY OFF"; else fmt = "SET FMTONLY ON %s SET FMTONLY OFF"; if (TDS_FAILED(rc=tds_submit_queryf(tds, fmt, bcpinfo->tablename))) /* TODO return an error ?? */ /* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */ return rc; /* TODO possibly stop at ROWFMT and copy before going to idle */ /* TODO check what happen if table is not present, cleanup on error */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) continue; if (TDS_FAILED(rc)) return rc; /* copy the results info from the TDS socket */ if (!tds->res_info) return TDS_FAIL; resinfo = tds->res_info; if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL) { rc = TDS_FAIL; goto cleanup; } bindinfo->row_size = resinfo->row_size; /* Copy the column metadata */ rc = TDS_FAIL; for (i = 0; i < bindinfo->num_cols; i++) { curcol = bindinfo->columns[i]; /* * TODO use memcpy ?? * curcol and resinfo->columns[i] are both TDSCOLUMN. * Why not "curcol = resinfo->columns[i];"? Because the rest of TDSCOLUMN (below column_timestamp) * isn't being used. Perhaps this "upper" part of TDSCOLUMN should be a substructure. * Or, see if the "lower" part is unused (and zeroed out) at this point, and just do one assignment. */ curcol->funcs = resinfo->columns[i]->funcs; curcol->column_type = resinfo->columns[i]->column_type; curcol->column_usertype = resinfo->columns[i]->column_usertype; curcol->column_flags = resinfo->columns[i]->column_flags; if (curcol->column_varint_size == 0) curcol->column_cur_size = resinfo->columns[i]->column_cur_size; else curcol->column_cur_size = -1; curcol->column_size = resinfo->columns[i]->column_size; curcol->column_varint_size = resinfo->columns[i]->column_varint_size; curcol->column_prec = resinfo->columns[i]->column_prec; curcol->column_scale = resinfo->columns[i]->column_scale; curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type; curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size; curcol->char_conv = resinfo->columns[i]->char_conv; if (!tds_dstr_dup(&curcol->column_name, &resinfo->columns[i]->column_name)) goto cleanup; if (!tds_dstr_dup(&curcol->table_column_name, &resinfo->columns[i]->table_column_name)) goto cleanup; curcol->column_nullable = resinfo->columns[i]->column_nullable; curcol->column_identity = resinfo->columns[i]->column_identity; curcol->column_timestamp = resinfo->columns[i]->column_timestamp; memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5); if (is_numeric_type(curcol->column_type)) { curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC)); ((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec; ((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale; } else if (bcpinfo->bind_count != 0 /* ctlib */ && is_blob_col(curcol)) { curcol->bcp_column_data = tds_alloc_bcp_column_data(0); } else { curcol->bcp_column_data = tds_alloc_bcp_column_data(MAX(curcol->column_size,curcol->on_server.column_size)); } if (!curcol->bcp_column_data) goto cleanup; } if (!IS_TDS7_PLUS(tds->conn)) { bindinfo->current_row = (unsigned char*) malloc(bindinfo->row_size); if (!bindinfo->current_row) goto cleanup; bindinfo->row_free = tds_bcp_row_free; } if (bcpinfo->identity_insert_on) { rc = tds_submit_queryf(tds, "set identity_insert %s on", bcpinfo->tablename); if (TDS_FAILED(rc)) goto cleanup; /* TODO use tds_process_simple_query */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) { } if (rc != TDS_NO_MORE_RESULTS) goto cleanup; } bcpinfo->bindinfo = bindinfo; bcpinfo->bind_count = 0; return TDS_SUCCESS; cleanup: tds_free_results(bindinfo); return rc; }
/* * TDS 5 style result sets */ static int read_result(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read) { TDS_SMALLINT hdrsize; int pos = 0; int namelen; int col; TDSSOCKET *tds = pmbr->tds; int num_cols; TDSCOLUMN *curcol; TDSRESULTINFO *info; if (bytes_left(pmbr, buf, pos, maxlen, 3)) { *bytes_read = maxlen; return 0; } /* FIX ME -- endian */ hdrsize = buf[1] + buf[2] * 256; pos += 3; /* read number of columns and allocate the columns structure */ num_cols = buf[pos] + buf[pos+1] * 256; pos += 2; tds_free_all_results(tds); tds->res_info = tds_alloc_results(num_cols); info = pmbr->tds->res_info; /* * loop through the columns populating COLINFO struct from * server response */ for (col = 0; col < info->num_cols; col++) { curcol = info->columns[col]; namelen = buf[pos++]; strncpy(curcol->column_name, (char *) &buf[pos], namelen); curcol->column_name[namelen] = '\0'; pos += namelen; curcol->column_namelen = namelen; pos++; /* flags */ pos += 4; /* user type */ tds_set_column_type(tds->conn, curcol, (int)buf[pos]); switch(curcol->column_varint_size) { /* FIX ME - endian */ case 2: curcol->column_size = buf[pos] + buf[pos+1]*256; break; case 1: curcol->column_size = buf[pos]; break; case 0: break; } pos+=curcol->column_varint_size; if (is_numeric_type(curcol->column_type)) pos+=2; /* skip locale information */ pos += buf[pos]; } return tds_alloc_row(info); }
static int read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read) { TDS_SMALLINT hdrsize; int pos = 0; int num_cols = 0; int namelen; struct tmp_col_struct *head = NULL, *cur = NULL, *prev; int col; TDSCOLUMN *curcol; TDSRESULTINFO *info; /* header size */ if (bytes_left(pmbr, buf, pos, maxlen, 3)) { *bytes_read = maxlen; return 0; } /* FIXME -- endian */ hdrsize = buf[1] + buf[2] * 256; pos += 3; for (;;) { prev = cur; cur = (struct tmp_col_struct *) malloc(sizeof(struct tmp_col_struct)); cur->next = NULL; cur->column_name = NULL; if (prev) prev->next = cur; if (!head) head = cur; if (bytes_left(pmbr, buf, pos, maxlen, 1)) { *bytes_read = maxlen; free_col_struct(head); return 0; } namelen = buf[pos++]; if (bytes_left(pmbr, buf, pos, maxlen, namelen)) { *bytes_read = maxlen; free_col_struct(head); return 0; } cur->column_name = (char *) malloc(namelen + 1); strncpy(cur->column_name, (char *) &buf[pos], namelen); cur->column_name[namelen] = '\0'; pos += namelen; num_cols++; if (pos >= hdrsize) break; } tds_free_all_results(pmbr->tds); pmbr->tds->res_info = tds_alloc_results(num_cols); info = pmbr->tds->res_info; cur = head; for (col = 0; col < info->num_cols; col++) { curcol = info->columns[col]; strncpy(curcol->column_name, cur->column_name, sizeof(curcol->column_name)); /* FIXME ucs2 client and others */ curcol->column_name[sizeof(curcol->column_name) - 1] = 0; curcol->column_namelen = strlen(curcol->column_name); prev = cur; cur = cur->next; free(prev->column_name); free(prev); } *bytes_read = pos; return 1; }
int main(int argc, char **argv) { TDSCONTEXT *ctx; TDSSOCKET *tds; TDSLOGIN *login; TDSRESULTINFO *resinfo; if (argc < 2 || atoi(argv[1]) <= 0) { fprintf(stderr, "syntax: %s <port>\n", argv[0]); return 1; } ctx = tds_alloc_context(NULL); tds = tds_listen(ctx, atoi(argv[1])); if (!tds) return 1; /* get_incoming(tds->s); */ login = tds_alloc_read_login(tds); if (!login) { fprintf(stderr, "Error reading login\n"); exit(1); } dump_login(login); if (!strcmp(tds_dstr_cstr(&login->user_name), "guest") && !strcmp(tds_dstr_cstr(&login->password), "sybase")) { tds->out_flag = TDS_REPLY; tds_env_change(tds, TDS_ENV_DATABASE, "master", "pubs2"); tds_send_msg(tds, 5701, 2, 10, "Changed database context to 'pubs2'.", "JDBC", "ZZZZZ", 1); if (!login->suppress_language) { tds_env_change(tds, TDS_ENV_LANG, NULL, "us_english"); tds_send_msg(tds, 5703, 1, 10, "Changed language setting to 'us_english'.", "JDBC", "ZZZZZ", 1); } tds_env_change(tds, TDS_ENV_PACKSIZE, NULL, "512"); /* TODO set mssql if tds7+ */ tds_send_login_ack(tds, "sql server"); if (IS_TDS50(tds)) tds_send_capabilities_token(tds); tds_send_done_token(tds, 0, 1); } else { /* send nack before exiting */ exit(1); } tds_flush_packet(tds); tds_free_login(login); login = NULL; /* printf("incoming packet %d\n", tds_read_packet(tds)); */ printf("query : %s\n", tds_get_generic_query(tds)); tds->out_flag = TDS_REPLY; resinfo = tds_alloc_results(1); resinfo->columns[0]->column_type = SYBVARCHAR; resinfo->columns[0]->column_size = 30; strcpy(resinfo->columns[0]->column_name, "name"); resinfo->columns[0]->column_namelen = 4; resinfo->current_row = (TDS_UCHAR*) "pubs2"; resinfo->columns[0]->column_data = resinfo->current_row; tds_send_result(tds, resinfo); tds_send_control_token(tds, 1); tds_send_row(tds, resinfo); tds_send_done_token(tds, 16, 1); tds_flush_packet(tds); sleep(30); tds_free_results(resinfo); tds_free_socket(tds); tds_free_context(ctx); return 0; }