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