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