]> jfr.im git - irc/gameservirc.git/blame - gameserv/tcpclient.cpp
*** empty log message ***
[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);
e1c41a84 185#elif defined(P10)
186 // Server numeric is: [] <-- must be unique
187 raw("PASS :%s", remotepass);
188 raw("SERVER %s 1 %d %d P10 []AAF :%s", servername, time(NULL), time(NULL), servername);
6f727d4c 189 raw("[] N %S 1 %d %s %s %s DAqAoB %s :%S", time(NULL), gsident, gshost,
c8117c0f 190 (isBOper() ? "+o" : ""), gsnum);
03a4bdbb 191 raw("[] B %s %d +tn %s:o", c_Forest, time(NULL) - 864000, gsnum);
c7340cbd 192#endif
e1c41a84 193
194#if defined(P10)
195 raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic);
fc9d2643 196 raw("[] EB"); // End burst
581ec09e 197#else
198#ifndef HYBRID
85ce9d3e 199 raw(":%S MODE %s +o %S", c_Forest);
581ec09e 200#endif
c7340cbd 201 raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic);
e1c41a84 202#endif
85ce9d3e 203
204 sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to
205 David Duchene <dave@ltd.com> for pointing out the possible
206 buffer overflow resulting from the linefeed added below. */
207
208
9f8c2acc 209 #ifdef DEBUGMODE
210 log("Server: %s",buffer);
211 #endif
212
85ce9d3e 213 while (connected) {
214 if (sock_gets(sock,buffer,sizeof(buffer)) == -1) {
215 connected = 0;
216 }
217 strcpy(buf, buffer);
218
e1c41a84 219 #if !defined(P10)
85ce9d3e 220 if (buffer[0] == ':')
221 {
222 source = strtok(buf, " ");
223 cmd = strtok(NULL, " ");
224 }
225 else
226 cmd = strtok(buf, " ");
e1c41a84 227 #else
228 source = strtok(buf, " ");
229 cmd = strtok(NULL, " ");
230 #endif
85ce9d3e 231
9f8c2acc 232 #ifdef DEBUGMODE
233 log("Server: %s", buffer);
234 #endif
5963944b 235
bf2cabcd 236 // Wait N seconds then we're loaded.
5963944b 237 if (!loaded)
238 {
922daad7 239 if (time(NULL) >= welcomedelay + loadtime)
05c527e6 240 {
5963944b 241 loaded = true;
05c527e6 242 retry = 0; // Start the reconnection cycle over
243 }
5963944b 244 }
40251952 245 else
246 {
247 long TIME = time(NULL);
248 if (TIME - lastidlecheck >= idlecheckperiod)
249 {
250 check_idles();
251 lastidlecheck = TIME;
252 }
253 }
5963944b 254
922daad7 255 // Save the player data every updateperiod seconds
256 currentTime = time(NULL);
257 if (currentTime - oldTime >= updateperiod)
258 {
259 oldTime = currentTime;
0b6098d5 260 log("Saving to %s", playerdata);
922daad7 261 save_gs_dbase();
5aa1d28d 262 saveNews(newsdata, todaysnews);
922daad7 263 }
264
e1c41a84 265
266 #if !defined(P10)
85ce9d3e 267 if (stricmp(cmd, "PING") == 0) {
0a1518fa 268 char *timestamp;
269 timestamp = strtok(NULL, "");
270 raw("PONG %s", timestamp);
e1c41a84 271 #else
272 if (stricmp(cmd, "G") == 0) {
273 char *timestamp;
274 timestamp = strtok(NULL, " ");
275 raw("[] Z [] %s 0 %s", timestamp + 1, timestamp);
276 #endif
fc9d2643 277 #ifdef P10
278 } else if (stricmp(cmd, "EB") == 0) {
279 raw("[] EA");
280 #endif
0501fe18 281 } else if (stricmp(cmd, "VERSION") == 0) {
282 char *server;
283 server = strtok(NULL, " ");
284 server++;
2e9db9c4 285 raw(":%s 351 %s %s_%s. %s", servername, source+1, PACKAGE, VERSION, servername);
ba2a880f 286 #if !defined(P10)
85ce9d3e 287 } else if (strncmp(cmd, "NICK", 4) == 0) {
288 if (buffer[0] == ':')
289 {
290 aClient *tempPtr;
28f552b8 291 if ((tempPtr = find((source + 1))))
85ce9d3e 292 {
293 char *nick;
59dc3990 294 unsigned long oldhv, newhv;
85ce9d3e 295 nick = strtok(NULL, " ");
448a1531 296 oldhv = iHASH((unsigned char *) tempPtr->getNick());
297 newhv = iHASH((unsigned char *) nick);
85ce9d3e 298 tempPtr->setNick(nick);
59dc3990 299 clients[oldhv].remove(tempPtr);
300 clients[newhv].insertAtBack(tempPtr);
85ce9d3e 301 }
302 }
303 else
304 {
305 char *nick;
ba2a880f 306 #else
307 } else if (stricmp(cmd, "N") == 0 && strlen(source) == 2) {
308 {
ce61cdfa 309 char *nick, *realnick;
310 realnick = strtok(NULL, " ");
ba2a880f 311
ce61cdfa 312 for (int x = 0; x < 5; x++)
ba2a880f 313 nick = strtok(NULL, " ");
fc9d2643 314
ba2a880f 315 if (nick[0] == '+')
fc9d2643 316 {
317 #ifdef DEBUGMODE
318 log ("aClient has modes");
319 #endif
320
321 // Searching for the +r mode (extra parameter)
322 for (unsigned int count = 1; count < strlen(nick); count++)
323 {
324 if (nick[count] == 'r')
325 {
326 nick = strtok(NULL, " ");
327 break;
328 }
329 }
330 nick = strtok(NULL, " ");
331 }
ba2a880f 332 #endif
448a1531 333 aClient *newuser, *temp;
ba2a880f 334
85ce9d3e 335 nick = strtok(NULL, " ");
ba2a880f 336
ce61cdfa 337 #ifdef P10
338 newuser = new aClient(nick, realnick);
339 #else
340 newuser = new aClient(nick);
341 #endif
342
343
5963944b 344 if (loaded)
18b84d11 345
346 if (isWelcome())
347 {
348 #ifdef P10
349 notice(s_GameServ, nick, welcomemsg, realnick);
350 #else
351 notice(s_GameServ, nick, welcomemsg, nick);
352 #endif
353 }
448a1531 354 #ifdef P10
c8117c0f 355 unsigned long hv = sHASH((unsigned char *) nick);
448a1531 356 #else
357 unsigned long hv = iHASH((unsigned char *) nick);
358 #endif
359
360 temp = clients[hv].insertAtBack(newuser);
361
69fb5a93 362 #if defined(HYBRID) || defined(BAHAMUT)
448a1531 363 char *nickserver;
364 strtok(NULL, " ");
365 strtok(NULL, " ");
366 nickserver = strtok(NULL, " ");
367 if (nickserver[0] == '+')
368 strtok(NULL, " ");
369 strtok(NULL, " ");
370
903cd861 371 nickserver = strtok(NULL, " ");
372 for (int x = 0; x < 32; x++)
373 {
374 if (stricmp(ignoreservers[x], nickserver) == 0)
375 {
376 setIgnore(temp);
377 break;
378 }
379 }
380 #elif defined(UNREAL)
381 char *nickserver;
382 strtok(NULL, " ");
383 strtok(NULL, " ");
384 strtok(NULL, " ");
385 strtok(NULL, " ");
448a1531 386 nickserver = strtok(NULL, " ");
387 for (int x = 0; x < 32; x++)
388 {
389 if (stricmp(ignoreservers[x], nickserver) == 0)
390 {
391 setIgnore(temp);
392 break;
393 }
394 }
395 #endif
85ce9d3e 396 delete newuser;
397 }
ba2a880f 398 #if defined(P10)
399 } else if (stricmp(cmd, "Q") == 0) {
0b259dff 400// unsigned long hv = sHASH((unsigned char *) source);
ba2a880f 401 #else
85ce9d3e 402 } else if (stricmp(cmd, "QUIT") == 0) {
0b259dff 403// unsigned long hv = iHASH((unsigned char *) source);
ba2a880f 404 #endif
85ce9d3e 405 aClient *quitter;
fc9d2643 406 char z = source[0];
407
408 if (z == ':')
409 source++;
410
3f243b0b 411 if (!(quitter = find(source)))
412 {
413 log("Fatal Error: could not find %s in the "\
414 "clients list", source);
415 goto end;
416 }
417
418 logout(quitter);
419
420 if (z == ':')
421 source--;
422
423 /* Attempting to use the logout() function
fc9d2643 424 if ((quitter = find(source)))
7996e5fd 425 clients[hv].remove(quitter);
fc9d2643 426 if ((quitter = findIRCplayer(source)))
ee38284f 427 {
7f17db99 428 if (player_fight(quitter))
429 {
430 // Stop the fight on the other client
431 aClient *otherplayer = quitter->stats->battle;
432 otherplayer->stats->battle = NULL;
433 notice(s_GameServ, otherplayer->getNick(), "%s "\
434 "has quit IRC. The fight stops here.",
435 quitter->stats->name);
436 }
437 quitter->stats->battle = NULL;
438 quitter->stats->fight = NULL;
439 quitter->stats->master = NULL;
440
85bcf836 441 quitter->setNick("Not Playing");
a5316c52 442 #ifdef P10
85bcf836 443 quitter->setRealNick("Not Playing");
a5316c52 444 #endif
85bcf836 445 quitter->stats->client = NULL; // Unidentify them
ee38284f 446 }
3f243b0b 447 */
fc9d2643 448
ba2a880f 449 #if defined(P10)
450 } else if (stricmp(cmd, "P") == 0) {
451 char *rest, *dest;
452 char *longname;
453 longname = new char[strlen(s_GameServ) + strlen(servername) + 2];
454
455 sprintf(longname, "%S@%s", servername);
85ce9d3e 456
ba2a880f 457 dest = strtok(NULL, " ");
458 rest = strtok(NULL, "");
459 if (stricmp(dest, gsnum) == 0 || stricmp(dest, longname) == 0)
460 {
461 delete [] longname;
462 gameserv(source, rest);
463 }
6f727d4c 464 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
ba2a880f 465 {
466 delete [] longname;
467 forest(source, rest);
468 }
469 #else
85ce9d3e 470 } else if (stricmp(cmd, "PRIVMSG") == 0) {
471 char *rest, *dest;
472 dest = strtok(NULL, " ");
473 rest = strtok(NULL, "");
ad7dfaa0 474 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
85ce9d3e 475 gameserv(source, rest);
1546c3da 476 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
85ce9d3e 477 forest(source, rest);
ba2a880f 478 #endif
f2072f1a 479 #if defined(P10)
480 } else if (stricmp(cmd, "J") == 0) {
481 #else
85ce9d3e 482 } else if (stricmp(cmd, "JOIN") == 0) {
f2072f1a 483 #endif
85ce9d3e 484 char *channel;
f2072f1a 485 aClient *joiner;
85ce9d3e 486 channel = strtok(NULL, " ");
f2072f1a 487
488 char z = source[0];
489
490 if (z == ':')
491 source++;
492
493 joiner = find(source);
494
495 if (stricmp(channel, c_Forest) == 0 && is_playing(joiner))
496 {
497 #ifdef DEBUGMODE
498 log("Player %s (IRC: %s) joined %s",
499 joiner->stats->name,
500 #ifdef P10
501 joiner->getRealNick(),
502 #else
503 joiner->getNick(),
504 #endif
505 c_Forest);
506 #endif
507 raw(":%S MODE %s +v %s", c_Forest, (source));
508 }
509
510 if (z == ':')
511 source--;
c7340cbd 512
513 #if defined(BAHAMUT)
514 } else if (stricmp(cmd, "SJOIN") == 0) {
581ec09e 515 char *channel, *nick, *tmp, *rest;
c7340cbd 516 strtok(NULL, " "); // Ignore the TS
581ec09e 517#ifndef HYBRID
c7340cbd 518 strtok(NULL, " "); // Ignore the TS
581ec09e 519#endif
c7340cbd 520 channel = strtok(NULL, " ");
581ec09e 521 rest = strtok(NULL, "");
522 tmp = strchr(rest, ':');
523 tmp++;
524 nick = strtok(tmp, " ");
525 while (nick != NULL)
526 {
527 if (*nick == '@')
528 nick++;
529 if (*nick == '+')
530 nick++; // Assume for users set op and voice, they
531 // are never passed as +@nick
532 if (stricmp(channel, c_Forest) == 0 && is_playing(nick))
533 raw(":%S MODE %s +v %s", channel, nick);
534
535 nick = strtok(NULL, " ");
536 }
537#endif
85ce9d3e 538 } else {
9f8c2acc 539 #ifdef DEBUGMODE
540 log("Unrecognized Message: cmd = %s source = %s", cmd, source);
541 #endif
85ce9d3e 542 }
543 }
4dde2ed9 544
05c527e6 545 } // for loop for connection retry
546
4dde2ed9 547 end:
548
c8ada07e 549 save_gs_dbase();
5aa1d28d 550 saveNews(newsdata, todaysnews);
abbfcdb9 551 save_day();
4dde2ed9 552
c8ada07e 553 delete_monsters();
554 delete_masters();
555
9f8c2acc 556 #ifdef DEBUGMODE
557 log("<CLOSED>");
558 #endif
559
85ce9d3e 560 close(sock);
561 unload_config_file();
562 return 0;
563}
564
565aClient *find(char *nick)
566{
567 return findbynick(nick);
568}
569
570aClient *find(const char *nick)
571{
572 return findbynick(nick);
573}
574
ce61cdfa 575#ifdef P10
576
577aClient *findbyrealnick(char *realnick)
578{
579 ListNode <aClient> *newPtr;
448a1531 580 unsigned long hv = sHASH((unsigned char *) realnick);
7996e5fd 581 newPtr = clients[hv].First();
ce61cdfa 582
583 aClient *client = NULL;
584
585 while (newPtr)
586 {
587 client = newPtr->getData();
588 if (stricmp(client->getRealNick(), realnick) == 0)
589 return client;
590 client = NULL;
591 newPtr = newPtr->Next();
592 }
593 return client;
594}
4e5760fd 595
596#else
597
598aClient *findbyrealnick(char *realnick)
599{
600 return findbynick(realnick);
601}
602
ce61cdfa 603#endif
85ce9d3e 604
605aClient *findbynick(char *nick)
606{
607 ListNode <aClient> *newPtr;
448a1531 608 #ifdef P10
609 unsigned long hv = sHASH((unsigned char *) nick);
610 #else
611 unsigned long hv = iHASH((unsigned char *) nick);
612 #endif
613
7996e5fd 614 newPtr = clients[hv].First();
85ce9d3e 615
616 aClient *client = NULL;
617
618 while (newPtr)
619 {
620 client = newPtr->getData();
23ec3ff4 621 #ifdef P10
23ec3ff4 622 if (strcmp(client->getNick(), nick) == 0)
623 #else
624 if (stricmp(client->getNick(), nick) == 0)
625 #endif
85ce9d3e 626 return client;
627 client = NULL;
628 newPtr = newPtr->Next();
629 }
630 return client;
631}
632
ee38284f 633aClient *findIRCplayer(const char *nick)
634{
635 ListNode <aClient> *newPtr;
636 aClient *p = NULL;
637
448a1531 638 p = find(nick);
639
640 if (!is_playing(p))
641 return NULL;
642
643 unsigned long hv = iHASH((unsigned char *) p->stats->name);
644
7996e5fd 645 for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next())
ee38284f 646 {
647 p = newPtr->getData();
23ec3ff4 648 #ifdef P10
649 if (strcmp(p->getNick(), nick) == 0)
650 #else
651 if (stricmp(p->getNick(), nick) == 0)
652 #endif
ee38284f 653 return p;
654 p = NULL;
655 }
656 return NULL;
657}
40251952 658
0a1518fa 659aClient *findplayer(const char *name)
660{
661 ListNode <aClient> *newPtr;
662 Player *p = NULL;
448a1531 663 unsigned long hv = iHASH((unsigned char *) name);
7996e5fd 664 for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next())
0a1518fa 665 {
666 p = newPtr->getData()->stats;
667 if (stricmp(p->name, name) == 0)
668 return newPtr->getData();
669 p = NULL;
670 }
671 return NULL;
672}
673
40251952 674void check_idles()
675{
676 ListNode <aClient> *newPtr;
677 Player *p = NULL;
678
679 for (int x = 0; x < U_TABLE_SIZE; x++)
680 {
681 for (newPtr = players[x].First(); newPtr; newPtr = newPtr->Next())
682 {
683 p = newPtr->getData()->stats;
684 if (timedOut(p))
685 {
686 timeOutEvent(p);
687 }
688 }
689 }
690}
691
85ce9d3e 692aClient *findbynick(const char *nick)
693{
694 ListNode <aClient> *newPtr;
448a1531 695 #ifdef P10
696 unsigned long hv = sHASH((unsigned char *) nick);
697 #else
698 unsigned long hv = iHASH((unsigned char *) nick);
699 #endif
700
7996e5fd 701 newPtr = clients[hv].First();
85ce9d3e 702
703 aClient *client = NULL;
704
705 while (newPtr)
706 {
707 client = newPtr->getData();
23ec3ff4 708 #ifdef P10
709 if (strcmp(client->getNick(), nick) == 0)
710 #else
711 if (stricmp(client->getNick(), nick) == 0)
712 #endif
85ce9d3e 713 return client;
714 client = NULL;
715 newPtr = newPtr->Next();
716 }
717 return client;
718}
719
abbfcdb9 720void load_day()
44ea29f7 721{
722 ifstream infile;
723
abbfcdb9 724 infile.open(".gsday");
44ea29f7 725
726 if (infile.fail())
727 {
9f8c2acc 728 #ifdef DEBUGMODE
abbfcdb9 729 log("Error opening .gsday");
9f8c2acc 730 #endif
731
44ea29f7 732 generate:
9f8c2acc 733 #ifdef DEBUGMODE
abbfcdb9 734 log("Generating new day");
9f8c2acc 735 #endif
abbfcdb9 736 struct tm *tm;
737 time_t ti;
738 time(&ti);
739 tm = localtime(&ti);
740
741 day = tm->tm_mday;
742
743 save_day();
44ea29f7 744 return;
745 }
746
abbfcdb9 747 infile >> day;
44ea29f7 748 infile.close();
abbfcdb9 749 if (day < 1 || day > 31)
44ea29f7 750 goto generate;
751}
752
abbfcdb9 753void save_day()
44ea29f7 754{
755 ofstream outfile;
756
abbfcdb9 757 outfile.open(".gsday");
44ea29f7 758
759 if (outfile.fail())
760 {
abbfcdb9 761 log("Error creating new file .gsday");
44ea29f7 762 return;
763 }
764
abbfcdb9 765 outfile << day << endl;
44ea29f7 766
767 outfile.close();
768}
769
ce61cdfa 770/* daemon() - detach process from user and disappear into the background
771 * returns -1 on failure, but you can't do much except exit in that case
772 * since we may already have forked. This is based on the BSD version,
773 * so the caller is responsible for things like the umask, etc.
774 */
775
776/* believed to work on all Posix systems */
777
778int daemon(int nochdir, int noclose)
779{
780 pid_t pid;
781 switch (pid = fork())
782 {
783 case 0: break;
784 case -1: return -1;
785 default: _exit(0); /* exit the original process */
786 }
787
788 if (setsid() < 0) /* shoudn't fail */
789 return -1;
790
791 /* dyke out this switch if you want to acquire a control tty in */
792 /* the future -- not normally advisable for daemons */
793
794 switch (pid = fork())
795 {
796 case 0: break;
797 case -1: return -1;
798 default:
799 ofstream outfile;
69ae096c 800 outfile.open(pidfile);
ce61cdfa 801 if (outfile.fail())
69ae096c 802 cerr << "Unable to open " << pidfile << endl;
ce61cdfa 803 outfile << pid << endl;
804 outfile.close();
805
806 _exit(0);
807 }
808
809 if (!nochdir)
810 chdir("/");
811
812 if (!noclose)
813 {
814 closeall(0);
815 open("/dev/null",O_RDWR);
816 dup(0); dup(0);
817 }
818
819 return 0;
820}
821
822
823/* closeall() -- close all FDs >= a specified value */
824
825void closeall(int fd)
826{
827 int fdlimit = sysconf(_SC_OPEN_MAX);
828
829 while (fd < fdlimit)
830 close(fd++);
831}
832
15838737 833void prettyIntro()
834{
835cout << endl;
836cout << " GGGG AAA MM MM EEEEEEE SSSSS EEEEEEE RRRRRR VV VV " << endl;
837cout << " GG GG AAAAA MMM MMM EE SS EE RR RR VV VV " << endl;
838cout << "GG AA AA MM MM MM EEEEE SSSSS EEEEE RRRRRR VV VV " << endl;
839cout << "GG GGG AAAAAAA MM MM EE SS EE RR RR VV VV " << endl;
840cout << "G G AA AA MM MM EEEEEEE SSSSS EEEEEEE RR RR VVV" << endl;
841cout << " GGGGG V\n\n" << endl;
842cout << "Version: " << VERSION << endl;
843}