]> jfr.im git - irc/gameservirc.git/blame - gameserv/tcpclient.cpp
Fixed bug 966653
[irc/gameservirc.git] / gameserv / tcpclient.cpp
CommitLineData
85ce9d3e 1/*
2 * This file is provided for use with the unix-socket-faq. It is public
3 * domain, and may be copied freely. There is no copyright on it. The
4 * original work was by Vic Metcalfe (vic@brutus.tlug.org), and any
5 * modifications made to that work were made with the understanding that
6 * the finished work would be in the public domain.
7 *
8 * If you have found a bug, please pass it on to me at the above address
9 * acknowledging that there will be no copyright on your work.
10 *
11 * The most recent version of this file, and the unix-socket-faq can be
12 * found at http://www.interlog.com/~vic/sock-faq/.
13 */
14
15#include "sockhelp.h"
c7340cbd 16#include "options.h"
85ce9d3e 17#include "list.h"
18#include "aClient.h"
19#include "extern.h"
448a1531 20#include "flags.h"
85ce9d3e 21#include <stdio.h>
22#include <unistd.h>
23#include <string.h>
fb37ecc7 24#include <fstream>
85ce9d3e 25#include <stdlib.h>
ce61cdfa 26#include <fcntl.h>
27#include <signal.h>
28//#include <sys/types.h>
29//#include <sys/wait.h>
30//#include <errno.h>
31
fb37ecc7 32using std::ofstream;
33using std::ifstream;
ce61cdfa 34using std::cerr;
35using std::endl;
fb37ecc7 36
91c0b563 37char *PACKAGE = "GameServ";
4f7dd884 38char *VERSION = "1.2.3 +devel";
173302fe 39
85ce9d3e 40int sock;
abbfcdb9 41int day;
44ea29f7 42
7996e5fd 43List<aClient> clients[U_TABLE_SIZE];
85ce9d3e 44
abbfcdb9 45void save_day();
46void load_day();
15838737 47void prettyIntro();
40251952 48void check_idles();
44ea29f7 49
ce61cdfa 50// Make this a daemon
51int daemon(int nochdir, int noclose);
52
53// Close all file descriptors from >= fd
54void closeall(int fd);
55
624c0352 56int main(int argc, char *argv[])
85ce9d3e 57{
e3ede4a7 58 char buffer[1024], buf[1024];
59 memset(buffer, 0, 1024);
60 memset(buf, 0, 1024);
61 int connected;
62 long lastidlecheck;
63 char *cmd, *source = NULL, *conf;
64 srand(time(NULL));
65 conf = new char[16];
66 strcpy(conf, "gameserv.conf");
624c0352 67
1579dfa2 68 /*
69 * This needs to be fixed to work for any number of arguments in any
70 * order
71 *
72 */
624c0352 73 if (argc > 1)
74 {
75 if ( argc > 2 || stricmp(argv[1], "--help") == 0)
76 {
77 cout << "Usage: gameserv [options] [configfile]" << endl;
78 cout << "Options:" << endl;
79 cout << "--help Displays this help dialogue" << endl;
80 return 1;
81 }
e3ede4a7 82 delete []conf;
83 conf = argv[1];
624c0352 84 }
85
15838737 86 prettyIntro();
624c0352 87
88 if (load_config_file(conf))
89 {
90 cout << "Config file loaded ok...\n"
91 << "Turning into a daemon" << endl;
92 }
93 else
94 exit(2);
324ab87f 95
e3ede4a7 96 if (argc <= 1)
97 delete []conf;
98
ce61cdfa 99 // Turn into a daemon
100 if (daemon(1,0) < 0)
101 {
102 perror("Could not turn into a daemon");
448a1531 103 exit(3);
ce61cdfa 104 }
666feac6 105
05c527e6 106 init_masters();
107 load_gs_dbase();
5aa1d28d 108 cout << "Loading news" << endl;
109 loadNews(newsdata, todaysnews);
05c527e6 110
111 if (load_monsters() == false)
112 goto end;
113
448a1531 114 shuttingdown = false;
115
116 char ignoreservers[32][256];
117 char *currentserver;
118 currentserver = strtok(ignoreserverslist, " ");
119 for (int server = 0; server < 32 && currentserver != NULL; server++)
120 {
121 strncpy(ignoreservers[server], currentserver, 255);
122 log("Placing %s on the server ignore list", currentserver);
123 currentserver = strtok(NULL, " ");
124 }
05c527e6 125
126 strcpy(boss.name, "Red Dragon");
127 strcpy(boss.weapon, "Breath of Unholy Fire");
68379f96 128 boss.strength = 2500;
05c527e6 129 boss.gold = 2000000000;
130 boss.exp = 2000000000;
6d053d90 131 boss.maxhp = 6667;
132 boss.hp = 6667;
05c527e6 133 strcpy(boss.death, "You finally snuff out the deadly murderous "\
134 "dragon's dark flames. You have freed the land of its terror "\
135 "filled reign from above!");
136
448a1531 137
05c527e6 138 // This loop will retry the connection 3 times
139 for (int retry = 0; retry < 3 && !shuttingdown; retry++)
140 {
0b6098d5 141 connected = 1;
142 load_day();
05c527e6 143
448a1531 144
0b6098d5 145 long int loadtime = time(NULL);
146 long int currentTime;
147 long int oldTime = loadtime;
40251952 148
0b6098d5 149 lastidlecheck = loadtime;
05c527e6 150
0b6098d5 151 #ifdef DEBUGMODE
152 log("Setting primary Idle Check timestamp: %ld", lastidlecheck);
153 #endif
154 bool loaded = false;
155
156 ignore_pipe();
157 sock = make_connection(remoteport, SOCK_STREAM, remoteserver);
158 if (sock == -1) {
159 fprintf(stderr,"make_connection failed.\n");
85ce9d3e 160 unload_config_file();
161 return -1;
162 }
448a1531 163 log("%S socket connected.");
85ce9d3e 164
c7340cbd 165#ifdef UNREAL
85ce9d3e 166 raw("PROTOCTL NICKv2 VHP");
167 raw("PASS :%s", remotepass);
c7340cbd 168 raw("SERVER %s 1 :%s", servername, servername);
6f727d4c 169 raw("NICK %S 1 %d %S %s %s %d +w%s %s :%s v%s", time(NULL), gshost,
170 servername, time(NULL), (isBOper() ? "o" : ""), gshost, PACKAGE, VERSION);
85ce9d3e 171 raw(":%S JOIN %s", c_Forest);
03a4bdbb 172 raw(":%S MODE %s +tn", c_Forest);
c7340cbd 173#elif defined(BAHAMUT)
174 raw("PASS %s :TS", remotepass);
175 raw("SERVER %s 1 :%s", servername, servername);
6f727d4c 176 raw("NICK %S 1 %d +w%s %s %s %s 0 :GameServ", time(NULL), (isBOper() ? "o" : ""),
177 gsident, gshost, servername);
03a4bdbb 178 raw(":%s SJOIN %d %d %s +nt :@%S", servername, time(NULL), time(NULL), c_Forest);
581ec09e 179#elif defined(HYBRID)
180 raw("PASS %s :TS", remotepass);
181 raw("SERVER %s 1 :%s", servername, servername);
6f727d4c 182 raw("NICK %S 1 %d +w%s %s %s %s :GameServ", time(NULL), (isBOper() ? "o" : ""),
183 gsident, gshost, servername);
448a1531 184 raw(":%s SJOIN %ld %s +nt :@%S", servername, time(NULL), c_Forest);
7cc338f6 185#elif defined(ULTIMATE2)
186 raw("PASS %s :TS", remotepass);
187 raw("SERVER %s 1 :%s", servername, servername);
188 raw("NICK %S 1 %d %s %s %s 0 :GameServ",
189 time(NULL), gsident, gshost, servername);
190 if (isBOper())
191 raw(":%S mode %S +o");
192 raw(":%S JOIN %s", c_Forest);
e1c41a84 193#elif defined(P10)
194 // Server numeric is: [] <-- must be unique
195 raw("PASS :%s", remotepass);
196 raw("SERVER %s 1 %d %d P10 []AAF :%s", servername, time(NULL), time(NULL), servername);
6f727d4c 197 raw("[] N %S 1 %d %s %s %s DAqAoB %s :%S", time(NULL), gsident, gshost,
c8117c0f 198 (isBOper() ? "+o" : ""), gsnum);
03a4bdbb 199 raw("[] B %s %d +tn %s:o", c_Forest, time(NULL) - 864000, gsnum);
c7340cbd 200#endif
e1c41a84 201
202#if defined(P10)
203 raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic);
fc9d2643 204 raw("[] EB"); // End burst
581ec09e 205#else
7cc338f6 206 #ifndef HYBRID
207 #if defined(ULTIMATE2)
208 raw(":%s MODE %s +o %S %ld", servername, c_Forest,
209 time(NULL));
210 #else
211 raw(":%S MODE %s +o %S", c_Forest);
212 #endif
213 #endif
c7340cbd 214 raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic);
e1c41a84 215#endif
85ce9d3e 216
217 sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to
218 David Duchene <dave@ltd.com> for pointing out the possible
219 buffer overflow resulting from the linefeed added below. */
220
221
9f8c2acc 222 #ifdef DEBUGMODE
223 log("Server: %s",buffer);
224 #endif
225
85ce9d3e 226 while (connected) {
227 if (sock_gets(sock,buffer,sizeof(buffer)) == -1) {
228 connected = 0;
229 }
230 strcpy(buf, buffer);
231
e1c41a84 232 #if !defined(P10)
85ce9d3e 233 if (buffer[0] == ':')
234 {
235 source = strtok(buf, " ");
236 cmd = strtok(NULL, " ");
237 }
238 else
239 cmd = strtok(buf, " ");
e1c41a84 240 #else
241 source = strtok(buf, " ");
242 cmd = strtok(NULL, " ");
243 #endif
85ce9d3e 244
9f8c2acc 245 #ifdef DEBUGMODE
246 log("Server: %s", buffer);
247 #endif
5963944b 248
bf2cabcd 249 // Wait N seconds then we're loaded.
5963944b 250 if (!loaded)
251 {
922daad7 252 if (time(NULL) >= welcomedelay + loadtime)
05c527e6 253 {
5963944b 254 loaded = true;
05c527e6 255 retry = 0; // Start the reconnection cycle over
256 }
5963944b 257 }
40251952 258 else
259 {
260 long TIME = time(NULL);
261 if (TIME - lastidlecheck >= idlecheckperiod)
262 {
263 check_idles();
264 lastidlecheck = TIME;
265 }
266 }
5963944b 267
922daad7 268 // Save the player data every updateperiod seconds
269 currentTime = time(NULL);
270 if (currentTime - oldTime >= updateperiod)
271 {
272 oldTime = currentTime;
0b6098d5 273 log("Saving to %s", playerdata);
922daad7 274 save_gs_dbase();
5aa1d28d 275 saveNews(newsdata, todaysnews);
922daad7 276 }
277
e1c41a84 278
279 #if !defined(P10)
85ce9d3e 280 if (stricmp(cmd, "PING") == 0) {
0a1518fa 281 char *timestamp;
282 timestamp = strtok(NULL, "");
283 raw("PONG %s", timestamp);
e1c41a84 284 #else
285 if (stricmp(cmd, "G") == 0) {
286 char *timestamp;
287 timestamp = strtok(NULL, " ");
288 raw("[] Z [] %s 0 %s", timestamp + 1, timestamp);
289 #endif
fc9d2643 290 #ifdef P10
291 } else if (stricmp(cmd, "EB") == 0) {
292 raw("[] EA");
293 #endif
0501fe18 294 } else if (stricmp(cmd, "VERSION") == 0) {
295 char *server;
296 server = strtok(NULL, " ");
297 server++;
2e9db9c4 298 raw(":%s 351 %s %s_%s. %s", servername, source+1, PACKAGE, VERSION, servername);
ba2a880f 299 #if !defined(P10)
85ce9d3e 300 } else if (strncmp(cmd, "NICK", 4) == 0) {
301 if (buffer[0] == ':')
302 {
303 aClient *tempPtr;
28f552b8 304 if ((tempPtr = find((source + 1))))
85ce9d3e 305 {
306 char *nick;
59dc3990 307 unsigned long oldhv, newhv;
85ce9d3e 308 nick = strtok(NULL, " ");
448a1531 309 oldhv = iHASH((unsigned char *) tempPtr->getNick());
310 newhv = iHASH((unsigned char *) nick);
85ce9d3e 311 tempPtr->setNick(nick);
59dc3990 312 clients[oldhv].remove(tempPtr);
313 clients[newhv].insertAtBack(tempPtr);
85ce9d3e 314 }
315 }
316 else
317 {
318 char *nick;
ba2a880f 319 #else
320 } else if (stricmp(cmd, "N") == 0 && strlen(source) == 2) {
321 {
ce61cdfa 322 char *nick, *realnick;
323 realnick = strtok(NULL, " ");
ba2a880f 324
ce61cdfa 325 for (int x = 0; x < 5; x++)
ba2a880f 326 nick = strtok(NULL, " ");
fc9d2643 327
ba2a880f 328 if (nick[0] == '+')
fc9d2643 329 {
330 #ifdef DEBUGMODE
331 log ("aClient has modes");
332 #endif
333
334 // Searching for the +r mode (extra parameter)
335 for (unsigned int count = 1; count < strlen(nick); count++)
336 {
337 if (nick[count] == 'r')
338 {
339 nick = strtok(NULL, " ");
340 break;
341 }
342 }
343 nick = strtok(NULL, " ");
344 }
ba2a880f 345 #endif
448a1531 346 aClient *newuser, *temp;
ba2a880f 347
85ce9d3e 348 nick = strtok(NULL, " ");
ba2a880f 349
ce61cdfa 350 #ifdef P10
351 newuser = new aClient(nick, realnick);
352 #else
353 newuser = new aClient(nick);
354 #endif
355
356
5963944b 357 if (loaded)
18b84d11 358
359 if (isWelcome())
360 {
361 #ifdef P10
362 notice(s_GameServ, nick, welcomemsg, realnick);
363 #else
364 notice(s_GameServ, nick, welcomemsg, nick);
365 #endif
366 }
448a1531 367 #ifdef P10
c8117c0f 368 unsigned long hv = sHASH((unsigned char *) nick);
448a1531 369 #else
370 unsigned long hv = iHASH((unsigned char *) nick);
371 #endif
372
373 temp = clients[hv].insertAtBack(newuser);
374
7cc338f6 375 #if defined(HYBRID) || defined(BAHAMUT) || defined(ULTIMATE2)
448a1531 376 char *nickserver;
377 strtok(NULL, " ");
378 strtok(NULL, " ");
379 nickserver = strtok(NULL, " ");
380 if (nickserver[0] == '+')
381 strtok(NULL, " ");
382 strtok(NULL, " ");
903cd861 383 nickserver = strtok(NULL, " ");
384 for (int x = 0; x < 32; x++)
385 {
386 if (stricmp(ignoreservers[x], nickserver) == 0)
387 {
388 setIgnore(temp);
389 break;
390 }
391 }
392 #elif defined(UNREAL)
393 char *nickserver;
394 strtok(NULL, " ");
395 strtok(NULL, " ");
396 strtok(NULL, " ");
397 strtok(NULL, " ");
448a1531 398 nickserver = strtok(NULL, " ");
399 for (int x = 0; x < 32; x++)
400 {
401 if (stricmp(ignoreservers[x], nickserver) == 0)
402 {
403 setIgnore(temp);
404 break;
405 }
406 }
407 #endif
85ce9d3e 408 delete newuser;
409 }
ba2a880f 410 #if defined(P10)
411 } else if (stricmp(cmd, "Q") == 0) {
0b259dff 412// unsigned long hv = sHASH((unsigned char *) source);
ba2a880f 413 #else
85ce9d3e 414 } else if (stricmp(cmd, "QUIT") == 0) {
0b259dff 415// unsigned long hv = iHASH((unsigned char *) source);
ba2a880f 416 #endif
85ce9d3e 417 aClient *quitter;
fc9d2643 418 char z = source[0];
419
420 if (z == ':')
421 source++;
422
3f243b0b 423 if (!(quitter = find(source)))
424 {
425 log("Fatal Error: could not find %s in the "\
426 "clients list", source);
427 goto end;
428 }
429
430 logout(quitter);
431
432 if (z == ':')
433 source--;
434
435 /* Attempting to use the logout() function
fc9d2643 436 if ((quitter = find(source)))
7996e5fd 437 clients[hv].remove(quitter);
fc9d2643 438 if ((quitter = findIRCplayer(source)))
ee38284f 439 {
7f17db99 440 if (player_fight(quitter))
441 {
442 // Stop the fight on the other client
443 aClient *otherplayer = quitter->stats->battle;
444 otherplayer->stats->battle = NULL;
445 notice(s_GameServ, otherplayer->getNick(), "%s "\
446 "has quit IRC. The fight stops here.",
447 quitter->stats->name);
448 }
449 quitter->stats->battle = NULL;
450 quitter->stats->fight = NULL;
451 quitter->stats->master = NULL;
452
85bcf836 453 quitter->setNick("Not Playing");
a5316c52 454 #ifdef P10
85bcf836 455 quitter->setRealNick("Not Playing");
a5316c52 456 #endif
85bcf836 457 quitter->stats->client = NULL; // Unidentify them
ee38284f 458 }
3f243b0b 459 */
fc9d2643 460
ba2a880f 461 #if defined(P10)
462 } else if (stricmp(cmd, "P") == 0) {
463 char *rest, *dest;
464 char *longname;
465 longname = new char[strlen(s_GameServ) + strlen(servername) + 2];
466
467 sprintf(longname, "%S@%s", servername);
85ce9d3e 468
ba2a880f 469 dest = strtok(NULL, " ");
470 rest = strtok(NULL, "");
471 if (stricmp(dest, gsnum) == 0 || stricmp(dest, longname) == 0)
472 {
473 delete [] longname;
474 gameserv(source, rest);
475 }
6f727d4c 476 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
ba2a880f 477 {
478 delete [] longname;
479 forest(source, rest);
480 }
481 #else
85ce9d3e 482 } else if (stricmp(cmd, "PRIVMSG") == 0) {
483 char *rest, *dest;
484 dest = strtok(NULL, " ");
485 rest = strtok(NULL, "");
ad7dfaa0 486 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
85ce9d3e 487 gameserv(source, rest);
1546c3da 488 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
85ce9d3e 489 forest(source, rest);
ba2a880f 490 #endif
f2072f1a 491 #if defined(P10)
492 } else if (stricmp(cmd, "J") == 0) {
493 #else
85ce9d3e 494 } else if (stricmp(cmd, "JOIN") == 0) {
f2072f1a 495 #endif
85ce9d3e 496 char *channel;
f2072f1a 497 aClient *joiner;
85ce9d3e 498 channel = strtok(NULL, " ");
f2072f1a 499
500 char z = source[0];
501
502 if (z == ':')
503 source++;
504
505 joiner = find(source);
506
507 if (stricmp(channel, c_Forest) == 0 && is_playing(joiner))
508 {
509 #ifdef DEBUGMODE
510 log("Player %s (IRC: %s) joined %s",
511 joiner->stats->name,
512 #ifdef P10
513 joiner->getRealNick(),
514 #else
515 joiner->getNick(),
516 #endif
517 c_Forest);
518 #endif
519 raw(":%S MODE %s +v %s", c_Forest, (source));
520 }
521
522 if (z == ':')
523 source--;
c7340cbd 524
525 #if defined(BAHAMUT)
526 } else if (stricmp(cmd, "SJOIN") == 0) {
581ec09e 527 char *channel, *nick, *tmp, *rest;
c7340cbd 528 strtok(NULL, " "); // Ignore the TS
581ec09e 529#ifndef HYBRID
c7340cbd 530 strtok(NULL, " "); // Ignore the TS
581ec09e 531#endif
c7340cbd 532 channel = strtok(NULL, " ");
581ec09e 533 rest = strtok(NULL, "");
534 tmp = strchr(rest, ':');
535 tmp++;
536 nick = strtok(tmp, " ");
537 while (nick != NULL)
538 {
539 if (*nick == '@')
540 nick++;
541 if (*nick == '+')
542 nick++; // Assume for users set op and voice, they
543 // are never passed as +@nick
544 if (stricmp(channel, c_Forest) == 0 && is_playing(nick))
545 raw(":%S MODE %s +v %s", channel, nick);
546
547 nick = strtok(NULL, " ");
548 }
549#endif
85ce9d3e 550 } else {
9f8c2acc 551 #ifdef DEBUGMODE
552 log("Unrecognized Message: cmd = %s source = %s", cmd, source);
553 #endif
85ce9d3e 554 }
555 }
4dde2ed9 556
05c527e6 557 } // for loop for connection retry
558
4dde2ed9 559 end:
560
c8ada07e 561 save_gs_dbase();
5aa1d28d 562 saveNews(newsdata, todaysnews);
abbfcdb9 563 save_day();
4dde2ed9 564
c8ada07e 565 delete_monsters();
566 delete_masters();
567
9f8c2acc 568 #ifdef DEBUGMODE
569 log("<CLOSED>");
570 #endif
571
85ce9d3e 572 close(sock);
573 unload_config_file();
574 return 0;
575}
576
577aClient *find(char *nick)
578{
579 return findbynick(nick);
580}
581
582aClient *find(const char *nick)
583{
584 return findbynick(nick);
585}
586
ce61cdfa 587#ifdef P10
588
589aClient *findbyrealnick(char *realnick)
590{
591 ListNode <aClient> *newPtr;
448a1531 592 unsigned long hv = sHASH((unsigned char *) realnick);
7996e5fd 593 newPtr = clients[hv].First();
ce61cdfa 594
595 aClient *client = NULL;
596
597 while (newPtr)
598 {
599 client = newPtr->getData();
600 if (stricmp(client->getRealNick(), realnick) == 0)
601 return client;
602 client = NULL;
603 newPtr = newPtr->Next();
604 }
605 return client;
606}
4e5760fd 607
608#else
609
610aClient *findbyrealnick(char *realnick)
611{
612 return findbynick(realnick);
613}
614
ce61cdfa 615#endif
85ce9d3e 616
617aClient *findbynick(char *nick)
618{
619 ListNode <aClient> *newPtr;
448a1531 620 #ifdef P10
621 unsigned long hv = sHASH((unsigned char *) nick);
622 #else
623 unsigned long hv = iHASH((unsigned char *) nick);
624 #endif
625
7996e5fd 626 newPtr = clients[hv].First();
85ce9d3e 627
628 aClient *client = NULL;
629
630 while (newPtr)
631 {
632 client = newPtr->getData();
23ec3ff4 633 #ifdef P10
23ec3ff4 634 if (strcmp(client->getNick(), nick) == 0)
635 #else
636 if (stricmp(client->getNick(), nick) == 0)
637 #endif
85ce9d3e 638 return client;
639 client = NULL;
640 newPtr = newPtr->Next();
641 }
642 return client;
643}
644
ee38284f 645aClient *findIRCplayer(const char *nick)
646{
647 ListNode <aClient> *newPtr;
648 aClient *p = NULL;
649
448a1531 650 p = find(nick);
651
652 if (!is_playing(p))
653 return NULL;
654
655 unsigned long hv = iHASH((unsigned char *) p->stats->name);
656
7996e5fd 657 for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next())
ee38284f 658 {
659 p = newPtr->getData();
23ec3ff4 660 #ifdef P10
661 if (strcmp(p->getNick(), nick) == 0)
662 #else
663 if (stricmp(p->getNick(), nick) == 0)
664 #endif
ee38284f 665 return p;
666 p = NULL;
667 }
668 return NULL;
669}
40251952 670
0a1518fa 671aClient *findplayer(const char *name)
672{
673 ListNode <aClient> *newPtr;
674 Player *p = NULL;
448a1531 675 unsigned long hv = iHASH((unsigned char *) name);
7996e5fd 676 for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next())
0a1518fa 677 {
678 p = newPtr->getData()->stats;
679 if (stricmp(p->name, name) == 0)
680 return newPtr->getData();
681 p = NULL;
682 }
683 return NULL;
684}
685
40251952 686void check_idles()
687{
688 ListNode <aClient> *newPtr;
689 Player *p = NULL;
690
691 for (int x = 0; x < U_TABLE_SIZE; x++)
692 {
693 for (newPtr = players[x].First(); newPtr; newPtr = newPtr->Next())
694 {
695 p = newPtr->getData()->stats;
696 if (timedOut(p))
697 {
698 timeOutEvent(p);
699 }
700 }
701 }
702}
703
85ce9d3e 704aClient *findbynick(const char *nick)
705{
706 ListNode <aClient> *newPtr;
448a1531 707 #ifdef P10
708 unsigned long hv = sHASH((unsigned char *) nick);
709 #else
710 unsigned long hv = iHASH((unsigned char *) nick);
711 #endif
712
7996e5fd 713 newPtr = clients[hv].First();
85ce9d3e 714
715 aClient *client = NULL;
716
717 while (newPtr)
718 {
719 client = newPtr->getData();
23ec3ff4 720 #ifdef P10
721 if (strcmp(client->getNick(), nick) == 0)
722 #else
723 if (stricmp(client->getNick(), nick) == 0)
724 #endif
85ce9d3e 725 return client;
726 client = NULL;
727 newPtr = newPtr->Next();
728 }
729 return client;
730}
731
abbfcdb9 732void load_day()
44ea29f7 733{
734 ifstream infile;
735
abbfcdb9 736 infile.open(".gsday");
44ea29f7 737
738 if (infile.fail())
739 {
9f8c2acc 740 #ifdef DEBUGMODE
abbfcdb9 741 log("Error opening .gsday");
9f8c2acc 742 #endif
743
44ea29f7 744 generate:
9f8c2acc 745 #ifdef DEBUGMODE
abbfcdb9 746 log("Generating new day");
9f8c2acc 747 #endif
abbfcdb9 748 struct tm *tm;
749 time_t ti;
750 time(&ti);
751 tm = localtime(&ti);
752
753 day = tm->tm_mday;
754
755 save_day();
44ea29f7 756 return;
757 }
758
abbfcdb9 759 infile >> day;
44ea29f7 760 infile.close();
abbfcdb9 761 if (day < 1 || day > 31)
44ea29f7 762 goto generate;
763}
764
abbfcdb9 765void save_day()
44ea29f7 766{
767 ofstream outfile;
768
abbfcdb9 769 outfile.open(".gsday");
44ea29f7 770
771 if (outfile.fail())
772 {
abbfcdb9 773 log("Error creating new file .gsday");
44ea29f7 774 return;
775 }
776
abbfcdb9 777 outfile << day << endl;
44ea29f7 778
779 outfile.close();
780}
781
ce61cdfa 782/* daemon() - detach process from user and disappear into the background
783 * returns -1 on failure, but you can't do much except exit in that case
784 * since we may already have forked. This is based on the BSD version,
785 * so the caller is responsible for things like the umask, etc.
786 */
787
788/* believed to work on all Posix systems */
789
790int daemon(int nochdir, int noclose)
791{
792 pid_t pid;
793 switch (pid = fork())
794 {
795 case 0: break;
796 case -1: return -1;
797 default: _exit(0); /* exit the original process */
798 }
799
800 if (setsid() < 0) /* shoudn't fail */
801 return -1;
802
803 /* dyke out this switch if you want to acquire a control tty in */
804 /* the future -- not normally advisable for daemons */
805
806 switch (pid = fork())
807 {
808 case 0: break;
809 case -1: return -1;
810 default:
811 ofstream outfile;
69ae096c 812 outfile.open(pidfile);
ce61cdfa 813 if (outfile.fail())
69ae096c 814 cerr << "Unable to open " << pidfile << endl;
ce61cdfa 815 outfile << pid << endl;
816 outfile.close();
817
818 _exit(0);
819 }
820
821 if (!nochdir)
822 chdir("/");
823
824 if (!noclose)
825 {
826 closeall(0);
827 open("/dev/null",O_RDWR);
828 dup(0); dup(0);
829 }
830
831 return 0;
832}
833
834
835/* closeall() -- close all FDs >= a specified value */
836
837void closeall(int fd)
838{
839 int fdlimit = sysconf(_SC_OPEN_MAX);
840
841 while (fd < fdlimit)
842 close(fd++);
843}
844
15838737 845void prettyIntro()
846{
847cout << endl;
848cout << " GGGG AAA MM MM EEEEEEE SSSSS EEEEEEE RRRRRR VV VV " << endl;
849cout << " GG GG AAAAA MMM MMM EE SS EE RR RR VV VV " << endl;
850cout << "GG AA AA MM MM MM EEEEE SSSSS EEEEE RRRRRR VV VV " << endl;
851cout << "GG GGG AAAAAAA MM MM EE SS EE RR RR VV VV " << endl;
852cout << "G G AA AA MM MM EEEEEEE SSSSS EEEEEEE RR RR VVV" << endl;
853cout << " GGGGG V\n\n" << endl;
854cout << "Version: " << VERSION << endl;
855}