00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #if HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include <stdio.h>
00026
00027 #ifdef HAVE_UNISTD_H
00028 #include <unistd.h>
00029 #endif
00030
00031 #ifdef HAVE_STDLIB_H
00032 #include <stdlib.h>
00033 #endif
00034
00035 #ifdef HAVE_STRING_H
00036 #include <string.h>
00037 #endif
00038
00039 #include <assert.h>
00040
00041 #include "tds.h"
00042 #include "tdsconvert.h"
00043 #include "sybfront.h"
00044 #include "sybdb.h"
00045 #include "dblib.h"
00046 #include "replacements.h"
00047
00048 #ifdef DMALLOC
00049 #include <dmalloc.h>
00050 #endif
00051
00052 TDS_RCSID(var, "$Id: rpc.c 86967 2006-07-31 15:44:10Z ssikorsk $");
00053
00054 static void rpc_clear(DBREMOTE_PROC * rpc);
00055 static void param_clear(DBREMOTE_PROC_PARAM * pparam);
00056
00057 static TDSPARAMINFO *param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc);
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 RETCODE
00075 dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options)
00076 {
00077 DBREMOTE_PROC **rpc;
00078 int dbrpcrecompile = 0;
00079
00080
00081 if (dbproc == NULL || rpcname == NULL)
00082 return FAIL;
00083
00084 if (options & DBRPCRESET) {
00085 rpc_clear(dbproc->rpc);
00086 dbproc->rpc = NULL;
00087 return SUCCEED;
00088 }
00089
00090
00091 dbrpcrecompile = options & DBRPCRECOMPILE;
00092 options &= ~DBRPCRECOMPILE;
00093
00094
00095 if (options) {
00096
00097 return FAIL;
00098 }
00099
00100
00101 for (rpc = &dbproc->rpc; *rpc != NULL; rpc = &(*rpc)->next) {
00102
00103 if (!(*rpc)->name)
00104 return FAIL;
00105 if (strcmp((*rpc)->name, rpcname) == 0)
00106 return FAIL ;
00107 }
00108
00109
00110
00111
00112 *rpc = (DBREMOTE_PROC *) malloc(sizeof(DBREMOTE_PROC));
00113 if (*rpc == NULL)
00114 return FAIL;
00115 memset(*rpc, 0, sizeof(DBREMOTE_PROC));
00116
00117 (*rpc)->name = strdup(rpcname);
00118 if ((*rpc)->name == NULL) {
00119 free(*rpc);
00120 *rpc = NULL;
00121 return FAIL;
00122 }
00123
00124
00125 (*rpc)->options = options & DBRPCRECOMPILE;
00126 (*rpc)->param_list = NULL;
00127
00128
00129 tdsdump_log(TDS_DBG_INFO1, "dbrpcinit() added rpcname \"%s\"\n", rpcname);
00130
00131 return SUCCEED;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 RETCODE
00155 dbrpcparam(DBPROCESS * dbproc, char *paramname, BYTE status, int type, DBINT maxlen, DBINT datalen, BYTE * value)
00156 {
00157 char *name = NULL;
00158 DBREMOTE_PROC *rpc;
00159 DBREMOTE_PROC_PARAM **pparam;
00160 DBREMOTE_PROC_PARAM *param;
00161
00162
00163 if (dbproc == NULL)
00164 return FAIL;
00165 if (dbproc->rpc == NULL)
00166 return FAIL;
00167
00168
00169
00170 if (is_fixed_type(type)) {
00171 if (datalen > 0)
00172 return FAIL;
00173 } else {
00174 if (datalen < 0)
00175 return FAIL;
00176 }
00177
00178
00179
00180 if (status & DBRPCRETURN) {
00181 if (is_fixed_type(type)) {
00182 if (maxlen != -1)
00183 return FAIL;
00184 } else {
00185 if (maxlen == -1)
00186 maxlen = 255;
00187 }
00188 } else {
00189
00190
00191
00192
00193
00194 if (maxlen != -1 && maxlen != 0)
00195 return FAIL;
00196 maxlen = -1;
00197 }
00198
00199
00200
00201
00202 param = (DBREMOTE_PROC_PARAM *) malloc(sizeof(DBREMOTE_PROC_PARAM));
00203 if (param == NULL)
00204 return FAIL;
00205
00206 if (paramname) {
00207 name = strdup(paramname);
00208 if (name == NULL) {
00209 free(param);
00210 return FAIL;
00211 }
00212 }
00213
00214
00215 param->next = NULL;
00216 param->name = name;
00217 param->status = status;
00218 param->type = type;
00219 param->maxlen = maxlen;
00220 param->datalen = datalen;
00221
00222
00223
00224
00225
00226
00227 if (datalen == 0)
00228 param->value = NULL;
00229 else
00230 param->value = value;
00231
00232
00233
00234
00235
00236
00237
00238
00239 for (rpc = dbproc->rpc; rpc->next != NULL; rpc = rpc->next)
00240 ;
00241 for (pparam = &rpc->param_list; *pparam != NULL; pparam = &(*pparam)->next);
00242
00243
00244
00245 *pparam = param;
00246
00247 tdsdump_log(TDS_DBG_INFO1, "dbrpcparam() added parameter \"%s\"\n", (paramname) ? paramname : "");
00248
00249 return SUCCEED;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 RETCODE
00262 dbrpcsend(DBPROCESS * dbproc)
00263 {
00264 DBREMOTE_PROC *rpc;
00265
00266
00267 if (dbproc == NULL || dbproc->rpc == NULL
00268 || dbproc->rpc->name == NULL) {
00269 return FAIL;
00270 }
00271
00272 dbproc->dbresults_state = _DB_RES_INIT;
00273
00274
00275 tdsdump_log(TDS_DBG_FUNC, "dbrpcsend()\n");
00276
00277 for (rpc = dbproc->rpc; rpc != NULL; rpc = rpc->next) {
00278 int erc;
00279 TDSPARAMINFO *pparam_info = NULL;
00280
00281
00282
00283
00284
00285 if (rpc->param_list != NULL) {
00286 pparam_info = param_info_alloc(dbproc->tds_socket, rpc);
00287 if (!pparam_info)
00288 return FAIL;
00289 }
00290 erc = tds_submit_rpc(dbproc->tds_socket, dbproc->rpc->name, pparam_info);
00291 tds_free_param_results(pparam_info);
00292 if (erc == TDS_FAIL)
00293 return FAIL;
00294 }
00295
00296
00297 rpc_clear(dbproc->rpc);
00298 dbproc->rpc = NULL;
00299
00300 return SUCCEED;
00301 }
00302
00303
00304
00305
00306 static const unsigned char *
00307 param_row_alloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *value, int size)
00308 {
00309 const unsigned char *row = tds_alloc_param_row(params, curcol);
00310 tdsdump_log(TDS_DBG_INFO1, "parameter size = %d, offset = %d, row_size = %d\n",
00311 size, curcol->column_offset, params->row_size);
00312 if (!row)
00313 return NULL;
00314 if (size > 0 && value) {
00315 tdsdump_log(TDS_DBG_FUNC, "copying %d bytes of data to parameter #%d\n", size, param_num);
00316 if (!is_blob_type(curcol->column_type)) {
00317 memcpy(¶ms->current_row[curcol->column_offset], value, size);
00318 } else {
00319 TDSBLOB *blob = (TDSBLOB *) ¶ms->current_row[curcol->column_offset];
00320 blob->textvalue = malloc(size);
00321 tdsdump_log(TDS_DBG_FUNC, "blob parameter supported, size %d textvalue pointer is %p\n", size, blob->textvalue);
00322 if (!blob->textvalue)
00323 return NULL;
00324 memcpy(blob->textvalue, value, size);
00325 }
00326 }
00327 else {
00328 tdsdump_log(TDS_DBG_FUNC, "setting parameter #%d to NULL\n", param_num);
00329 curcol->column_cur_size = -1;
00330 }
00331
00332 return row;
00333 }
00334
00335
00336
00337
00338 static TDSPARAMINFO *
00339 param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc)
00340 {
00341 int i;
00342 DBREMOTE_PROC_PARAM *p;
00343 TDSCOLUMN *pcol;
00344 TDSPARAMINFO *params = NULL, *new_params;
00345 BYTE *temp_value;
00346 int temp_datalen;
00347 int temp_type;
00348 int param_is_null;
00349
00350
00351 if (rpc == NULL)
00352 return NULL;
00353
00354
00355
00356 for (i = 0, p = rpc->param_list; p != NULL; p = p->next, i++) {
00357 const unsigned char *prow;
00358
00359 if (!(new_params = tds_alloc_param_result(params))) {
00360 tds_free_param_results(params);
00361 tdsdump_log(TDS_DBG_ERROR, "out of rpc memory!");
00362 return NULL;
00363 }
00364 params = new_params;
00365
00366
00367
00368
00369
00370
00371 param_is_null = 0;
00372 temp_type = p->type;
00373 temp_value = p->value;
00374 temp_datalen = p->datalen;
00375
00376 if (p->datalen == 0)
00377 param_is_null = 1;
00378
00379 tdsdump_log(TDS_DBG_INFO1, "parm_info_alloc(): parameter null-ness = %d\n", param_is_null);
00380
00381 if (param_is_null || (p->status & DBRPCRETURN)) {
00382 if (param_is_null) {
00383 temp_datalen = 0;
00384 temp_value = NULL;
00385 } else if (is_fixed_type(temp_type)) {
00386 temp_datalen = tds_get_size_by_type(temp_type);
00387 }
00388 temp_type = tds_get_null_type(temp_type);
00389 } else if (is_fixed_type(temp_type)) {
00390 temp_datalen = tds_get_size_by_type(temp_type);
00391 }
00392
00393 pcol = params->columns[i];
00394
00395
00396 if (p->name) {
00397 tds_strlcpy(pcol->column_name, p->name, sizeof(pcol->column_name));
00398 pcol->column_namelen = strlen(pcol->column_name);
00399 }
00400
00401 tds_set_param_type(tds, pcol, temp_type);
00402
00403 if (p->maxlen > 0)
00404 pcol->column_size = p->maxlen;
00405 else {
00406 if (is_fixed_type(p->type)) {
00407 pcol->column_size = tds_get_size_by_type(p->type);
00408 } else {
00409 pcol->column_size = p->datalen;
00410 }
00411 }
00412 pcol->on_server.column_size = pcol->column_size;
00413
00414 pcol->column_output = p->status;
00415 pcol->column_cur_size = temp_datalen;
00416
00417 prow = param_row_alloc(params, pcol, i, temp_value, temp_datalen);
00418
00419 if (!prow) {
00420 tds_free_param_results(params);
00421 tdsdump_log(TDS_DBG_ERROR, "out of memory for rpc row!");
00422 return NULL;
00423 }
00424
00425 }
00426
00427 return params;
00428
00429 }
00430
00431
00432
00433
00434 static void
00435 rpc_clear(DBREMOTE_PROC * rpc)
00436 {
00437 DBREMOTE_PROC * next;
00438
00439 while (rpc) {
00440 next = rpc->next;
00441 param_clear(rpc->param_list);
00442 if (rpc->name)
00443 free(rpc->name);
00444 free(rpc);
00445 rpc = next;
00446 }
00447 }
00448
00449
00450
00451
00452 static void
00453 param_clear(DBREMOTE_PROC_PARAM * pparam)
00454 {
00455 DBREMOTE_PROC_PARAM * next;
00456
00457 while (pparam) {
00458 next = pparam->next;
00459 if (pparam->name)
00460 free(pparam->name);
00461
00462 free(pparam);
00463 pparam = next;
00464 }
00465 }
00466
00467