00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <errno.h>
00005 #include <string.h>
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <sys/types.h>
00009 #include <arpa/inet.h>
00010 #include <sys/wait.h>
00011 #include <netinet/in.h>
00012 #include <zlib.h>
00013 #include <pthread.h>
00014 #include <alloca.h>
00015 #include "db.h"
00016 #include "xassert.h"
00017 #ifdef DEBUG
00018 #include "timer.h"
00019 #endif
00020
00021
00022 void db_write_statncnt(int sockfd, int status, int row_count)
00023 {
00024 struct iovec vec[2];
00025 status = htonl(status);
00026 vec[0].iov_len = sizeof(status);
00027 vec[0].iov_base = &status;
00028 row_count = htonl(row_count);
00029 vec[1].iov_len = sizeof(row_count);
00030 vec[1].iov_base = &row_count;
00031 Writevn(sockfd, vec, 2);
00032 }
00033
00034
00035 int db_tcp_listen(char *host, int len, short *port)
00036 {
00037 int on = 1;
00038 struct sockaddr_in server;
00039 int sockfd, size = sizeof(struct sockaddr_in);
00040
00041 if (gethostname(host, len))
00042 return -1;
00043
00044
00045
00046
00047 for (;;)
00048 {
00049 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) != -1)
00050 break;
00051 }
00052
00053 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
00054 {
00055 perror("setsockopt error");
00056 return -1;
00057 }
00058
00059
00060 server.sin_family = AF_INET;
00061 server.sin_port = 0;
00062 server.sin_addr.s_addr = 0;
00063 memset(&(server.sin_zero), 0, 8);
00064
00065 struct sockaddr *serverp = (struct sockaddr *)&server;
00066 if ( bind(sockfd, serverp, size) < 0)
00067 {
00068 perror("bind call failed.");
00069 close(sockfd);
00070 return -1;
00071 }
00072
00073
00074 if (getsockname(sockfd, serverp, (socklen_t *)&size))
00075 {
00076 perror("getsockname call failed.");
00077 return -1;
00078 }
00079 #ifdef BLAHBLAH
00080 {
00081 int rcvbuf, sndbuf;
00082 db_getsocketbufsize(sockfd, &sndbuf,&rcvbuf);
00083 #ifdef DEBUG
00084 printf("Original socket buffer sizes: SO_SNDBUF = %d, SO_RCVBUF = %d\n",sndbuf,rcvbuf);
00085 #endif
00086 if (sndbuf<65536)
00087 {
00088 sndbuf = 65536/2;
00089 db_setsocketbufsize(sockfd, sndbuf, rcvbuf/2);
00090 }
00091 db_getsocketbufsize(sockfd, &sndbuf,&rcvbuf);
00092 #ifdef DEBUG
00093 printf("New socket buffer sizes: SO_SNDBUF = %d, SO_RCVBUF = %d\n",sndbuf,rcvbuf);
00094 #endif
00095 }
00096 #endif
00097
00098 if ( listen(sockfd, 5) < 0 )
00099 {
00100 perror("listen call failed.");
00101 return -1;
00102 }
00103
00104 *port = ntohs(server.sin_port);
00105 return sockfd;
00106 }
00107
00108
00109
00110 int db_send_text_result(int sockfd, DB_Text_Result_t *result, int comp)
00111 {
00112 int buflen;
00113 unsigned long zlen;
00114 char *zbuf;
00115 int tmp[4];
00116 struct iovec vec[5];
00117
00118 if (result)
00119 {
00120
00121 tmp[0] = htonl(result->num_rows);
00122 vec[0].iov_len = sizeof(tmp[0]);
00123 vec[0].iov_base = &tmp[0];
00124 tmp[1] = htonl(result->num_cols);
00125 vec[1].iov_len = sizeof(tmp[1]);
00126 vec[1].iov_base = &tmp[1];
00127
00128 if (result->num_rows>0)
00129 {
00130
00131 buflen = ntohl(*((int *)result->buffer));
00132 if (comp)
00133 {
00134 zlen = buflen+buflen/100+24;
00135 zbuf = malloc(zlen);
00136 XASSERT(zbuf);
00137 if (compress ((unsigned char *)zbuf, &zlen,
00138 ((unsigned char *)result->buffer+sizeof(int)),
00139 (buflen-sizeof(int))) != Z_OK)
00140 return 1;
00141
00142 tmp[2] = htonl(zlen);
00143 vec[2].iov_len = sizeof(tmp[0]);
00144 vec[2].iov_base = &tmp[0];
00145 tmp[3] = htonl(buflen);
00146 vec[3].iov_len = sizeof(tmp[1]);
00147 vec[3].iov_base = &tmp[1];
00148 vec[4].iov_len = zlen;
00149 vec[4].iov_base = zbuf;
00150 Writevn(sockfd, vec, 5);
00151 free(zbuf);
00152 }
00153 else
00154 {
00155
00156
00157
00158
00159
00160
00161
00162 vec[2].iov_len = buflen;
00163 vec[2].iov_base = result->buffer;
00164 Writevn(sockfd, vec, 3);
00165 }
00166 }
00167 else
00168 Writevn(sockfd, vec, 2);
00169 }
00170 return 0;
00171 }
00172
00173
00174
00175 int db_send_binary_result(int sockfd, DB_Binary_Result_t *result, int comp)
00176 {
00177 int i,j;
00178 int vc,tc;
00179 DB_Column_t *col;
00180 struct iovec *vec;
00181 int *tmp;
00182 int anynull;
00183
00184 if (result)
00185 {
00186 vec = malloc((3+7*result->num_cols)*sizeof(struct iovec));
00187 XASSERT(vec);
00188 tmp = malloc((3+7*result->num_cols)*sizeof(int));
00189 XASSERT(tmp);
00190
00191
00192 for (i=0; i<result->num_cols; i++)
00193 {
00194 col = &result->column[i];
00195 db_hton(col->type, result->num_rows, col->data);
00196 db_hton(DB_INT2, result->num_rows, col->is_null);
00197 }
00198
00199
00200 vc=0; tc=0;
00201
00202 tmp[tc] = htonl(result->num_rows);
00203 vec[vc].iov_len = sizeof(tmp[tc]);
00204 vec[vc].iov_base = &tmp[tc];
00205 ++tc; ++vc;
00206
00207 tmp[tc] = htonl(result->num_cols);
00208 vec[vc].iov_len = sizeof(tmp[tc]);
00209 vec[vc].iov_base = &tmp[tc];
00210 ++tc; ++vc;
00211
00212 for (i=0; i<result->num_cols; i++)
00213 {
00214 col = &result->column[i];
00215
00216 vec[vc+1].iov_len = strlen(col->column_name);
00217 vec[vc+1].iov_base = col->column_name;
00218
00219 tmp[tc] = htonl(vec[vc+1].iov_len);
00220 vec[vc].iov_len = sizeof(tmp[tc]);
00221 vec[vc].iov_base = &tmp[tc];
00222 vc+=2; ++tc;
00223
00224 tmp[tc] = htonl(col->type);
00225 vec[vc].iov_len = sizeof(tmp[tc]);
00226 vec[vc].iov_base = &tmp[tc];
00227 ++tc; ++vc;
00228
00229 tmp[tc] = htonl(col->size);
00230 vec[vc].iov_len = sizeof(tmp[tc]);
00231 vec[vc].iov_base = &tmp[tc];
00232 ++tc; ++vc;
00233
00234 vec[vc].iov_len = result->num_rows*col->size;
00235 vec[vc].iov_base = col->data;
00236 ++vc;
00237
00238
00239 anynull = 0;
00240 for (j=0; j<result->num_rows; j++)
00241 anynull = anynull | (int)col->is_null[j];
00242 if (anynull)
00243 anynull = 1;
00244
00245 tmp[tc] = htonl(anynull);
00246 vec[vc].iov_len = sizeof(tmp[tc]);
00247 vec[vc].iov_base = &tmp[tc];
00248 ++tc; ++vc;
00249 if (anynull)
00250 {
00251
00252 vec[vc].iov_len = sizeof(short)*result->num_rows;
00253 vec[vc].iov_base = col->is_null;
00254 ++vc;
00255 }
00256 }
00257 Writevn(sockfd, vec,vc);
00258
00259
00260 for (i=0; i<result->num_cols; i++)
00261 {
00262 col = &result->column[i];
00263 db_hton(col->type, result->num_rows, col->data);
00264 db_hton(DB_INT2, result->num_rows, col->is_null);
00265 }
00266 free(vec);
00267 free(tmp);
00268 }
00269 return 0;
00270 }
00271
00272 int db_server_query_bin(int sockfd, DB_Handle_t *db_handle)
00273 {
00274 int tmp, len,status, comp;
00275 char *query;
00276 DB_Binary_Result_t *result;
00277
00278 status = -1;
00279 if ( Readn(sockfd, &tmp, sizeof(int)) == sizeof(int) )
00280 {
00281
00282 len = ntohl(tmp);
00283 query = malloc(len+1);
00284 XASSERT(query);
00285 Readn(sockfd, query, len);
00286 query[len] = '\0';
00287
00288
00289 comp = Readint(sockfd);
00290
00291
00292 result = db_query_bin(db_handle, query);
00293
00294
00295 if (result)
00296 {
00297 status = 0;
00298 if (db_send_binary_result(sockfd, result, comp))
00299 {
00300 fprintf(stderr,"Query transmission failed.\n");
00301 status = -1;
00302 }
00303 db_free_binary_result(result);
00304 }
00305 else
00306 {
00307 fprintf(stderr,"Query failed, check query string.\n");
00308 Writeint(sockfd, -1);
00309
00310 if (*db_handle->errmsg)
00311 {
00312 send_string(sockfd, db_handle->errmsg);
00313 }
00314 else
00315 {
00316 send_string(sockfd, "no message");
00317 }
00318 }
00319 free(query);
00320 }
00321
00322 return status;
00323 }
00324
00325
00326
00327
00328 int db_server_query_bin_array(int sockfd, DB_Handle_t *db_handle)
00329 {
00330 int i, tmp, len,status, comp, n_args;
00331 char *query;
00332 DB_Binary_Result_t *result;
00333 DB_Type_t intype[MAXARG];
00334 void *argin[MAXARG];
00335
00336 status = -1;
00337 if ( Readn(sockfd, &tmp, sizeof(int)) == sizeof(int) )
00338 {
00339
00340 len = ntohl(tmp);
00341 query = malloc(len+1);
00342 XASSERT(query);
00343 Readn(sockfd, query, len);
00344 query[len] = '\0';
00345
00346
00347 comp = Readint(sockfd);
00348
00349
00350 n_args = Readint(sockfd);
00351 for (i=0; i<n_args; i++)
00352 {
00353 argin[i] = (void *)Read_dbtype(&(intype[i]), sockfd);
00354 }
00355
00356
00357 result = db_query_bin_array(db_handle, query, n_args, intype, argin);
00358
00359
00360 for (i=0; i<n_args; i++)
00361 free(argin[i]);
00362
00363
00364 if (result)
00365 {
00366 status = 0;
00367 if (db_send_binary_result(sockfd, result, comp))
00368 {
00369 fprintf(stderr,"Query transmission failed.\n");
00370 status = -1;
00371 }
00372 db_free_binary_result(result);
00373 }
00374 else
00375 {
00376 fprintf(stderr,"Query failed, check query string.\n");
00377
00378
00379
00380
00381
00382
00383 Writeint(sockfd, 0);
00384 }
00385 free(query);
00386 }
00387
00388 return status;
00389 }
00390
00391 int db_server_query_bin_ntuple(int sockfd, DB_Handle_t *db_handle)
00392 {
00393 DB_Binary_Result_t **result = NULL;
00394 DB_Binary_Result_t *exeResult = NULL;
00395 int tmp;
00396 int len;
00397 char *stmnt = NULL;
00398 int nexes;
00399 int nargs;
00400 int iExe;
00401 int iArg;
00402 DB_Type_t dbtypes[MAXARG];
00403 void *values[MAXARG];
00404 char *buffer[MAXARG];
00405 char *pBuf = NULL;
00406 int status = -1;
00407
00408
00409 if (Readn(sockfd, &tmp, sizeof(int)) == sizeof(int))
00410 {
00411
00412 len = ntohl(tmp);
00413 stmnt = calloc(len + 1, sizeof(char));
00414 XASSERT(stmnt);
00415 Readn(sockfd, stmnt, len);
00416
00417
00418 nexes = Readint(sockfd);
00419
00420
00421 nargs = Readint(sockfd);
00422
00423
00424 for (iArg = 0; iArg < nargs; iArg++)
00425 {
00426 dbtypes[iArg] = (DB_Type_t)Readint(sockfd);
00427 }
00428
00429
00430 for (iArg = 0; iArg < nargs; iArg++)
00431 {
00432 if (dbtypes[iArg] == DB_STRING || dbtypes[iArg] == DB_VARCHAR)
00433 {
00434
00435 len = Readint(sockfd);
00436 buffer[iArg] = calloc(len, sizeof(char));
00437 XASSERT(buffer[iArg]);
00438 values[iArg] = calloc(nexes, sizeof(void *));
00439 XASSERT(values[iArg]);
00440
00441
00442 Readn(sockfd, buffer[iArg], len);
00443 pBuf = buffer[iArg];
00444
00445
00446 for (iExe = 0; iExe < nexes; iExe++)
00447 {
00448 ((char **)values[iArg])[iExe] = pBuf;
00449 while(*pBuf)
00450 {
00451 ++pBuf;
00452 }
00453 ++pBuf;
00454 }
00455 }
00456 else
00457 {
00458
00459
00460 buffer[iArg] = NULL;
00461
00462
00463 len = nexes * db_sizeof(dbtypes[iArg]);
00464 values[iArg] = calloc(len, sizeof(char));
00465 XASSERT(values[iArg]);
00466 Readn(sockfd, values[iArg], len);
00467 db_ntoh(dbtypes[iArg], nexes, values[iArg]);
00468 }
00469 }
00470
00471 result = db_query_bin_ntuple(db_handle, stmnt, nexes, nargs, dbtypes, values);
00472
00473 if (result)
00474 {
00475
00476 Writeint(sockfd, nexes);
00477
00478
00479 status = 0;
00480 for (iExe = 0; iExe < nexes; iExe++)
00481 {
00482 exeResult = result[iExe];
00483 if (db_send_binary_result(sockfd, exeResult, 0))
00484 {
00485 fprintf(stderr, "Transmission of binary result failed.\n");
00486 status = -1;
00487 db_free_binary_result(exeResult);
00488
00489
00490 Writeint(sockfd, -1);
00491 break;
00492 }
00493
00494 db_free_binary_result(exeResult);
00495 }
00496 }
00497 else
00498 {
00499 fprintf(stderr, "Prepared statement failed: %s.\n", stmnt);
00500 status = -1;
00501
00502
00503 Writeint(sockfd, -1);
00504 }
00505
00506
00507 free(stmnt);
00508
00509 for (iArg = 0; iArg < nargs; iArg++)
00510 {
00511 if (buffer[iArg])
00512 {
00513 free(buffer[iArg]);
00514 }
00515
00516 if (values[iArg])
00517 {
00518 free(values[iArg]);
00519 }
00520 }
00521 }
00522
00523 return status;
00524 }
00525
00526
00527 int db_server_query_txt(int sockfd, DB_Handle_t *db_handle)
00528 {
00529 int tmp, len, status;
00530 char *query;
00531 DB_Text_Result_t *result;
00532 int comp;
00533
00534 status = -1;
00535 if ( Readn(sockfd, &tmp, sizeof(int)) == sizeof(int) )
00536 {
00537
00538 len = ntohl(tmp);
00539 query = alloca(len+1);
00540 Readn(sockfd, query, len);
00541 query[len] = '\0';
00542
00543
00544 comp = Readint(sockfd);
00545
00546
00547 result = db_query_txt(db_handle, query);
00548
00549
00550 if (result)
00551 {
00552 status = 0;
00553 if (db_send_text_result(sockfd, result, comp))
00554 {
00555 fprintf(stderr,"Query transmission failed.\n");
00556 status = -1;
00557 }
00558 db_free_text_result(result);
00559 }
00560 else
00561 {
00562 fprintf(stderr,"Query failed, check query string.\n");
00563 Writeint(sockfd, -1);
00564 Writeint(sockfd, -1);
00565
00566 if (*db_handle->errmsg)
00567 {
00568 send_string(sockfd, db_handle->errmsg);
00569 }
00570 else
00571 {
00572 send_string(sockfd, "no message");
00573 }
00574 }
00575 }
00576
00577 return status;
00578 }
00579
00580
00581 int db_server_dms(int sockfd, DB_Handle_t *db_handle)
00582 {
00583 int tmp, len, status, row_count;
00584 char *query;
00585
00586 status = -1;
00587 if ( Readn(sockfd, &tmp, sizeof(int)) == sizeof(int) )
00588 {
00589
00590 len = ntohl(tmp);
00591 query = malloc(len+1);
00592 XASSERT(query);
00593 Readn(sockfd, query, len);
00594 query[len] = '\0';
00595
00596 status = db_dms(db_handle, &row_count, query);
00597 db_write_statncnt(sockfd, status, row_count);
00598 free(query);
00599 }
00600
00601 return status;
00602 }
00603
00604
00605 int db_server_dms_array(int sockfd, DB_Handle_t *db_handle)
00606 {
00607 int i,j;
00608 int tmp, len, status, row_count;
00609 char *query, *p, **buffer;
00610 int n_rows, n_args;
00611 void **argin;
00612 DB_Type_t *intype;
00613
00614
00615 status = -1;
00616 if (Readn(sockfd, &tmp, sizeof(int)) == sizeof(int))
00617 {
00618 #ifdef DEBUG
00619 StartTimer(1);
00620 #endif
00621
00622 len = ntohl(tmp);
00623 query = malloc(len+1);
00624 XASSERT(query);
00625 Readn(sockfd, query, len);
00626 query[len] = '\0';
00627
00628
00629 n_rows = Readint(sockfd);
00630 n_args = Readint(sockfd);
00631 intype = malloc(n_args*sizeof(int));
00632 XASSERT(intype);
00633 argin = malloc(n_args*sizeof(void *));
00634 XASSERT(argin);
00635 buffer = malloc(n_args*sizeof(char *));
00636 XASSERT(buffer);
00637 for (i=0; i<n_args; i++)
00638 intype[i] = (DB_Type_t) Readint(sockfd);
00639
00640 for (i=0; i<n_args; i++)
00641 {
00642 if ( intype[i] == DB_STRING || intype[i] == DB_VARCHAR )
00643 {
00644 len = Readint(sockfd);
00645 buffer[i] = malloc(len);
00646 XASSERT(buffer[i]);
00647 argin[i] = malloc(n_rows*sizeof(void *));
00648 XASSERT(argin[i]);
00649
00650 Readn(sockfd, buffer[i], len);
00651 p = buffer[i];
00652 for (j=0; j<n_rows; j++)
00653 {
00654 ((char **)argin[i])[j] = p;
00655 while(*p)
00656 ++p;
00657 ++p;
00658 }
00659 }
00660 else
00661 {
00662 buffer[i] = NULL;
00663 len = n_rows*db_sizeof(intype[i]);
00664 argin[i] = malloc(len);
00665 XASSERT(argin[i]);
00666 Readn(sockfd, argin[i], len);
00667 db_ntoh(intype[i], n_rows, argin[i]);
00668 }
00669 }
00670 #ifdef DEBUG
00671 printf("Time to transfer data = %f.\n",StopTimer(1));
00672 StartTimer(1);
00673 #endif
00674
00675 status = db_dms_array(db_handle, &row_count, query,
00676 n_rows, n_args, intype, argin);
00677 #ifdef DEBUG
00678 printf("Time to perform query = %f.\n",StopTimer(1));
00679 #endif
00680
00681
00682 db_write_statncnt(sockfd, status, row_count);
00683
00684
00685 free(query);
00686 free(intype);
00687 for (i=0; i<n_args; i++)
00688 {
00689 if (buffer[i])
00690 free(buffer[i]);
00691 free(argin[i]);
00692 }
00693 free(buffer);
00694 free(argin);
00695 }
00696
00697 return status;
00698 }
00699
00700
00701 int db_server_bulk_insert_array(int sockfd, DB_Handle_t *db_handle)
00702 {
00703 int i,j;
00704 int tmp, len, status;
00705 char *table, *p, **buffer;
00706 int n_rows, n_args;
00707 void **argin;
00708 DB_Type_t *intype;
00709
00710
00711 status = -1;
00712 if (Readn(sockfd, &tmp, sizeof(int)) == sizeof(int))
00713 {
00714 #ifdef DEBUG
00715 StartTimer(1);
00716 #endif
00717
00718 len = ntohl(tmp);
00719 table = malloc(len+1);
00720 XASSERT(table);
00721 Readn(sockfd, table, len);
00722 table[len] = '\0';
00723
00724
00725 n_rows = Readint(sockfd);
00726 n_args = Readint(sockfd);
00727 intype = malloc(n_args*sizeof(int));
00728 XASSERT(intype);
00729 argin = malloc(n_args*sizeof(void *));
00730 XASSERT(argin);
00731 buffer = malloc(n_args*sizeof(char *));
00732 XASSERT(buffer);
00733 for (i=0; i<n_args; i++)
00734 intype[i] = (DB_Type_t) Readint(sockfd);
00735
00736 for (i=0; i<n_args; i++)
00737 {
00738 if ( intype[i] == DB_STRING || intype[i] == DB_VARCHAR )
00739 {
00740 len = Readint(sockfd);
00741 buffer[i] = malloc(len);
00742 XASSERT(buffer[i]);
00743 argin[i] = malloc(n_rows*sizeof(void *));
00744 XASSERT(argin[i]);
00745
00746 Readn(sockfd, buffer[i], len);
00747 p = buffer[i];
00748 for (j=0; j<n_rows; j++)
00749 {
00750 ((char **)argin[i])[j] = p;
00751 while(*p)
00752 ++p;
00753 ++p;
00754 }
00755 }
00756 else
00757 {
00758 buffer[i] = NULL;
00759 len = n_rows*db_sizeof(intype[i]);
00760 argin[i] = malloc(len);
00761 XASSERT(argin[i]);
00762 Readn(sockfd, argin[i], len);
00763 db_ntoh(intype[i], n_rows, argin[i]);
00764 }
00765 }
00766 #ifdef DEBUG
00767 printf("Time to transfer data = %f.\n",StopTimer(1));
00768 StartTimer(1);
00769 #endif
00770
00771 status = db_bulk_insert_array(db_handle, table,
00772 n_rows, n_args, intype, argin);
00773 #ifdef DEBUG
00774 printf("Time to perform query = %f.\n",StopTimer(1));
00775 #endif
00776
00777
00778 Writeint(sockfd, status);
00779
00780
00781 free(table);
00782 free(intype);
00783 for (i=0; i<n_args; i++)
00784 {
00785 if (buffer[i])
00786 free(buffer[i]);
00787 if (argin[i])
00788 free(argin[i]);
00789 }
00790 free(buffer);
00791 free(argin);
00792 }
00793
00794 return status;
00795 }
00796
00797
00798
00799 int db_server_sequence_drop(int sockfd, DB_Handle_t *db_handle)
00800 {
00801 int status;
00802 char *table;
00803
00804 table = receive_string(sockfd);
00805 status = db_sequence_drop(db_handle, table);
00806 Writeint(sockfd, status);
00807 free(table);
00808 return status;
00809 }
00810
00811 int db_server_sequence_create(int sockfd, DB_Handle_t *db_handle)
00812 {
00813 int status;
00814 char *table;
00815
00816 table = receive_string(sockfd);
00817 status = db_sequence_create(db_handle, table);
00818 Writeint(sockfd, status);
00819 free(table);
00820 return status;
00821 }
00822
00823
00824 int db_server_sequence_getnext(int sockfd, DB_Handle_t *db_handle)
00825 {
00826 char *table;
00827 long long id;
00828
00829 table = receive_string(sockfd);
00830 id = db_sequence_getnext(db_handle, table);
00831 Writelonglong(sockfd, id);
00832 free(table);
00833 if (id == -1LL)
00834 return 1;
00835 else
00836 return 0;
00837 }
00838
00839 int db_server_sequence_getnext_n(int sockfd, DB_Handle_t *db_handle)
00840 {
00841 char *table;
00842 int i,n, status;
00843 long long *seqnums;
00844 struct iovec vec[2];
00845
00846
00847 table = receive_string(sockfd);
00848 n = Readint(sockfd);
00849 if ((seqnums = db_sequence_getnext_n(db_handle, table, n)) == NULL)
00850 {
00851 status = 1;
00852 Writeint(sockfd, status);
00853 }
00854 else
00855 {
00856 int tmp;
00857 status = 0;
00858 tmp = htonl(status);
00859 vec[0].iov_len = sizeof(int);
00860 vec[0].iov_base = &tmp;
00861 for (i=0; i<n; i++)
00862 seqnums[i] = htonll( seqnums[i] );
00863 vec[1].iov_len = n*sizeof(long long);
00864 vec[1].iov_base = seqnums;
00865 Writevn(sockfd, vec, 2);
00866 free(seqnums);
00867 }
00868 free(table);
00869 return status;
00870 }
00871
00872 int db_server_sequence_getcurrent(int sockfd, DB_Handle_t *db_handle)
00873 {
00874 char *table;
00875
00876 table = receive_string(sockfd);
00877 Writelonglong(sockfd, db_sequence_getcurrent(db_handle, table));
00878 free(table);
00879 return 0;
00880 }
00881
00882 int db_server_sequence_getlast(int sockfd, DB_Handle_t *db_handle)
00883 {
00884 char *table;
00885
00886 table = receive_string(sockfd);
00887 Writelonglong(sockfd, db_sequence_getlast(db_handle, table));
00888 free(table);
00889 return 0;
00890 }