lib_sql.cc 18.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright (c)  2000
 * SWsoft  company
 *
 * This material is provided "as is", with absolutely no warranty expressed
 * or implied. Any use is at your own risk.
 *
 * Permission to use or copy this software for any purpose is hereby granted 
 * without fee, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
14 15 16

  This code was modified by the MySQL team
*/
17

18 19 20 21
/*
  The following is needed to not cause conflicts when we include mysqld.cc
*/

22 23 24 25
#define main main1
#define mysql_unix_port mysql_inix_port1
#define mysql_port mysql_port1

26 27 28 29 30
extern "C"
{
  unsigned long max_allowed_packet, net_buffer_length;
}

hf@genie.(none)'s avatar
hf@genie.(none) committed
31 32 33 34
static int fake_argc= 1;
static char *fake_argv[]= {(char *)"", 0};
static const char *fake_groups[] = { "server", "embedded", 0 };

35 36 37
#if defined (__WIN__)
#include "../sql/mysqld.cpp"
#else
38
#include "../sql/mysqld.cc"
39
#endif
40

hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
41 42 43
int check_user(THD *thd, enum enum_server_command command, 
	       const char *passwd, uint passwd_len, const char *db,
	       bool check_count);
44
C_MODE_START
45
#include <mysql.h>
hf@deer.(none)'s avatar
hf@deer.(none) committed
46
#undef ER
47
#include "errmsg.h"
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
48
#include <sql_common.h>
49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
void embedded_get_error(MYSQL *mysql)
{
  THD *thd=(THD *) mysql->thd;
  NET *net= &mysql->net;
  if ((net->last_errno= thd->net.last_errno))
  {
    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
  }
  else
  {
    net->last_error[0]= 0;
    strmov(net->sqlstate, not_error_sqlstate);
  }
}

66
static my_bool
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
67 68 69
emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
		     const char *header, ulong header_length,
		     const char *arg, ulong arg_length, my_bool skip_check)
70
{
71
  my_bool result= 1;
72
  THD *thd=(THD *) mysql->thd;
hf@deer.(none)'s avatar
hf@deer.(none) committed
73
  NET *net= &mysql->net;
74 75 76 77

  /* Check that we are calling the client functions in right order */
  if (mysql->status != MYSQL_STATUS_READY)
  {
hf@deer.(none)'s avatar
hf@deer.(none) committed
78 79
    strmov(net->last_error,
	   ER(net->last_errno=CR_COMMANDS_OUT_OF_SYNC));
80 81 82 83
    return 1;
  }

  /* Clear result variables */
84
  thd->clear_error();
85
  mysql->affected_rows= ~(my_ulonglong) 0;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
86
  mysql->field_count= 0;
87

88
  thd->store_globals();				// Fix if more than one connect
hf@deer.(none)'s avatar
hf@deer.(none) committed
89 90 91 92 93 94
  /* 
     We have to call free_old_query before we start to fill mysql->fields 
     for new query. In the case of embedded server we collect field data
     during query execution (not during data retrieval as it is in remote
     client). So we have to call free_old_query here
  */
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
95
  free_old_query(mysql);
hf@deer.(none)'s avatar
hf@deer.(none) committed
96 97 98 99

  thd->extra_length= arg_length;
  thd->extra_data= (char *)arg;
  if (header)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
100 101 102 103 104
  {
    arg= header;
    arg_length= header_length;
  }

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
105
  result= dispatch_command(command, thd, (char *) arg, arg_length + 1);
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
106

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
107
  if (!skip_check)
108
    result= thd->net.last_errno ? -1 : 0;
109

110
  embedded_get_error(mysql);
hf@deer.(none)'s avatar
hf@deer.(none) committed
111
  mysql->server_status= thd->server_status;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
112
  mysql->warning_count= ((THD*)mysql->thd)->total_warn_count;
113
  return result;
114 115
}

116
static MYSQL_DATA *
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
117
emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
118
	      unsigned int fields __attribute__((unused)))
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
119 120 121
{
  MYSQL_DATA *result= ((THD*)mysql->thd)->data;
  if (!result)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
122 123 124 125 126 127 128 129 130 131 132 133
  {
    if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
					 MYF(MY_WME | MY_ZEROFILL))))
    {
      NET *net = &mysql->net;
      net->last_errno=CR_OUT_OF_MEMORY;
      strmov(net->sqlstate, unknown_sqlstate);
      strmov(net->last_error,ER(net->last_errno));
      return NULL;
    }    
    return result;
  }
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
134 135 136 137 138
  *result->prev_ptr= NULL;
  ((THD*)mysql->thd)->data= NULL;
  return result;
}

139
static MYSQL_FIELD *emb_list_fields(MYSQL *mysql)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
140 141 142 143
{
  return mysql->fields;
}

144
static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
145 146
{
  THD *thd= (THD*)mysql->thd;
hf@deer.(none)'s avatar
hf@deer.(none) committed
147 148
  if (mysql->net.last_errno)
    return 1;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
149 150 151 152 153 154 155 156 157 158 159
  stmt->stmt_id= thd->client_stmt_id;
  stmt->param_count= thd->client_param_count;
  stmt->field_count= mysql->field_count;

  if (stmt->field_count != 0)
  {
    if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
      mysql->server_status|= SERVER_STATUS_IN_TRANS;

    stmt->fields= mysql->fields;
    stmt->mem_root= mysql->field_alloc;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
160
    mysql->fields= NULL;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
161
  }
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
162

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
163 164 165 166 167 168 169 170 171
  return 0;
}

/**************************************************************************
  Get column lengths of the current row
  If one uses mysql_use_result, res->lengths contains the length information,
  else the lengths are calculated from the offset between pointers.
**************************************************************************/

172 173
static void emb_fetch_lengths(ulong *to, MYSQL_ROW column,
			      unsigned int field_count)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
174 175 176 177 178 179 180
{ 
  MYSQL_ROW end;

  for (end=column + field_count; column != end ; column++,to++)
    *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0;
}

181
static my_bool emb_mysql_read_query_result(MYSQL *mysql)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
182 183 184 185 186 187 188 189 190 191
{
  if (mysql->net.last_errno)
    return -1;

  if (mysql->field_count)
    mysql->status=MYSQL_STATUS_GET_RESULT;

  return 0;
}

192
static int emb_stmt_execute(MYSQL_STMT *stmt)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
193 194 195 196
{
  DBUG_ENTER("emb_stmt_execute");
  THD *thd= (THD*)stmt->mysql->thd;
  thd->client_param_count= stmt->param_count;
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
197
  thd->client_params= stmt->params;
hf@deer.(none)'s avatar
hf@deer.(none) committed
198 199 200 201 202
  if (thd->data)
  {
    free_rows(thd->data);
    thd->data= 0;
  }
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
203
  if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
204 205 206
			   (const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),
			   1) ||
      emb_mysql_read_query_result(stmt->mysql))
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
207 208 209 210 211
  {
    NET *net= &stmt->mysql->net;
    set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
    DBUG_RETURN(1);
  }
212 213
  stmt->affected_rows= stmt->mysql->affected_rows;
  stmt->insert_id= stmt->mysql->insert_id;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
214 215 216
  DBUG_RETURN(0);
}

217
int emb_read_binary_rows(MYSQL_STMT *stmt)
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
218
{
219 220 221 222 223 224
  MYSQL_DATA *data;
  if (!(data= emb_read_rows(stmt->mysql, 0, 0)))
    return 1;
  stmt->result= *data;
  my_free((char *) data, MYF(0));
  return 0;
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
225 226
}

227
int emb_unbuffered_fetch(MYSQL *mysql, char **row)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
{
  MYSQL_DATA *data= ((THD*)mysql->thd)->data;
  if (!data || !data->data)
  {
    *row= NULL;
    if (data)
    {
      free_rows(data);
      ((THD*)mysql->thd)->data= NULL;
    }
  }
  else
  {
    *row= (char *)data->data->data;
    data->data= data->data->next;
  }
  return 0;
}

247
static void emb_free_embedded_thd(MYSQL *mysql)
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
248 249 250 251
{
  THD *thd= (THD*)mysql->thd;
  if (thd->data)
    free_rows(thd->data);
hf@deer.(none)'s avatar
hf@deer.(none) committed
252
  thread_count--;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
253
  delete thd;
254
  mysql->thd=0;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
255 256
}

konstantin@oak.local's avatar
Rename:  
konstantin@oak.local committed
257
static const char * emb_read_statistics(MYSQL *mysql)
hf@deer.(none)'s avatar
hf@deer.(none) committed
258 259 260 261 262
{
  THD *thd= (THD*)mysql->thd;
  return thd->net.last_error;
}

263 264 265 266 267 268

static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql)
{
  return mysql_store_result(mysql);
}

monty@mysql.com's avatar
monty@mysql.com committed
269
my_bool emb_next_result(MYSQL *mysql)
270 271 272 273 274
{
  THD *thd= (THD*)mysql->thd;
  DBUG_ENTER("emb_next_result");

  if (emb_advanced_command(mysql, COM_QUERY,0,0,
275 276
			   thd->query_rest.ptr(),thd->query_rest.length(),1) ||
      emb_mysql_read_query_result(mysql))
277 278 279 280
    DBUG_RETURN(1);

  DBUG_RETURN(0);				/* No more results */
}
281

282 283 284 285 286 287 288
int emb_read_change_user_result(MYSQL *mysql, 
				char *buff __attribute__((unused)),
				const char *passwd __attribute__((unused)))
{
  return mysql_errno(mysql);
}

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
289 290 291 292 293
MYSQL_METHODS embedded_methods= 
{
  emb_mysql_read_query_result,
  emb_advanced_command,
  emb_read_rows,
294
  emb_mysql_store_result,
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
295 296
  emb_fetch_lengths, 
  emb_list_fields,
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
297
  emb_read_prepare_result,
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
298
  emb_stmt_execute,
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
299
  emb_read_binary_rows,
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
300
  emb_unbuffered_fetch,
hf@deer.(none)'s avatar
hf@deer.(none) committed
301
  emb_free_embedded_thd,
konstantin@oak.local's avatar
Rename:  
konstantin@oak.local committed
302
  emb_read_statistics,
303 304
  emb_next_result,
  emb_read_change_user_result
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
305 306
};

307
C_MODE_END
308

309
void THD::clear_error()
310
{
311 312 313
  net.last_error[0]= 0;
  net.last_errno= 0;
  net.report_error= 0;
314 315
}

316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
/*
  Make a copy of array and the strings array points to
*/

char **copy_arguments(int argc, char **argv)
{
  uint length= 0;
  char **from, **res, **end= argv+argc;

  for (from=argv ; from != end ; from++)
    length+= strlen(*from);

  if ((res= (char**) my_malloc(sizeof(argv)*(argc+1)+length+argc,
			       MYF(MY_WME))))
  {
    char **to= res, *to_str= (char*) (res+argc+1);
    for (from=argv ; from != end ;)
    {
      *to++= to_str;
      to_str= strmov(to_str, *from++)+1;
    }
    *to= 0;					// Last ptr should be null
  }
  return res;
}


343 344 345
extern "C"
{

346
char **		copy_arguments_ptr= 0; 
347

348
int init_embedded_server(int argc, char **argv, char **groups)
hf@genie.(none)'s avatar
hf@genie.(none) committed
349
{
monty@mysql.com's avatar
monty@mysql.com committed
350 351 352 353
  /*
    This mess is to allow people to call the init function without
    having to mess with a fake argv
   */
hf@genie.(none)'s avatar
hf@genie.(none) committed
354 355 356 357 358 359 360
  int *argcp;
  char ***argvp;
  int fake_argc = 1;
  char *fake_argv[] = { (char *)"", 0 };
  const char *fake_groups[] = { "server", "embedded", 0 };
  if (argc)
  {
361 362
    argcp= &argc;
    argvp= (char***) &argv;
hf@genie.(none)'s avatar
hf@genie.(none) committed
363 364 365
  }
  else
  {
366 367
    argcp= &fake_argc;
    argvp= (char ***) &fake_argv;
hf@genie.(none)'s avatar
hf@genie.(none) committed
368 369
  }
  if (!groups)
370
    groups= (char**) fake_groups;
hf@genie.(none)'s avatar
hf@genie.(none) committed
371

372
  my_progname= (char *)"mysql_embedded";
hf@genie.(none)'s avatar
hf@genie.(none) committed
373

hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
374
  if (init_common_variables("my", *argcp, *argvp, (const char **)groups))
hf@genie.(none)'s avatar
hf@genie.(none) committed
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
  {
    mysql_server_end();
    return 1;
  }
    
  /* Get default temporary directory */
  opt_mysql_tmpdir=getenv("TMPDIR");	/* Use this if possible */
#if defined( __WIN__) || defined(OS2)
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir=getenv("TEMP");
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir=getenv("TMP");
#endif
  if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
    opt_mysql_tmpdir=(char*) P_tmpdir;		/* purecov: inspected */

  umask(((~my_umask) & 0666));
  if (init_server_components())
  {
    mysql_server_end();
    return 1;
  }

  error_handler_hook = my_message_sql;

hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
400
#ifndef NO_EMBEDDED_ACCESS_CHECKS
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
401
  if (acl_init((THD *)0, opt_noacl))
hf@genie.(none)'s avatar
hf@genie.(none) committed
402 403 404 405 406
  {
    mysql_server_end();
    return 1;
  }
  if (!opt_noacl)
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
407
    (void) grant_init((THD *)0);
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
408 409 410

#endif

hf@genie.(none)'s avatar
hf@genie.(none) committed
411 412 413 414
  init_max_user_conn();
  init_update_queries();

#ifdef HAVE_DLOPEN
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
415
#ifndef NO_EMBEDDED_ACCESS_CHECKS
hf@genie.(none)'s avatar
hf@genie.(none) committed
416
  if (!opt_noacl)
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
417
#endif
hf@genie.(none)'s avatar
hf@genie.(none) committed
418 419 420 421 422 423 424
    udf_init();
#endif

  (void) thr_setconcurrency(concurrency);	// 10 by default

  if (
#ifdef HAVE_BERKELEY_DB
425
      (have_berkeley_db == SHOW_OPTION_YES) ||
hf@genie.(none)'s avatar
hf@genie.(none) committed
426 427 428 429 430 431 432 433
#endif
      (flush_time && flush_time != ~(ulong) 0L))
  {
    pthread_t hThread;
    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
      sql_print_error("Warning: Can't create thread to manage maintenance");
  }

hf@deer.(none)'s avatar
hf@deer.(none) committed
434 435 436 437 438 439 440 441 442
  if (opt_init_file)
  {
    if (read_init_file(opt_init_file))
    {
      mysql_server_end();
      return 1;
    }
  }

hf@genie.(none)'s avatar
hf@genie.(none) committed
443 444 445 446 447 448 449 450 451 452 453
  /*
    Update mysqld variables from client variables if set
    The client variables are set also by get_one_option() in mysqld.cc
  */
  if (max_allowed_packet)
    global_system_variables.max_allowed_packet= max_allowed_packet;
  if (net_buffer_length)
    global_system_variables.net_buffer_length= net_buffer_length;
  return 0;
}

454
void end_embedded_server()
455
{
456 457
  my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
  copy_arguments_ptr=0;
458
  clean_up(0);
tim@black.box's avatar
tim@black.box committed
459 460
}

461
} /* extern "C" */
462

463
C_MODE_START
464 465
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db)
{
466
  THD *thd = (THD *)mysql->thd;
467
  thd->mysql= mysql;
hf@deer.(none)'s avatar
hf@deer.(none) committed
468
  mysql->server_version= server_version;
469
}
470

471
void *create_embedded_thd(int client_flag, char *db)
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
{
  THD * thd= new THD;
  thd->thread_id= thread_id++;

  if (thd->store_globals())
  {
    fprintf(stderr,"store_globals failed.\n");
    return NULL;
  }

  thd->mysys_var= my_thread_var;
  thd->dbug_thread_id= my_thread_id();
  thd->thread_stack= (char*) &thd;

  thd->proc_info=0;				// Remove 'login'
  thd->command=COM_SLEEP;
  thd->version=refresh_version;
  thd->set_time();
  init_sql_alloc(&thd->mem_root,8192,8192);
  thd->client_capabilities= client_flag;

  thd->db= db;
hf@bison.(none)'s avatar
hf@bison.(none) committed
494
  thd->db_length= db ? strip_sp(db) : 0;
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
495
#ifndef NO_EMBEDDED_ACCESS_CHECKS
496 497
  thd->db_access= DB_ACLS;
  thd->master_access= ~NO_ACCESS;
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
498
#endif
499
  thd->net.query_cache_query= 0;
500

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
501 502
  thd->data= 0;

hf@deer.(none)'s avatar
hf@deer.(none) committed
503
  thread_count++;
504 505
  return thd;
}
506

507 508 509 510 511 512
#ifdef NO_EMBEDDED_ACCESS_CHECKS
int check_embedded_connection(MYSQL *mysql)
{
  THD *thd= (THD*)mysql->thd;
  thd->host= (char*)my_localhost;
  thd->host_or_ip= thd->host;
hf@deer.(none)'s avatar
hf@deer.(none) committed
513
  thd->user= my_strdup(mysql->user, MYF(0));
514
  return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
515 516 517
}

#else
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
518 519 520 521 522 523 524
int check_embedded_connection(MYSQL *mysql)
{
  THD *thd= (THD*)mysql->thd;
  int result;
  char scramble_buff[SCRAMBLE_LENGTH];
  int passwd_len;

525 526
  if (mysql->options.client_ip)
  {
hf@deer.(none)'s avatar
hf@deer.(none) committed
527 528
    thd->host= my_strdup(mysql->options.client_ip, MYF(0));
    thd->ip= my_strdup(thd->host, MYF(0));
529 530 531
  }
  else
    thd->host= (char*)my_localhost;
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
532 533 534 535 536 537 538 539
  thd->host_or_ip= thd->host;

  if (acl_check_host(thd->host,thd->ip))
  {
    result= ER_HOST_NOT_PRIVILEGED;
    goto err;
  }

hf@deer.(none)'s avatar
hf@deer.(none) committed
540
  thd->user= my_strdup(mysql->user, MYF(0));
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
  if (mysql->passwd && mysql->passwd[0])
  {
    memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
    thd->scramble[SCRAMBLE_LENGTH]= 0;
    scramble(scramble_buff, thd->scramble, mysql->passwd);
    passwd_len= SCRAMBLE_LENGTH;
  }
  else
    passwd_len= 0;

  if((result= check_user(thd, COM_CONNECT, 
			 scramble_buff, passwd_len, thd->db, true)))
     goto err;

  return 0;
err:
  {
    NET *net= &mysql->net;
    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
  }
  return result;
}
#endif

566
C_MODE_END
567

hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
568 569 570 571
bool Protocol::send_fields(List<Item> *list, uint flag)
{
  List_iterator_fast<Item> it(*list);
  Item                     *item;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
572
  MYSQL_FIELD              *client_field;
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
573
  MYSQL                    *mysql= thd->mysql;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
574
  MEM_ROOT                 *field_alloc;
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
575
  
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
576
  DBUG_ENTER("send_fields");
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
577

hf@deer.(none)'s avatar
hf@deer.(none) committed
578 579 580
  if (!mysql)            // bootstrap file handling
    DBUG_RETURN(0);

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
581
  field_count= list->elements;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
582 583 584 585
  field_alloc= &mysql->field_alloc;
  if (!(client_field= thd->mysql->fields= 
	(MYSQL_FIELD *)alloc_root(field_alloc, 
				  sizeof(MYSQL_FIELD) * field_count)))
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
586 587 588 589 590 591 592
    goto err;

  while ((item= it++))
  {
    Send_field server_field;
    item->make_field(&server_field);

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
593 594 595 596 597
    client_field->db=	  strdup_root(field_alloc, server_field.db_name);
    client_field->table=  strdup_root(field_alloc, server_field.table_name);
    client_field->name=   strdup_root(field_alloc, server_field.col_name);
    client_field->org_table= strdup_root(field_alloc, server_field.org_table_name);
    client_field->org_name=  strdup_root(field_alloc, server_field.org_col_name);
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
598 599 600 601
    client_field->length= server_field.length;
    client_field->type=   server_field.type;
    client_field->flags= server_field.flags;
    client_field->decimals= server_field.decimals;
602 603 604 605 606 607
    client_field->db_length=		strlen(client_field->db);
    client_field->table_length=		strlen(client_field->table);
    client_field->name_length=		strlen(client_field->name);
    client_field->org_name_length=	strlen(client_field->org_name);
    client_field->org_table_length=	strlen(client_field->org_table);
    client_field->charsetnr=		server_field.charsetnr;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
608 609 610

    client_field->catalog= strdup_root(field_alloc, "std");
    client_field->catalog_length= 3;
611
    
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
612 613 614 615 616 617 618 619 620
    if (INTERNAL_NUM_FIELD(client_field))
      client_field->flags|= NUM_FLAG;

    if (flag & 2)
    {
      char buff[80];
      String tmp(buff, sizeof(buff), default_charset_info), *res;

      if (!(res=item->val_str(&tmp)))
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
621 622
      {
	client_field->def_length= 0;
623
	client_field->def= strmake_root(field_alloc, "",0);
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
624
      }
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
625
      else
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
626
      {
627
	client_field->def_length= res->length();
628 629
	client_field->def= strmake_root(field_alloc, res->ptr(),
					client_field->def_length);
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
630
      }
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
631 632 633 634 635 636
    }
    else
      client_field->def=0;
    client_field->max_length= 0;
    ++client_field;
  }
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
637
  thd->mysql->field_count= field_count;
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
638

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
639
  DBUG_RETURN(prepare_for_send(list));
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
640 641
 err:
  send_error(thd, ER_OUT_OF_RESOURCES);	/* purecov: inspected */
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
642
  DBUG_RETURN(1);				/* purecov: inspected */
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
643 644
}

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
645
bool Protocol::send_records_num(List<Item> *list, ulonglong records)
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
646 647 648 649
{
  return false;
}

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
650
bool Protocol::write()
hf@genie.(none)'s avatar
hf@genie.(none) committed
651
{
hf@deer.(none)'s avatar
hf@deer.(none) committed
652 653 654
  if (!thd->mysql)            // bootstrap file handling
    return false;

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
655 656
  *next_field= 0;
  return false;
hf@genie.(none)'s avatar
hf@genie.(none) committed
657
}
658

hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
bool Protocol_prep::write()
{
  MYSQL_ROWS *cur;
  MYSQL_DATA *data= thd->data;

  if (!data)
  {
    if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
					MYF(MY_WME | MY_ZEROFILL))))
      return true;
    
    alloc= &data->alloc;
    init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
    alloc->min_malloc=sizeof(MYSQL_ROWS);
    data->rows=0;
    data->fields=field_count;
    data->prev_ptr= &data->data;
    thd->data= data;
  }

  data->rows++;
  if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+packet->length())))
  {
    my_error(ER_OUT_OF_RESOURCES,MYF(0));
    return true;
  }
  cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
686
  memcpy(cur->data, packet->ptr()+1, packet->length()-1);
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
687 688 689

  *data->prev_ptr= cur;
  data->prev_ptr= &cur->next;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
690 691
  cur->next= 0;
  
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
692 693 694
  return false;
}

695
void
696
send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
697 698 699
{
  DBUG_ENTER("send_ok");
  MYSQL *mysql= current_thd->mysql;
hf@deer.(none)'s avatar
hf@deer.(none) committed
700 701
  if (!mysql)            // bootstrap file handling
    DBUG_VOID_RETURN;
702 703 704
  mysql->affected_rows= affected_rows;
  mysql->insert_id= id;
  if (message)
705
  {
706
    strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
707 708
    mysql->info= thd->net.last_error;
  }
709 710 711
  DBUG_VOID_RETURN;
}

712 713 714 715 716
void
send_eof(THD *thd, bool no_flush)
{
}

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
717 718
void Protocol_simple::prepare_for_resend()
{
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
719 720
  MYSQL_ROWS *cur;
  MYSQL_DATA *data= thd->data;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
721 722 723

  DBUG_ENTER("send_data");

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
  if (!data)
  {
    if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
					MYF(MY_WME | MY_ZEROFILL))))
      goto err;
    
    alloc= &data->alloc;
    init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
    alloc->min_malloc=sizeof(MYSQL_ROWS);
    data->rows=0;
    data->fields=field_count;
    data->prev_ptr= &data->data;
    thd->data= data;
  }

  data->rows++;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
740 741 742 743 744 745 746
  if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
  {
    my_error(ER_OUT_OF_RESOURCES,MYF(0));
    DBUG_VOID_RETURN;
  }
  cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
747 748
  *data->prev_ptr= cur;
  data->prev_ptr= &cur->next;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
749
  next_field=cur->data;
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
750 751
  next_mysql_field= thd->mysql->fields;
err:
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
752 753 754
  DBUG_VOID_RETURN;
}

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
755 756 757 758 759 760 761
bool Protocol_simple::store_null()
{
  *(next_field++)= NULL;
  ++next_mysql_field;
  return false;
}

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
762 763
bool Protocol::net_store_data(const char *from, uint length)
{
hf@deer.(none)'s avatar
hf@deer.(none) committed
764
  char *field_buf;
hf@deer.(none)'s avatar
hf@deer.(none) committed
765 766 767
  if (!thd->mysql)            // bootstrap file handling
    return false;

hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
768
  if (!(field_buf=alloc_root(alloc, length + sizeof(uint) + 1)))
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
769
    return true;
hf@deer.(none)'s avatar
hf@deer.(none) committed
770 771
  *(uint *)field_buf= length;
  *next_field= field_buf + sizeof(uint);
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
772
  memcpy(*next_field, from, length);
hf@deer.(none)'s avatar
SCRUM  
hf@deer.(none) committed
773
  (*next_field)[length]= 0;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
774 775 776 777 778 779 780
  if (next_mysql_field->max_length < length)
    next_mysql_field->max_length=length;
  ++next_field;
  ++next_mysql_field;
  return false;
}

781
#if 0
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
782 783 784 785 786 787 788 789 790 791
/* The same as Protocol::net_store_data but does the converstion
*/
bool Protocol::convert_str(const char *from, uint length)
{
  if (!(*next_field=alloc_root(alloc, length + 1)))
    return true;
  convert->store_dest(*next_field, from, length);
  (*next_field)[length]= 0;
  if (next_mysql_field->max_length < length)
    next_mysql_field->max_length=length;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
792
  ++next_field;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
793 794
  ++next_mysql_field;

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
795 796
  return false;
}
797
#endif
hf@deer.(none)'s avatar
SCRUM:  
hf@deer.(none) committed
798