]> jfr.im git - irc/gameservirc.git/blob - gameserv/tcpclient.cpp
bc0e9107d14fd2777f05732c4a9b150c5471f520
[irc/gameservirc.git] / gameserv / tcpclient.cpp
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"
16 #include "options.h"
17 #include "aClient.h"
18 #include "extern.h"
19 #include "flags.h"
20 #include "item.h"
21 #include "toplist.h"
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <fstream>
26 #include <stdlib.h>
27 #include <fcntl.h>
28 #include <signal.h>
29 #include <algorithm>
30
31 //#include <sys/types.h>
32 //#include <sys/wait.h>
33 //#include <errno.h>
34
35 using namespace std;
36
37 const string PACKAGE = "GameServ";
38 const string VERSION = "1.3.4 +devel";
39
40 int sock;
41 long lastrefresh;
42 long lastrollover;
43
44 list<aClient*> clients[U_TABLE_SIZE];
45
46 void save_lastrefresh();
47 void load_lastrefresh();
48 void load_lastrollover();
49 void save_lastrollover();
50 void prettyIntro();
51 void check_idles();
52 void clearClients();
53 void clearPlayers();
54 void clearItems();
55
56 // Make this a daemon
57 int daemon(int nochdir, int noclose);
58
59 // Close all file descriptors from >= fd
60 void closeall(int fd);
61
62 int main(int argc, char *argv[])
63 {
64 char buffer[1024], buf[1024];
65 memset(buffer, 0, 1024);
66 memset(buf, 0, 1024);
67 int connected;
68 long lastidlecheck;
69 char *cmd, *source = NULL, *conf;
70 srand(time(NULL));
71 conf = new char[16];
72 strcpy(conf, "gameserv.conf");
73
74 /*
75 * This needs to be fixed to work for any number of arguments in any
76 * order
77 *
78 */
79 if (argc > 1)
80 {
81 if ( argc > 2 || stricmp(argv[1], "--help") == 0)
82 {
83 cout << "Usage: gameserv [options] [configfile]" << endl;
84 cout << "Options:" << endl;
85 cout << "--help Displays this help dialogue" << endl;
86 delete []conf;
87 return 1;
88 }
89 delete []conf;
90 conf = argv[1];
91 }
92
93 prettyIntro();
94
95 if (load_config_file(conf))
96 {
97 cout << "Config file loaded ok...\n"
98 << "Turning into a daemon" << endl;
99 }
100 else
101 exit(2);
102
103 if (argc <= 1)
104 delete []conf;
105
106 // Turn into a daemon
107 if (daemon(1,0) < 0)
108 {
109 perror("Could not turn into a daemon");
110 exit(3);
111 }
112
113 if (load_items() == 0)
114 {
115 log("Error loading items");
116 goto end;
117 }
118
119 if (load_store() == 0)
120 {
121 log("Error loading store");
122 goto end;
123 }
124 if (load_tavern() == 0)
125 {
126 log("Error loading tavern");
127 goto end;
128 }
129
130 load_gs_dbase();
131 loadNews(newsdata, todaysnews);
132
133
134 if (load_masters() == false)
135 {
136 log("Error loading masters");
137 goto end;
138 }
139
140 if (load_monsters() == false)
141 {
142 log("Error loading monsters");
143 goto end;
144 }
145
146 if (!load_dragon())
147 {
148 log("Error loading dragon");
149 goto end;
150 }
151
152 if (load_levels() == false)
153 {
154 log("Error loading levels");
155 goto end;
156 }
157
158 shuttingdown = false;
159
160 char ignoreservers[32][256];
161 char *currentserver;
162 currentserver = strtok(ignoreserverslist, " ");
163 for (int server = 0; server < 32 && currentserver != NULL; server++)
164 {
165 strncpy(ignoreservers[server], currentserver, 255);
166 log("Placing %s on the server ignore list", currentserver);
167 currentserver = strtok(NULL, " ");
168 }
169
170 // This loop will retry the connection 3 times
171 for (int retry = 0; retry < 3 && !shuttingdown; retry++)
172 {
173 connected = 1;
174 load_lastrefresh();
175 load_lastrollover();
176
177 long int loadtime = time(NULL);
178 long int currentTime;
179 long int oldTime = loadtime;
180
181 lastidlecheck = loadtime;
182
183 #ifdef DEBUGMODE
184 log("Setting primary Idle Check timestamp: %ld", lastidlecheck);
185 #endif
186 bool loaded = false;
187
188 ignore_pipe();
189 sock = conn(remoteserver, remoteport, localhost, 0);
190 // sock = make_connection(remoteport, SOCK_STREAM, remoteserver);
191 if (sock == -1)
192 {
193 fprintf(stderr,"make_connection failed.\n");
194 unload_config_file();
195 return -1;
196 }
197 log("<S socket connected.");
198
199 #ifdef UNREAL
200 raw("PASS :%s", remotepass);
201 raw("SERVER %s 1 :%s", servername, servername);
202 raw("NICK <S 1 %d %s %s %s %d :%s v%s", time(NULL), gsident, gshost,
203 servername, time(NULL), PACKAGE.c_str(), VERSION.c_str());
204 raw(":<S JOIN %s", c_Forest);
205 raw(":<S MODE %s +tn", c_Forest);
206 #elif defined(BAHAMUT)
207 raw("PASS %s :TS", remotepass);
208 raw("SERVER %s 1 :%s", servername, servername);
209 raw("NICK <S 1 %d +w%s %s %s %s 0 :GameServ", time(NULL), (isBOper() ? "o" : ""),
210 gsident, gshost, servername);
211 raw(":%s SJOIN %d %d %s +nt :@<S", servername, time(NULL), time(NULL), c_Forest);
212 #elif defined(HYBRID)
213 raw("PASS %s :TS", remotepass);
214 raw("SERVER %s 1 :%s", servername, servername);
215 raw("NICK <S 1 %d +w%s %s %s %s :GameServ", time(NULL), (isBOper() ? "o" : ""),
216 gsident, gshost, servername);
217 raw(":%s SJOIN %ld %s +nt :@<S", servername, time(NULL), c_Forest);
218 #elif defined(ULTIMATE2)
219 raw("PASS %s :TS", remotepass);
220 raw("SERVER %s 1 :%s", servername, servername);
221 raw("NICK <S 1 %d %s %s %s 0 :GameServ",
222 time(NULL), gsident, gshost, servername);
223 if (isBOper())
224 raw(":<S mode <S +o");
225 raw(":<S JOIN %s", c_Forest);
226 #elif defined(PTLINK)
227 raw("PASS %s :TS", remotepass);
228 raw("SERVER %s 1 :%s", servername, servername);
229 raw("NICK <S 1 %d %s%s %s %s %s :GameServ", time(NULL), (isBOper() ? "+iow " : ""), gsident, gshost, gshost, servername);
230 raw(":%s SJOIN %d %s +nt :@<S", servername, time(NULL), c_Forest);
231 #elif defined(VLIFE)
232 raw("PASS %s :TS", remotepass);
233 raw("SERVER %s 1 %d :%s", servername, time(NULL), servername);
234 raw("NNICK <S 1 %d +w%s %s %s %s %s :GameServ", time(NULL),(isBOper() ? "o" : ""), gsident, gshost, gshost, servername);
235 raw(":%s SJOIN %d %s +nt :@<S", servername, time(NULL), c_Forest);
236 #elif defined(BAHAMUT8)
237 raw("PASS %s :TS", remotepass);
238 raw("SERVER %s %d :%s", servername, time(NULL), servername);
239 raw("NICK <S 1 %d +w%s %s %s %s 0 %d :GameServ", time(NULL), (isBOper() ? "o" : ""), gsident, gshost, servername, time(NULL));
240 raw(":%s SJOIN %d %d %s +nt :@<S", servername, time(NULL), time(NULL), c_Forest);
241 #elif defined(P10)
242 // Server numeric is: [] <-- must be unique
243 raw("PASS :%s", remotepass);
244 raw("SERVER %s 1 %d %d P10 []AAF :%s", servername, time(NULL), time(NULL), servername);
245 raw("[] N <S 1 %d %s %s %s DAqAoB %s :<S", time(NULL), gsident, gshost,
246 (isBOper() ? "+o" : ""), gsnum);
247 raw("[] B %s %d +tn %s:o", c_Forest, time(NULL) - 864000, gsnum);
248 #endif
249
250 #if defined(P10)
251 raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic);
252 raw("[] EB"); // End burst
253 #else
254 #ifndef HYBRID
255 #if defined(ULTIMATE2)
256 raw(":%s MODE %s +o <S %ld", servername, c_Forest,
257 time(NULL));
258 #else
259 raw(":<S MODE %s +o <S", c_Forest);
260 #endif
261 #endif
262 raw(":<S TOPIC %s :%s", c_Forest, c_ForestTopic);
263 #endif
264
265 #ifndef P10
266 if (isUseNickServ())
267 {
268 raw(":<S PRIVMSG %s :IDENTIFY %s", nsname, nspass);
269 }
270 #endif
271 sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to
272 David Duchene <dave@ltd.com> for pointing out the possible
273 buffer overflow resulting from the linefeed added below. */
274
275
276 #ifdef DEBUGMODE
277 log("Server: %s",buffer);
278 #endif
279
280 while (connected)
281 {
282 if (sock_gets(sock,buffer,sizeof(buffer)) == -1)
283 {
284 connected = 0;
285 }
286 strcpy(buf, buffer);
287
288 #if !defined(P10)
289 if (buffer[0] == ':')
290 {
291 source = strtok(buf, " ");
292 cmd = strtok(NULL, " ");
293 }
294 else
295 {
296 cmd = strtok(buf, " ");
297 }
298 #else
299 source = strtok(buf, " ");
300 cmd = strtok(NULL, " ");
301 #endif
302
303 #ifdef DEBUGMODE
304 log("Server: %s", buffer);
305 #endif
306
307 // Wait N seconds then we're loaded.
308 if (!loaded)
309 {
310 if (time(NULL) >= welcomedelay + loadtime)
311 {
312 loaded = true;
313 retry = 0; // Start the reconnection cycle over
314 }
315 }
316 else
317 {
318 long TIME = time(NULL);
319 if (TIME - lastidlecheck >= idlecheckperiod)
320 {
321 check_idles();
322 lastidlecheck = TIME;
323 }
324 }
325
326 // Refresh players and clear news if the time is up
327 currentTime = time(NULL);
328
329 if (isRolloverForestFights())
330 {
331 if (currentTime - lastrollover >= rolloverperiod)
332 {
333 rolloverall();
334 lastrollover = currentTime;
335 save_lastrollover();
336 notice(s_GameServ, c_Forest, "Adding %d forest fights to all players!", numrolloverfights);
337 }
338 }
339
340 if (currentTime - lastrefresh >= refreshperiod)
341 {
342 refreshall();
343 clearNews(todaysnews);
344 saveNews(newsdata, todaysnews);
345 lastrefresh = currentTime;
346 save_lastrefresh();
347 notice(s_GameServ, c_Forest, "Refreshing all players "\
348 "and resetting news!");
349 }
350
351 // Save the player data every updateperiod seconds
352 if (currentTime - oldTime >= updateperiod)
353 {
354 oldTime = currentTime;
355 log("Saving to %s", playerdata);
356
357 save_gs_dbase();
358 saveNews(newsdata, todaysnews);
359 if (isSavedNotice())
360 {
361 // Send notice to the channel of the update
362 notice(s_GameServ, c_Forest, "<S player data saved");
363 }
364 }
365
366
367 #if !defined(P10)
368 if (stricmp(cmd, "PING") == 0)
369 {
370 char *timestamp;
371 timestamp = strtok(NULL, "");
372 raw("PONG %s", timestamp);
373 }
374 #else
375 // P10 Ping
376 if (stricmp(cmd, "G") == 0)
377 {
378 char *timestamp;
379 timestamp = strtok(NULL, " ");
380 raw("[] Z [] %s 0 %s", timestamp + 1, timestamp);
381 }
382 #endif
383 #ifdef P10
384 else if (stricmp(cmd, "EB") == 0)
385 {
386 raw("[] EA");
387 }
388 #endif
389 else if (stricmp(cmd, "VERSION") == 0)
390 {
391 char *server;
392 server = strtok(NULL, " ");
393 server++;
394 raw(":%s 351 %s %s_%s. %s", servername, source+1, PACKAGE.c_str(), VERSION.c_str(), servername);
395 }
396 // Code indenting is clean up until here!
397 #if !defined(P10)
398 else if (strncmp(cmd, "NICK", 4) == 0
399 #ifdef VLIFE
400 || strncmp(cmd, "NNICK", 5) == 0
401 #endif
402 )
403 {
404 if (buffer[0] == ':')
405 {
406 aClient *tempPtr;
407 if ((tempPtr = find((source + 1))))
408 {
409 char *nick;
410 unsigned long oldhv, newhv;
411 nick = strtok(NULL, " ");
412 oldhv = iHASH((unsigned char *) tempPtr->getNick());
413 newhv = iHASH((unsigned char *) nick);
414 tempPtr->setNick(nick);
415 clients[oldhv].remove(tempPtr);
416 clients[newhv].push_back(tempPtr);
417 }
418 }
419 else
420 {
421 char *nick;
422 #else
423 } else if (stricmp(cmd, "N") == 0 && strlen(source) == 2) {
424 {
425 char *nick, *realnick;
426 realnick = strtok(NULL, " ");
427
428 for (int x = 0; x < 5; x++)
429 nick = strtok(NULL, " ");
430
431 if (nick[0] == '+')
432 {
433 #ifdef DEBUGMODE
434 log ("aClient has modes");
435 #endif
436 // Searching for the +r mode (extra parameter)
437 for (unsigned int count = 1; count < strlen(nick); count++)
438 {
439 if (nick[count] == 'r')
440 {
441 nick = strtok(NULL, " ");
442 break;
443 }
444 }
445 nick = strtok(NULL, " ");
446 }
447 #endif
448 aClient *newuser;
449
450 nick = strtok(NULL, " ");
451
452 #ifdef P10
453 newuser = new aClient(nick, realnick);
454 #else
455 newuser = new aClient(nick);
456 #endif
457
458
459 if (loaded)
460 if (isWelcome())
461 {
462 #ifdef P10
463 notice(s_GameServ, nick, welcomemsg, realnick);
464 #else
465 notice(s_GameServ, nick, welcomemsg, nick);
466 #endif
467 }
468 #ifdef P10
469 unsigned long hv = sHASH((unsigned char *) nick);
470 #else
471 unsigned long hv = iHASH((unsigned char *) nick);
472 #endif
473
474 #if defined(HYBRID) || defined(BAHAMUT) || defined(ULTIMATE2) || defined(PTLINK)
475 char *nickserver;
476 strtok(NULL, " ");
477 strtok(NULL, " ");
478 nickserver = strtok(NULL, " ");
479 if (nickserver[0] == '+')
480 strtok(NULL, " ");
481 strtok(NULL, " ");
482 nickserver = strtok(NULL, " ");
483 for (int x = 0; x < 32; x++)
484 {
485 if (stricmp(ignoreservers[x], nickserver) == 0)
486 {
487 setIgnore(newuser);
488 break;
489 }
490 }
491 #elif defined(UNREAL)
492 char *nickserver;
493 strtok(NULL, " ");
494 strtok(NULL, " ");
495 strtok(NULL, " ");
496 strtok(NULL, " ");
497 nickserver = strtok(NULL, " ");
498 for (int x = 0; x < 32; x++)
499 {
500 if (stricmp(ignoreservers[x], nickserver) == 0)
501 {
502 setIgnore(newuser);
503 break;
504 }
505 }
506 #endif
507 clients[hv].push_back(newuser);
508 }
509 #if defined(P10)
510 } else if (stricmp(cmd, "Q") == 0) {
511 // unsigned long hv = sHASH((unsigned char *) source);
512 #else
513 } else if (stricmp(cmd, "QUIT") == 0)
514 {
515
516 #endif
517 aClient *quitter;
518 char z = source[0];
519
520 if (z == ':')
521 source++;
522
523 unsigned long hv = iHASH((unsigned char *) source);
524 if (!(quitter = find(source)))
525 {
526 log("Fatal Error: could not find %s in the "\
527 "clients list", source);
528 goto end;
529 }
530
531 clients[hv].remove(quitter);
532 logout(quitter);
533
534 delete quitter;
535
536 if (z == ':')
537 source--;
538
539 #if defined(P10)
540 }
541 else if (stricmp(cmd, "P") == 0)
542 {
543 char *rest, *dest;
544 char *longname;
545 longname = new char[strlen(s_GameServ) + strlen(servername) + 2];
546
547 sprintf(longname, "<S@%s", servername);
548
549 dest = strtok(NULL, " ");
550 rest = strtok(NULL, "");
551 if (stricmp(dest, gsnum) == 0 || stricmp(dest, longname) == 0)
552 {
553 delete [] longname;
554 gameserv(source, rest);
555 }
556 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
557 {
558 delete [] longname;
559 forest(source, rest);
560 }
561 #else
562 }
563 else if (stricmp(cmd, "PRIVMSG") == 0)
564 {
565 char *rest, *dest;
566 dest = strtok(NULL, " ");
567 rest = strtok(NULL, "");
568 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
569 gameserv(source, rest);
570 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
571 forest(source, rest);
572 #endif
573 #if defined(P10)
574 } else if (stricmp(cmd, "J") == 0) {
575 #else
576 } else if (stricmp(cmd, "JOIN") == 0) {
577 #endif
578 char *channel;
579 aClient *joiner;
580 channel = strtok(NULL, " ");
581
582 char z = source[0];
583
584 if (z == ':')
585 source++;
586
587 joiner = find(source);
588
589 if (stricmp(channel, c_Forest) == 0 && is_playing(joiner))
590 {
591 #ifdef DEBUGMODE
592 log("Player %s (IRC: %s) joined %s",
593 joiner->stats->getName().c_str(),
594 #ifdef P10
595 joiner->getRealNick(),
596 #else
597 joiner->getNick(),
598 #endif
599 c_Forest);
600 #endif
601 raw(":<S MODE %s +v %s", c_Forest, (source));
602 }
603
604 if (z == ':')
605 source--;
606
607 #if defined(BAHAMUT)
608 } else if (stricmp(cmd, "SJOIN") == 0) {
609 char *channel, *nick, *tmp, *rest;
610 strtok(NULL, " "); // Ignore the TS
611 #ifndef HYBRID
612 strtok(NULL, " "); // Ignore the TS
613 #endif
614 channel = strtok(NULL, " ");
615 rest = strtok(NULL, "");
616 tmp = strchr(rest, ':');
617 tmp++;
618 nick = strtok(tmp, " ");
619 while (nick != NULL)
620 {
621 if (*nick == '@')
622 nick++;
623 if (*nick == '+')
624 nick++; // Assume for users set op and voice, they
625 // are never passed as +@nick
626 if (stricmp(channel, c_Forest) == 0 && is_playing(nick))
627 raw(":<S MODE %s +v %s", channel, nick);
628
629 nick = strtok(NULL, " ");
630 }
631 #endif
632 } else {
633 #ifdef DEBUGMODE
634 log("Unrecognized Message: cmd = %s source = %s", cmd, source);
635 #endif
636 }
637 }
638
639 } // for loop for connection retry
640
641 end:
642
643 save_gs_dbase();
644 save_dragon();
645 saveNews(newsdata, todaysnews);
646 clearClients();
647 clearPlayers();
648 clearItems();
649 delete_monsters();
650
651 #ifdef DEBUGMODE
652 log("<CLOSED>");
653 #endif
654
655 close(sock);
656 unload_config_file();
657 return 0;
658 }
659
660 aClient *find(char *nick)
661 {
662 return findbynick(nick);
663 }
664
665 aClient *find(const char *nick)
666 {
667 return findbynick(nick);
668 }
669
670 #ifdef P10
671
672 aClient *findbyrealnick(char *realnick)
673 {
674 ListNode <aClient> *newPtr;
675 unsigned long hv = sHASH((unsigned char *) realnick);
676 newPtr = clients[hv].First();
677
678 aClient *client = NULL;
679
680 while (newPtr)
681 {
682 client = newPtr->getData();
683 if (stricmp(client->getRealNick(), realnick) == 0)
684 return client;
685 client = NULL;
686 newPtr = newPtr->Next();
687 }
688 return client;
689 }
690
691 #else
692
693 aClient *findbyrealnick(char *realnick)
694 {
695 return findbynick(realnick);
696 }
697
698 #endif
699
700 aClient *findbynick(char *nick)
701 {
702 list<aClient*>::iterator iter;
703 #ifdef P10
704 unsigned long hv = sHASH((unsigned char *) nick);
705 #else
706 unsigned long hv = iHASH((unsigned char *) nick);
707 #endif
708
709 aClient *client = NULL;
710
711 for(iter = clients[hv].begin(); iter != clients[hv].end(); iter++)
712 {
713 client = (*iter);
714 #ifdef P10
715 if (strcmp(client->getNick(), nick) == 0)
716 {
717 #else
718 if (stricmp(client->getNick(), nick) == 0)
719 {
720 #endif
721 return client;
722 }
723 client = NULL;
724 }
725 return client;
726 }
727
728 Player *findplayer(const char *name)
729 {
730 list<Player*>::iterator iter;
731 Player *p;
732 unsigned long hv = iHASH((unsigned char *) name);
733 for (iter = players[hv].begin(); iter != players[hv].end(); iter++)
734 {
735 p = (*iter);
736 if (stricmp(p->getName().c_str(), name) == 0)
737 return p;
738 p = NULL;
739 }
740 return NULL;
741 }
742
743 void check_idles()
744 {
745 list<Player*>::iterator iter;
746 Player *p;
747
748 for (int x = 0; x < U_TABLE_SIZE; x++)
749 {
750 for (iter = players[x].begin(); iter != players[x].end(); iter++)
751 {
752 p = (*iter);
753
754 switch(p->getLevel())
755 {
756 case 1:
757 if ((time(NULL) - p->lastlogin) / 86400 >= level1expire)
758 {
759 logout(p->getClient());
760 return;
761 }
762 break;
763
764 default:
765 if ((time(NULL) - p->lastlogin) / 86400 >= defaultexpire)
766 {
767 logout(p->getClient());
768 return;
769 }
770 break;
771 }
772 if (timedOut(p))
773 {
774 timeOutEvent(p);
775 }
776 }
777 }
778 }
779
780 aClient *findbynick(const char *nick)
781 {
782 list<aClient*>::iterator iter;
783 #ifdef P10
784 unsigned long hv = sHASH((unsigned char *) nick);
785 #else
786 unsigned long hv = iHASH((unsigned char *) nick);
787 #endif
788
789 aClient *client = NULL;
790
791 for (iter = clients[hv].begin(); iter != clients[hv].end(); iter++)
792 {
793 client = (*iter);
794 #ifdef P10
795 if (strcmp(client->getNick(), nick) == 0)
796 #else
797 if (stricmp(client->getNick(), nick) == 0)
798 #endif
799 return client;
800 client = NULL;
801 }
802 return client;
803 }
804
805 /* daemon() - detach process from user and disappear into the background
806 * returns -1 on failure, but you can't do much except exit in that case
807 * since we may already have forked. This is based on the BSD version,
808 * so the caller is responsible for things like the umask, etc.
809 */
810
811 /* believed to work on all Posix systems */
812
813 int daemon(int nochdir, int noclose)
814 {
815 pid_t pid;
816 switch (pid = fork())
817 {
818 case 0: break;
819 case -1: return -1;
820 default: _exit(0); /* exit the original process */
821 }
822
823 if (setsid() < 0) /* shoudn't fail */
824 return -1;
825
826 /* dyke out this switch if you want to acquire a control tty in */
827 /* the future -- not normally advisable for daemons */
828
829 switch (pid = fork())
830 {
831 case 0: break;
832 case -1: return -1;
833 default:
834 ofstream outfile;
835 outfile.open(pidfile);
836 if (outfile.fail())
837 cerr << "Unable to open " << pidfile << endl;
838 outfile << pid << endl;
839 outfile.close();
840
841 _exit(0);
842 }
843
844 if (!nochdir)
845 chdir("/");
846
847 if (!noclose)
848 {
849 closeall(0);
850 open("/dev/null",O_RDWR);
851 dup(0); dup(0);
852 }
853
854 return 0;
855 }
856
857
858 /* closeall() -- close all FDs >= a specified value */
859
860 void closeall(int fd)
861 {
862 int fdlimit = sysconf(_SC_OPEN_MAX);
863
864 while (fd < fdlimit)
865 close(fd++);
866 }
867
868 void prettyIntro()
869 {
870 cout << endl;
871 cout << " GGGG AAA MM MM EEEEEEE SSSSS EEEEEEE RRRRRR VV VV " << endl;
872 cout << " GG GG AAAAA MMM MMM EE SS EE RR RR VV VV " << endl;
873 cout << "GG AA AA MM MM MM EEEEE SSSSS EEEEE RRRRRR VV VV " << endl;
874 cout << "GG GGG AAAAAAA MM MM EE SS EE RR RR VV VV " << endl;
875 cout << "G G AA AA MM MM EEEEEEE SSSSS EEEEEEE RR RR VVV" << endl;
876 cout << " GGGGG V\n\n" << endl;
877 cout << "Version: " << VERSION << endl;
878 cout << "http://www.gameserv.us - http://www.sourceforge.net/projects/gameservirc" << endl;
879 }
880
881 void load_lastrefresh()
882 {
883 ifstream infile;
884 infile.open(".gsrefresh");
885 if (infile.fail())
886 {
887 #ifdef DEBUGMODE
888 log("Error opening .gsrefresh");
889 #endif
890
891 generate:
892 long mytime = time(NULL);
893 #ifdef DEBUGMODE
894 log("Generating new refresh time");
895 #endif
896
897 // Just a safety measure... tho no one should
898 // get anywhere near the actual time as their refreshperiod
899 if (refreshperiod >= mytime)
900 {
901 log("Refresh period is greater than or equal to the actual time... setting it to 86400");
902 refreshperiod = 86400;
903 }
904
905 lastrefresh = mytime - (mytime % refreshperiod);
906
907 refreshall();
908 save_lastrefresh();
909 return;
910 }
911 infile >> lastrefresh;
912
913 infile.close();
914 if (lastrefresh < 0)
915 goto generate;
916 }
917
918 void load_lastrollover()
919 {
920 ifstream infile;
921 infile.open(".gsrollover");
922 if (infile.fail())
923 {
924 #ifdef DEBUGMODE
925 log("Error opening .gsrollover");
926 #endif
927
928 generate:
929 long mytime = time(NULL);
930 #ifdef DEBUGMODE
931 log("Generating new rollover time");
932 #endif
933 lastrollover = mytime;
934 return;
935 }
936 infile >> lastrollover;
937
938 infile.close();
939 if (lastrollover < 0)
940 goto generate;
941 }
942
943 void save_lastrefresh()
944 {
945 ofstream outfile;
946
947 outfile.open(".gsrefresh");
948
949 if (outfile.fail())
950 {
951 log("Error creating new file .gsrefresh");
952 return;
953 }
954 outfile << lastrefresh << endl << lastrollover;
955
956 outfile.close();
957 }
958
959 void save_lastrollover()
960 {
961 ofstream outfile;
962
963 outfile.open(".gsrollover");
964
965 if (outfile.fail())
966 {
967 log("Error creating new file .gsrollover");
968 return;
969 }
970 outfile << lastrollover << endl;
971 outfile.close();
972 }
973 void clearItems()
974 {
975 list<item*>::iterator iter;
976 for (iter = Items.begin(); iter != Items.end(); iter++)
977 {
978 delete (*iter);
979 Items.erase(iter);
980 }
981 }
982 void clearClients()
983 {
984 list<aClient*>::iterator iter;
985 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
986 {
987 for (iter = clients[x].begin(); iter != clients[x].end(); iter++)
988 {
989 delete (*iter);
990 clients[x].erase(iter);
991 }
992 }
993 }
994
995 void clearPlayers()
996 {
997 list<Player*>::iterator iter;
998 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
999 {
1000 for (iter = players[x].begin(); iter != players[x].end(); iter++)
1001 {
1002 delete (*iter);
1003 players[x].erase(iter);
1004 }
1005 }
1006 }