Logo
~Apps~
~Projects~
~Contact~

eol.cpp File Reference

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <libmysqlwrapped.h>
#include <libeamon.h>
#include "a.h"
#include "ParserIO.h"
#include "Parser.h"
#include "THREAD.h"
#include "eol.h"

Include dependency graph for eol.cpp:

Go to the source code of this file.


Defines

#define PRINT(x)
#define INPUT(x)

Functions

void * sock_thread (void *zz)
void * listen_thread (void *zz)
void sighandler (int sig)
void sigpipe (int sig)
void strzcpy (char *slask, char *s)
void read_games (void)
int main (int argc, char *argv[])

Variables

ADVadvbase = NULL
EVENTeventbase = NULL
THREADthreadbase = NULL
static int quit_listen = 0
static int quit_main = 0
pthread_mutex_t event_mutex
pthread_mutex_t thread_mutex

Define Documentation

#define INPUT  ) 
 

Value:

n = 200; \
        if (pThread -> read_text(x, &n) == -1) \
        { \
                perror("read() failed"); \
                goto crap; \
        }

Definition at line 35 of file eol.cpp.

Referenced by THREAD::get_adv(), and sock_thread().

#define PRINT  ) 
 

Value:

if (pThread -> write_text(x) == -1) \
                goto crap;

Definition at line 32 of file eol.cpp.

Referenced by THREAD::catchup(), THREAD::get_adv(), THREAD::read_text(), and sock_thread().


Function Documentation

void* listen_thread void *  zz  ) 
 

Definition at line 305 of file eol.cpp.

References next, quit_listen, running, sock_thread(), and thread_mutex.

Referenced by main().

00306 {
00307         THREAD *t;
00308         THREAD *prev;
00309         FILE *fil;
00310         void *retval;
00311         struct sockaddr_in sa;
00312         socklen_t len;
00313         struct timeval tv;
00314         fd_set rfds;
00315         long l = 0;
00316         int s = socket(AF_INET, SOCK_STREAM, 0);
00317         int a_s;
00318         int optval;
00319         int n;
00320 
00321         sa.sin_family = AF_INET; // hp -> h_addrtype;
00322         sa.sin_port = htons(4444);
00323 //      sa.sin_addr.s_addr = 0;
00324         memmove(&sa.sin_addr,&l,4);
00325 //      sa.sin_zero[0] = 0;
00326 //      sa.sin_zero[1] = 0;
00327 //      sa.sin_zero[2] = 0;
00328 //      sa.sin_zero[3] = 0;
00329 //      sa.sin_zero[4] = 0;
00330 //      sa.sin_zero[5] = 0;
00331 //      sa.sin_zero[6] = 0;
00332 //      sa.sin_zero[7] = 0;
00333 
00334         if (s == -1)
00335         {
00336                 perror("socket() failed");
00337                 exit(-1);
00338         }
00339         optval = 1;
00340         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval)) == -1)
00341         {
00342                 perror("setsockopt() failed");
00343                 exit(-1);
00344         }
00345         optval = 1;
00346         if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(optval)) == -1)
00347         {
00348                 perror("setsockopt() failed");
00349                 exit(-1);
00350         }
00351         if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1)
00352         {
00353                 perror("bind() failed");
00354                 exit(-1);
00355         }
00356         if (listen(s, 3) == -1)
00357         {
00358                 perror("listen() failed");
00359                 exit(-1);
00360         }
00361         
00362         while (!quit_listen)
00363         {
00364                 FD_ZERO(&rfds);
00365                 FD_SET(s, &rfds);
00366 
00367                 tv.tv_sec = 1;
00368                 tv.tv_usec = 0;
00369                 n = select(s + 1, &rfds, NULL, NULL, &tv);
00370                 if (n == -1)
00371                 {
00372                         perror("select() failed");
00373                 } else
00374                 if (n > 0)
00375                 {
00376                         if (FD_ISSET(s, &rfds))
00377                         {
00378                                 a_s = accept(s, (struct sockaddr *)&sa, &len);
00379                                 if (a_s == -1)
00380                                 {
00381                                         perror("accept() failed");
00382                                 }
00383                                 else
00384                                 {
00385                                         fil = fopen("sa_log.bin","ab");
00386                                         fwrite(&len,1,sizeof(len),fil);
00387                                         fwrite(&sa,1,len,fil);
00388                                         fclose(fil);
00389 
00390                                         for (int i = 0; i < (int)len; i++)
00391                                         {
00392                                                 if (i)
00393                                                         printf(".");
00394                                                 printf("%d",((unsigned char *)&sa)[i]);
00395                                         }
00396                                         printf("\n");
00397 
00398                                         t = new THREAD;
00399                                         t -> socket = a_s;
00400                                         t -> running = 1;
00401                                         pthread_mutex_lock(&thread_mutex);
00402                                         t -> next = threadbase;
00403                                         threadbase = t;
00404                                         pthread_mutex_unlock(&thread_mutex);
00405                                         if (pthread_create(&t -> thread, NULL, sock_thread, t))
00406                                         {
00407                                                 printf("Couldn't create socket thread\n");
00408                                                 exit(-1);
00409                                         }
00410                                 }
00411                         }
00412                 } // if (n > 0)
00413                 pthread_mutex_lock(&thread_mutex);
00414                 do
00415                 {
00416                         prev = NULL;
00417                         for (t = threadbase; t; t = t -> next)
00418                                 if (!t -> running)
00419                                 {
00420                                         if (pthread_join(t -> thread,&retval))
00421                                         {
00422                                                 printf("pthread_join failed\n");
00423                                         }
00424                                         if (!prev)
00425                                                 threadbase = t -> next;
00426                                         else
00427                                                 prev -> next = t -> next;
00428                                         delete t;
00429                                         printf("sock_thread() removed\n");
00430                                         break;
00431                                 }
00432                                 else
00433                                 {
00434                                         prev = t;
00435                                 }
00436                 } while (t);
00437                 pthread_mutex_unlock(&thread_mutex);
00438         }
00439         close(s);
00440         printf("Listen loop end\n");
00441         for (t = threadbase; t; t = t -> next)
00442         {
00443                 t -> running = 0;
00444                 if (pthread_join(t -> thread,&zz))
00445                 {
00446                         printf("pthread_join() failed: socket thread\n");
00447                 }
00448         }
00449         pthread_mutex_lock(&thread_mutex);
00450         for (t = threadbase; t; t = prev)
00451         {
00452                 prev = t -> next;
00453                 delete t;
00454         }
00455         pthread_mutex_unlock(&thread_mutex);
00456         return zz;
00457 }

int main int  argc,
char *  argv[]
 

Definition at line 536 of file eol.cpp.

References event_mutex, listen_thread(), next, quit_main, read_games(), sighandler(), sigpipe(), and thread_mutex.

00537 {
00538         void *zz;
00539         pthread_t listen_t;
00540 
00541         signal(SIGINT, sighandler);
00542         signal(SIGPIPE, sigpipe);
00543 
00544         read_games();
00545 
00546         eventbase = new EVENT;
00547         eventbase -> next = NULL;
00548         strcpy(eventbase -> text,"Startup.");
00549 
00550         pthread_mutex_init(&event_mutex, NULL);
00551         pthread_mutex_init(&thread_mutex, NULL);
00552 
00553         if (pthread_create(&listen_t, NULL, listen_thread, NULL))
00554         {
00555                 printf("Couldn't create listen thread\n");
00556                 exit(-1);
00557         }
00558         while (!quit_main)
00559         {
00560                 sleep(1);
00561         }
00562         printf("Main loop end\n");
00563         if (pthread_join(listen_t,&zz))
00564         {
00565                 printf("listen thread pthread_join() failed\n");
00566         }
00567         return 0;
00568 }

void read_games void   ) 
 

Definition at line 477 of file eol.cpp.

References EA_GAMES, next, and strzcpy().

Referenced by main().

00478 {
00479         FILE *fil;
00480         ADV *adv;
00481         ADV *q;
00482         char *s;
00483         char descr[200];
00484         char slask[200];
00485         char dirname[200];
00486 
00487         if ((fil = fopen(EA_GAMES,"rt")) != NULL)
00488         {
00489                 fgets(slask,200,fil);
00490                 while (!feof(fil))
00491                 {
00492                         slask[strlen(slask) - 1] = 0;
00493                         adv = new ADV;
00494                         s = strtok(slask,";");
00495                         strzcpy(descr,s);
00496                         s = strtok(NULL, ";");
00497                         strzcpy(adv -> author,s);
00498                         s = strtok(NULL, ";");
00499                         strzcpy(adv -> rating,s);
00500                         s = strtok(NULL, ";");
00501                         strzcpy(adv -> flags,s);
00502                         s = strtok(NULL, ";");
00503                         strzcpy(dirname,s);
00504                         if (*dirname)
00505                         {
00506                                 adv -> next = NULL;
00507                                 descr[3] = 0;
00508                                 adv -> num = atoi(descr);
00509                                 strcpy(adv -> descr,descr + 5);
00510                                 strcpy(adv -> dir,dirname);
00511                                 if (!advbase)
00512                                         advbase = adv;
00513                                 else
00514                                 {
00515                                         q = advbase;
00516                                         while (q -> next)
00517                                                 q = q -> next;
00518                                         q -> next = adv;
00519                                 }
00520                                 printf("%d: '%s' by '%s' rating '%s'\n",
00521                                         adv -> num,
00522                                         adv -> descr,
00523                                         adv -> author,
00524                                         adv -> rating);
00525                         }
00526                         else
00527                         {
00528                                 delete adv;
00529                         }
00530                         fgets(slask,200,fil);
00531                 }
00532                 fclose(fil);
00533         }
00534 }

void sighandler int  sig  ) 
 

Definition at line 459 of file eol.cpp.

References quit_listen, and quit_main.

Referenced by main().

00460 {
00461         printf("Signal: %d\n",sig);
00462         quit_main = 1;
00463         quit_listen = 1;
00464 }

void sigpipe int  sig  ) 
 

Definition at line 466 of file eol.cpp.

Referenced by main().

00467 {
00468 }

void* sock_thread void *  zz  ) 
 

Definition at line 43 of file eol.cpp.

References c(), EA_ACCTS, EA_DISKS, EA_UTILS, INPUT, PRINT, and running.

Referenced by listen_thread().

00044 {
00045         Database db("localhost","root","","eamon");
00046         Query q(db);
00047         THREAD *pThread = (THREAD *)zz;
00048         FILE *fil;
00049         int s = pThread -> socket;
00050         int quit = 0;
00051         int n;
00052         int i;
00053         int menu;
00054         char slask[200];
00055         char cmd[200];
00056 
00057         pThread -> cmdline.SetParserIO( pThread );
00058         pThread -> m_more = 1;
00059         pThread -> account = NULL;
00060 
00061         while (!pThread -> account)
00062         {
00063                 PRINT("--------------------------------------------------\n");
00064                 PRINT(" Welcome to The Wonderful World of Eamon *Online*\n");
00065                 PRINT("--------------------------------------------------\n");
00066                 PRINT(" These are the original Eamon Adventures, being\n");
00067                 PRINT(" run on an applesoft basic interpreter for Linux.\n");
00068                 PRINT(" Some special commands extend your stay here:\n");
00069                 PRINT("  'hi or \"hi         - speak to other players\n");
00070                 PRINT("  /who               - see who's online right now\n");
00071                 PRINT("  /emote <something> - emote is cool\n");
00072                 PRINT("  /abort             - well, sometimes programs hang\n");
00073                 PRINT(" New user? Just enter your preferred login handle\n");
00074                 PRINT(" at the prompt below, and you will be up & away.\n");
00075                 PRINT("--------------------------------------------------\n");
00076                 PRINT("           My email: eamon@alhem.net\n");
00077                 PRINT("--------------------------------------------------\n");
00078                 PRINT("\n");
00079                 PRINT("Login: ");
00080                 pThread -> adjust_case = 1;
00081                 INPUT(cmd) else
00082                 {
00083                         sprintf(slask,"select * from account where login='%s'",cmd);
00084                         pThread -> account = new db::Account(&db,slask);
00085                         if (!pThread -> account -> num)
00086                         {
00087                                 PRINT("Account '%s' does not exist, create (y,N)? ");
00088                                 INPUT(slask)
00089                                 if (*slask == 'Y')
00090                                 {
00091                                         PRINT("Enter password: ");
00092                                         INPUT(slask)
00093                                         pThread -> account -> password = slask;
00094                                         PRINT("Verify password: ");
00095                                         INPUT(slask)
00096                                         if (!strcmp(slask,pThread -> account -> password.c_str()))
00097                                         {
00098                                                 pThread -> account -> login = cmd;
00099                                                 pThread -> account -> num_logins = 1;
00100                                                 pThread -> account -> save();
00101                                                 sprintf(slask,"update account set created_date=curdate() where num=%ld",pThread -> account -> num);
00102                                                 q.execute(slask);
00103                                         }
00104                                         else
00105                                         {
00106                                                 delete pThread -> account;
00107                                                 pThread -> account = NULL;
00108                                         }
00109                                 }
00110                                 else
00111                                 {
00112                                         delete pThread -> account;
00113                                         pThread -> account = NULL;
00114                                 }
00115                         }
00116                         else
00117                         {
00118                                 PRINT("Password: ");
00119                                 INPUT(slask);
00120                                 if (!strcmp(slask,pThread -> account -> password.c_str()))
00121                                 {
00122                                         sprintf(slask,"update account set last_login=curdate(),num_logins=num_logins+1 where num=%ld",pThread -> account -> num);
00123                                         q.execute(slask);
00124                                 }
00125                                 else
00126                                 {
00127                                         delete pThread -> account;
00128                                         pThread -> account = NULL;
00129                                 }
00130                         }
00131                 }
00132         }
00133 
00134         sprintf(slask,"%s/%s",EA_ACCTS,pThread -> account -> login.c_str());
00135         if (chdir(slask) == -1)
00136         {
00137                 perror("chdir() failed");
00138                 if (mkdir(slask, 0755) == -1)
00139                 {
00140                         perror("mkdir() failed");
00141                         PRINT("Failed\n");
00142                         goto crap;
00143                 }
00144                 if (chdir(slask) == -1)
00145                 {
00146                         perror("chdir() failed again");
00147                         PRINT("Failed\n");
00148                         goto crap;
00149                 }
00150                 sprintf(slask,"cp -a %s/ea.master .",EA_DISKS);
00151                 system(slask);
00152         }
00153 
00154         sprintf(slask,"%s/%s/ea.master",EA_ACCTS,pThread -> account -> login.c_str());
00155         if (chdir(slask) == -1)
00156         {
00157                 perror("chdir(ea.master) failed");
00158                 PRINT("Failed\n");
00159                 goto crap;
00160         }
00161 
00162         sprintf(slask, "%s has entered.", pThread -> account -> login.c_str());
00163         pThread -> add_event( slask );
00164 
00165         menu = 1;
00166         while (!quit)
00167         {
00168                 PRINT("\n");
00169 
00170                 pThread -> adjust_case = 0;
00171 
00172                 if (menu)
00173                 {
00174                         sprintf(slask,"*** The Wonderful World of Eamon (Online): %s ***\n",pThread -> account -> login.c_str());
00175                         PRINT(slask);
00176                         PRINT(" 1/ Play\n");
00177                         PRINT(" 2/ Display characters\n");
00178                         PRINT(" 3/ Edit (remove) characters\n");
00179 //                      PRINT(" 4/ Select adventure\n");
00180                         PRINT(" 5/ Resume adventure\n");
00181                         PRINT(" 6/ Install utility disks\n");
00182                         PRINT(" 7/ BUILD mode (just type HELP after entering)\n");
00183                         PRINT(" 8/ Backup CHARACTERS - BEFORE, not after ;)\n");
00184                         PRINT(" 9/ Restore backup\n");
00185                         PRINT(" 0/ Quit\n");
00186                         menu = 0;
00187                 }
00188                 PRINT("1-9,0,?> ");
00189 
00190                 INPUT(slask)
00191                 if (!*slask)
00192                         strcpy(slask,"7");
00193                 switch (atoi(slask))
00194                 {
00195                 case 1:
00196                         pThread -> cmdline.finish();
00197                         pThread -> adjust_case = 1;
00198                         strcpy(cmd,"RUN HELLO");
00199                         pThread -> cmdline.cmd(cmd);
00200                         pThread -> cmdline.finish();
00201                         menu = 1;
00202                         break;
00203                 case 2:
00204                         pThread -> cmdline.finish();
00205                         pThread -> adjust_case = 1;
00206                         strcpy(cmd,"RUN DISPLAY CHARACTERS");
00207                         pThread -> cmdline.cmd(cmd);
00208                         pThread -> cmdline.finish();
00209                         menu = 1;
00210                         break;
00211                 case 3:
00212                         pThread -> cmdline.finish();
00213                         pThread -> adjust_case = 1;
00214                         strcpy(cmd,"RUN EDIT CHARACTERS");
00215                         pThread -> cmdline.cmd(cmd);
00216                         pThread -> cmdline.finish();
00217                         menu = 1;
00218                         break;
00219                 case 4:
00220                         if (pThread -> get_adv() == -1)
00221                                 goto crap;
00222                         break;
00223                 case 5:
00224                         if (pThread -> selected)
00225                         {
00226                                 sprintf(slask,"../%s",pThread -> selected -> dir);
00227                                 if (chdir(slask) == -1)
00228                                         perror("chdir() failed");
00229                         }
00230                         if ((fil = fopen("EAMON.NAME","rb")) != NULL)
00231                         {
00232                                 unsigned char c;
00233 
00234                                 i = 0;
00235                                 fread(&c,1,1,fil);
00236                                 while (!feof(fil) && c && c != 0x8d)
00237                                 {
00238                                         slask[i++] = c & 0x7f;
00239                                         fread(&c,1,1,fil);
00240                                 }
00241                                 fclose(fil);
00242                                 slask[i] = 0;
00243 
00244                                 PRINT("Resuming adventure '");
00245                                 PRINT( slask );
00246                                 PRINT("'\n");
00247 
00248                                 pThread -> cmdline.finish();
00249                                 pThread -> adjust_case = 1;
00250                                 sprintf(cmd,"RUN %s",slask);
00251                                 pThread -> cmdline.cmd( cmd );
00252                                 pThread -> cmdline.finish();
00253                                 menu = 1;
00254                         }
00255                         else
00256                         {
00257                                 chdir("../ea.master");
00258                         }
00259                         break;
00260                 case 6:
00261                         sprintf(slask,"cp -a %s/* %s/%s",EA_UTILS,EA_ACCTS,pThread -> account -> login.c_str());
00262                         system(slask);
00263                         PRINT("Ok.\n");
00264                         break;
00265                 case 7:
00266                         PRINT("Just type HELP\n");
00267                         pThread -> cmdline.m_current_line = pThread -> cmdline.m_linebase;
00268                         while (1)
00269                         {
00270                                 PRINT("\n>");
00271                                 INPUT( slask )
00272                                 if (!strncasecmp(slask,"quit",4) || !*slask)
00273                                         break;
00274                                 else
00275                                         pThread -> cmdline.cmd( slask );
00276                         }
00277                         break;
00278                 case 8:
00279                         system("cp CHARACTERS CHARACTERS.BACKUP");
00280                         break;
00281                 case 9:
00282                         system("cp CHARACTERS.BACKUP CHARACTERS");
00283                         break;
00284 
00285                 default:
00286                         if (*slask == '0')
00287                         {
00288                                 sprintf(slask,"%s has left.",pThread -> account -> login.c_str());
00289                                 pThread -> add_event(slask);
00290                                 quit++;
00291                         }
00292                         else
00293                         if (*slask == '?')
00294                                 menu = 1;
00295                 }
00296         }
00297 crap:
00298         close(s);
00299         delete pThread -> account;
00300         pThread -> account = NULL;
00301         pThread -> running = 0;
00302         return zz;
00303 }

void strzcpy char *  slask,
char *  s
 

Definition at line 470 of file eol.cpp.

Referenced by read_games().

00471 {
00472         strcpy(slask,s ? s : "");
00473         while (strlen(slask) && slask[strlen(slask) - 1] == ' ')
00474                 slask[strlen(slask) - 1] = 0;
00475 }


Variable Documentation

ADV* advbase = NULL
 

Definition at line 23 of file eol.cpp.

Referenced by THREAD::get_adv().

pthread_mutex_t event_mutex
 

Definition at line 28 of file eol.cpp.

Referenced by THREAD::add_event(), THREAD::catchup(), main(), and THREAD::THREAD().

EVENT* eventbase = NULL
 

Definition at line 24 of file eol.cpp.

Referenced by THREAD::add_event(), and THREAD::THREAD().

int quit_listen = 0 [static]
 

Definition at line 26 of file eol.cpp.

Referenced by listen_thread(), and sighandler().

int quit_main = 0 [static]
 

Definition at line 27 of file eol.cpp.

Referenced by main(), and sighandler().

pthread_mutex_t thread_mutex
 

Definition at line 29 of file eol.cpp.

Referenced by listen_thread(), main(), and THREAD::read_text().

THREAD* threadbase = NULL
 

Definition at line 25 of file eol.cpp.

Referenced by THREAD::read_text().

Page, code, and content Copyright (C) 2005 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4