Anope IRC Services  Version 1.8
mysql.c
Go to the documentation of this file.
1 
2 /* MySQL functions.
3  *
4  * (C) 2003-2014 Anope Team
5  * Contact us at team@anope.org
6  *
7  * Please read COPYING and README for further details.
8  *
9  * Based on the original code of Epona by Lara.
10  * Based on the original code of Services by Andy Church.
11  *
12  *
13  */
14 #include "services.h"
15 
16 /*************************************************************************/
17 
18 /* Database Global Variables */
19 MYSQL *mysql; /* MySQL Handler */
20 MYSQL_RES *mysql_res; /* MySQL Result */
21 MYSQL_FIELD *mysql_fields; /* MySQL Fields */
22 MYSQL_ROW mysql_row; /* MySQL Row */
23 
24 int mysql_is_connected = 0; /* Are we currently connected? */
25 
26 /*************************************************************************/
27 
28 /* Throw a mysql error into the logs. If severity is MYSQL_ERROR, we
29  * also exit Anope...
30  */
31 void db_mysql_error(int severity, char *msg)
32 {
33  static char buf[512];
34 
35  if (mysql_error(mysql)) {
36  snprintf(buf, sizeof(buf), "MySQL %s %s: %s", msg,
37  severity == MYSQL_WARNING ? "warning" : "error",
38  mysql_error(mysql));
39  } else {
40  snprintf(buf, sizeof(buf), "MySQL %s %s", msg,
41  severity == MYSQL_WARNING ? "warning" : "error");
42  }
43 
44  log_perror(buf);
45 
46  if (severity == MYSQL_ERROR) {
47  log_perror("MySQL FATAL error... aborting.");
48  exit(0);
49  }
50 
51 }
52 
53 /*************************************************************************/
54 
55 /* Initialize the MySQL code */
57 {
58 
59  /* If the host is not defined, assume we don't want MySQL */
60  if (!MysqlHost) {
61  do_mysql = 0;
62  alog("MySQL: has been disabled.");
63  return 0;
64  } else {
65  do_mysql = 1;
66  alog("MySQL: has been enabled.");
67  alog("MySQL: client version %s.", mysql_get_client_info());
68  }
69 
70  /* The following configuration options are required.
71  * If missing disable MySQL to avoid any problems.
72  */
73 
74  if ((do_mysql) && (!MysqlName || !MysqlUser)) {
75  do_mysql = 0;
76  alog("MySQL Error: Set all required configuration options.");
77  return 0;
78  }
79 
80  if (!db_mysql_open()) {
81  do_mysql = 0;
82  return 0;
83  }
84 
85  return 1;
86 }
87 
88 /*************************************************************************/
89 
90 /* Open a connection to the mysql database. Return 0 on failure, or
91  * 1 on success. If this succeeds, we're guaranteed of a working
92  * mysql connection (unless something unexpected happens ofcourse...)
93  */
95 {
96  /* If MySQL is disabled, return 0 */
97  if (!do_mysql)
98  return 0;
99 
100  /* If we are reported to be connected, ping MySQL to see if we really are
101  * still connected. (yes mysql_ping() returns 0 on success)
102  */
103  if (mysql_is_connected && !mysql_ping(mysql))
104  return 1;
105 
106  mysql_is_connected = 0;
107 
108  mysql = mysql_init(NULL);
109  if (mysql == NULL) {
110  db_mysql_error(MYSQL_WARNING, "Unable to create mysql object");
111  return 0;
112  }
113 
114  if (!MysqlPort)
115  MysqlPort = MYSQL_DEFAULT_PORT;
116 
117  if (!mysql_real_connect(mysql, MysqlHost, MysqlUser, MysqlPass, MysqlName, MysqlPort, MysqlSock, 0)) {
118  log_perror("MySQL Error: Cant connect to MySQL: %s\n", mysql_error(mysql));
119  return 0;
120  }
121 
122  mysql_is_connected = 1;
123 
124  return 1;
125 
126 }
127 
128 
129 /*************************************************************************/
130 
131 /* Perform a MySQL query. Return 1 if the query succeeded and 0 if the
132  * query failed. Before returning failure, re-try the query a few times
133  * and die if it still fails.
134  */
135 int db_mysql_query(char *sql)
136 {
137  int lcv;
138 
139  if (!do_mysql)
140  return 0;
141 
142  if (debug)
143  alog("debug: MySQL: %s", sql);
144 
145  /* Try as many times as configured in MysqlRetries */
146  for (lcv = 0; lcv < MysqlRetries; lcv++) {
147  if (db_mysql_open() && (mysql_query(mysql, sql) == 0))
148  return 1;
149 
150  /* If we get here, we could not run the query */
151  log_perror("Unable to run query: %s\n", mysql_error(mysql));
152 
153  /* Wait for MysqlRetryGap seconds and try again */
154  sleep(MysqlRetryGap);
155  }
156 
157  /* Unable to run the query even after MysqlRetries tries */
158  db_mysql_error(MYSQL_WARNING, "query");
159 
160  return 0;
161 
162 }
163 
164 /*************************************************************************/
165 
166 /* Quote a string to be safely included in a query. The result of this
167  * function is allocated; it MUST be freed by the caller.
168  */
169 char *db_mysql_quote(char *sql)
170 {
171  int slen;
172  char *quoted;
173 
174 
175  if (!sql)
176  return sstrdup("");
177 
178  slen = strlen(sql);
179  quoted = malloc((1 + (slen * 2)) * sizeof(char));
180 
181  mysql_real_escape_string(mysql, quoted, sql, slen);
182 
183  return quoted;
184 
185 }
186 
191 char *db_mysql_quote_buffer(char *sql, int size)
192 {
193  char *ret;
194  ret = scalloc((1 + 2 * size), sizeof(char));
195 
196  mysql_real_escape_string(mysql, ret, sql, size);
197 
198  return ret;
199 }
200 
201 /*************************************************************************/
202 
203 /* Close the MySQL database connection. */
205 {
206  mysql_close(mysql);
207 
208  mysql_is_connected = 0;
209 
210  return 1;
211 }
212 
213 /*************************************************************************/
214 
215 /* Try to execute a query and issue a warning when failed. Return 1 on
216  * success and 0 on failure.
217  */
218 int db_mysql_try(const char *fmt, ...)
219 {
220  va_list args;
221  static char sql[MAX_SQL_BUF];
222 
223  va_start(args, fmt);
224  vsnprintf(sql, MAX_SQL_BUF, fmt, args);
225  va_end(args);
226 
227  if (!db_mysql_query(sql)) {
228  log_perror("Can't create sql query: %s", sql);
229  db_mysql_error(MYSQL_WARNING, "query");
230  return 0;
231  }
232 
233  return 1;
234 }
235 
236 /*************************************************************************/
237 
248 char *db_mysql_secure(char *pass, int size)
249 {
250  char tmp_pass[PASSMAX];
251  char *str, *tmp;
252  unsigned bufsize = (2 * PASSMAX + 15);
253 
254  if (MysqlSecure)
255  bufsize += strlen(MysqlSecure);
256 
257  /* Initialize the buffer. Bug #86 */
258  memset(tmp_pass, 0, PASSMAX);
259 
260  /* Return all zeros if no pass is set. */
261  if (!pass)
262  return NULL;
263 
264  str = scalloc(bufsize, sizeof(char));
265  if (enc_decrypt(pass, tmp_pass, PASSMAX - 1) != 1) {
266  /* We couldnt decrypt the pass... */
267  /* Make sure the hash is MySQL safe.. */
268  tmp = db_mysql_quote_buffer(pass, size);
269  snprintf(str, bufsize, "'%s'", tmp);
270  free(tmp);
271  } else { /* if we could decrypt the pass */
272  /* Make sure the pass itself pass is MySQL safe.. */
273  tmp = db_mysql_quote_buffer(tmp_pass, strlen(tmp_pass));
274  if ((!MysqlSecure) || (strcmp(MysqlSecure, "") == 0)) {
275  snprintf(str, bufsize, "'%s'", tmp);
276  } else if (strcmp(MysqlSecure, "des") == 0) {
277  snprintf(str, bufsize, "ENCRYPT('%s')", tmp);
278  } else if (strcmp(MysqlSecure, "md5") == 0) {
279  snprintf(str, bufsize, "MD5('%s')", tmp);
280  } else if (strcmp(MysqlSecure, "sha") == 0) {
281  snprintf(str, bufsize, "SHA('%s')", tmp);
282  } else {
283  snprintf(str, bufsize, "ENCODE('%s','%s')", tmp, MysqlSecure);
284  }
285  free(tmp);
286  }
287 
288  return str;
289 }
290 
291 /*************************************************************************/
292 
293 /*
294  * NickServ Specific Secion
295  */
296 
297 /*************************************************************************/
298 
299 /* Save the given NickRequest into the database
300  * Return 1 on success, 0 on failure
301  * These tables are tagged and will be cleaned:
302  * - anope_ns_request
303  */
305 {
306  int ret;
307  char *q_nick, *q_passcode, *q_password, *q_email;
308 
309  q_nick = db_mysql_quote(nr->nick);
310  q_passcode = db_mysql_quote(nr->passcode);
311  q_password = db_mysql_quote_buffer(nr->password, PASSMAX);
312  q_email = db_mysql_quote(nr->email);
313 
314  ret = db_mysql_try("UPDATE anope_ns_request "
315  "SET passcode = '%s', password = '%s', email = '%s', requested = %d, active = 1 "
316  "WHERE nick = '%s'",
317  q_passcode, q_password, q_email, (int) nr->requested,
318  q_nick);
319 
320  if (ret && (mysql_affected_rows(mysql) == 0)) {
321  ret = db_mysql_try("INSERT DELAYED INTO anope_ns_request "
322  "(nick, passcode, password, email, requested, active) "
323  "VALUES ('%s', '%s', '%s', '%s', %d, 1)",
324  q_nick, q_passcode, q_password, q_email,
325  (int) nr->requested);
326  }
327 
328  free(q_nick);
329  free(q_passcode);
330  free(q_password);
331  free(q_email);
332 
333  return ret;
334 }
335 
336 /*************************************************************************/
337 
338 /* Save the given NickCore into the database
339  * Also save the access list and memo's for this user
340  * Return 1 on success, 0 on failure
341  * These tables are tagged and will be cleaned:
342  * - anope_ns_core
343  * - anope_ns_alias
344  * - anope_ns_access
345  * - anope_ms_info (serv='NICK')
346  */
348 {
349  int ret;
350  int i;
351  char *q_display, *q_pass, *q_email, *q_greet, *q_url,
352  *q_access, *q_sender, *q_text;
353 
354  q_display = db_mysql_quote(nc->display);
355  q_email = db_mysql_quote(nc->email);
356  q_greet = db_mysql_quote(nc->greet);
357  q_url = db_mysql_quote(nc->url);
358 
359  /* First secure the pass, then make it MySQL safe.. - Viper */
360  q_pass = db_mysql_secure(nc->pass, PASSMAX);
361  if (!q_pass)
362  fatal("Unable to encrypt password for MySQL");
363 
364  /* Let's take care of the core itself */
365  /* Update the existing records */
366  ret = db_mysql_try("UPDATE anope_ns_core "
367  "SET pass = %s, email = '%s', greet = '%s', icq = %d, url = '%s', flags = %d, language = %d, "
368  "accesscount = %d, memocount = %d, memomax = %d, channelcount = %d, channelmax = %d, active = 1 "
369  "WHERE display = '%s'",
370  q_pass, q_email, q_greet, nc->icq, q_url, nc->flags,
371  nc->language, nc->accesscount, nc->memos.memocount,
372  nc->memos.memomax, nc->channelcount, nc->channelmax,
373  q_display);
374 
375  /* Our previous UPDATE affected no rows, therefore this is a new record */
376  if (ret && (mysql_affected_rows(mysql) == 0))
377  ret = db_mysql_try("INSERT DELAYED INTO anope_ns_core "
378  "(display, pass, email, greet, icq, url, flags, language, accesscount, memocount, memomax, channelcount, channelmax, active) "
379  "VALUES ('%s', %s, '%s', '%s', %d, '%s', %d, %d, %d, %d, %d, %d, %d, 1)",
380  q_display, q_pass, q_email, q_greet, nc->icq, q_url,
381  nc->flags, nc->language, nc->accesscount,
382  nc->memos.memocount, nc->memos.memomax,
383  nc->channelcount, nc->channelmax);
384 
385  /* Now let's do the access */
386  for (i = 0; ret && (i < nc->accesscount); i++) {
387  q_access = db_mysql_quote(nc->access[i]);
396  ret = db_mysql_try("INSERT DELAYED INTO anope_ns_access "
397  "(display, access) "
398  "VALUES ('%s','%s')",
399  q_display, q_access);
400 /* } */
401 
402  free(q_access);
403  }
404 
405  /* Memos */
406  for (i = 0; ret && (i < nc->memos.memocount); i++) {
407  q_sender = db_mysql_quote(nc->memos.memos[i].sender);
408  q_text = db_mysql_quote(nc->memos.memos[i].text);
409 
410  if (nc->memos.memos[i].id != 0)
411  {
412  ret = db_mysql_try("UPDATE anope_ms_info "
413  "SET receiver = '%s', number = %d, flags = %d, time = %d, sender = '%s', text = '%s', active = 1 "
414  "WHERE nm_id = %d AND serv = 'NICK'",
415  q_display, nc->memos.memos[i].number,
416  nc->memos.memos[i].flags,
417  (int) nc->memos.memos[i].time, q_sender, q_text,
418  nc->memos.memos[i].id);
419  }
420  if (nc->memos.memos[i].id == 0 || (ret && (mysql_affected_rows(mysql) == 0))) {
421  ret = db_mysql_try("INSERT INTO anope_ms_info "
422  "(receiver, number, flags, time, sender, text, serv, active) "
423  "VALUES ('%s', %d, %d, %d, '%s', '%s', 'NICK', 1)",
424  q_display, nc->memos.memos[i].number,
425  nc->memos.memos[i].flags,
426  (int) nc->memos.memos[i].time, q_sender,
427  q_text);
428 
429  /* This is to make sure we can UPDATE memos instead of TRUNCATE
430  * the table each time and then INSERT them all again. Ideally
431  * everything in core would have it's dbase-id stored, but that's
432  * something for phase 3. -GD
433  */
434  if (ret)
435  nc->memos.memos[i].id = mysql_insert_id(mysql);
436  }
437 
438  free(q_sender);
439  free(q_text);
440  }
441 
442  free(q_display);
443  free(q_pass);
444  free(q_email);
445  free(q_greet);
446  free(q_url);
447 
448  return ret;
449 }
450 
451 
452 /*************************************************************************/
453 
454 /* Save the given NickAlias into the database
455  * Return 1 on success, 0 on failure
456  * These tables are tagged and will be cleaned:
457  * - anope_ns_core
458  * - anope_ns_alias
459  * - anope_ns_access
460  * - anope_ms_info (serv='NICK')
461  */
463 {
464  int ret;
465  char *q_nick, *q_lastmask, *q_lastrname, *q_lastquit, *q_display;
466 
467  q_nick = db_mysql_quote(na->nick);
468  q_lastmask = db_mysql_quote(na->last_usermask);
469  q_lastrname = db_mysql_quote(na->last_realname);
470  q_lastquit = db_mysql_quote(na->last_quit);
471  q_display = db_mysql_quote(na->nc->display);
472 
473  ret = db_mysql_try("UPDATE anope_ns_alias "
474  "SET last_usermask = '%s', last_realname = '%s', last_quit = '%s', time_registered = %d, last_seen = %d, status = %d, "
475  " display = '%s', active = 1 "
476  "WHERE nick = '%s'",
477  q_lastmask, q_lastrname, q_lastquit,
478  (int) na->time_registered, (int) na->last_seen,
479  (int) na->status, q_display, q_nick);
480 
481  /* Our previous UPDATE affected no rows, therefore this is a new record */
482  if (ret && (mysql_affected_rows(mysql) == 0)) {
483  ret = db_mysql_try("INSERT DELAYED INTO anope_ns_alias "
484  "(nick, last_usermask, last_realname, last_quit, time_registered, last_seen, status, display, active) "
485  "VALUES ('%s', '%s', '%s', '%s', %d, %d, %d, '%s', 1)",
486  q_nick, q_lastmask, q_lastrname, q_lastquit,
487  (int) na->time_registered, (int) na->last_seen,
488  (int) na->status, q_display);
489  }
490 
491  free(q_nick);
492  free(q_lastmask);
493  free(q_lastrname);
494  free(q_lastquit);
495  free(q_display);
496 
497  return ret;
498 }
499 
500 /*************************************************************************/
501 
502 /*
503  * ChanServ Specific Secion
504  */
505 
506 /*************************************************************************/
507 
508 /* Save the given ChannelInfo into the database
509  * Also save the access list, levels, akicks, badwords, ttb, and memo's for this channel
510  * Return 1 on success, 0 on failure
511  * These tables are tagged and will be cleaned:
512  * - anope_cs_info
513  * - anope_cs_access
514  * - anope_cs_levels
515  * - anope_cs_akicks
516  * - anope_cs_badwords
517  * - anope_cs_ttb
518  * - anope_ms_info (serv='CHAN')
519  */
521 {
522  int ret, i;
523  char *q_name;
524  char *q_founder;
525  char *q_successor;
526  char *q_pass;
527  char *q_desc;
528  char *q_url;
529  char *q_email;
530  char *q_lasttopic;
531  char *q_lasttopicsetter;
532  char *q_forbidby;
533  char *q_forbidreason;
534  char *q_mlock_key;
535  char *q_mlock_flood;
536  char *q_mlock_redirect;
537  char *q_entrymsg;
538  char *q_botnick;
539  char *q_sender;
540  char *q_text;
541  char *q_accessdisp;
542  char *q_akickdisp;
543  char *q_akickreason;
544  char *q_akickcreator;
545  char *q_badwords;
546 
547  q_name = db_mysql_quote(ci->name);
548  if (ci->founder) {
549  q_founder = db_mysql_quote(ci->founder->display);
550  } else {
551  q_founder = db_mysql_quote("");
552  }
553  if (ci->successor) {
554  q_successor = db_mysql_quote(ci->successor->display);
555  } else {
556  q_successor = db_mysql_quote("");
557  }
558  q_desc = db_mysql_quote(ci->desc);
559  q_url = db_mysql_quote(ci->url);
560  q_email = db_mysql_quote(ci->email);
561  q_lasttopic = db_mysql_quote(ci->last_topic);
562  q_lasttopicsetter = db_mysql_quote(ci->last_topic_setter);
563  q_forbidby = db_mysql_quote(ci->forbidby);
564  q_forbidreason = db_mysql_quote(ci->forbidreason);
565  q_mlock_key = db_mysql_quote(ci->mlock_key);
566  q_mlock_flood = db_mysql_quote(ci->mlock_flood);
567  q_mlock_redirect = db_mysql_quote(ci->mlock_redirect);
568  q_entrymsg = db_mysql_quote(ci->entry_message);
569  if (ci->bi) {
570  q_botnick = db_mysql_quote(ci->bi->nick);
571  } else {
572  q_botnick = db_mysql_quote("");
573  }
574 
575  /* First secure the pass, then make it MySQL safe.. - Viper */
576  q_pass = db_mysql_secure(ci->founderpass, PASSMAX);
577  if (!q_pass)
578  fatal("Unable to encrypt password for MySQL");
579 
580  /* Let's take care of the core itself */
581  ret = db_mysql_try("UPDATE anope_cs_info "
582  "SET founder = '%s', successor = '%s', founderpass = %s, descr = '%s', url = '%s', email = '%s', time_registered = %d, "
583  " last_used = %d, last_topic = '%s', last_topic_setter = '%s', last_topic_time = %d, flags = %d, forbidby = '%s', "
584  " forbidreason = '%s', bantype = %d, accesscount = %d, akickcount = %d, mlock_on = %d, mlock_off = %d, mlock_limit = %d, "
585  " mlock_key = '%s', mlock_flood = '%s', mlock_redirect = '%s', entry_message = '%s', memomax = %d, botnick = '%s', botflags = %d, "
586  " bwcount = %d, capsmin = %d, capspercent = %d, floodlines = %d, floodsecs = %d, repeattimes = %d, active = 1 "
587  "WHERE name = '%s'",
588  q_founder, q_successor, q_pass, q_desc, q_url, q_email,
589  (int) ci->time_registered, (int) ci->last_used,
590  q_lasttopic, q_lasttopicsetter,
591  (int) ci->last_topic_time, (int) ci->flags, q_forbidby,
592  q_forbidreason, (int) ci->bantype,
593  (int) ci->accesscount, (int) ci->akickcount,
594  (int) ci->mlock_on, (int) ci->mlock_off,
595  (int) ci->mlock_limit, q_mlock_key, q_mlock_flood,
596  q_mlock_redirect, q_entrymsg, (int) ci->memos.memomax,
597  q_botnick, (int) ci->botflags, (int) ci->bwcount,
598  (int) ci->capsmin, (int) ci->capspercent,
599  (int) ci->floodlines, (int) ci->floodsecs,
600  (int) ci->repeattimes, q_name);
601 
602  /* Our previous UPDATE affected no rows, therefore this is a new record */
603  if (ret && (mysql_affected_rows(mysql) == 0))
604  ret = db_mysql_try("INSERT DELAYED INTO anope_cs_info "
605  "(name, founder, successor, founderpass, descr, url, email, time_registered, last_used, last_topic, last_topic_setter, "
606  " last_topic_time, flags, forbidby, forbidreason, bantype, accesscount, akickcount, mlock_on, mlock_off, mlock_limit, "
607  " mlock_key, mlock_flood, mlock_redirect, entry_message, botnick, botflags, bwcount, capsmin, capspercent, floodlines, "
608  " floodsecs, repeattimes, active) "
609  "VALUES ('%s', '%s', '%s', %s, '%s', '%s', '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', %d, %d, %d, %d, %d, %d, '%s', '%s', "
610  " '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, 1)",
611  q_name, q_founder, q_successor, q_pass, q_desc,
612  q_url, q_email, (int) ci->time_registered,
613  (int) ci->last_used, q_lasttopic,
614  q_lasttopicsetter, (int) ci->last_topic_time,
615  (int) ci->flags, q_forbidby, q_forbidreason,
616  (int) ci->bantype, (int) ci->accesscount,
617  (int) ci->akickcount, (int) ci->mlock_on,
618  (int) ci->mlock_off, (int) ci->mlock_limit,
619  q_mlock_key, q_mlock_flood, q_mlock_redirect,
620  q_entrymsg, q_botnick, (int) ci->botflags,
621  (int) ci->bwcount, (int) ci->capsmin,
622  (int) ci->capspercent, (int) ci->floodlines,
623  (int) ci->floodsecs, (int) ci->repeattimes);
624 
625  /* Memos */
626  for (i = 0; ret && (i < ci->memos.memocount); i++) {
627  q_sender = db_mysql_quote(ci->memos.memos[i].sender);
628  q_text = db_mysql_quote(ci->memos.memos[i].text);
629 
630  if (ci->memos.memos[i].id != 0)
631  {
632  ret = db_mysql_try("UPDATE anope_ms_info "
633  "SET receiver = '%s', number = %d, flags = %d, time = %d, sender = '%s', text = '%s', active = 1 "
634  "WHERE nm_id = %d AND serv = 'CHAN'",
635  q_name, ci->memos.memos[i].number,
636  ci->memos.memos[i].flags,
637  (int) ci->memos.memos[i].time, q_sender, q_text,
638  ci->memos.memos[i].id);
639  }
640  if (ci->memos.memos[i].id == 0 || (ret && (mysql_affected_rows(mysql) == 0))) {
641  ret = db_mysql_try("INSERT INTO anope_ms_info "
642  "(receiver, number,flags, time, sender, text, serv, active) "
643  "VALUES ('%s', %d, %d, %d, '%s', '%s', 'CHAN', 1)",
644  q_name, ci->memos.memos[i].number,
645  ci->memos.memos[i].flags,
646  (int) ci->memos.memos[i].time, q_sender,
647  q_text);
648 
649  /* See comment at db_mysql_save_ns_core */
650  if (ret)
651  ci->memos.memos[i].id = mysql_insert_id(mysql);
652  }
653 
654  free(q_sender);
655  free(q_text);
656  }
657 
658  /* Access */
659  for (i = 0; ret && (i < ci->accesscount); i++) {
660  if (ci->access[i].in_use) {
661  q_accessdisp = db_mysql_quote(ci->access[i].nc->display);
662 
663  ret = db_mysql_try("UPDATE anope_cs_access "
664  "SET in_use = %d, level = %d, last_seen = %d, active = 1 "
665  "WHERE channel = '%s' AND display = '%s'",
666  (int) ci->access[i].in_use,
667  (int) ci->access[i].level,
668  (int) ci->access[i].last_seen,
669  q_name, q_accessdisp);
670 
671  if (ret && (mysql_affected_rows(mysql) == 0)) {
672  ret = db_mysql_try("INSERT DELAYED INTO anope_cs_access "
673  "(channel, display, in_use, level, last_seen, active) "
674  "VALUES ('%s', '%s', %d, %d, %d, 1)",
675  q_name, q_accessdisp,
676  (int) ci->access[i].in_use,
677  (int) ci->access[i].level,
678  (int) ci->access[i].last_seen);
679  }
680 
681  free(q_accessdisp);
682  }
683  }
684 
685  /* Levels */
686  for (i = 0; ret && (i < CA_SIZE); i++) {
687  ret = db_mysql_try("UPDATE anope_cs_levels "
688  "SET level = %d, active = 1 "
689  "WHERE channel = '%s' AND position = %d",
690  (int) ci->levels[i], q_name, i);
691 
692  if (ret && (mysql_affected_rows(mysql) == 0)) {
693  ret = db_mysql_try("INSERT DELAYED INTO anope_cs_levels "
694  "(channel, position, level, active) "
695  "VALUES ('%s', %d, %d, 1)",
696  q_name, i, (int) ci->levels[i]);
697  }
698  }
699 
700  /* Akicks */
701  for (i = 0; ret && (i < ci->akickcount); i++) {
702  if (ci->akick[i].flags & AK_USED) {
703  if (ci->akick[i].flags & AK_ISNICK)
704  q_akickdisp = db_mysql_quote(ci->akick[i].u.nc->display);
705  else
706  q_akickdisp = db_mysql_quote(ci->akick[i].u.mask);
707 
708  q_akickreason = db_mysql_quote(ci->akick[i].reason);
709  q_akickcreator = db_mysql_quote(ci->akick[i].creator);
710  } else {
711  q_akickdisp = "";
712  q_akickreason = "";
713  q_akickcreator = "";
714  }
715 
716  ret = db_mysql_try("UPDATE anope_cs_akicks "
717  "SET flags = %d, reason = '%s', creator = '%s', addtime = %d, active = 1 "
718  "WHERE channel = '%s' AND dmask = '%s'",
719  (int) ci->akick[i].flags, q_akickreason,
720  q_akickcreator, (ci->akick[i].flags & AK_USED ?
721  (int) ci->akick[i].addtime : 0),
722  q_name, q_akickdisp);
723 
724  if (ret && (mysql_affected_rows(mysql) == 0)) {
725  ret = db_mysql_try("INSERT DELAYED INTO anope_cs_akicks "
726  "(channel, dmask, flags, reason, creator, addtime, active) "
727  "VALUES ('%s', '%s', %d, '%s', '%s', %d, 1)",
728  q_name, q_akickdisp, (int) ci->akick[i].flags,
729  q_akickreason, q_akickcreator,
730  (ci->akick[i].flags & AK_USED ?
731  (int) ci->akick[i].addtime : 0));
732  }
733 
734  if (ci->akick[i].flags & AK_USED) {
735  free(q_akickdisp);
736  free(q_akickreason);
737  free(q_akickcreator);
738  }
739  }
740 
741  /* Bad Words */
742  for (i = 0; ret && (i < ci->bwcount); i++) {
743  if (ci->badwords[i].in_use) {
744  q_badwords = db_mysql_quote(ci->badwords[i].word);
745 
746  ret = db_mysql_try("UPDATE anope_cs_badwords "
747  "SET type = %d, active = 1 "
748  "WHERE channel = '%s' AND word = '%s'",
749  (int) ci->badwords[i].type, q_name,
750  q_badwords);
751 
752  if (ret && (mysql_affected_rows(mysql) == 0)) {
753  ret = db_mysql_try("INSERT DELAYED INTO anope_cs_badwords "
754  "(channel, word, type, active) "
755  "VALUES ('%s', '%s', %d, 1)",
756  q_name, q_badwords,
757  (int) ci->badwords[i].type);
758  }
759 
760  free(q_badwords);
761  }
762  }
763 
764  /* TTB's */
765  for (i = 0; ret && (i < TTB_SIZE); i++) {
766  ret = db_mysql_try("UPDATE anope_cs_ttb "
767  "SET value = %d, active = 1 "
768  "WHERE channel = '%s' AND ttb_id = %d",
769  ci->ttb[i], q_name, i);
770 
771  if (ret && (mysql_affected_rows(mysql) == 0)) {
772  ret = db_mysql_try("INSERT DELAYED INTO anope_cs_ttb "
773  "(channel, ttb_id, value, active) "
774  "VALUES ('%s', %d, %d, 1)",
775  q_name, i, ci->ttb[i]);
776  }
777  }
778 
779  free(q_name);
780  free(q_founder);
781  free(q_successor);
782  free(q_pass);
783  free(q_desc);
784  free(q_url);
785  free(q_email);
786  free(q_lasttopic);
787  free(q_lasttopicsetter);
788  free(q_mlock_key);
789  free(q_mlock_flood);
790  free(q_mlock_redirect);
791  free(q_entrymsg);
792  free(q_botnick);
793  free(q_forbidby);
794  free(q_forbidreason);
795 
796  return ret;
797 }
798 
799 /*************************************************************************/
800 
801 
802 /*
803  * OperServ Specific Section
804  */
805 
806 /*************************************************************************/
807 
808 /* Save the OperServ database into MySQL
809  * Return 1 on success, 0 on failure
810  * These tables are tagged and will be cleaned:
811  * - anope_os_akills
812  * - anope_os_sglines
813  * - anope_os_sqlines
814  * - anope_os_szlines
815  * These tables are emptied:
816  * - anope_os_core
817  */
818 
819 int db_mysql_save_os_db(unsigned int maxucnt, unsigned int maxutime,
820  SList * ak, SList * sgl, SList * sql, SList * szl)
821 {
822  int ret;
823  int i;
824  Akill *akl;
825  SXLine *sl;
826  char *q_user;
827  char *q_host;
828  char *q_mask;
829  char *q_by;
830  char *q_reason;
831 
832 
833  /* First save the core info */
834  ret = db_mysql_try("INSERT DELAYED INTO anope_os_core "
835  "(maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count) "
836  "VALUES (%d, %d, %d, %d, %d, %d)",
837  maxucnt, maxutime, ak->count, sgl->count, sql->count,
838  szl->count);
839 
840  /* Next save all AKILLs */
841  for (i = 0; ret && (i < ak->count); i++) {
842  akl = ak->list[i];
843  q_user = db_mysql_quote(akl->user);
844  q_host = db_mysql_quote(akl->host);
845  q_by = db_mysql_quote(akl->by);
846  q_reason = db_mysql_quote(akl->reason);
847 
848  ret = db_mysql_try("UPDATE anope_os_akills "
849  "SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
850  "WHERE user = '%s' AND host = '%s'",
851  q_by, q_reason, (int) akl->seton,
852  (int) akl->expires, q_user, q_host);
853 
854  if (ret && (mysql_affected_rows(mysql) == 0)) {
855  ret = db_mysql_try("INSERT DELAYED INTO anope_os_akills "
856  "(user, host, xby, reason, seton, expire, active) "
857  "VALUES ('%s', '%s', '%s', '%s', %d, %d, 1)",
858  q_user, q_host, q_by, q_reason,
859  (int) akl->seton, (int) akl->expires);
860  }
861 
862  free(q_user);
863  free(q_host);
864  free(q_by);
865  free(q_reason);
866  }
867 
868  /* Time to save the SGLINEs */
869  for (i = 0; ret && (i < sgl->count); i++) {
870  sl = sgl->list[i];
871  q_mask = db_mysql_quote(sl->mask);
872  q_by = db_mysql_quote(sl->by);
873  q_reason = db_mysql_quote(sl->reason);
874 
875  ret = db_mysql_try("UPDATE anope_os_sglines "
876  "SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
877  "WHERE mask = '%s'",
878  q_by, q_reason, (int) sl->seton, (int) sl->expires,
879  q_mask);
880 
881  if (ret && (mysql_affected_rows(mysql) == 0)) {
882  ret = db_mysql_try("INSERT DELAYED INTO anope_os_sglines "
883  "(mask, xby, reason, seton, expire, active) "
884  "VALUES ('%s', '%s', '%s', %d, %d, 1)",
885  q_mask, q_by, q_reason, (int) sl->seton,
886  (int) sl->expires);
887  }
888 
889  free(q_mask);
890  free(q_by);
891  free(q_reason);
892  }
893 
894  /* Save the SQLINEs */
895  for (i = 0; ret && (i < sql->count); i++) {
896  sl = sql->list[i];
897 
898  q_mask = db_mysql_quote(sl->mask);
899  q_by = db_mysql_quote(sl->by);
900  q_reason = db_mysql_quote(sl->reason);
901 
902  ret = db_mysql_try("UPDATE anope_os_sqlines "
903  "SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
904  "WHERE mask = '%s'",
905  q_by, q_reason, (int) sl->seton, (int) sl->expires,
906  q_mask);
907 
908  if (ret && (mysql_affected_rows(mysql) == 0)) {
909  ret = db_mysql_try("INSERT DELAYED INTO anope_os_sqlines "
910  "(mask, xby, reason, seton, expire, active) "
911  "VALUES ('%s', '%s', '%s', %d, %d, 1)",
912  q_mask, q_by, q_reason, (int) sl->seton,
913  (int) sl->expires);
914  }
915 
916  free(q_mask);
917  free(q_by);
918  free(q_reason);
919  }
920 
921  /* Now save the SZLINEs */
922  for (i = 0; ret && (i < szl->count); i++) {
923  sl = szl->list[i];
924 
925  q_mask = db_mysql_quote(sl->mask);
926  q_by = db_mysql_quote(sl->by);
927  q_reason = db_mysql_quote(sl->reason);
928 
929  ret = db_mysql_try("UPDATE anope_os_szlines "
930  "SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
931  "WHERE mask = '%s'",
932  q_by, q_reason, (int) sl->seton, (int) sl->expires,
933  q_mask);
934 
935  if (ret && (mysql_affected_rows(mysql) == 0)) {
936  ret = db_mysql_try("INSERT DELAYED INTO anope_os_szlines "
937  "(mask, xby, reason, seton, expire, active) "
938  "VALUES ('%s', '%s', '%s', %d, %d, 1)",
939  q_mask, q_by, q_reason, (int) sl->seton,
940  (int) sl->expires);
941  }
942 
943  free(q_mask);
944  free(q_by);
945  free(q_reason);
946  }
947 
948  return ret;
949 }
950 
951 /*************************************************************************/
952 
953 /* Save the given NewsItem
954  * These tables are tagged and will be cleaned:
955  * - anope_os_news
956  */
958 {
959  int ret;
960  char *q_text;
961  char *q_who;
962 
963  q_text = db_mysql_quote(ni->text);
964  q_who = db_mysql_quote(ni->who);
965 
966  ret = db_mysql_try("UPDATE anope_os_news "
967  "SET ntext = '%s', who = '%s', active = 1 "
968  "WHERE type = %d AND num = %d AND `time` = %d",
969  q_text, q_who, ni->type, ni->num, (int) ni->time);
970 
971  if (ret && (mysql_affected_rows(mysql) == 0)) {
972  ret = db_mysql_try("INSERT DELAYED INTO anope_os_news "
973  "(type, num, ntext, who, `time`, active) "
974  "VALUES (%d, %d, '%s', '%s', %d, 1)",
975  ni->type, ni->num, q_text, q_who, (int) ni->time);
976  }
977 
978  free(q_text);
979  free(q_who);
980 
981  return ret;
982 }
983 
984 /*************************************************************************/
985 
986 /* Save the given Exception
987  * These tables are tagged and will be cleaned:
988  * - anope_os_exceptions
989  */
990 
992 {
993  int ret;
994  char *q_mask;
995  char *q_who;
996  char *q_reason;
997 
998  q_mask = db_mysql_quote(e->mask);
999  q_who = db_mysql_quote(e->who);
1000  q_reason = db_mysql_quote(e->reason);
1001 
1002  ret = db_mysql_try("UPDATE anope_os_exceptions "
1003  "SET lim = %d, who = '%s', reason = '%s', `time` = %d, expires = %d, active = 1 "
1004  "WHERE mask = '%s'",
1005  e->limit, q_who, q_reason, (int) e->time,
1006  (int) e->expires, q_mask);
1007 
1008  if (ret && (mysql_affected_rows(mysql)) == 0) {
1009  ret = db_mysql_try("INSERT DELAYED INTO anope_os_exceptions "
1010  "(mask, lim, who, reason, `time`, expires, active) "
1011  "VALUES ('%s', %d, '%s', '%s', %d, %d, 1)",
1012  q_mask, e->limit, q_who, q_reason, (int) e->time,
1013  (int) e->expires);
1014  }
1015 
1016  free(q_mask);
1017  free(q_who);
1018  free(q_reason);
1019 
1020  return ret;
1021 }
1022 
1023 /*************************************************************************/
1024 
1025 
1026 /*
1027  * HostServ Specific Section
1028  */
1029 
1030 /*************************************************************************/
1031 
1032 /* Save the given HostCore
1033  * These tables are tagged and will be cleaned:
1034  * - anope_hs_core
1035  */
1036 
1038 {
1039  int ret;
1040  char *q_nick;
1041  char *q_ident;
1042  char *q_host;
1043  char *q_creator;
1044 
1045  q_nick = db_mysql_quote(hc->nick);
1046  q_ident = db_mysql_quote(hc->vIdent);
1047  q_host = db_mysql_quote(hc->vHost);
1048  q_creator = db_mysql_quote(hc->creator);
1049 
1050  ret = db_mysql_try("UPDATE anope_hs_core "
1051  "SET vident = '%s', vhost = '%s', creator = '%s', `time` = %d, active = 1 "
1052  "WHERE nick = '%s'",
1053  q_ident, q_host, q_creator, (int) hc->time, q_nick);
1054 
1055  if (ret && (mysql_affected_rows(mysql) == 0)) {
1056  ret = db_mysql_try("INSERT DELAYED INTO anope_hs_core "
1057  "(nick, vident, vhost, creator, `time`, active) "
1058  "VALUES ('%s', '%s', '%s', '%s', %d, 1)",
1059  q_nick, q_ident, q_host, q_creator,
1060  (int) hc->time);
1061  }
1062 
1063  free(q_nick);
1064  free(q_ident);
1065  free(q_host);
1066  free(q_creator);
1067 
1068  return ret;
1069 }
1070 
1071 /*************************************************************************/
1072 
1073 /*
1074  * BotServ Specific Section
1075  */
1076 
1077 /*************************************************************************/
1078 
1080 {
1081  int ret;
1082  char *q_nick;
1083  char *q_user;
1084  char *q_host;
1085  char *q_real;
1086 
1087  q_nick = db_mysql_quote(bi->nick);
1088  q_user = db_mysql_quote(bi->user);
1089  q_host = db_mysql_quote(bi->host);
1090  q_real = db_mysql_quote(bi->real);
1091 
1092  ret = db_mysql_try("UPDATE anope_bs_core "
1093  "SET user = '%s', host = '%s', rname = '%s', flags = %d, created = %d, chancount = %d, active = 1 "
1094  "WHERE nick = '%s'",
1095  q_user, q_host, q_real, bi->flags, (int) bi->created,
1096  bi->chancount, q_nick);
1097 
1098  if (ret && (mysql_affected_rows(mysql) == 0)) {
1099  ret = db_mysql_try("INSERT DELAYED INTO anope_bs_core "
1100  "(nick, user, host, rname, flags, created, chancount, active) "
1101  "VALUES ('%s', '%s', '%s', '%s', %d, %d, %d, 1)",
1102  q_nick, q_user, q_host, q_real, bi->flags,
1103  (int) bi->created, bi->chancount);
1104  }
1105 
1106  free(q_nick);
1107  free(q_user);
1108  free(q_host);
1109  free(q_real);
1110 
1111  return ret;
1112 }
1113 
1114 /*************************************************************************/
1115 /*************************************************************************/
1116 
1117 /* Some loading code! */
1118 
1119 /*************************************************************************/
1120 /*************************************************************************/
1121 
1123 {
1124  int ret;
1125  BotInfo *bi;
1126 
1127  if (!do_mysql)
1128  return 0;
1129 
1130  ret = db_mysql_try("SELECT nick, user, host, rname, flags, created, chancount "
1131  "FROM anope_bs_core "
1132  "WHERE active = 1");
1133 
1134  if (!ret)
1135  return 0;
1136 
1137  mysql_res = mysql_use_result(mysql);
1138 
1139  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1140  bi = makebot(mysql_row[0]);
1141  bi->user = sstrdup(mysql_row[1]);
1142  bi->host = sstrdup(mysql_row[2]);
1143  bi->real = sstrdup(mysql_row[3]);
1144  bi->flags = strtol(mysql_row[4], (char **) NULL, 10);
1145  bi->created = strtol(mysql_row[5], (char **) NULL, 10);
1146  bi->chancount = strtol(mysql_row[6], (char **) NULL, 10);
1147  }
1148 
1149  mysql_free_result(mysql_res);
1150 
1151  return 1;
1152 }
1153 
1155 {
1156  int ret;
1157  char *vident = NULL;
1158  int32 time;
1159 
1160  if (!do_mysql)
1161  return 0;
1162 
1163  ret = db_mysql_try("SELECT nick, vident, vhost, creator, `time` "
1164  "FROM anope_hs_core "
1165  "WHERE active = 1");
1166 
1167  if (!ret)
1168  return 0;
1169 
1170  mysql_res = mysql_use_result(mysql);
1171 
1172  while ((mysql_row = mysql_fetch_row(mysql_res)))
1173  {
1174  /* FIX: we can never allow an empty vident, it must *always* be NULL. */
1175  vident = mysql_row[1];
1176  if (!strcmp(vident, ""))
1177  {
1178  vident = NULL;
1179  }
1180 
1181  time = strtol(mysql_row[4], (char **) NULL, 10);
1182  addHostCore(mysql_row[0], NULL, mysql_row[2], mysql_row[3], time);
1183  }
1184 
1185  mysql_free_result(mysql_res);
1186 
1187  return 1;
1188 }
1189 
1191 {
1192  int ret;
1193  int i;
1194 
1195  if (!do_mysql)
1196  return 0;
1197 
1198  ret = db_mysql_try("SELECT type, num, ntext, who, `time` "
1199  "FROM anope_os_news "
1200  "WHERE active = 1");
1201 
1202  if (!ret)
1203  return 0;
1204 
1205  mysql_res = mysql_store_result(mysql);
1206 
1207  nnews = mysql_num_rows(mysql_res);
1208  if (nnews < 8) /* 2^3 */
1209  news_size = 16; /* 2^4 */
1210  else if (nnews >= 16384) /* 2^14 */
1211  news_size = 32767; /* 2^15 - 1 */
1212  else
1213  news_size = 2 * nnews;
1214 
1215  news = scalloc(news_size, sizeof(*news));
1216 
1217  i = 0;
1218  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1219  news[i].type = strtol(mysql_row[0], (char **) NULL, 10);
1220  news[i].num = strtol(mysql_row[1], (char **) NULL, 10);
1221  news[i].text = sstrdup(mysql_row[2]);
1222  snprintf(news[i].who, NICKMAX, "%s", mysql_row[3]);
1223  news[i].time = strtol(mysql_row[4], (char **) NULL, 10);
1224  i++;
1225  }
1226 
1227  mysql_free_result(mysql_res);
1228 
1229  return 1;
1230 }
1231 
1233 {
1234  int ret;
1235  int i;
1236 
1237  if (!do_mysql)
1238  return 0;
1239 
1240  ret = db_mysql_try("SELECT mask, lim, who, reason, `time`, expires "
1241  "FROM anope_os_exceptions "
1242  "WHERE active = 1");
1243 
1244  if (!ret)
1245  return 0;
1246 
1247  mysql_res = mysql_store_result(mysql);
1248  nexceptions = mysql_num_rows(mysql_res);
1250 
1251  i = 0;
1252  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1253  exceptions[i].mask = sstrdup(mysql_row[0]);
1254  exceptions[i].limit = strtol(mysql_row[1], (char **) NULL, 10);
1255  snprintf(exceptions[i].who, NICKMAX, "%s", mysql_row[2]);
1257  exceptions[i].time = strtol(mysql_row[4], (char **) NULL, 10);
1258  exceptions[i].expires = strtol(mysql_row[5], (char **) NULL, 10);
1259  i++;
1260  }
1261 
1262  mysql_free_result(mysql_res);
1263 
1264  return 1;
1265 }
1266 
1268 {
1269  int ret;
1270  Akill *ak;
1271  SXLine *sl;
1272  int akc, sglc, sqlc, szlc;
1273 
1274  if (!do_mysql)
1275  return 0;
1276 
1277  ret = db_mysql_try("SELECT maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count "
1278  "FROM anope_os_core");
1279 
1280  if (!ret)
1281  return 0;
1282 
1283  mysql_res = mysql_use_result(mysql);
1284 
1285  if ((mysql_row = mysql_fetch_row(mysql_res))) {
1286  maxusercnt = strtol(mysql_row[0], (char **) NULL, 10);
1287  maxusertime = strtol(mysql_row[1], (char **) NULL, 10);
1288  /* I'm not too happy with the idea of storing thse counts in a field
1289  * instead of just using mysql_num_rows on the actual tables when
1290  * filling the data. For now this will do, but it's bound to give
1291  * problems sooner or later... (it probably does if you are looking
1292  * at this) -GD
1293  */
1294  akc = strtol(mysql_row[2], (char **) NULL, 10);
1295  sglc = strtol(mysql_row[3], (char **) NULL, 10);
1296  sqlc = strtol(mysql_row[4], (char **) NULL, 10);
1297  szlc = strtol(mysql_row[5], (char **) NULL, 10);
1298  } else {
1299  maxusercnt = 0;
1300  maxusertime = time(NULL);
1301  akc = 0;
1302  sglc = 0;
1303  sqlc = 0;
1304  szlc = 0;
1305  }
1306 
1307  mysql_free_result(mysql_res);
1308 
1309 
1310  /* Load the AKILLs */
1311 
1312  ret = db_mysql_try("SELECT user, host, xby, reason, seton, expire "
1313  "FROM anope_os_akills "
1314  "WHERE active = 1");
1315 
1316  if (!ret)
1317  return 0;
1318 
1319  mysql_res = mysql_use_result(mysql);
1320  slist_setcapacity(&akills, akc);
1321 
1322  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1323  ak = scalloc(1, sizeof(Akill));
1324  ak->user = sstrdup(mysql_row[0]);
1325  ak->host = sstrdup(mysql_row[1]);
1326  ak->by = sstrdup(mysql_row[2]);
1327  ak->reason = sstrdup(mysql_row[3]);
1328  ak->seton = strtol(mysql_row[4], (char **) NULL, 10);
1329  ak->expires = strtol(mysql_row[5], (char **) NULL, 10);
1330  slist_add(&akills, ak);
1331  }
1332 
1333  mysql_free_result(mysql_res);
1334 
1335 
1336  /* Load the SGLINEs */
1337 
1338  ret = db_mysql_try("SELECT mask, xby, reason, seton, expire "
1339  "FROM anope_os_sglines "
1340  "WHERE active = 1");
1341 
1342  if (!ret)
1343  return 0;
1344 
1345  mysql_res = mysql_use_result(mysql);
1346  slist_setcapacity(&sglines, sglc);
1347 
1348  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1349  sl = scalloc(1, sizeof(SXLine));
1350  sl->mask = sstrdup(mysql_row[0]);
1351  sl->by = sstrdup(mysql_row[1]);
1352  sl->reason = sstrdup(mysql_row[2]);
1353  sl->seton = strtol(mysql_row[3], (char **) NULL, 10);
1354  sl->expires = strtol(mysql_row[4], (char **) NULL, 10);
1355  slist_add(&sglines, sl);
1356  }
1357 
1358  mysql_free_result(mysql_res);
1359 
1360 
1361  /* Load the SQLINEs */
1362 
1363  ret = db_mysql_try("SELECT mask, xby, reason, seton, expire "
1364  "FROM anope_os_sqlines "
1365  "WHERE active = 1");
1366 
1367  if (!ret)
1368  return 0;
1369 
1370  mysql_res = mysql_use_result(mysql);
1371  slist_setcapacity(&sqlines, sqlc);
1372 
1373  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1374  sl = scalloc(1, sizeof(SXLine));
1375  sl->mask = sstrdup(mysql_row[0]);
1376  sl->by = sstrdup(mysql_row[1]);
1377  sl->reason = sstrdup(mysql_row[2]);
1378  sl->seton = strtol(mysql_row[3], (char **) NULL, 10);
1379  sl->expires = strtol(mysql_row[4], (char **) NULL, 10);
1380  slist_add(&sqlines, sl);
1381  }
1382 
1383  mysql_free_result(mysql_res);
1384 
1385 
1386  /* Load the SZLINEs */
1387 
1388  ret = db_mysql_try("SELECT mask, xby, reason, seton, expire "
1389  "FROM anope_os_szlines "
1390  "WHERE active = 1");
1391 
1392  if (!ret)
1393  return 0;
1394 
1395  mysql_res = mysql_use_result(mysql);
1396  slist_setcapacity(&szlines, szlc);
1397 
1398  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1399  sl = scalloc(1, sizeof(SXLine));
1400  sl->mask = sstrdup(mysql_row[0]);
1401  sl->by = sstrdup(mysql_row[1]);
1402  sl->reason = sstrdup(mysql_row[2]);
1403  sl->seton = strtol(mysql_row[3], (char **) NULL, 10);
1404  sl->expires = strtol(mysql_row[4], (char **) NULL, 10);
1405  slist_add(&szlines, sl);
1406  }
1407 
1408  mysql_free_result(mysql_res);
1409 
1410  return 1;
1411 }
1412 
1414 {
1415  int ret;
1416  char *q_name;
1417  ChannelInfo *ci;
1418  int i;
1419  MYSQL_RES *res;
1420  MYSQL_ROW row;
1421  unsigned long *lengths;
1422 
1423  if (!do_mysql)
1424  return 0;
1425 
1426  ret = db_mysql_try("SELECT name, founder, successor, founderpass, descr, url, email, time_registered, last_used, last_topic, last_topic_setter, "
1427  " last_topic_time, flags, forbidby, forbidreason, bantype, accesscount, akickcount, mlock_on, mlock_off, mlock_limit, "
1428  " mlock_key, mlock_flood, mlock_redirect, entry_message, memomax, botnick, botflags, bwcount, capsmin, capspercent, floodlines, "
1429  " floodsecs, repeattimes "
1430  "FROM anope_cs_info "
1431  "WHERE active = 1");
1432 
1433  if (!ret)
1434  return 0;
1435 
1436  /* I'd really like to use mysql_use_result here, but it'd tie up with
1437  * all the queries being run inside each iteration... -GD
1438  */
1439  mysql_res = mysql_store_result(mysql);
1440 
1441  while (ret && (mysql_row = mysql_fetch_row(mysql_res))) {
1442  /* We need to get the length of the password.. - Viper */
1443  lengths = mysql_fetch_lengths(mysql_res);
1444  ci = scalloc(1, sizeof(ChannelInfo));
1445 
1446  /* Name, founder, successor, password */
1447  snprintf(ci->name, CHANMAX, "%s", mysql_row[0]);
1448  ci->founder = findcore(mysql_row[1]);
1449  if (mysql_row[2] && *(mysql_row[2]))
1450  ci->successor = findcore(mysql_row[2]);
1451  else
1452  ci->successor = NULL;
1453 
1454  /* Copy the password from what we got back from the DB and
1455  * keep in mind that lengths may vary. We should never
1456  * use more than we have. - Viper */
1457  memset(ci->founderpass, 0, PASSMAX);
1458  if (lengths[3] >= PASSMAX)
1459  memcpy(ci->founderpass, mysql_row[3], PASSMAX - 1);
1460  else
1461  memcpy(ci->founderpass, mysql_row[3], lengths[3]);
1462 
1463  /* Description, URL, email -- scalloc() initializes to 0/NULL */
1464  ci->desc = sstrdup(mysql_row[4]);
1465  if (mysql_row[5] && *(mysql_row[5]))
1466  ci->url = sstrdup(mysql_row[5]);
1467  if (mysql_row[6] && *(mysql_row[6]))
1468  ci->email = sstrdup(mysql_row[6]);
1469 
1470  /* Time registered, last used, last topic, last topic setter + time */
1471  ci->time_registered = strtol(mysql_row[7], (char **) NULL, 10);
1472  ci->last_used = strtol(mysql_row[8], (char **) NULL, 10);
1473  if (mysql_row[9] && *(mysql_row[9])) {
1474  ci->last_topic = sstrdup(mysql_row[9]);
1475  snprintf(ci->last_topic_setter, NICKMAX, "%s", mysql_row[10]);
1476  ci->last_topic_time = strtol(mysql_row[11], (char **) NULL, 10);
1477  }
1478 
1479  /* Flags, forbidden by, forbid reason, bantype
1480  * NOTE: CI_INHABIT will be disabled in flags!!
1481  */
1482  ci->flags =
1483  strtol(mysql_row[12], (char **) NULL, 10) & ~CI_INHABIT;
1484 
1485  if (mysql_row[13] && *(mysql_row[13])) {
1486  ci->forbidby = sstrdup(mysql_row[13]);
1487  if (mysql_row[14] && *(mysql_row[14]))
1488  ci->forbidreason = sstrdup(mysql_row[14]);
1489  }
1490 
1491  ci->bantype = strtol(mysql_row[15], (char **) NULL, 10);
1492 
1493  /* Accesscount, akickcount */
1494  ci->accesscount = strtol(mysql_row[16], (char **) NULL, 10);
1495  ci->akickcount = strtol(mysql_row[17], (char **) NULL, 10);
1496 
1497  /* Mlock: on, off, limit, key, flood, redirect */
1498  ci->mlock_on = strtol(mysql_row[18], (char **) NULL, 10);
1499  ci->mlock_off = strtol(mysql_row[19], (char **) NULL, 10);
1500  ci->mlock_limit = strtol(mysql_row[20], (char **) NULL, 10);
1501  if (mysql_row[21] && *(mysql_row[21])) {
1502  ci->mlock_key = sstrdup(mysql_row[21]);
1503  if (mysql_row[22] && *(mysql_row[22])) {
1504  ci->mlock_flood = sstrdup(mysql_row[22]);
1505  }
1506  if (mysql_row[23] && *(mysql_row[23])) {
1507  ci->mlock_redirect = sstrdup(mysql_row[23]);
1508  }
1509  }
1510 
1511  /* MemoMax, entrymessage, botinfo, botflags, badwordcount */
1512  ci->memos.memomax = strtol(mysql_row[25], (char **) NULL, 10);
1513  if (mysql_row[24] && *(mysql_row[24]))
1514  ci->entry_message = sstrdup(mysql_row[24]);
1515  ci->bi = findbot(mysql_row[26]);
1516  ci->botflags = strtol(mysql_row[27], (char **) NULL, 10);
1517  ci->bwcount = strtol(mysql_row[28], (char **) NULL, 10);
1518 
1519  /* Capsmin, capspercent, floodlines, floodsecs, repeattimes */
1520  ci->capsmin = strtol(mysql_row[29], (char **) NULL, 10);
1521  ci->capspercent = strtol(mysql_row[30], (char **) NULL, 10);
1522  ci->floodlines = strtol(mysql_row[31], (char **) NULL, 10);
1523  ci->floodsecs = strtol(mysql_row[32], (char **) NULL, 10);
1524  ci->repeattimes = strtol(mysql_row[33], (char **) NULL, 10);
1525 
1526 
1527  /* Get info from other tables; we'll need the channel name */
1528  q_name = db_mysql_quote(ci->name);
1529 
1530  /* Get the LEVELS list */
1531  ret = db_mysql_try("SELECT position, level "
1532  "FROM anope_cs_levels "
1533  "WHERE channel = '%s' AND active = 1",
1534  q_name);
1535 
1536  if (ret) {
1537  res = mysql_use_result(mysql);
1538  ci->levels = scalloc(CA_SIZE, sizeof(*ci->levels));
1539  reset_levels(ci);
1540 
1541  while ((row = mysql_fetch_row(res))) {
1542  i = strtol(row[0], (char **) NULL, 10);
1543  ci->levels[i] = strtol(row[1], (char **) NULL, 10);
1544  }
1545 
1546  mysql_free_result(res);
1547  }
1548 
1549  /* Get the channel ACCESS list */
1550  if (ret && (ci->accesscount > 0)) {
1551  ci->access = scalloc(ci->accesscount, sizeof(ChanAccess));
1552 
1553  ret = db_mysql_try("SELECT level, display, last_seen "
1554  "FROM anope_cs_access "
1555  "WHERE channel = '%s' AND in_use = 1 AND active = 1",
1556  q_name);
1557 
1558  if (ret) {
1559  res = mysql_store_result(mysql);
1560 
1561  i = 0;
1562  while ((row = mysql_fetch_row(res))) {
1563  ci->access[i].in_use = 1;
1564  ci->access[i].level = strtol(row[0], (char **) NULL, 10);
1565  ci->access[i].nc = findcore(row[1]);
1566  if (!(ci->access[i].nc))
1567  ci->access[i].in_use = 0;
1568  ci->access[i].last_seen =
1569  strtol(row[2], (char **) NULL, 10);
1570  i++;
1571  }
1572 
1573  mysql_free_result(res);
1574  }
1575  }
1576 
1577  /* Get the channel AKICK list */
1578  if (ret && (ci->akickcount > 0)) {
1579  ci->akick = scalloc(ci->akickcount, sizeof(AutoKick));
1580 
1581  ret = db_mysql_try("SELECT flags, dmask, reason, creator, addtime "
1582  "FROM anope_cs_akicks "
1583  "WHERE channel = '%s' AND active = 1 AND (flags & %d) <> 0",
1584  q_name, AK_USED);
1585 
1586  if (ret) {
1587  res = mysql_use_result(mysql);
1588 
1589  i = 0;
1590  while ((row = mysql_fetch_row(res))) {
1591  ci->akick[i].flags = strtol(row[0], (char **) NULL, 10);
1592  if (ci->akick[i].flags & AK_ISNICK) {
1593  ci->akick[i].u.nc = findcore(row[1]);
1594  if (!(ci->akick[i].u.nc))
1595  ci->akick[i].flags &= ~AK_USED;
1596  } else {
1597  ci->akick[i].u.mask = sstrdup(row[1]);
1598  }
1599  if (row[2] && *(row[2])) {
1600  ci->akick[i].reason = sstrdup(row[2]);
1601  }
1602  ci->akick[i].creator = sstrdup(row[3]);
1603  ci->akick[i].addtime = strtol(row[4], (char **) NULL, 10);
1604  i++;
1605  }
1606 
1607  mysql_free_result(res);
1608  }
1609  }
1610 
1611  if (ret) {
1612  /* Get the channel memos */
1613  ret = db_mysql_try("SELECT nm_id, number, flags, time, sender, text "
1614  "FROM anope_ms_info "
1615  "WHERE receiver = '%s' AND serv = 'CHAN' AND active = 1",
1616  q_name);
1617 
1618  if (ret) {
1619  res = mysql_store_result(mysql);
1620  ci->memos.memocount = mysql_num_rows(res);
1621 
1622  if (ci->memos.memocount > 0) {
1623  Memo *memos;
1624 
1625  memos = scalloc(ci->memos.memocount, sizeof(Memo));
1626  ci->memos.memos = memos;
1627 
1628  i = 0;
1629  while ((row = mysql_fetch_row(res))) {
1630  memos[i].id = strtol(row[0], (char **) NULL, 10);
1631  memos[i].number = strtol(row[1], (char **) NULL, 10);
1632  memos[i].flags = strtol(row[2], (char **) NULL, 10);
1633  memos[i].time = strtol(row[3], (char **) NULL, 10);
1634  snprintf(memos[i].sender, NICKMAX, "%s", row[4]);
1635  memos[i].text = sstrdup(row[5]);
1636  i++;
1637  }
1638  }
1639 
1640  mysql_free_result(res);
1641  }
1642  }
1643 
1644  /* Get the TTB data */
1645  if (ret) {
1646  ci->ttb = scalloc(TTB_SIZE, sizeof(*ci->ttb));
1647 
1648  ret = db_mysql_try("SELECT ttb_id, value "
1649  "FROM anope_cs_ttb "
1650  "WHERE channel = '%s' AND active = 1",
1651  q_name);
1652 
1653  if (ret) {
1654  res = mysql_use_result(mysql);
1655 
1656  while ((row = mysql_fetch_row(res))) {
1657  i = strtol(row[0], (char **) NULL, 10);
1658  /* Should we do a sanity check on the value of i? -GD */
1659  ci->ttb[i] = strtol(row[1], (char **) NULL, 10);
1660  }
1661 
1662  mysql_free_result(res);
1663  }
1664  }
1665 
1666  /* Get the badwords */
1667  if (ret && (ci->bwcount > 0)) {
1668  ci->badwords = scalloc(ci->bwcount, sizeof(BadWord));
1669 
1670  ret = db_mysql_try("SELECT word, type "
1671  "FROM anope_cs_badwords "
1672  "WHERE channel = '%s' AND active = 1",
1673  q_name);
1674 
1675  if (ret) {
1676  res = mysql_use_result(mysql);
1677 
1678  i = 0;
1679  while ((row = mysql_fetch_row(res))) {
1680  ci->badwords[i].in_use = 1;
1681  ci->badwords[i].word = sstrdup(row[0]);
1682  ci->badwords[i].type = strtol(row[1], (char **) NULL, 10);
1683  i++;
1684  }
1685 
1686  mysql_free_result(res);
1687  }
1688  }
1689 
1690  /* YAY! all done; free q_name and insert the channel */
1691  free(q_name);
1692  alpha_insert_chan(ci);
1693  }
1694 
1695  mysql_free_result(mysql_res);
1696 
1697  /* Check to be sure that all channels still have a founder. If not,
1698  * delete them. This code seems to be required in the old mysql code
1699  * so i'll leave it in just to be sure. I also wonder why they didn't
1700  * do that check up above immediately when it was known there was no
1701  * founder... -GD
1702  */
1703  for (i = 0; i < 256; i++) {
1704  ChannelInfo *next;
1705  for (ci = chanlists[i]; ci; ci = next) {
1706  next = ci->next;
1707  if (!(ci->flags & CI_VERBOTEN) && !ci->founder) {
1708  alog("%s: database load: Deleting founderless channel %s",
1709  s_ChanServ, ci->name);
1710  delchan(ci);
1711  }
1712  }
1713  }
1714 
1715  return ret;
1716 }
1717 
1719 {
1720  int ret;
1721  NickRequest *nr;
1722  unsigned long *lengths;
1723 
1724  if (!do_mysql)
1725  return 0;
1726 
1727  ret = db_mysql_try("SELECT nick, passcode, password, email, requested "
1728  "FROM anope_ns_request "
1729  "WHERE active = 1");
1730 
1731  if (ret) {
1732  mysql_res = mysql_use_result(mysql);
1733 
1734  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1735  /* We need to get the length of the password.. - Viper */
1736  lengths = mysql_fetch_lengths(mysql_res);
1737  nr = scalloc(1, sizeof(NickRequest));
1738 
1739  nr->nick = sstrdup(mysql_row[0]);
1740  nr->passcode = sstrdup(mysql_row[1]);
1741  nr->email = sstrdup(mysql_row[3]);
1742  nr->requested = strtol(mysql_row[4], (char **) NULL, 10);
1743 
1744  /* Copy the password from what we got back from the DB and
1745  * keep in mind that lengths may vary. We should never
1746  * use more than we have. - Viper */
1747  memset(nr->password, 0, PASSMAX);
1748  if (lengths[2] >= PASSMAX)
1749  memcpy(nr->password, mysql_row[2], PASSMAX - 1);
1750  else
1751  memcpy(nr->password, mysql_row[2], lengths[2]);
1752 
1753 
1754  insert_requestnick(nr);
1755  }
1756 
1757  mysql_free_result(mysql_res);
1758  }
1759 
1760  return ret;
1761 }
1762 
1764 {
1765  int ret;
1766  char *q_display;
1767  NickCore *nc;
1768  NickAlias *na;
1769  MYSQL_RES *res;
1770  MYSQL_ROW row;
1771  int i;
1772  unsigned long *lengths;
1773 
1774 
1775  if (!do_mysql)
1776  return 0;
1777 
1778  ret = db_mysql_try("SELECT display, pass, email, icq, url, flags, language, accesscount, memocount, memomax, channelcount, channelmax, greet "
1779  "FROM anope_ns_core "
1780  "WHERE active = 1");
1781 
1782  if (!ret)
1783  return 0;
1784 
1785  /* I'd really like to use mysql_use_result here, but it'd tie up with
1786  * all the queries being run inside each iteration... -GD
1787  */
1788  mysql_res = mysql_store_result(mysql);
1789 
1790  while (ret && (mysql_row = mysql_fetch_row(mysql_res))) {
1791  /* We need to get the length of the password.. - Viper */
1792  lengths = mysql_fetch_lengths(mysql_res);
1793 
1794  nc = scalloc(1, sizeof(NickCore));
1795 
1796  /* Display, password, email, ICQ, URL, flags */
1797  nc->display = sstrdup(mysql_row[0]);
1798  if (mysql_row[2] && *(mysql_row[2])) {
1799  nc->email = sstrdup(mysql_row[2]);
1800  }
1801  nc->icq = strtol(mysql_row[3], (char **) NULL, 10);
1802  if (mysql_row[4] && *(mysql_row[4])) {
1803  nc->url = sstrdup(mysql_row[4]);
1804  }
1805  nc->flags = strtol(mysql_row[5], (char **) NULL, 10);
1806 
1807  /* Copy the password from what we got back from the DB and
1808  * keep in mind that lengths may vary. We should never
1809  * use more than we have. - Viper */
1810  memset(nc->pass, 0, PASSMAX);
1811  if (lengths[1] >= PASSMAX)
1812  memcpy(nc->pass, mysql_row[1], PASSMAX - 1);
1813  else
1814  memcpy(nc->pass, mysql_row[1], lengths[1]);
1815 
1816  /* Language, accesscount, memocount, memomax */
1817  nc->language = strtol(mysql_row[6], (char **) NULL, 10);
1818  nc->accesscount = strtol(mysql_row[7], (char **) NULL, 10);
1819  nc->memos.memocount = strtol(mysql_row[8], (char **) NULL, 10);
1820  nc->memos.memomax = strtol(mysql_row[9], (char **) NULL, 10);
1821 
1822  /* Channelcount, channelmax, greet */
1823  nc->channelcount = strtol(mysql_row[10], (char **) NULL, 10);
1824  nc->channelmax = strtol(mysql_row[11], (char **) NULL, 10);
1825  if (mysql_row[12] && *(mysql_row[12]))
1826  nc->greet = sstrdup(mysql_row[12]);
1827 
1828  /* Don't allow KILL_IMMED if the config doesn't allow it */
1829  if (!NSAllowKillImmed)
1830  nc->flags &= ~NI_KILL_IMMED;
1831 
1832  /* Check if the current user is important enough to be added to
1833  * services admin or services oper lists
1834  */
1835  if (nc->flags & NI_SERVICES_ADMIN)
1836  slist_add(&servadmins, nc);
1837  if (nc->flags & NI_SERVICES_OPER)
1838  slist_add(&servopers, nc);
1839 
1840  /* Unset the SERVICES_ROOT flag; we will set it again later if this
1841  * user is really a services root (checked per NickAlias) -GD
1842  */
1843  nc->flags &= ~NI_SERVICES_ROOT;
1844 
1845  /* Get info from other tables; we'll need the display */
1846  q_display = db_mysql_quote(nc->display);
1847 
1848  /* Fill the accesslist */
1849  if (ret && (nc->accesscount > 0)) {
1850  nc->access = scalloc(nc->accesscount, sizeof(char *));
1851 
1852  ret = db_mysql_try("SELECT access "
1853  "FROM anope_ns_access "
1854  "WHERE display = '%s' AND active = 1",
1855  q_display);
1856 
1857  if (ret) {
1858  res = mysql_use_result(mysql);
1859 
1860  i = 0;
1861  while ((row = mysql_fetch_row(res))) {
1862  if (row[0] && *(row[0])) {
1863  nc->access[i] = sstrdup(row[0]);
1864  i++;
1865  }
1866  }
1867 
1868  /* Versions previous to 1.8.3 have a problem with saving nick access lists to sql
1869  * because of the way the table is set up, causing nc->accesscount to be higher
1870  * than what is in the database, which causes numerious problems including crashes. - Adam
1871  */
1872  if (nc->accesscount > i)
1873  {
1874  nc->accesscount = i;
1875  nc->access = srealloc(nc->access, sizeof(char *) * nc->accesscount);
1876  }
1877 
1878  mysql_free_result(res);
1879  }
1880  }
1881 
1882  /* Load the memos */
1883  if (ret && (nc->memos.memocount > 0)) {
1884  nc->memos.memos = scalloc(nc->memos.memocount, sizeof(Memo));
1885 
1886  ret = db_mysql_try("SELECT nm_id, number, flags, time, sender, text "
1887  "FROM anope_ms_info "
1888  "WHERE receiver = '%s' AND active = 1 AND serv = 'NICK' "
1889  "ORDER BY number ASC",
1890  q_display);
1891 
1892  if (ret) {
1893  res = mysql_use_result(mysql);
1894 
1895  i = 0;
1896  while ((row = mysql_fetch_row(res))) {
1897  nc->memos.memos[i].id = strtol(row[0], (char **) NULL, 10);
1898  nc->memos.memos[i].number = strtol(row[1], (char **) NULL, 10);
1899  nc->memos.memos[i].flags = strtol(row[2], (char **) NULL, 10);
1900  nc->memos.memos[i].time = strtol(row[3], (char **) NULL, 10);
1901  snprintf(nc->memos.memos[i].sender, NICKMAX, "%s", row[4]);
1902  nc->memos.memos[i].text = sstrdup(row[5]);
1903 
1904  i++;
1905  }
1906 
1907  mysql_free_result(res);
1908  }
1909  }
1910 
1911  /* Done with the core; insert it */
1912  insert_core(nc);
1913  }
1914 
1915  mysql_free_result(mysql_res);
1916 
1917  if (!ret)
1918  return 0;
1919 
1920  /* Load the nickaliases */
1921  ret = db_mysql_try("SELECT nick, display, time_registered, last_seen, status, last_usermask, last_realname, last_quit "
1922  "FROM anope_ns_alias "
1923  "WHERE active = 1");
1924 
1925  if (!ret)
1926  return 0;
1927 
1928  mysql_res = mysql_use_result(mysql);
1929 
1930  while ((mysql_row = mysql_fetch_row(mysql_res))) {
1931  /* First make sure this NickAlias has a NickCore; else we don't even
1932  * bother adding it to the aliases at all...
1933  */
1934  NickCore *nc;
1935 
1936  if (!(nc = findcore(mysql_row[1])))
1937  continue;
1938 
1939  na = scalloc(1, sizeof(NickAlias));
1940 
1941  /* nick, time_registered, last_seen, status
1942  * NOTE: remove NS_TEMPORARY from status on load
1943  */
1944  na->nick = sstrdup(mysql_row[0]);
1945  na->nc = nc;
1946  na->time_registered = strtol(mysql_row[2], (char **) NULL, 10);
1947  na->last_seen = strtol(mysql_row[3], (char **) NULL, 10);
1948  na->status =
1949  strtol(mysql_row[4], (char **) NULL, 10) & ~NS_TEMPORARY;
1950 
1951  /* last_usermask, last_realname, last_quit */
1952  na->last_usermask = sstrdup(mysql_row[5]);
1953  na->last_realname = sstrdup(mysql_row[6]);
1954 
1955  if (mysql_row[7] && *(mysql_row[7])) {
1956  na->last_quit = sstrdup(mysql_row[7]);
1957  }
1958 
1959  /* Assign to the nickcore aliases */
1960  slist_add(&na->nc->aliases, na);
1961 
1962  /* Check if this user is a services root */
1963  for (i = 0; i < RootNumber; i++) {
1964  if (stricmp(ServicesRoots[i], na->nick) == 0)
1965  na->nc->flags |= NI_SERVICES_ROOT;
1966  }
1967 
1968  /* Last, but not least: insert the alias! */
1969  alpha_insert_alias(na);
1970  }
1971 
1972  mysql_free_result(mysql_res);
1973 
1974  return ret;
1975 }
1976 
1977 /* get random mysql number for the generator */
1978 unsigned int mysql_rand(void)
1979 {
1980  unsigned int num = 0;
1981 
1982  if (!do_mysql)
1983  return 0;
1984 
1985  db_mysql_try("SELECT RAND()");
1986 
1987  mysql_res = mysql_store_result(mysql);
1988 
1989  if (!(mysql_row = mysql_fetch_row(mysql_res))) {
1990  mysql_free_result(mysql_res);
1991  return 0;
1992  }
1993 
1994  num = UserKey3 * strtol(mysql_row[0], (char **) NULL, 10);
1995 
1996  mysql_free_result(mysql_res);
1997 
1998  return num;
1999 }
char * url
Definition: services.h:660
time_t time
Definition: services.h:1113
E time_t maxusertime
Definition: extern.h:1142
char * email
Definition: services.h:519
char * MysqlSecure
Definition: config.c:316
uint16 akickcount
Definition: services.h:678
#define NI_SERVICES_ROOT
Definition: services.h:1305
int db_mysql_save_ns_alias(NickAlias *na)
Definition: mysql.c:462
E void addHostCore(char *nick, char *vIdent, char *vhost, char *creator, int32 tmp_time)
Definition: hostserv.c:291
char sender[NICKMAX]
Definition: services.h:494
#define NI_KILL_IMMED
Definition: services.h:1301
#define CI_INHABIT
Definition: services.h:746
char ** access
Definition: services.h:551
int db_mysql_save_exceptions(Exception *e)
Definition: mysql.c:991
E void insert_core(NickCore *nc)
Definition: nickserv.c:1370
E int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: compat.c:37
char * MysqlName
Definition: config.c:314
uint32 botflags
Definition: services.h:700
MYSQL_FIELD * mysql_fields
Definition: mysql.c:21
char * url
Definition: services.h:547
time_t expires
Definition: services.h:1099
char * by
Definition: services.h:1096
char * word
Definition: services.h:642
int16 capspercent
Definition: services.h:705
MYSQL_ROW mysql_row
Definition: mysql.c:22
E uint32 maxusercnt
Definition: extern.h:1141
char * mask
Definition: services.h:1095
char * passcode
Definition: services.h:517
uint16 type
Definition: services.h:643
char * mlock_redirect
Definition: services.h:685
E SList servadmins
Definition: extern.h:971
time_t time
Definition: services.h:1134
time_t last_used
Definition: services.h:664
char * host
Definition: services.h:1081
char * last_quit
Definition: services.h:527
char * mlock_flood
Definition: services.h:684
uint32 num
Definition: services.h:1120
E int slist_setcapacity(SList *slist, int16 capacity)
Definition: slist.c:379
char founderpass[PASSMAX]
Definition: services.h:658
int MysqlPort
Definition: config.c:315
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
int db_mysql_load_bs_dbase(void)
Definition: mysql.c:1122
int16 level
Definition: services.h:594
time_t expires
Definition: services.h:1087
E long unsigned int UserKey3
Definition: extern.h:577
#define CI_VERBOTEN
Definition: services.h:725
char * reason
Definition: services.h:1084
char who[NICKMAX]
Definition: services.h:1122
int16 chancount
Definition: services.h:579
int MysqlRetries
Definition: config.c:318
uint16 language
Definition: services.h:549
int db_mysql_init()
Definition: mysql.c:56
E SList sglines
Definition: extern.h:970
char password[PASSMAX]
Definition: services.h:518
int db_mysql_load_os_dbase(void)
Definition: mysql.c:1267
char * MysqlSock
Definition: config.c:317
void db_mysql_error(int severity, char *msg)
Definition: mysql.c:31
uint16 accesscount
Definition: services.h:550
MemoInfo memos
Definition: services.h:552
int16 memocount
Definition: services.h:505
union AutoKick::@1 u
unsigned int mysql_rand(void)
Definition: mysql.c:1978
#define AK_USED
Definition: services.h:634
E void alpha_insert_alias(NickAlias *na)
Definition: nickserv.c:1338
char name[CHANMAX]
Definition: services.h:654
#define AK_ISNICK
Definition: services.h:635
#define CA_SIZE
Definition: services.h:790
char * user
Definition: services.h:1080
time_t last_topic_time
Definition: services.h:667
char last_topic_setter[NICKMAX]
Definition: services.h:666
E ChannelInfo * chanlists[256]
Definition: extern.h:167
char * forbidreason
Definition: services.h:671
char * last_topic
Definition: services.h:665
char * MysqlHost
Definition: config.c:311
int mysql_is_connected
Definition: mysql.c:24
time_t expires
Definition: services.h:1135
E char * sstrdup(const char *s)
Definition: memory.c:105
time_t requested
Definition: services.h:520
NickCore * nc
Definition: services.h:533
char * mask
Definition: services.h:1130
E void * scalloc(long elsize, long els)
Definition: memory.c:55
int16 bantype
Definition: services.h:673
char * email
Definition: services.h:661
E NickCore * findcore(const char *nick)
Definition: nickserv.c:1263
time_t last_seen
Definition: services.h:596
char * display
Definition: services.h:542
uint16 flags
Definition: services.h:492
int db_mysql_save_news(NewsItem *ni)
Definition: mysql.c:957
char * db_mysql_secure(char *pass, int size)
Definition: mysql.c:248
E void E void E void fatal(const char *fmt,...) FORMAT(printf
E Exception * exceptions
Definition: extern.h:1081
int db_mysql_save_os_db(unsigned int maxucnt, unsigned int maxutime, SList *ak, SList *sgl, SList *sql, SList *szl)
Definition: mysql.c:819
void ** list
Definition: slist.h:21
BadWord * badwords
Definition: services.h:704
int db_mysql_load_cs_dbase(void)
Definition: mysql.c:1413
time_t seton
Definition: services.h:1098
uint32 flags
Definition: services.h:669
char * entry_message
Definition: services.h:688
E NewsItem * news
Definition: extern.h:911
int16 memomax
Definition: services.h:505
char * text
Definition: services.h:495
int16 count
Definition: slist.h:23
int16 flags
Definition: services.h:577
#define PASSMAX
Definition: config.h:65
uint16 bwcount
Definition: services.h:703
int32_t int32
Definition: db-merger.c:122
uint16 status
Definition: services.h:532
E BotInfo * findbot(char *nick)
Definition: db-merger.c:1989
char * db_mysql_quote_buffer(char *sql, int size)
Definition: mysql.c:191
char * reason
Definition: services.h:628
uint16 channelcount
Definition: services.h:553
uint16 accesscount
Definition: services.h:676
char * MysqlPass
Definition: config.c:313
uint32 mlock_off
Definition: services.h:681
int MysqlRetryGap
Definition: config.c:319
int db_mysql_open()
Definition: mysql.c:94
MYSQL_RES * mysql_res
Definition: mysql.c:20
char * reason
Definition: services.h:1133
char * real
Definition: services.h:576
char * by
Definition: services.h:1083
NickCore * nc
Definition: services.h:626
time_t time
Definition: services.h:1123
int db_mysql_close()
Definition: mysql.c:204
E void alog(const char *fmt,...) FORMAT(printf
int db_mysql_query(char *sql)
Definition: mysql.c:135
int db_mysql_load_ns_req_dbase(void)
Definition: mysql.c:1718
uint32 number
Definition: services.h:491
int db_mysql_save_cs_info(ChannelInfo *ci)
Definition: mysql.c:520
#define NS_TEMPORARY
Definition: services.h:1285
NickCore * nc
Definition: services.h:595
E void reset_levels(ChannelInfo *ci)
Definition: chanserv.c:2233
uint32 mlock_limit
Definition: services.h:682
time_t time_registered
Definition: services.h:530
E SList akills
Definition: extern.h:970
int db_mysql_try(const char *fmt,...)
Definition: mysql.c:218
int db_mysql_load_news(void)
Definition: mysql.c:1190
#define CHANMAX
Definition: config.h:56
E int delchan(ChannelInfo *ci)
Definition: chanserv.c:2063
E int debug
Definition: extern.h:775
char * vHost
Definition: services.h:1111
char * mask
Definition: services.h:625
char * db_mysql_quote(char *sql)
Definition: mysql.c:169
int db_mysql_save_hs_core(HostCore *hc)
Definition: mysql.c:1037
int16 floodlines
Definition: services.h:706
E int32 nnews
Definition: extern.h:910
char who[NICKMAX]
Definition: services.h:1132
E void alpha_insert_chan(ChannelInfo *ci)
Definition: db-merger.c:2010
char * nick
Definition: services.h:526
MYSQL_ROW row
Definition: mypasql.c:7
uint16 channelmax
Definition: services.h:554
#define NI_SERVICES_OPER
Definition: services.h:1302
time_t created
Definition: services.h:578
char * last_realname
Definition: services.h:528
int db_mysql_save_ns_core(NickCore *nc)
Definition: mysql.c:347
char * vIdent
Definition: services.h:1110
E int NSAllowKillImmed
Definition: extern.h:389
Definition: slist.h:20
int db_mysql_load_ns_dbase(void)
Definition: mysql.c:1763
E int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
E int16 nexceptions
Definition: extern.h:1082
E char ** ServicesRoots
Definition: extern.h:434
char * host
Definition: services.h:575
#define NICKMAX
Definition: config.h:62
char * mlock_key
Definition: services.h:683
char pass[PASSMAX]
Definition: services.h:543
int db_mysql_load_exceptions(void)
Definition: mysql.c:1232
time_t seton
Definition: services.h:1086
char * text
Definition: services.h:1121
MemoInfo memos
Definition: services.h:690
int16 floodsecs
Definition: services.h:706
SList aliases
Definition: services.h:559
int16 * ttb
Definition: services.h:701
char * nick
Definition: services.h:573
#define TTB_SIZE
Definition: services.h:819
time_t time_registered
Definition: services.h:663
E SList szlines
Definition: extern.h:970
MYSQL * mysql
Definition: mysql.c:19
E void * srealloc(void *oldptr, long newsize)
Definition: memory.c:80
time_t addtime
Definition: services.h:631
E BotInfo * makebot(char *nick)
Definition: botserv.c:578
AutoKick * akick
Definition: services.h:679
E void insert_requestnick(NickRequest *nr)
Definition: nickserv.c:1391
uint32 flags
Definition: services.h:548
ChanAccess * access
Definition: services.h:677
int16 capsmin
Definition: services.h:705
char * creator
Definition: services.h:630
E int enc_decrypt(const char *src, char *dest, int size)
Definition: encrypt.c:80
#define NI_SERVICES_ADMIN
Definition: services.h:1303
uint16 in_use
Definition: services.h:641
int16 * levels
Definition: services.h:674
time_t time
Definition: services.h:493
uint16 flags
Definition: services.h:623
int16 repeattimes
Definition: services.h:707
time_t last_seen
Definition: services.h:531
char * greet
Definition: services.h:545
E char * s_ChanServ
Definition: extern.h:285
E int slist_add(SList *slist, void *item)
Definition: slist.c:29
char * desc
Definition: services.h:659
E int32 news_size
Definition: extern.h:910
char * creator
Definition: services.h:1112
Memo * memos
Definition: services.h:506
int db_mysql_save_ns_req(NickRequest *nr)
Definition: mysql.c:304
E void E void log_perror(const char *fmt,...) FORMAT(printf
char * nick
Definition: services.h:516
uint16 in_use
Definition: services.h:593
E SList sqlines
Definition: extern.h:970
BotInfo * bi
Definition: services.h:699
E SList servopers
Definition: extern.h:972
NickCore * founder
Definition: services.h:655
char * last_usermask
Definition: services.h:529
char * reason
Definition: services.h:1097
uint16 type
Definition: services.h:1119
char * user
Definition: services.h:574
char * forbidby
Definition: services.h:670
int db_mysql_save_bs_core(BotInfo *bi)
Definition: mysql.c:1079
ChannelInfo * next
Definition: services.h:653
uint32 icq
Definition: services.h:546
char * MysqlUser
Definition: config.c:312
char * nick
Definition: services.h:1109
E int RootNumber
Definition: extern.h:435
int db_mysql_load_hs_dbase(void)
Definition: mysql.c:1154
uint32 mlock_on
Definition: services.h:681
char * email
Definition: services.h:544
NickCore * successor
Definition: services.h:656