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