00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "copyright.h"
00012 #include "config.h"
00013
00014 #include <time.h>
00015
00016 #include "db.h"
00017 #include "mudconf.h"
00018 #include "file_c.h"
00019 #include "interface.h"
00020 #include "command.h"
00021 #include "externs.h"
00022 #include "alloc.h"
00023 #include "attrs.h"
00024 #include "mguests.h"
00025 #include "ansi.h"
00026 #include "mail.h"
00027 #include "powers.h"
00028 #include "alloc.h"
00029 #include "config.h"
00030 #include "p.comsys.h"
00031
00032 #ifdef DEBUG_NETCOMMON
00033 #ifndef DEBUG
00034 #define DEBUG
00035 #endif
00036 #endif
00037 #include "debug.h"
00038
00039 extern int process_output(DESC * d);
00040 extern void handle_prog(DESC *, char *);
00041 extern void fcache_dump_conn(DESC *, int);
00042 extern void do_comconnect(dbref, DESC *);
00043 extern void do_comdisconnect(dbref);
00044 void set_lastsite(DESC *, char *);
00045
00046
00047
00048
00049
00050
00051 void make_portlist(dbref player, dbref target, char *buff, char **bufc)
00052 {
00053 DESC *d;
00054 int i = 0;
00055
00056 DESC_ITER_CONN(d) {
00057 if(d->player == target) {
00058 safe_str(tprintf("%d ", d->descriptor), buff, bufc);
00059 i = 1;
00060 }
00061 }
00062 if(i) {
00063 (*bufc)--;
00064 }
00065 **bufc = '\0';
00066 }
00067
00068
00069
00070
00071
00072
00073 struct timeval timeval_sub(struct timeval now, struct timeval then)
00074 {
00075 now.tv_sec -= then.tv_sec;
00076 now.tv_usec -= then.tv_usec;
00077 if(now.tv_usec < 0) {
00078 now.tv_usec += 1000000;
00079 now.tv_sec--;
00080 }
00081 return now;
00082 }
00083
00084
00085
00086
00087
00088
00089 int msec_diff(struct timeval now, struct timeval then)
00090 {
00091 return ((now.tv_sec - then.tv_sec) * 1000 + (now.tv_usec -
00092 then.tv_usec) / 1000);
00093 }
00094
00095
00096
00097
00098
00099
00100 struct timeval msec_add(struct timeval t, int x)
00101 {
00102 t.tv_sec += x / 1000;
00103 t.tv_usec += (x % 1000) * 1000;
00104 if(t.tv_usec >= 1000000) {
00105 t.tv_sec += t.tv_usec / 1000000;
00106 t.tv_usec = t.tv_usec % 1000000;
00107 }
00108 return t;
00109 }
00110
00111
00112
00113
00114
00115
00116 struct timeval update_quotas(struct timeval last, struct timeval current)
00117 {
00118 int nslices;
00119 DESC *d;
00120
00121 nslices =
00122 msec_diff(current,
00123 last) / (mudconf.timeslice > 0 ? mudconf.timeslice : 1);
00124
00125 if(nslices > 0) {
00126 DESC_ITER_ALL(d) {
00127 d->quota += mudconf.cmd_quota_incr * nslices;
00128 if(d->quota > mudconf.cmd_quota_max)
00129 d->quota = mudconf.cmd_quota_max;
00130 }
00131 }
00132 return msec_add(last, nslices * mudconf.timeslice);
00133 }
00134
00135 #ifdef TCP_CORK // Linux 2.4, 2.6
00136
00137 void choke_player(dbref player)
00138 {
00139 DESC *d;
00140 int eins = 1, null = 0;
00141
00142 DESC_ITER_PLAYER(player, d) {
00143 if(d->chokes == 0) {
00144 if(setsockopt
00145 (d->descriptor, IPPROTO_TCP, TCP_CORK, &eins,
00146 sizeof(eins)) < 0) {
00147
00148
00149 }
00150 }
00151 d->chokes++;
00152 }
00153 }
00154
00155 void release_player(dbref player)
00156 {
00157 DESC *d;
00158 int eins = 1, null = 0;
00159
00160 DESC_ITER_PLAYER(player, d) {
00161 d->chokes--;
00162 if(d->chokes == 0) {
00163 if(setsockopt
00164 (d->descriptor, IPPROTO_TCP, TCP_CORK, &null,
00165 sizeof(null)) < 0) {
00166
00167
00168 }
00169 }
00170 if(d->chokes < 0)
00171 d->chokes = 0;
00172 }
00173 }
00174 #else
00175 #ifdef TCP_NOPUSH // *BSD, Mac OSX
00176
00177 void choke_player(dbref player)
00178 {
00179 DESC *d;
00180 int eins = 1, null = 0;
00181
00182 DESC_ITER_PLAYER(player, d) {
00183 if(setsockopt
00184 (d->descriptor, IPPROTO_TCP, TCP_NOPUSH, &eins,
00185 sizeof(eins)) < 0) {
00186 log_perror("NET", "FAIL", "choke_player", "setsockopt");
00187 }
00188 }
00189 }
00190
00191 void release_player(dbref player)
00192 {
00193 DESC *d;
00194 int eins = 1, null = 0;
00195
00196 DESC_ITER_PLAYER(player, d) {
00197 if(setsockopt
00198 (d->descriptor, IPPROTO_TCP, TCP_NOPUSH, &null,
00199 sizeof(null)) < 0) {
00200 log_perror("NET", "FAIL", "release_player", "setsockopt");
00201 }
00202 }
00203 }
00204 #else
00205 void choke_player(dbref player)
00206 {
00207
00208 }
00209 void release_player(dbref player)
00210 {
00211
00212 }
00213 #endif
00214 #endif
00215
00216
00217
00218 void raw_notify_raw(dbref player, const char *msg, char *append)
00219 {
00220 DESC *d;
00221
00222 if(!msg || !*msg)
00223 return;
00224
00225 if(mudstate.inpipe && (player == mudstate.poutobj)) {
00226 safe_str((char *) msg, mudstate.poutnew, &mudstate.poutbufc);
00227 if(append != NULL)
00228 safe_str(append, mudstate.poutnew, &mudstate.poutbufc);
00229 return;
00230 }
00231
00232 if(!Connected(player))
00233 return;
00234
00235 DESC_ITER_PLAYER(player, d) {
00236 queue_string(d, msg);
00237 if(append != NULL)
00238 queue_write(d, append, strlen(append));
00239 }
00240 }
00241
00242
00243 void raw_notify(dbref player, const char *msg)
00244 {
00245 raw_notify_raw(player, msg, "\r\n");
00246 }
00247
00248 void notify_printf(dbref player, const char *format, ...)
00249 {
00250 DESC *d;
00251 char buffer[LBUF_SIZE];
00252 va_list ap;
00253 memset(buffer, 0, LBUF_SIZE);
00254
00255 va_start(ap, format);
00256
00257 vsnprintf(buffer, LBUF_SIZE-1, format, ap);
00258 va_end(ap);
00259
00260 strncat(buffer, "\r\n", LBUF_SIZE-1);
00261 buffer[LBUF_SIZE-1] = '\0';
00262
00263 DESC_ITER_PLAYER(player, d) {
00264 queue_string(d, buffer);
00265 }
00266 }
00267
00268 void raw_notify_newline(dbref player)
00269 {
00270 DESC *d;
00271
00272 if(mudstate.inpipe && (player == mudstate.poutobj)) {
00273 safe_str("\r\n", mudstate.poutnew, &mudstate.poutbufc);
00274 return;
00275 }
00276 if(!Connected(player))
00277 return;
00278
00279 DESC_ITER_PLAYER(player, d) {
00280 queue_write(d, "\r\n", 2);
00281 }
00282 }
00283
00284 #ifdef HUDINFO_SUPPORT
00285 void hudinfo_notify(DESC * d, const char *msgclass, const char *msgtype,
00286 const char *msg)
00287 {
00288 char buf[LBUF_SIZE];
00289
00290 memset(buf, 0, LBUF_SIZE);
00291
00292 if(!msgclass || !msgtype) {
00293 queue_write(d, msg, strnlen(msg, LBUF_SIZE-1));
00294 queue_write(d, "\r\n", 2);
00295 return;
00296 }
00297
00298 snprintf(buf, LBUF_SIZE-1, "#HUD:%s:%s:%s# %s\r\n",
00299 d->hudkey[0] ? d->hudkey : "???", msgclass, msgtype, msg);
00300 buf[LBUF_SIZE - 1] = '\0';
00301 queue_write(d, buf, strnlen(buf, LBUF_SIZE-1));
00302 }
00303 #endif
00304
00305
00306
00307
00308
00309
00310 void raw_broadcast(int inflags, char *template, ...)
00311 {
00312 char buff[LBUF_SIZE];
00313 DESC *d;
00314 va_list ap;
00315
00316 va_start(ap, template);
00317 if(!template || !*template)
00318 return;
00319
00320 vsnprintf(buff, LBUF_SIZE, template, ap);
00321 buff[LBUF_SIZE-1] = '\0';
00322
00323 DESC_ITER_CONN(d) {
00324 if((Flags(d->player) & inflags) == inflags) {
00325 queue_write(d, buff, strnlen(buff, LBUF_SIZE-1));
00326 queue_write(d, "\r\n", 2);
00327 }
00328 }
00329 flush_sockets();
00330 va_end(ap);
00331 }
00332
00333
00334
00335
00336
00337
00338 void clearstrings(DESC * d)
00339 {
00340 if(d->output_prefix) {
00341 free_lbuf(d->output_prefix);
00342 d->output_prefix = NULL;
00343 }
00344 if(d->output_suffix) {
00345 free_lbuf(d->output_suffix);
00346 d->output_suffix = NULL;
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355 void queue_write(DESC * d, char *b, int n)
00356 {
00357 int retval;
00358 if(n <= 0)
00359 return;
00360
00361 bufferevent_write(d->sock_buff, b, n);
00362 d->output_tot += n;
00363 return;
00364 }
00365
00366 void queue_string(DESC * d, const char *s)
00367 {
00368 char new[LBUF_SIZE];
00369
00370 strncpy(new, s, LBUF_SIZE-1);
00371 new[LBUF_SIZE-1] = '\0';
00372
00373 if(!Ansi(d->player) && index(s, ESC_CHAR))
00374 strip_ansi_r(new, s, strlen(s));
00375 queue_write(d, new, strlen(new));
00376 }
00377
00378 void freeqs(DESC * d)
00379 {
00380 CBLK *cb, *cnext;
00381
00382 d->input_tail = 0;
00383 memset(d->input, 0, sizeof(d->input));
00384 }
00385 extern int fcache_conn_c;
00386
00387 void welcome_user(DESC * d)
00388 {
00389 if(d->host_info & H_REGISTRATION)
00390 fcache_dump(d, FC_CONN_REG);
00391 else {
00392 if(fcache_conn_c) {
00393 fcache_dump_conn(d, rand() % fcache_conn_c);
00394 return;
00395 }
00396 fcache_dump(d, FC_CONN);
00397 }
00398 }
00399
00400 void set_lastsite(DESC * d, char *lastsite)
00401 {
00402 int i, j;
00403 char buf[LBUF_SIZE];
00404
00405 if(d->player) {
00406 if(lastsite) {
00407 strncpy(buf, lastsite, LBUF_SIZE-1);
00408 buf[LBUF_SIZE-1] = '\0';
00409 } else {
00410 atr_get_str(buf, d->player, A_LASTSITE, &i, &j);
00411 }
00412 atr_add_raw(d->player, A_LASTSITE, buf);
00413 }
00414 }
00415
00416 static void set_userstring(char **userstring, const char *command)
00417 {
00418 while (*command && isascii(*command) && isspace(*command))
00419 command++;
00420 if(!*command) {
00421 if(*userstring != NULL) {
00422 free_lbuf(*userstring);
00423 *userstring = NULL;
00424 }
00425 } else {
00426 if(*userstring == NULL) {
00427 *userstring = alloc_lbuf("set_userstring");
00428 }
00429 snprintf(*userstring, LBUF_SIZE-1, "%s\r\n", command);
00430 }
00431 }
00432
00433 static void parse_connect(const char *msg, char *command, char *user,
00434 char *pass) {
00435 char *p;
00436
00437 if(strlen(msg) > (MBUF_SIZE-1)) {
00438 *command = '\0';
00439 *user = '\0';
00440 *pass = '\0';
00441 return;
00442 }
00443 while (*msg && isascii(*msg) && isspace(*msg))
00444 msg++;
00445 p = command;
00446 while (*msg && isascii(*msg) && !isspace(*msg))
00447 *p++ = *msg++;
00448 *p = '\0';
00449 while (*msg && isascii(*msg) && isspace(*msg))
00450 msg++;
00451 p = user;
00452 if(mudconf.name_spaces && (*msg == '\"')) {
00453 for(; *msg && (*msg == '\"' || isspace(*msg)); msg++);
00454 while (*msg && *msg != '\"') {
00455 while (*msg && !isspace(*msg) && (*msg != '\"'))
00456 *p++ = *msg++;
00457 if(*msg == '\"')
00458 break;
00459 while (*msg && isspace(*msg))
00460 msg++;
00461 if(*msg && (*msg != '\"'))
00462 *p++ = ' ';
00463 }
00464 for(; *msg && *msg == '\"'; msg++);
00465 } else
00466 while (*msg && isascii(*msg) && !isspace(*msg))
00467 *p++ = *msg++;
00468 *p = '\0';
00469 while (*msg && isascii(*msg) && isspace(*msg))
00470 msg++;
00471 p = pass;
00472 while (*msg && isascii(*msg) && !isspace(*msg))
00473 *p++ = *msg++;
00474 *p = '\0';
00475 }
00476
00477 static const char *time_format_1(time_t dt)
00478 {
00479 register struct tm *delta;
00480 static char buf[64];
00481
00482 if(dt < 0)
00483 dt = 0;
00484
00485 delta = gmtime(&dt);
00486 if(delta->tm_yday > 0) {
00487 sprintf(buf, "%dd %02d:%02d", delta->tm_yday, delta->tm_hour,
00488 delta->tm_min);
00489 } else {
00490 sprintf(buf, "%02d:%02d", delta->tm_hour, delta->tm_min);
00491 }
00492 return buf;
00493 }
00494
00495 static const char *time_format_2(time_t dt)
00496 {
00497 register struct tm *delta;
00498 static char buf[64];
00499
00500 if(dt < 0)
00501 dt = 0;
00502
00503 delta = gmtime(&dt);
00504 if(delta->tm_yday > 0) {
00505 sprintf(buf, "%dd", delta->tm_yday);
00506 } else if(delta->tm_hour > 0) {
00507 sprintf(buf, "%dh", delta->tm_hour);
00508 } else if(delta->tm_min > 0) {
00509 sprintf(buf, "%dm", delta->tm_min);
00510 } else {
00511 sprintf(buf, "%ds", delta->tm_sec);
00512 }
00513 return buf;
00514 }
00515
00516 extern char *mux_version;
00517 void desc_addhash(DESC *);
00518
00519 static void announce_connect(dbref player, DESC * d)
00520 {
00521 dbref loc, aowner, temp;
00522 dbref zone, obj;
00523
00524 int aflags, num, key, count;
00525 char *buf, *time_str;
00526 DESC *dtemp;
00527
00528 queue_string(d, "Connected.\n");
00529 queue_string(d, mux_version);
00530 queue_string(d, "\n\n");
00531
00532 desc_addhash(d);
00533
00534 choke_player(player);
00535
00536 count = 0;
00537 DESC_ITER_CONN(dtemp)
00538 count++;
00539
00540 if(mudstate.record_players < count)
00541 mudstate.record_players = count;
00542
00543 buf = atr_pget(player, A_TIMEOUT, &aowner, &aflags);
00544 if(buf) {
00545 d->timeout = atoi(buf);
00546 if(d->timeout <= 0)
00547 d->timeout = mudconf.idle_timeout;
00548 }
00549 free_lbuf(buf);
00550
00551 loc = Location(player);
00552 s_Connected(player);
00553
00554
00555 queue_string(d, tprintf("\n%sMOTD:%s %s\n", ANSI_HILITE,
00556 ANSI_NORMAL, mudconf.motd_msg));
00557 if(Wizard(player)) {
00558 raw_notify(player, tprintf("%sWIZMOTD:%s %s\n", ANSI_HILITE,
00559 ANSI_NORMAL, mudconf.wizmotd_msg));
00560 if(!(mudconf.control_flags & CF_LOGIN)) {
00561 raw_notify(player, "*** Logins are disabled.");
00562 }
00563 }
00564 buf = atr_get(player, A_LPAGE, &aowner, &aflags);
00565 if(buf && *buf) {
00566 raw_notify(player,
00567 "Your PAGE LOCK is set. You may be unable to receive some pages.");
00568 }
00569 num = 0;
00570 DESC_ITER_PLAYER(player, dtemp) num++;
00571
00572
00573
00574
00575 s_Flags2(player, Flags2(player) & ~VACATION);
00576
00577 if(num < 2) {
00578 sprintf(buf, "%s has connected.", Name(player));
00579
00580 if(mudconf.have_comsys)
00581 do_comconnect(player, d);
00582
00583 if(Dark(player)) {
00584 raw_broadcast(MONITOR, (char *) "GAME: %s has DARK-connected.",
00585 Name(player), 0, 0, 0, 0, 0);
00586 } else {
00587 raw_broadcast(MONITOR, (char *) "GAME: %s has connected.",
00588 Name(player), 0, 0, 0, 0, 0);
00589 }
00590 } else {
00591 sprintf(buf, "%s has reconnected.", Name(player));
00592 raw_broadcast(MONITOR, (char *) "GAME: %s has reconnected.",
00593 Name(player), 0, 0, 0, 0, 0);
00594 }
00595
00596 key = MSG_INV;
00597 if((loc != NOTHING) && !(Dark(player) && Wizard(player)))
00598 key |= (MSG_NBR | MSG_NBR_EXITS | MSG_LOC | MSG_FWDLIST);
00599
00600 temp = mudstate.curr_enactor;
00601 mudstate.curr_enactor = player;
00602 notify_checked(player, player, buf, key);
00603 free_lbuf(buf);
00604 if(Suspect(player)) {
00605 send_channel("Suspect", "%s has connected.", Name(player));
00606
00607 }
00608 if(d->host_info & H_SUSPECT)
00609 send_channel("Suspect", "[Suspect site: %s] %s has connected.",
00610 d->addr, Name(player));
00611 buf = atr_pget(player, A_ACONNECT, &aowner, &aflags);
00612 if(buf)
00613 wait_que(player, player, 0, NOTHING, 0, buf, (char **) NULL, 0, NULL);
00614 free_lbuf(buf);
00615 if(mudconf.master_room != NOTHING) {
00616 buf = atr_pget(mudconf.master_room, A_ACONNECT, &aowner, &aflags);
00617 if(buf)
00618 wait_que(mudconf.master_room, player, 0, NOTHING, 0, buf,
00619 (char **) NULL, 0, NULL);
00620 free_lbuf(buf);
00621 DOLIST(obj, Contents(mudconf.master_room)) {
00622 buf = atr_pget(obj, A_ACONNECT, &aowner, &aflags);
00623 if(buf) {
00624 wait_que(obj, player, 0, NOTHING, 0, buf, (char **) NULL,
00625 0, NULL);
00626 }
00627 free_lbuf(buf);
00628 }
00629 }
00630
00631
00632
00633 if(mudconf.have_zones && ((zone = Zone(loc)) != NOTHING)) {
00634 switch (Typeof(zone)) {
00635 case TYPE_THING:
00636 buf = atr_pget(zone, A_ACONNECT, &aowner, &aflags);
00637 if(buf) {
00638 wait_que(zone, player, 0, NOTHING, 0, buf, (char **) NULL,
00639 0, NULL);
00640 }
00641 free_lbuf(buf);
00642 break;
00643 case TYPE_ROOM:
00644
00645
00646
00647
00648 DOLIST(obj, Contents(zone)) {
00649 buf = atr_pget(obj, A_ACONNECT, &aowner, &aflags);
00650 if(buf) {
00651 wait_que(obj, player, 0, NOTHING, 0, buf,
00652 (char **) NULL, 0, NULL);
00653 }
00654 free_lbuf(buf);
00655 }
00656 break;
00657 default:
00658 log_text(tprintf
00659 ("Invalid zone #%d for %s(#%d) has bad type %d", zone,
00660 Name(player), player, Typeof(zone)));
00661 }
00662 }
00663 time_str = ctime(&mudstate.now);
00664 time_str[strlen(time_str) - 1] = '\0';
00665 record_login(player, 1, time_str, d->addr, d->username);
00666 look_in(player, Location(player),
00667 (LK_SHOWEXIT | LK_OBEYTERSE));
00668 mudstate.curr_enactor = temp;
00669 release_player(player);
00670 }
00671
00672 void announce_disconnect(dbref player, DESC * d, const char *reason)
00673 {
00674 dbref loc, aowner, temp, zone, obj;
00675 int num, aflags, key;
00676 char *buf, *atr_temp;
00677 DESC *dtemp;
00678 char *argv[1];
00679
00680 if(Suspect(player)) {
00681 send_channel("Suspect", "%s has disconnected.", Name(player));
00682 }
00683 if(d->host_info & H_SUSPECT) {
00684 send_channel("Suspect", "[Suspect site: %s] %s has disconnected.",
00685 d->addr, Name(d->player));
00686 }
00687 loc = Location(player);
00688 num = 0;
00689 DESC_ITER_PLAYER(player, dtemp) num++;
00690
00691 temp = mudstate.curr_enactor;
00692 mudstate.curr_enactor = player;
00693
00694 if(num < 2) {
00695 buf = alloc_mbuf("announce_disconnect.only");
00696
00697 sprintf(buf, "%s has disconnected.", Name(player));
00698 key = MSG_INV;
00699 if((loc != NOTHING) && !(Dark(player) && Wizard(player)))
00700 key |= (MSG_NBR | MSG_NBR_EXITS | MSG_LOC | MSG_FWDLIST);
00701 notify_checked(player, player, buf, key);
00702 free_mbuf(buf);
00703
00704 if(mudconf.have_comsys)
00705 do_comdisconnect(player);
00706
00707 if(mudconf.have_mailer)
00708 do_mail_purge(player);
00709
00710 raw_broadcast(MONITOR, (char *) "GAME: %s has disconnected.",
00711 Name(player), 0, 0, 0, 0, 0);
00712
00713 if(Guest(player) && mudconf.have_comsys)
00714 toast_player(player);
00715
00716 argv[0] = (char *) reason;
00717 c_Connected(player);
00718
00719 atr_temp = atr_pget(player, A_ADISCONNECT, &aowner, &aflags);
00720 if(atr_temp && *atr_temp)
00721 wait_que(player, player, 0, NOTHING, 0, atr_temp, argv, 1, NULL);
00722 free_lbuf(atr_temp);
00723 if(mudconf.master_room != NOTHING) {
00724 atr_temp =
00725 atr_pget(mudconf.master_room, A_ADISCONNECT, &aowner,
00726 &aflags);
00727 if(atr_temp)
00728 wait_que(mudconf.master_room, player, 0, NOTHING, 0,
00729 atr_temp, (char **) NULL, 0, NULL);
00730 free_lbuf(atr_temp);
00731 DOLIST(obj, Contents(mudconf.master_room)) {
00732 atr_temp = atr_pget(obj, A_ADISCONNECT, &aowner, &aflags);
00733 if(atr_temp) {
00734 wait_que(obj, player, 0, NOTHING, 0, atr_temp,
00735 (char **) NULL, 0, NULL);
00736 }
00737 free_lbuf(atr_temp);
00738 }
00739 }
00740
00741
00742
00743
00744 if(mudconf.have_zones && ((zone = Zone(loc)) != NOTHING)) {
00745 switch (Typeof(zone)) {
00746 case TYPE_THING:
00747 atr_temp = atr_pget(zone, A_ADISCONNECT, &aowner, &aflags);
00748 if(atr_temp) {
00749 wait_que(zone, player, 0, NOTHING, 0, atr_temp,
00750 (char **) NULL, 0, NULL);
00751 }
00752 free_lbuf(atr_temp);
00753 break;
00754 case TYPE_ROOM:
00755
00756
00757
00758
00759 DOLIST(obj, Contents(zone)) {
00760 atr_temp = atr_pget(obj, A_ADISCONNECT, &aowner, &aflags);
00761 if(atr_temp) {
00762 wait_que(obj, player, 0, NOTHING, 0, atr_temp,
00763 (char **) NULL, 0, NULL);
00764 }
00765 free_lbuf(atr_temp);
00766 }
00767 break;
00768 default:
00769 log_text(tprintf
00770 ("Invalid zone #%d for %s(#%d) has bad type %d",
00771 zone, Name(player), player, Typeof(zone)));
00772 }
00773 }
00774 if(d->flags & DS_AUTODARK) {
00775 s_Flags(d->player, Flags(d->player) & ~DARK);
00776 d->flags &= ~DS_AUTODARK;
00777 }
00778
00779 if(Guest(player))
00780 s_Flags(player, Flags(player) | DARK);
00781 } else {
00782 buf = alloc_mbuf("announce_disconnect.partial");
00783 sprintf(buf, "%s has partially disconnected.", Name(player));
00784 key = MSG_INV;
00785 if((loc != NOTHING) && !(Dark(player) && Wizard(player)))
00786 key |= (MSG_NBR | MSG_NBR_EXITS | MSG_LOC | MSG_FWDLIST);
00787 notify_checked(player, player, buf, key);
00788 raw_broadcast(MONITOR,
00789 (char *) "GAME: %s has partially disconnected.",
00790 Name(player), 0, 0, 0, 0, 0);
00791 free_mbuf(buf);
00792 }
00793
00794 mudstate.curr_enactor = temp;
00795 release_player(player);
00796 }
00797
00798 int boot_off(dbref player, char *message)
00799 {
00800 DESC *d, *dnext;
00801 int count;
00802
00803 count = 0;
00804 DESC_SAFEITER_PLAYER(player, d, dnext) {
00805 if(message && *message) {
00806 queue_string(d, message);
00807 queue_string(d, "\r\n");
00808 }
00809 shutdownsock(d, R_BOOT);
00810 count++;
00811 }
00812 return count;
00813 }
00814
00815 int boot_by_port(int port, int no_god, char *message)
00816 {
00817 DESC *d, *dnext;
00818 int count;
00819
00820 count = 0;
00821 DESC_SAFEITER_ALL(d, dnext) {
00822 if((d->descriptor == port) && (!no_god || !God(d->player))) {
00823 if(message && *message) {
00824 queue_string(d, message);
00825 queue_string(d, "\r\n");
00826 }
00827 shutdownsock(d, R_BOOT);
00828 count++;
00829 }
00830 }
00831 return count;
00832 }
00833
00834
00835
00836
00837
00838
00839 void desc_reload(dbref player)
00840 {
00841 DESC *d;
00842 char *buf;
00843 dbref aowner;
00844 FLAG aflags;
00845
00846 DESC_ITER_PLAYER(player, d) {
00847 buf = atr_pget(player, A_TIMEOUT, &aowner, &aflags);
00848 if(buf) {
00849 d->timeout = atoi(buf);
00850 if(d->timeout <= 0)
00851 d->timeout = mudconf.idle_timeout;
00852 }
00853 free_lbuf(buf);
00854 }
00855 }
00856
00857
00858
00859
00860
00861
00862
00863 int fetch_idle(dbref target)
00864 {
00865 DESC *d;
00866 int result, idletime;
00867
00868 result = -1;
00869 DESC_ITER_PLAYER(target, d) {
00870 idletime = (mudstate.now - d->last_time);
00871 if((result == -1) || (idletime < result))
00872 result = idletime;
00873 }
00874 return result;
00875 }
00876
00877 int fetch_connect(dbref target)
00878 {
00879 DESC *d;
00880 int result, conntime;
00881
00882 result = -1;
00883 DESC_ITER_PLAYER(target, d) {
00884 conntime = (mudstate.now - d->connected_at);
00885 if(conntime > result)
00886 result = conntime;
00887 }
00888 return result;
00889 }
00890
00891 static char *trimmed_name(dbref player)
00892 {
00893 static char cbuff[18];
00894
00895 if(strlen(Name(player)) <= 16)
00896 return Name(player);
00897 StringCopyTrunc(cbuff, Name(player), 16);
00898 cbuff[16] = '\0';
00899 return cbuff;
00900 }
00901
00902 static char *trimmed_site(char *name)
00903 {
00904 static char buff[MBUF_SIZE];
00905
00906 if((strlen(name) <= mudconf.site_chars) || (mudconf.site_chars == 0))
00907 return name;
00908 StringCopyTrunc(buff, name, mudconf.site_chars);
00909 buff[mudconf.site_chars + 1] = '\0';
00910 return buff;
00911 }
00912
00913 static void dump_users(DESC * e, char *match, int key)
00914 {
00915 DESC *d;
00916 int count, rcount;
00917 char *buf, *fp, *sp, flist[4], slist[4];
00918 dbref room_it;
00919
00920 while (match && *match && isspace(*match))
00921 match++;
00922 if(!match || !*match)
00923 match = NULL;
00924
00925
00926
00927 buf = alloc_mbuf("dump_users");
00928 if(key == CMD_SESSION) {
00929 queue_string(e, " ");
00930 queue_string(e,
00931 " Characters Input---- Characters Output---\r\n");
00932 }
00933 queue_string(e, "Player Name On For Idle ");
00934 if(key == CMD_SESSION) {
00935 queue_string(e,
00936 "Port Pend Lost Total Pend Lost Total\r\n");
00937 } else if((e->flags & DS_CONNECTED) && (Wizard_Who(e->player)) &&
00938 (key == CMD_WHO)) {
00939 queue_string(e, " Room Cmds Host\r\n");
00940 } else {
00941 if(Wizard_Who(e->player))
00942 queue_string(e, " ");
00943 else
00944 queue_string(e, " ");
00945 queue_string(e, mudstate.doing_hdr);
00946 queue_string(e, "\r\n");
00947 }
00948 count = 0;
00949 rcount = 0;
00950 DESC_ITER_CONN(d) {
00951 if((!mudconf.show_unfindable_who || !Hidden(d->player)) ||
00952 (e->flags & DS_CONNECTED) & Wizard_Who(e->player)) {
00953 count++;
00954 if(match && !(string_prefix(Name(d->player), match)))
00955 continue;
00956 #if 0
00957 if((!((Wizard_Who(e->player)) && (e->flags & DS_CONNECTED)) &&
00958 (d->player != e->player)))
00959 if(In_Character(Location(d->player)) &&
00960 In_Character(Location(Location(d->player))))
00961 continue;
00962 #endif
00963 rcount++;
00964 if((key == CMD_SESSION) && !(Wizard_Who(e->player) && (e->flags & DS_CONNECTED)) && (d->player != e->player))
00965 continue;
00966
00967
00968
00969
00970
00971 fp = flist;
00972 sp = slist;
00973 if((e->flags & DS_CONNECTED) && Wizard_Who(e->player)) {
00974 if(Hidden(d->player)) {
00975 if(d->flags & DS_AUTODARK)
00976 *fp++ = 'd';
00977 else if(Dark(d->player))
00978 *fp++ = 'D';
00979 }
00980 if(!Findable(d->player)) {
00981 *fp++ = 'U';
00982 } else {
00983 room_it = where_room(d->player);
00984 if(Good_obj(room_it)) {
00985 if(Hideout(room_it))
00986 *fp++ = 'u';
00987 } else {
00988 *fp++ = 'u';
00989 }
00990 }
00991
00992 if(Suspect(d->player))
00993 *fp++ = '+';
00994 if(d->host_info & H_FORBIDDEN)
00995 *sp++ = 'F';
00996 if(d->host_info & H_REGISTRATION)
00997 *sp++ = 'R';
00998 if(d->host_info & H_SUSPECT)
00999 *sp++ = '+';
01000 }
01001 *fp = '\0';
01002 *sp = '\0';
01003
01004 if((e->flags & DS_CONNECTED) && Wizard_Who(e->player) &&
01005 (key == CMD_WHO)) {
01006 sprintf(buf, "%-16s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n",
01007 trimmed_name(d->player),
01008 time_format_1(mudstate.now - d->connected_at),
01009 time_format_2(mudstate.now - d->last_time), flist,
01010 Location(d->player), d->command_count, slist,
01011 trimmed_site(((d->username[0] !=
01012 '\0') ? tprintf("%s@%s", d->username,
01013 d->addr) : d->addr)));
01014 } else if(key == CMD_SESSION) {
01015 sprintf(buf, "%-16s%9s %4s%5d%5d%6d%10d%6d%6d%10d\r\n",
01016 trimmed_name(d->player),
01017 time_format_1(mudstate.now - d->connected_at),
01018 time_format_2((mudstate.now - d->last_time) >
01019 HIDDEN_IDLESECS ? (mudstate.now -
01020 d->last_time) : 0),
01021 d->descriptor, d->input_size, d->input_lost,
01022 d->input_tot, d->output_size, d->output_lost,
01023 d->output_tot);
01024 } else if(Wizard_Who(e->player)) {
01025 sprintf(buf, "%-16s%9s %4s%-3s%s\r\n",
01026 trimmed_name(d->player),
01027 time_format_1(mudstate.now - d->connected_at),
01028 time_format_2((mudstate.now - d->last_time) >
01029 HIDDEN_IDLESECS ? (mudstate.now -
01030 d->last_time) : 0),
01031 flist, d->doing);
01032 } else {
01033 sprintf(buf, "%-16s%9s %4s %s\r\n",
01034 trimmed_name(d->player),
01035 time_format_1(mudstate.now - d->connected_at),
01036 time_format_2((mudstate.now - d->last_time) >
01037 HIDDEN_IDLESECS ? (mudstate.now -
01038 d->last_time) : 0),
01039 d->doing);
01040 }
01041 queue_string(e, buf);
01042 }
01043 }
01044 count = rcount;
01045
01046
01047
01048
01049 sprintf(buf, "%d Player%slogged in, %d record, %s maximum.\r\n", count,
01050 (count == 1) ? " " : "s ", mudstate.record_players,
01051 (mudconf.max_players == -1) ? "no" : tprintf("%d",
01052 mudconf.
01053 max_players));
01054 queue_string(e, buf);
01055
01056
01057 free_mbuf(buf);
01058 }
01059
01060
01061
01062
01063
01064
01065
01066 void do_doing(dbref player, dbref cause, int key, char *arg)
01067 {
01068 DESC *d;
01069 char *c, *e;
01070 int foundany, over;
01071
01072 if(key == DOING_MESSAGE) {
01073 foundany = 0;
01074 over = 0;
01075 DESC_ITER_PLAYER(player, d) {
01076 c = d->doing;
01077
01078 over =
01079 safe_copy_str(arg, d->doing, &c,
01080 DOINGLEN - 2 - strlen(ANSI_NORMAL));
01081
01082 if(over) {
01083 e = c;
01084 c--;
01085 if(isdigit(*c)) {
01086 while (isdigit(*c) && c > e)
01087 c--;
01088 if(*c == '[') {
01089 c--;
01090 if(c > e && *c == '\033') {
01091 *c = 0;
01092 e = c;
01093 }
01094 }
01095 }
01096 StringCopy(e, ANSI_NORMAL);
01097 } else
01098 StringCopy(c, ANSI_NORMAL);
01099 foundany = 1;
01100 }
01101 if(foundany) {
01102 if(over) {
01103 notify_printf(player, "Warning: %d characters lost.", over);
01104 }
01105 if(!Quiet(player))
01106 notify(player, "Set.");
01107 } else {
01108 notify(player, "Not connected.");
01109 }
01110 } else if(key == DOING_HEADER) {
01111 if(!(Can_Poll(player))) {
01112 notify(player, "Permission denied.");
01113 return;
01114 }
01115 if(!arg || !*arg) {
01116 StringCopy(mudstate.doing_hdr, "Doing");
01117 over = 0;
01118 } else {
01119 c = mudstate.doing_hdr;
01120 over = safe_copy_str(arg, mudstate.doing_hdr, &c, DOINGLEN - 1);
01121 *c = '\0';
01122 }
01123 if(over) {
01124 notify_printf(player, "Warning: %d characters lost.", over);
01125 }
01126 if(!Quiet(player))
01127 notify(player, "Set.");
01128 } else {
01129 notify_printf(player, "Poll: %s", mudstate.doing_hdr);
01130 }
01131 }
01132
01133 NAMETAB logout_cmdtable[] = {
01134 {(char *) "DOING", 5, CA_PUBLIC, CMD_DOING},
01135 {(char *) "LOGOUT", 6, CA_PUBLIC, CMD_LOGOUT},
01136 {(char *) "OUTPUTPREFIX", 12, CA_PUBLIC, CMD_PREFIX | CMD_NOxFIX},
01137 {(char *) "OUTPUTSUFFIX", 12, CA_PUBLIC, CMD_SUFFIX | CMD_NOxFIX},
01138 {(char *) "QUIT", 4, CA_PUBLIC, CMD_QUIT},
01139 {(char *) "SESSION", 7, CA_PUBLIC, CMD_SESSION},
01140 {(char *) "WHO", 3, CA_PUBLIC, CMD_WHO},
01141 {(char *) "PUEBLOCLIENT", 12, CA_PUBLIC, CMD_PUEBLOCLIENT},
01142 {NULL, 0, 0, 0}
01143 };
01144
01145 void init_logout_cmdtab(void)
01146 {
01147 NAMETAB *cp;
01148
01149
01150
01151
01152
01153
01154
01155 hashinit(&mudstate.logout_cmd_htab, 3 * HASH_FACTOR);
01156 for(cp = logout_cmdtable; cp->flag; cp++)
01157 hashadd(cp->name, (int *) cp, &mudstate.logout_cmd_htab);
01158 }
01159
01160 static void failconn(const char *logcode, const char *logtype,
01161 const char *logreason, DESC * d, int disconnect_reason,
01162 dbref player, int filecache, char *motd_msg,
01163 char *command, char *user, char *password, char *cmdsave)
01164 {
01165 char *buff;
01166
01167 STARTLOG(LOG_LOGIN | LOG_SECURITY, logcode, "RJCT") {
01168 buff = alloc_mbuf("failconn.LOG");
01169 sprintf(buff, "[%d/%s] %s rejected to ", d->descriptor, d->addr,
01170 logtype);
01171 log_text(buff);
01172 free_mbuf(buff);
01173 if(player != NOTHING)
01174 log_name(player);
01175 else
01176 log_text(user);
01177 log_text((char *) " (");
01178 log_text((char *) logreason);
01179 log_text((char *) ")");
01180 ENDLOG;
01181 } fcache_dump(d, filecache);
01182
01183 if(*motd_msg) {
01184 queue_string(d, motd_msg);
01185 queue_write(d, "\r\n", 2);
01186 }
01187 free_lbuf(command);
01188 free_lbuf(user);
01189 free_lbuf(password);
01190 shutdownsock(d, disconnect_reason);
01191 mudstate.debug_cmd = cmdsave;
01192 return;
01193 }
01194
01195 static const char *connect_fail =
01196 "Either that player does not exist, or has a different password.\r\n";
01197 static const char *create_fail =
01198 "Either there is already a player with that name, or that name is illegal.\r\n";
01199
01200 static int check_connect(DESC * d, char *msg)
01201 {
01202 char *command, *user, *password, *buff, *cmdsave;
01203 dbref player, aowner;
01204 int aflags, nplayers;
01205 DESC *d2;
01206 char *p;
01207
01208 cmdsave = mudstate.debug_cmd;
01209 mudstate.debug_cmd = (char *) "< check_connect >";
01210
01211
01212
01213
01214
01215 d->input_tot -= (strlen(msg) + 1);
01216
01217
01218
01219
01220
01221 command = alloc_lbuf("check_conn.cmd");
01222 user = alloc_lbuf("check_conn.user");
01223 password = alloc_lbuf("check_conn.pass");
01224 parse_connect(msg, command, user, password);
01225
01226 if(!strncmp(command, "co", 2) || !strncmp(command, "cd", 2)) {
01227 if((string_prefix(user, mudconf.guest_prefix)) &&
01228 (mudconf.guest_char != NOTHING) &&
01229 (mudconf.control_flags & CF_LOGIN)) {
01230 if((p = make_guest(d)) == NULL) {
01231 queue_string(d,
01232 "All guests are tied up, please try again later.\n");
01233 free_lbuf(command);
01234 free_lbuf(user);
01235 free_lbuf(password);
01236 return 0;
01237 }
01238 StringCopy(user, p);
01239 StringCopy(password, mudconf.guest_prefix);
01240 }
01241
01242
01243
01244
01245 if(mudconf.max_players < 0) {
01246 nplayers = mudconf.max_players - 1;
01247 } else {
01248 nplayers = 0;
01249 DESC_ITER_CONN(d2)
01250 nplayers++;
01251 }
01252
01253 player = connect_player(user, password, d->addr, d->username);
01254 if(player == NOTHING) {
01255
01256
01257
01258
01259
01260 queue_string(d, connect_fail);
01261 STARTLOG(LOG_LOGIN | LOG_SECURITY, "CON", "BAD") {
01262 buff = alloc_lbuf("check_conn.LOG.bad");
01263 user[3800] = '\0';
01264 sprintf(buff, "[%d/%s] Failed connect to '%s'",
01265 d->descriptor, d->addr, user);
01266 log_text(buff);
01267 free_lbuf(buff);
01268 ENDLOG;
01269 }
01270 if(--(d->retries_left) <= 0) {
01271 free_lbuf(command);
01272 free_lbuf(user);
01273 free_lbuf(password);
01274 shutdownsock(d, R_BADLOGIN);
01275 mudstate.debug_cmd = cmdsave;
01276 return 0;
01277 }
01278 } else if(((mudconf.control_flags & CF_LOGIN) &&
01279 (nplayers < mudconf.max_players)) || WizRoy(player) ||
01280 God(player)) {
01281
01282 if(!strncmp(command, "cd", 2) && (Wizard(player) || God(player)))
01283 s_Flags(player, Flags(player) | DARK);
01284
01285
01286
01287
01288
01289 STARTLOG(LOG_LOGIN, "CON", "LOGIN") {
01290 buff = alloc_mbuf("check_conn.LOG.login");
01291 sprintf(buff, "[%d/%s] Connected to ", d->descriptor,
01292 d->addr);
01293 log_text(buff);
01294 log_name_and_loc(player);
01295 free_mbuf(buff);
01296 ENDLOG;
01297 }
01298 d->flags |= DS_CONNECTED;
01299
01300 d->connected_at = time(0);
01301 d->player = player;
01302 set_lastsite(d, NULL);
01303
01304
01305
01306
01307
01308
01309 DESC_ITER_PLAYER(player, d2) {
01310 if(d2->program_data != NULL) {
01311 d->program_data = d2->program_data;
01312 break;
01313 }
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323 if(Guest(player)) {
01324 fcache_dump(d, FC_CONN_GUEST);
01325 } else {
01326 buff = atr_get(player, A_LAST, &aowner, &aflags);
01327 if((buff == NULL) || (*buff == '\0'))
01328 fcache_dump(d, FC_CREA_NEW);
01329 else
01330 fcache_dump(d, FC_MOTD);
01331 if(Wizard(player))
01332 fcache_dump(d, FC_WIZMOTD);
01333 free_lbuf(buff);
01334 }
01335 announce_connect(player, d);
01336
01337
01338
01339 if(d->program_data != NULL)
01340 queue_string(d, ">\377\371");
01341
01342 } else if(!(mudconf.control_flags & CF_LOGIN)) {
01343 failconn("CON", "Connect", "Logins Disabled", d, R_GAMEDOWN,
01344 player, FC_CONN_DOWN, mudconf.downmotd_msg, command,
01345 user, password, cmdsave);
01346 return 0;
01347 } else {
01348 failconn("CON", "Connect", "Game Full", d, R_GAMEFULL, player,
01349 FC_CONN_FULL, mudconf.fullmotd_msg, command, user,
01350 password, cmdsave);
01351 return 0;
01352 }
01353 } else if(!strncmp(command, "cr", 2)) {
01354
01355
01356
01357
01358
01359 if(!(mudconf.control_flags & CF_LOGIN)) {
01360 failconn("CRE", "Create", "Logins Disabled", d, R_GAMEDOWN,
01361 NOTHING, FC_CONN_DOWN, mudconf.downmotd_msg, command,
01362 user, password, cmdsave);
01363 return 0;
01364 }
01365
01366
01367
01368
01369 if(mudconf.max_players < 0) {
01370 nplayers = mudconf.max_players;
01371 } else {
01372 nplayers = 0;
01373 DESC_ITER_CONN(d2)
01374 nplayers++;
01375 }
01376 if(nplayers > mudconf.max_players) {
01377
01378
01379
01380
01381
01382 failconn("CRE", "Create", "Game Full", d, R_GAMEFULL, NOTHING,
01383 FC_CONN_FULL, mudconf.fullmotd_msg, command, user,
01384 password, cmdsave);
01385 return 0;
01386 }
01387 if(d->host_info & H_REGISTRATION) {
01388 fcache_dump(d, FC_CREA_REG);
01389 } else {
01390 player = create_player(user, password, NOTHING, 0, 0);
01391 if(player == NOTHING) {
01392 queue_string(d, create_fail);
01393 STARTLOG(LOG_SECURITY | LOG_PCREATES, "CON", "BAD") {
01394 buff = alloc_mbuf("check_conn.LOG.badcrea");
01395 sprintf(buff, "[%d/%s] Create of '%s' failed",
01396 d->descriptor, d->addr, user);
01397 log_text(buff);
01398 free_mbuf(buff);
01399 ENDLOG;
01400 }
01401 } else {
01402 STARTLOG(LOG_LOGIN | LOG_PCREATES, "CON", "CREA") {
01403 buff = alloc_mbuf("check_conn.LOG.create");
01404 sprintf(buff, "[%d/%s] Created ", d->descriptor, d->addr);
01405 log_text(buff);
01406 log_name(player);
01407 free_mbuf(buff);
01408 ENDLOG;
01409 }
01410 move_object(player, mudconf.start_room);
01411
01412 d->flags |= DS_CONNECTED;
01413 d->connected_at = time(0);
01414 d->player = player;
01415 set_lastsite(d, NULL);
01416 fcache_dump(d, FC_CREA_NEW);
01417 announce_connect(player, d);
01418 }
01419 }
01420 } else {
01421 welcome_user(d);
01422 STARTLOG(LOG_LOGIN | LOG_SECURITY, "CON", "BAD") {
01423 buff = alloc_mbuf("check_conn.LOG.bad");
01424 msg[150] = '\0';
01425 sprintf(buff, "[%d/%s] Failed connect: '%s'", d->descriptor,
01426 d->addr, msg);
01427 log_text(buff);
01428 free_mbuf(buff);
01429 ENDLOG;
01430 }
01431 }
01432 free_lbuf(command);
01433 free_lbuf(user);
01434 free_lbuf(password);
01435
01436 mudstate.debug_cmd = cmdsave;
01437 return 1;
01438 }
01439
01440 int do_unauth_command(DESC *d, char *command) {
01441 char *arg;
01442 NAMETAB *cp;
01443
01444 d->last_time = mudstate.now;
01445 arg = command;
01446
01447 dassert(!(d->flags & DS_CONNECTED));
01448 if(d->flags & DS_DEAD) return 0;
01449
01450 while(*arg && !isspace(*arg)) arg++;
01451
01452 if(*arg)
01453 *arg++ = '\0';
01454
01455 cp = (NAMETAB *) hashfind(command, &mudstate.logout_cmd_htab);
01456 if(*arg)
01457 *--arg = ' ';
01458
01459 if(!cp)
01460 return check_connect(d, command);
01461
01462 d->command_count++;
01463 if(!(cp->flag & CMD_NOxFIX)) {
01464 if(d->output_prefix) {
01465 queue_string(d, d->output_prefix);
01466 }
01467 }
01468
01469 switch (cp->flag & CMD_MASK) {
01470 case CMD_QUIT:
01471 shutdownsock(d, R_QUIT);
01472 return 0;
01473 case CMD_WHO:
01474 if(d->player || mudconf.allow_unloggedwho) {
01475 dump_users(d, arg, CMD_WHO);
01476 } else {
01477 queue_string(d, "This MUX does not allow WHO at the login screen.\r\n");
01478 queue_string(d, "Please login or create a character first.\r\n");
01479 }
01480 break;
01481 case CMD_DOING:
01482 if(d->player || mudconf.allow_unloggedwho) {
01483 dump_users(d, arg, CMD_DOING);
01484 } else {
01485 queue_string(d, "This MUX does not allow DOING at the login screen.\r\n");
01486 queue_string(d, "Please login or create a character first.\r\n");
01487 }
01488 break;
01489 case CMD_SESSION:
01490 if(d->player || mudconf.allow_unloggedwho) {
01491 dump_users(d, arg, CMD_SESSION);
01492 } else {
01493 queue_string(d, "This MUX does not allow SESSION at the login screen.\r\n");
01494 queue_string(d, "Please login or create a character first.\r\n");
01495 }
01496 break;
01497 case CMD_PREFIX:
01498 set_userstring(&d->output_prefix, arg);
01499 break;
01500 case CMD_SUFFIX:
01501 set_userstring(&d->output_suffix, arg);
01502 break;
01503 default:
01504 log_error(LOG_BUGS, "BUG", "PARSE", "Prefix command with no handler: '%s'", command);
01505 }
01506
01507 if(!(cp->flag & CMD_NOxFIX)) {
01508 if(d->output_suffix) {
01509 queue_string(d, d->output_suffix);
01510 }
01511 }
01512 return 1;
01513 }
01514
01515
01516 int do_command(DESC * d, char *command)
01517 {
01518 char *arg, *cmdsave;
01519 NAMETAB *cp;
01520
01521 cmdsave = mudstate.debug_cmd;
01522 mudstate.debug_cmd = (char *) "< do_command >";
01523 d->last_time = mudstate.now;
01524
01525
01526
01527
01528
01529 arg = command;
01530 while (*arg && !isspace(*arg))
01531 arg++;
01532 if(*arg)
01533 *arg++ = '\0';
01534
01535 #ifdef HUDINFO_SUPPORT
01536
01537
01538
01539
01540
01541
01542
01543
01544 if(mudconf.hudinfo_enabled > 0 && d->flags & DS_CONNECTED
01545 && !strcmp(command, "hudinfo")) {
01546 d->command_count++;
01547 mudstate.curr_player = d->player;
01548 mudstate.curr_enactor = d->player;
01549 mudstate.debug_cmd = "hudinfo";
01550 do_hudinfo(d, arg);
01551 mudstate.debug_cmd = cmdsave;
01552 return 1;
01553 }
01554 #endif
01555
01556 cp = (NAMETAB *) hashfind(command, &mudstate.logout_cmd_htab);
01557
01558 if(*arg)
01559 *--arg = ' ';
01560 if(cp == NULL) {
01561 d->command_count++;
01562 if(d->output_prefix) {
01563 queue_string(d, d->output_prefix);
01564 }
01565 mudstate.curr_player = d->player;
01566 mudstate.curr_enactor = d->player;
01567 process_command(d->player, d->player, 1, command, (char **) NULL, 0);
01568 if(d->output_suffix) {
01569 queue_string(d, d->output_suffix);
01570 }
01571 } else {
01572 if(d->output_prefix) {
01573 queue_string(d, d->output_prefix);
01574 }
01575 switch (cp->flag & CMD_MASK) {
01576 case CMD_QUIT:
01577 shutdownsock(d, R_QUIT);
01578 return 0;
01579 case CMD_WHO:
01580 if(d->player || mudconf.allow_unloggedwho) {
01581 dump_users(d, arg, CMD_WHO);
01582 } else {
01583 queue_string(d, "This MUX does not allow WHO at the login screen.\r\n");
01584 queue_string(d, "Please login or create a character first.\r\n");
01585 }
01586 break;
01587 case CMD_DOING:
01588 if(d->player || mudconf.allow_unloggedwho) {
01589 dump_users(d, arg, CMD_DOING);
01590 } else {
01591 queue_string(d, "This MUX does not allow DOING at the login screen.\r\n");
01592 queue_string(d, "Please login or create a character first.\r\n");
01593 }
01594 break;
01595 case CMD_SESSION:
01596 if(d->player || mudconf.allow_unloggedwho) {
01597 dump_users(d, arg, CMD_SESSION);
01598 } else {
01599 queue_string(d, "This MUX does not allow SESSION at the login screen.\r\n");
01600 queue_string(d, "Please login or create a character first.\r\n");
01601 }
01602 break;
01603 case CMD_PREFIX:
01604 set_userstring(&d->output_prefix, arg);
01605 break;
01606 case CMD_SUFFIX:
01607 set_userstring(&d->output_suffix, arg);
01608 break;
01609 default:
01610 log_error(LOG_BUGS, "BUG", "PARSE", "Prefix command with no handler: '%s'", command);
01611 }
01612 if(d->output_suffix) {
01613 queue_string(d, d->output_suffix);
01614 }
01615 }
01616 mudstate.debug_cmd = cmdsave;
01617 return 1;
01618 }
01619
01620
01621
01622
01623
01624
01625 int site_check(struct sockaddr_storage *saddr, int saddr_len,
01626 SITE * site_list)
01627 {
01628 SITE *this;
01629 #ifdef XXX
01630 for(this = site_list; this; this = this->next) {
01631 if((host.s_addr & this->mask.s_addr) == this->saddr.s_addr)
01632 return this->flag;
01633 }
01634 #endif
01635 return 0;
01636 }
01637
01638
01639
01640
01641
01642
01643 #define S_SUSPECT 1
01644 #define S_ACCESS 2
01645
01646 static const char *stat_string(int strtype, int flag)
01647 {
01648 const char *str;
01649
01650 switch (strtype) {
01651 case S_SUSPECT:
01652 if(flag)
01653 str = "Suspected";
01654 else
01655 str = "Trusted";
01656 break;
01657 case S_ACCESS:
01658 switch (flag) {
01659 case H_FORBIDDEN:
01660 str = "Forbidden";
01661 break;
01662 case H_REGISTRATION:
01663 str = "Registration";
01664 break;
01665 case 0:
01666 str = "Unrestricted";
01667 break;
01668 default:
01669 str = "Strange";
01670 }
01671 break;
01672 default:
01673 str = "Strange";
01674 }
01675 return str;
01676 }
01677
01678 static void list_sites(dbref player, SITE * site_list, const char *header_txt,
01679 int stat_type)
01680 {
01681 char *buff, *buff1, *str;
01682 SITE *this;
01683
01684 buff = alloc_mbuf("list_sites.buff");
01685 buff1 = alloc_sbuf("list_sites.addr");
01686 sprintf(buff, "----- %s -----", header_txt);
01687 notify(player, buff);
01688 notify(player, "Address Mask Status");
01689 for(this = site_list; this; this = this->next) {
01690 str = (char *) stat_string(stat_type, this->flag);
01691 StringCopy(buff1, inet_ntoa(this->mask));
01692 sprintf(buff, "%-20s %-20s %s", inet_ntoa(this->address), buff1, str);
01693 notify(player, buff);
01694 }
01695 free_mbuf(buff);
01696 free_sbuf(buff1);
01697 }
01698
01699
01700
01701
01702
01703
01704 void list_siteinfo(dbref player)
01705 {
01706 list_sites(player, mudstate.access_list, "Site Access", S_ACCESS);
01707 list_sites(player, mudstate.suspect_list, "Suspected Sites", S_SUSPECT);
01708 }
01709
01710
01711
01712
01713
01714
01715 void make_ulist(dbref player, char *buff, char **bufc)
01716 {
01717 DESC *d;
01718 char *cp;
01719
01720 cp = *bufc;
01721 DESC_ITER_CONN(d) {
01722 if(!WizRoy(player) && Hidden(d->player))
01723 continue;
01724 if(cp != *bufc)
01725 safe_chr(' ', buff, bufc);
01726 safe_chr('#', buff, bufc);
01727 safe_str(tprintf("%d", d->player), buff, bufc);
01728 }
01729 }
01730
01731
01732
01733
01734
01735
01736
01737
01738 dbref find_connected_name(dbref player, char *name)
01739 {
01740 DESC *d;
01741 dbref found;
01742
01743 found = NOTHING;
01744 DESC_ITER_CONN(d) {
01745 if(Good_obj(player) && !Wizard(player) && Hidden(d->player))
01746 continue;
01747 if(!string_prefix(Name(d->player), name))
01748 continue;
01749 if((found != NOTHING) && (found != d->player))
01750 return NOTHING;
01751 found = d->player;
01752 }
01753 return found;
01754 }
01755
01756 void run_command(DESC * d, char *command)
01757 {
01758 if(!Staff(d->player)) {
01759 if(d->quota <= 0) {
01760 queue_string(d, "quota exceed, dropping command.\n");
01761 dprintk("aborting execution of %s for #%d.", command, d->player);
01762 return;
01763 }
01764 d->quota--;
01765 }
01766 d->input_size -= (strlen(command) + 1);
01767 if(d->program_data != NULL)
01768 handle_prog(d, command);
01769 else
01770 do_command(d, command);
01771 }