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