src/bsd.c File Reference

#include "copyright.h"
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include "mudconf.h"
#include "db.h"
#include "file_c.h"
#include "externs.h"
#include "interface.h"
#include "flags.h"
#include "powers.h"
#include "alloc.h"
#include "command.h"
#include "attrs.h"
#include "rbtree.h"
#include "logcache.h"
#include "debug.h"

Include dependency graph for bsd.c:

Go to the source code of this file.

Defines

#define get_tod(x)   { (x)->tv_sec = time(NULL); (x)->tv_usec = 0; }

Functions

void mux_release_socket ()
void make_nonblocking (int s)
void accept_new_connection (int, short, void *)
DESCinitializesock (int, struct sockaddr_storage *, int)
DESCnew_connection (int)
int process_input (DESC *)
int desc_cmp (void *vleft, void *vright, void *token)
void desc_addhash (DESC *d)
void desc_delhash (DESC *d)
void bind_descriptor (DESC *d)
void release_descriptor (DESC *d)
void shutdown_services ()
int bind_mux_socket (int port)
int eradicate_broken_fd (int fd)
void accept_client_input (int fd, short event, void *arg)
void bsd_write_callback (struct bufferevent *bufev, void *arg)
void bsd_read_callback (struct bufferevent *bufev, void *arg)
void bsd_error_callback (struct bufferevent *bufev, short whut, void *arg)
void runqueues (int fd, short event, void *arg)
void shovechars (int port)
void shutdownsock (DESC *d, int reason)
void make_blocking (int s)
void flush_sockets ()
void close_sockets (int emergency, char *message)
void emergency_shutdown (void)

Variables

event listen_sock_ev
int mux_bound_socket = -1
int ndescriptors = 0
DESCdescriptor_list = NULL
timeval queue_slice = { 0, 0 }
event queue_ev
timeval last_slice current_time
static const char * disc_reasons []
static const char * disc_messages []
int fcache_conn_c


Define Documentation

#define get_tod ( x   )     { (x)->tv_sec = time(NULL); (x)->tv_usec = 0; }

Definition at line 325 of file bsd.c.

Referenced by runqueues(), and shovechars().


Function Documentation

void accept_client_input ( int  fd,
short  event,
void *  arg 
)

Definition at line 294 of file bsd.c.

References bind_descriptor(), DARK, descriptor_data::descriptor, DS_AUTODARK, descriptor_data::flags, Flags, descriptor_data::player, process_input(), release_descriptor(), and s_Flags.

Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().

00295 {
00296         DESC *connection = (DESC *) arg;
00297         if(connection->descriptor != fd) return;
00298 
00299     //dprintk("callback on fd %d DESC %p", fd, arg);
00300 
00301         if(connection->flags & DS_AUTODARK) {
00302                 connection->flags &= ~DS_AUTODARK;
00303                 s_Flags(connection->player, Flags(connection->player) & ~DARK);
00304         }
00305     bind_descriptor(connection);
00306         process_input(connection);
00307     //dprintk("finish on fd %d DESC %p", fd, arg);
00308     release_descriptor(connection);
00309 }

void accept_new_connection ( int  ,
short  ,
void *   
)

Definition at line 388 of file bsd.c.

References statedata::access_list, FC_CONN_SITE, fcache_rawdump(), H_FORBIDDEN, initializesock(), log_error(), LOG_NET, LOG_SECURITY, mudstate, and site_check().

Referenced by shovechars().

00389 {
00390         int newsock, addr_len, len;
00391         char *buff, *buff1;
00392         DESC *d;
00393         struct sockaddr_storage addr;
00394         char addrname[1024];
00395         char addrport[32];
00396 
00397 
00398         addr_len = sizeof(struct sockaddr);
00399 
00400         newsock =
00401                 accept(sock, (struct sockaddr *) &addr, (unsigned int *) &addr_len);
00402         if(newsock < 0)
00403                 return;
00404 
00405         getnameinfo((struct sockaddr *) &addr, addr_len,
00406                                 addrname, 1024, addrport, 32,
00407                                 NI_NUMERICHOST | NI_NUMERICSERV);
00408 
00409         if(site_check(&addr, addr_len, mudstate.access_list) == H_FORBIDDEN) {
00410                 log_error(LOG_NET | LOG_SECURITY, "NET", "SITE",
00411                                   "Connection refused from %s %s.", addrname, addrport);
00412 
00413                 fcache_rawdump(newsock, FC_CONN_SITE);
00414                 shutdown(newsock, 2);
00415                 close(newsock);
00416                 errno = 0;
00417                 d = NULL;
00418         } else {
00419                 log_error(LOG_NET, "NET", "CONN", "Connection opened from %s %s.",
00420                                   addrname, addrport);
00421 
00422                 d = initializesock(newsock, &addr, addr_len);
00423         }
00424         return;
00425 }

void bind_descriptor ( DESC d  ) 

Definition at line 131 of file bsd.c.

References descriptor_data::refcount.

Referenced by accept_client_input(), desc_addhash(), initializesock(), and process_input().

00131                               {
00132     d->refcount++;
00133     //dprintk("bound desciptor %p, refcount now %d", d, d->refcount);
00134 }

int bind_mux_socket ( int  port  ) 

Definition at line 213 of file bsd.c.

References dprintk, and log_perror().

Referenced by shovechars().

00214 {
00215         int s, opt;
00216         struct sockaddr_in server;
00217 
00218         s = socket(AF_INET, SOCK_STREAM, 0);
00219         if(s < 0) {
00220                 log_perror("NET", "FAIL", NULL, "creating master socket");
00221                 exit(3);
00222         }
00223         opt = 1;
00224         if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
00225                                   sizeof(opt)) < 0) {
00226                 log_perror("NET", "FAIL", NULL, "setsockopt");
00227         }
00228         
00229         if(fcntl(s, F_SETFD, FD_CLOEXEC) < 0) {
00230                 log_perror("LOGCACHE", "FAIL", NULL,
00231                                    "fcntl(fd, F_SETFD, FD_CLOEXEC)");
00232                 close(s);
00233                 abort();
00234         }
00235         server.sin_family = AF_INET;
00236         server.sin_addr.s_addr = INADDR_ANY;
00237         server.sin_port = htons(port);
00238         if(bind(s, (struct sockaddr *) &server, sizeof(server))) {
00239                 log_perror("NET", "FAIL", NULL, "bind");
00240                 close(s);
00241                 exit(4);
00242         }
00243         dprintk("connection socket raised and bound, %d", s);
00244         listen(s, 25);
00245         return s;
00246 }

void bsd_error_callback ( struct bufferevent *  bufev,
short  whut,
void *  arg 
)

Definition at line 319 of file bsd.c.

References dprintk.

Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().

00320 {
00321         dprintk("error %d", whut);
00322 }

void bsd_read_callback ( struct bufferevent *  bufev,
void *  arg 
)

Definition at line 315 of file bsd.c.

Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().

00316 {
00317 }

void bsd_write_callback ( struct bufferevent *  bufev,
void *  arg 
)

Definition at line 311 of file bsd.c.

Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().

00312 {
00313 }

void close_sockets ( int  emergency,
char *  message 
)

Definition at line 716 of file bsd.c.

References DESC_SAFEITER_ALL, descriptor_data::descriptor, dnschild_kill(), dprintk, listen_sock_ev, log_perror(), mux_bound_socket, descriptor_data::outstanding_dnschild_query, queue_string(), queue_write(), R_GOING_DOWN, shutdownsock(), descriptor_data::sock_buff, and descriptor_data::sock_ev.

Referenced by emergency_shutdown(), and main().

00717 {
00718         DESC *d, *dnext;
00719 
00720         DESC_SAFEITER_ALL(d, dnext) {
00721                 if(emergency) {
00722                         write(d->descriptor, message, strlen(message));
00723                         if(shutdown(d->descriptor, 2) < 0)
00724                                 log_perror("NET", "FAIL", NULL, "shutdown");
00725                         dprintk("shutting down fd %d", d->descriptor);
00726                         dprintk("output evbuffer misalign: %d, totallen: %d, off: %d",
00727                                         d->sock_buff->output->misalign,
00728                                         d->sock_buff->output->totallen,
00729                                         d->sock_buff->output->off);
00730                         fsync(d->descriptor);
00731                         if(d->outstanding_dnschild_query)
00732                                 dnschild_kill(d->outstanding_dnschild_query);
00733             d->outstanding_dnschild_query = NULL;
00734                         event_loop(EVLOOP_ONCE);
00735                         event_del(&d->sock_ev);
00736                         bufferevent_free(d->sock_buff);
00737                         close(d->descriptor);
00738                 } else {
00739                         queue_string(d, message);
00740                         queue_write(d, "\r\n", 2);
00741                         shutdownsock(d, R_GOING_DOWN);
00742                 }
00743         }
00744         close(mux_bound_socket);
00745         event_del(&listen_sock_ev);
00746 }

void desc_addhash ( DESC d  ) 

Definition at line 65 of file bsd.c.

References bind_descriptor(), statedata::desctree, descriptor_data::hashnext, mudstate, descriptor_data::player, rb_find(), and rb_insert().

Referenced by announce_connect(), load_restart_db(), and load_restart_db_xdr().

00066 {
00067     DESC *hdesc;
00068 
00069     bind_descriptor(d);
00070 
00071     hdesc = (DESC *) rb_find(mudstate.desctree, (void *) d->player);
00072 /*    if(!hdesc) {
00073         dprintk("Creating new list root for '%s'(#%d) at %p.", 
00074             Name(d->player), d->player, d); 
00075     } else {
00076         dprintk("Adding descriptor %p to list root at %p for '%s'(#%d).",
00077         d, hdesc, Name(d->player), d->player);
00078     }
00079 */  
00080     d->hashnext = hdesc;
00081     rb_insert(mudstate.desctree, (void *) d->player, d);
00082 }

int desc_cmp ( void *  vleft,
void *  vright,
void *  token 
)

Definition at line 57 of file bsd.c.

Referenced by main().

00058 {
00059     dbref left = (dbref) vleft;
00060     dbref right = (dbref) vright;
00061 
00062     return (left - right);
00063 }

void desc_delhash ( DESC d  ) 

Definition at line 84 of file bsd.c.

References statedata::desctree, descriptor_data::hashnext, log_text(), mudstate, descriptor_data::player, rb_delete(), rb_find(), rb_insert(), and release_descriptor().

Referenced by shutdownsock().

00085 {
00086     char buffer2[4096];
00087     DESC *hdesc = NULL;
00088     char buffer[4096];
00089 /*    dprintk("removing descriptor %p from list root %p for '%s'(#%d).", d, hdesc, Name(d->player), d->player); */
00090     hdesc = (DESC *) rb_find(mudstate.desctree, (void *) d->player);
00091 /*    dprintk("removing descriptor %p from list root %p for '%s'(#%d).", d, hdesc, Name(d->player), d->player); */
00092 
00093 
00094     if(!hdesc) {
00095         snprintf(buffer, 4096,
00096                  "desc_delhash: unable to find player(%d)'s descriptors from hashtable.\n",
00097                  d->player);
00098         log_text(buffer);
00099         release_descriptor(d);
00100         return;
00101     }
00102 
00103   /*  dprintk("hdesc: %p, d: %p, hdesc->hashnext: %p, d->hashnext: %p", hdesc,
00104             d, hdesc->hashnext, d->hashnext);
00105 */
00106     if(hdesc == d && hdesc->hashnext) {
00107   /*      dprintk("updating %d to use hashroot %p", d->player, d->hashnext);*/
00108         rb_insert(mudstate.desctree, (void *) d->player, d->hashnext);
00109         d->hashnext = NULL;
00110         release_descriptor(d);
00111         return;
00112     } else if(hdesc == d) {
00113 /*        dprintk("removing %d table", d->player); */
00114         rb_delete(mudstate.desctree, (void *) d->player);
00115         release_descriptor(d);
00116         return;
00117     }
00118 
00119     while(hdesc->hashnext != NULL) {
00120         if(hdesc->hashnext == d) {
00121             hdesc->hashnext = d->hashnext;
00122             break;
00123         }
00124         hdesc = hdesc->hashnext;
00125     }
00126     d->hashnext = NULL;
00127     release_descriptor(d);
00128     return;
00129 }

void emergency_shutdown ( void   ) 

Definition at line 748 of file bsd.c.

References close_sockets().

Referenced by do_shutdown().

00748                               {
00749         close_sockets(1, (char *) "Going down - Bye.\n");
00750 }

int eradicate_broken_fd ( int  fd  ) 

Definition at line 261 of file bsd.c.

References DESC_SAFEITER_ALL, log_error(), LOG_PROBLEMS, mux_bound_socket, R_SOCKDIED, and shutdownsock().

Referenced by signal_PIPE().

00262 {
00263         struct stat statbuf;
00264         DESC *d, *dtemp;
00265 
00266         DESC_SAFEITER_ALL(d, dtemp) {
00267                 if((fd && d->descriptor == fd) ||
00268                    (!fd && fstat(d->descriptor, &statbuf) < 0)) {
00269                         /* An invalid player connection... eject, eject, eject. */
00270                         log_error(LOG_PROBLEMS, "ERR", "EBADF",
00271                                           "Broken descriptor %d for player #%d", d->descriptor,
00272                                           d->player);
00273             close(d->descriptor);
00274                         shutdownsock(d, R_SOCKDIED);
00275                 }
00276         }
00277         if(mux_bound_socket != -1 && fstat(mux_bound_socket, &statbuf) < 0) {
00278                 log_error(LOG_PROBLEMS, "ERR", "EBADF",
00279                                   "Broken descriptor on our main port.");
00280                 mux_bound_socket = -1;
00281                 return -1;
00282         }
00283 #ifdef IPV6_SUPPORT
00284         if(mux_bound_socket6 != -1 && fstat(mux_bound_socket6, &statbuf) < 0) {
00285                 log_error(LOG_PROBLEMS, "ERR", "EBADF",
00286                                   "Broken descriptor for our ipv6 port.");
00287                 mux_bound_socket6 = -1;
00288                 return -1;
00289         }
00290 #endif
00291         return 0;
00292 }

void flush_sockets (  ) 

Definition at line 692 of file bsd.c.

References descriptor_data::chokes, DESC_SAFEITER_ALL, descriptor_data::descriptor, and descriptor_data::sock_buff.

Referenced by raw_broadcast(), and shutdown_services().

00693 {
00694         int null = 0;
00695         DESC *d, *dnext;
00696         DESC_SAFEITER_ALL(d, dnext) {
00697                 if(d->chokes) {
00698 #if TCP_CORK
00699                         setsockopt(d->descriptor, IPPROTO_TCP, TCP_CORK, &null,
00700                                            sizeof(null));
00701 #else
00702 #ifdef TCP_NOPUSH
00703                         setsockopt(d->descriptor, IPPROTO_TCP, TCP_NOPUSH, &null,
00704                                            sizeof(null));
00705 #endif
00706 #endif
00707                         d->chokes = 0;
00708                 }
00709                 if(d->sock_buff && EVBUFFER_LENGTH(d->sock_buff->output)) {
00710                         evbuffer_write(d->sock_buff->output, d->descriptor);
00711                 }
00712                 fsync(d->descriptor);
00713         }
00714 }

DESC * initializesock ( int  ,
struct sockaddr_storage *  ,
int   
)

Definition at line 548 of file bsd.c.

References accept_client_input(), statedata::access_list, descriptor_data::addr, bind_descriptor(), bsd_error_callback(), bsd_read_callback(), bsd_write_callback(), descriptor_data::chokes, confdata::cmd_quota_max, descriptor_data::command_count, descriptor_data::connected_at, descriptor_data::descriptor, descriptor_list, dnschild_request(), descriptor_data::doing, descriptor_data::flags, descriptor_data::hashnext, descriptor_data::host_info, descriptor_data::hudkey, confdata::idle_timeout, descriptor_data::input, descriptor_data::input_lost, descriptor_data::input_size, descriptor_data::input_tail, descriptor_data::input_tot, descriptor_data::last_time, make_nonblocking(), mudconf, mudstate, ndescriptors, descriptor_data::next, statedata::now, descriptor_data::output_lost, descriptor_data::output_prefix, descriptor_data::output_size, descriptor_data::output_suffix, descriptor_data::output_tot, descriptor_data::outstanding_dnschild_query, descriptor_data::player, descriptor_data::prev, descriptor_data::program_data, descriptor_data::quota, descriptor_data::retries_left, confdata::retry_limit, descriptor_data::saddr, descriptor_data::saddr_len, site_check(), descriptor_data::sock_buff, descriptor_data::sock_ev, statedata::suspect_list, descriptor_data::timeout, descriptor_data::username, and welcome_user().

Referenced by accept_new_connection().

00549 {
00550         DESC *d;
00551 
00552         ndescriptors++;
00553         d = malloc(sizeof(DESC));
00554         memset(d, 0, sizeof(DESC));
00555 
00556         d->descriptor = s;
00557         d->flags = 0;
00558         d->connected_at = mudstate.now;
00559         d->retries_left = mudconf.retry_limit;
00560         d->command_count = 0;
00561         d->timeout = mudconf.idle_timeout;
00562         d->host_info =
00563                 site_check(saddr, saddr_len, mudstate.access_list) |
00564                 site_check(saddr, saddr_len, mudstate.suspect_list);
00565         d->player = 0;                  
00566         d->chokes = 0;
00567         d->addr[0] = '\0';
00568         d->doing[0] = '\0';
00569         d->hudkey[0] = '\0';
00570         d->username[0] = '\0';
00571         make_nonblocking(s);
00572         d->output_prefix = NULL;
00573         d->output_suffix = NULL;
00574         d->output_size = 0;
00575         d->output_tot = 0;
00576         d->output_lost = 0;
00577         d->input_size = 0;
00578         d->input_tot = 0;
00579         d->input_lost = 0;
00580         memset(d->input, 0, sizeof(d->input));
00581     d->input_tail = 0;
00582         d->quota = mudconf.cmd_quota_max;
00583         d->program_data = NULL;
00584         d->last_time = 0;
00585         memcpy(&d->saddr, saddr, saddr_len);
00586         d->saddr_len = saddr_len;
00587 
00588         d->hashnext = NULL;
00589         getnameinfo((struct sockaddr *) saddr, saddr_len, d->addr,
00590                                 sizeof(d->addr), NULL, 0, NI_NUMERICHOST);
00591 
00592         if (descriptor_list)
00593                 descriptor_list->prev = d;
00594         d->next = descriptor_list;
00595         d->prev = NULL;
00596         descriptor_list = d;
00597        
00598         d->outstanding_dnschild_query = dnschild_request(d);
00599 
00600         d->sock_buff = bufferevent_new(d->descriptor, bsd_write_callback,
00601                                                                    bsd_read_callback, bsd_error_callback,
00602                                                                    NULL);
00603         bufferevent_disable(d->sock_buff, EV_READ);
00604         bufferevent_enable(d->sock_buff, EV_WRITE);
00605         event_set(&d->sock_ev, d->descriptor, EV_READ | EV_PERSIST, 
00606         accept_client_input, d);
00607         event_add(&d->sock_ev, NULL);
00608     bind_descriptor(d);
00609         welcome_user(d);
00610         return d;
00611 }

void make_blocking ( int  s  ) 

Definition at line 530 of file bsd.c.

References log_perror().

00531 {
00532         long flags = 0;
00533 
00534         if(fcntl(s, F_GETFL, &flags) < 0) {
00535                 log_perror("NET", "FAIL", "make_blocking", "fcntl F_GETFL");
00536         }
00537         flags &= ~O_NONBLOCK;
00538         if(fcntl(s, F_SETFL, flags) < 0) {
00539                 log_perror("NET", "FAIL", "make_blocking", "fcntl F_SETFL");
00540         }
00541         flags = 0;
00542         if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags)) < 0) {
00543                 log_perror("NET", "FAIL", "make_blocking", "setsockopt NDELAY");
00544         }
00545 }

void make_nonblocking ( int  s  ) 

Definition at line 513 of file bsd.c.

References log_perror().

Referenced by initializesock().

00514 {
00515         long flags = 0;
00516 
00517         if(fcntl(s, F_GETFL, &flags) < 0) {
00518                 log_perror("NET", "FAIL", "make_nonblocking", "fcntl F_GETFL");
00519         }
00520         flags |= O_NONBLOCK;
00521         if(fcntl(s, F_SETFL, flags) < 0) {
00522                 log_perror("NET", "FAIL", "make_nonblocking", "fcntl F_SETFL");
00523         }
00524         flags = 1;
00525         if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags)) < 0) {
00526                 log_perror("NET", "FAIL", "make_nonblocking", "setsockopt NDELAY");
00527         }
00528 }

void mux_release_socket (  ) 

Definition at line 248 of file bsd.c.

References dprintk, listen_sock_ev, and mux_bound_socket.

Referenced by signal_BUS(), signal_SEGV(), and signal_USR1().

00249 {
00250         dprintk("releasing mux main socket.");
00251         event_del(&listen_sock_ev);
00252         close(mux_bound_socket);
00253         mux_bound_socket = -1;
00254 #ifdef IPV6_SUPPORT
00255         event_del(&listen6_sock_ev);
00256         close(mux_bound_socket6);
00257         mux_bound_socket6 = -1;
00258 #endif
00259 }

DESC* new_connection ( int   ) 

int process_input ( DESC  ) 

Definition at line 613 of file bsd.c.

References bind_descriptor(), descriptor_data::descriptor, do_unauth_command(), dprintk, DS_CONNECTED, DS_DEAD, descriptor_data::flags, descriptor_data::input, descriptor_data::input_tail, LBUF_SIZE, Name(), descriptor_data::player, queue_string(), R_QUIT, R_SOCKDIED, run_command(), shutdownsock(), and Wizard.

Referenced by accept_client_input().

00614 {
00615         char buf[LBUF_SIZE];
00616         int got, in, iter;
00617     char current;
00618 
00619     if(d->flags & DS_DEAD) { 
00620         dprintk("Bailing on process_input %p %d %s %d", 
00621         d, d->descriptor, (d->player?Name(d->player):""), d->player);
00622         return 0;
00623     }
00624 
00625     memset(buf, 0, sizeof(buf));
00626 
00627         got = in = read(d->descriptor, buf, (sizeof buf - 1));
00628 
00629         if(got <= 0) {
00630                 if(errno == EINTR)
00631                         return 1;
00632         else if(errno == EAGAIN)
00633             return 1;
00634                 else {
00635             dprintk("error %s (errno %d) read on fd %d descriptor %p %s(%d)\n",
00636             strerror(errno), errno,
00637                 d->descriptor, d, (d->player?Name(d->player):""), d->player);
00638             shutdownsock(d, R_SOCKDIED);
00639             return 1;
00640         }
00641         }
00642 
00643     bind_descriptor(d);
00644     
00645         if(Wizard(d->player) && strncmp("@segfault", buf, 9) == 0) {
00646                 queue_string(d, "@segfault failed. (check logfile for reason.)\n");
00647                 *(char *) 0xDEADBEEF = '9';
00648         }
00649 
00650         for(iter = 0; iter < got; iter++) {
00651         current = buf[iter];
00652         if(current == '\n') {
00653             if(d->flags & DS_CONNECTED) {
00654                 //dprintk("authed as %s running command '%s' refcount %d descriptor %p fd %d", Name(d->player), d->input, d->refcount, d, d->descriptor);
00655                 run_command(d, (char *)d->input);
00656             } else {
00657                 //dprintk("unauth running command '%s' refcount %d descriptor %p fd %d", d->input, d->refcount, 
00658                 //d, d->descriptor);
00659                 if(!do_unauth_command(d, d->input))  {
00660                     dprintk("logout on %p fd %d, bailing.", d, d->descriptor);
00661                     shutdownsock(d, R_QUIT);
00662                     break;
00663                 }
00664             }
00665             memset(d->input, 0, sizeof(d->input));
00666             d->input_tail = 0;
00667             if(d->flags & DS_DEAD) break;
00668         } else if(current == '\b' || current == 0x7f) {
00669             if(current == 127) {
00670                 queue_string(d, "\b \b");
00671             } else {
00672                 queue_string(d, " \b");
00673             }
00674             if(d->input_tail > 0) {
00675                 d->input[--d->input_tail] = '\0';
00676             }
00677             d->input_size--;
00678         } else if(isascii(current) && isprint(current)) {
00679             if(d->input_tail >= sizeof(d->input)) {
00680                 continue;
00681             }
00682             d->input[d->input_tail++] = current;
00683             d->input_size++;
00684         }
00685         }
00686     //dprintk("finished %p fd %d", d, d->descriptor);
00687 
00688     release_descriptor(d);
00689         return 1;
00690 }

void release_descriptor ( DESC d  ) 

Definition at line 136 of file bsd.c.

References clearstrings(), DESC_ITER_PLAYER, descriptor_data::descriptor, descriptor_list, dprintk, free_lbuf, freeqs(), MAX_GLOBAL_REGS, ndescriptors, descriptor_data::next, descriptor_data::player, descriptor_data::prev, descriptor_data::program_data, descriptor_data::refcount, descriptor_data::sock_buff, descriptor_data::sock_ev, and prog_data::wait_regs.

Referenced by accept_client_input(), desc_delhash(), and shutdownsock().

00136                                  {
00137     d->refcount--;
00138     //dprintk("descriptor %p released, refcount now %d", d, d->refcount);
00139     if(d->refcount == 0) {
00140         dprintk("%p destructing", d);
00141         freeqs(d);
00142 
00143                 if(d->program_data != NULL) {
00144                         int num = 0;
00145             DESC *dtemp;
00146                         DESC_ITER_PLAYER(d->player, dtemp) num++;
00147 
00148                         if(num == 0) {
00149                                 for(int i = 0; i < MAX_GLOBAL_REGS; i++) {
00150                                         free_lbuf(d->program_data->wait_regs[i]);
00151                                 }
00152                                 free(d->program_data);
00153                         }
00154                 }
00155         clearstrings(d);
00156         if(d->descriptor) {
00157             fsync(d->descriptor);
00158             event_del(&d->sock_ev);
00159             shutdown(d->descriptor, 2);
00160             close(d->descriptor);
00161         }
00162         d->descriptor = 0;
00163         if(d->sock_buff)
00164             bufferevent_free(d->sock_buff);
00165         d->sock_buff = NULL;
00166         
00167 /*        if(descriptor_list == d) {
00168             descriptor_list = d->next;
00169         } else {
00170             if(!descriptor_list) {
00171                 dprintk("Oh sweet jesus, we have major braindamage.");
00172                 descriptor_list = d->next;
00173             } else {
00174                 DESC *dtemp = descriptor_list;
00175                 while(dtemp->next != NULL) {
00176                     if(dtemp->next == d) {
00177                         dtemp->next = d->next;
00178                         break;
00179                     } else {
00180                         dtemp = dtemp->next;
00181                     }
00182                 }
00183             }
00184         }
00185 
00186         d->next = NULL;
00187         */
00188          if (d->prev)
00189                      d->prev->next = d->next;
00190            else                          /* d was the first one! */
00191                        descriptor_list = d->next;
00192              if (d->next)
00193                          d->next->prev = d->prev;
00194 
00195         ndescriptors--;
00196         free(d);
00197     }
00198 }

void runqueues ( int  fd,
short  event,
void *  arg 
)

Definition at line 334 of file bsd.c.

References current_time, do_top(), dprintk, get_tod, mudconf, confdata::queue_chunk, queue_ev, queue_slice, and update_quotas().

Referenced by shovechars().

00335 {
00336         pid_t pchild;
00337         int status = 0;
00338         event_add(&queue_ev, &queue_slice);
00339         get_tod(&current_time);
00340         last_slice = update_quotas(last_slice, current_time);
00341         pchild = waitpid(-1, &status, WNOHANG);
00342         if(pchild > 0) {
00343                 dprintk("unexpected child %d exited with exit status %d.", pchild,
00344                                 WEXITSTATUS(status));
00345         }
00346         if(mudconf.queue_chunk)
00347                 do_top(mudconf.queue_chunk);
00348 }

void shovechars ( int  port  ) 

Definition at line 350 of file bsd.c.

References accept_new_connection(), bind_mux_socket(), current_time, dprintk, get_tod, listen_sock_ev, mudconf, mux_bound_socket, queue_ev, queue_slice, runqueues(), and confdata::timeslice.

Referenced by main().

00351 {
00352         unsigned int flags;
00353         queue_slice.tv_sec = 0;
00354         queue_slice.tv_usec = mudconf.timeslice * 1000;
00355 
00356         dprintk("shovechars starting, sock is %d.", mux_bound_socket);
00357 #ifdef IPV6_SUPPORT
00358         dprintk("shovechars starting, ipv6 sock is %d.", mux_bound_socket);
00359 #endif
00360 
00361         if(mux_bound_socket < 0) {
00362                 mux_bound_socket = bind_mux_socket(port);
00363         }
00364         event_set(&listen_sock_ev, mux_bound_socket, EV_READ | EV_PERSIST,
00365                           accept_new_connection, NULL);
00366         event_add(&listen_sock_ev, NULL);
00367 
00368         flags = fcntl(2, F_GETFD, 0); 
00369         dprintk("stderr is %x", flags);
00370 #ifdef IPV6_SUPPORT
00371         if(mux_bound_socket6 < 0) {
00372                 mux_bound_socket6 = bind_mux6_socket(port);
00373         }
00374         event_set(&listen6_sock_ev, mux_bound_socket6, EV_READ | EV_PERSIST,
00375                           accept_new6_connection, NULL);
00376         event_add(&listen6_sock_ev, NULL);
00377 #endif
00378 
00379         evtimer_set(&queue_ev, runqueues, NULL);
00380         evtimer_add(&queue_ev, &queue_slice);
00381 
00382         get_tod(&last_slice);
00383         get_tod(&current_time);
00384 
00385         event_dispatch();
00386 }

void shutdown_services (  ) 

Definition at line 200 of file bsd.c.

References dnschild_destruct(), flush_sockets(), logcache_destruct(), and sqlchild_destruct().

Referenced by do_restart().

00201 {
00202         dnschild_destruct();
00203         flush_sockets();
00204 #ifdef SQL_SUPPORT
00205         sqlchild_destruct();
00206 #endif
00207 #ifdef ARBITRARY_LOGFILES
00208         logcache_destruct();
00209 #endif
00210         event_loopexit(NULL);
00211 }

void shutdownsock ( DESC d,
int  reason 
)

Definition at line 460 of file bsd.c.

References descriptor_data::addr, announce_disconnect(), descriptor_data::command_count, descriptor_data::connected_at, decode_flags(), desc_delhash(), descriptor_data::descriptor, disc_messages, disc_reasons, dnschild_kill(), DS_CONNECTED, DS_DEAD, FC_QUIT, fcache_dump(), descriptor_data::flags, Flags, Flags2, Flags3, GOD, Location, LOG_ACCOUNTING, log_error(), LOG_LOGIN, LOG_NET, mudstate, Name(), statedata::now, descriptor_data::outstanding_dnschild_query, Pennies(), descriptor_data::player, R_LOGOUT, and release_descriptor().

Referenced by boot_by_port(), boot_off(), check_connect(), check_idle(), close_sockets(), do_command(), do_unauth_command(), eradicate_broken_fd(), failconn(), load_restart_db(), load_restart_db_xdr(), and process_input().

00461 {
00462         char *buff, *buff2;
00463         time_t now;
00464         int i, num;
00465         DESC *dtemp;
00466 
00467 /*    dprintk("shutdownsock called on %p %s(#%d) refcount %d", 
00468         d, (d->player?Name(d->player):""), d->player, d->refcount); */
00469 
00470     if(d->flags & DS_CONNECTED) {
00471                 if(d->outstanding_dnschild_query)
00472                         dnschild_kill(d->outstanding_dnschild_query);
00473 
00474                 /*
00475                  * Do the disconnect stuff if we aren't doing a LOGOUT * * *
00476                  * * * * (which keeps the connection open so the player can *
00477                  * * connect * * * * to a different character). 
00478                  */
00479 
00480                 if(reason != R_LOGOUT) {
00481                         fcache_dump(d, FC_QUIT);
00482                 }
00483 
00484                 log_error(LOG_NET | LOG_LOGIN, "NET", "DISC",
00485                                   "[%d/%s] Logout by %s(#%d), <Reason: %s>",
00486                                   d->descriptor, d->addr, Name(d->player), d->player,
00487                                   disc_reasons[reason]);
00488 
00489                 /*
00490                  * If requested, write an accounting record of the form: * *
00491                  * * * * * Plyr# Flags Cmds ConnTime Loc Money [Site]
00492                  * <DiscRsn>  * *  * Name 
00493                  */
00494 
00495                 log_error(LOG_ACCOUNTING, "DIS", "ACCT",
00496                                   "%d %s %d %d %d %d [%s] <%s> %s",
00497                                   d->player, decode_flags(GOD, Flags(d->player),
00498                                                                                   Flags2(d->player),
00499                                                                                   Flags3(d->player)),
00500                                   d->command_count, mudstate.now - d->connected_at,
00501                                   Location(d->player), Pennies(d->player), d->addr,
00502                                   disc_reasons[reason], Name(d->player));
00503 
00504         announce_disconnect(d->player, d, disc_messages[reason]);
00505         desc_delhash(d);
00506 
00507         }
00508     d->flags |= DS_DEAD;
00509     release_descriptor(d);
00510    /* dprintk("shutdown."); */
00511 }


Variable Documentation

struct timeval last_slice current_time

Definition at line 332 of file bsd.c.

Referenced by runqueues(), and shovechars().

DESC* descriptor_list = NULL

Definition at line 48 of file bsd.c.

Referenced by dump_restart_db(), dump_restart_db_xdr(), initializesock(), load_restart_db(), load_restart_db_xdr(), network_initialize_socket(), and release_descriptor().

const char* disc_messages[] [static]

Initial value:

 {
        "unknown",
        "quit",
        "timeout",
        "boot",
        "netdeath",
        "shutdown",
        "badlogin",
        "nologins",
        "logout"
}

Definition at line 448 of file bsd.c.

Referenced by shutdownsock().

const char* disc_reasons[] [static]

Initial value:

 {
        "Unspecified",
        "Quit",
        "Inactivity Timeout",
        "Booted",
        "Remote Close or Net Failure",
        "Game Shutdown",
        "Login Retry Limit",
        "Logins Disabled",
        "Logout (Connection Not Dropped)",
        "Too Many Connected Players"
}

Definition at line 431 of file bsd.c.

Referenced by shutdownsock().

int fcache_conn_c

Definition at line 79 of file file_c.c.

struct event listen_sock_ev

Definition at line 37 of file bsd.c.

Referenced by close_sockets(), mux_release_socket(), and shovechars().

int mux_bound_socket = -1

Definition at line 42 of file bsd.c.

Referenced by close_sockets(), eradicate_broken_fd(), mux_release_socket(), and shovechars().

int ndescriptors = 0

Definition at line 46 of file bsd.c.

Referenced by initializesock(), and release_descriptor().

struct event queue_ev

Definition at line 331 of file bsd.c.

Referenced by runqueues(), and shovechars().

struct timeval queue_slice = { 0, 0 }

Definition at line 330 of file bsd.c.

Referenced by runqueues(), and shovechars().


Generated on Mon May 28 04:25:26 2007 for BattletechMUX by  doxygen 1.4.7