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