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