home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-20 | 54.4 KB | 2,019 lines |
- Path: uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v17i015: gbp - Galactic Bloodshed+, an empire-like war game, Part03/21
- Message-ID: <4543@master.CNA.TEK.COM>
- Date: 12 Feb 93 17:29:59 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2007
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1694
-
- Submitted-by: deragon@harpo.cs.nyu.edu (Seeker)
- Posting-number: Volume 17, Issue 15
- Archive-name: gbp/Part03
- Supersedes: gb3: Volume 10, Issue 1-14
- Environment: sockets, curses
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 21)."
- # Contents: server/GB_server.c server/access.c
- # Wrapped by billr@saab on Fri Feb 12 09:14:24 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'server/GB_server.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'server/GB_server.c'\"
- else
- echo shar: Extracting \"'server/GB_server.c'\" \(48398 characters\)
- sed "s/^X//" >'server/GB_server.c' <<'END_OF_FILE'
- X/*
- X * Galactic Bloodshed, copyright (c) 1989 1990 by Robert P. Chansky,
- X * smq@ucscb.ucsc.edu, Univ of Ca Santa Cruz. You may copy, alter and
- X * distribute this game as you please as long as these notices remain intact.
- X * No duplication for commercial purposes without permission of the author.
- X *
- X * Version 1.0 - current mods by: Garrett Van Cleef, Ph.D Dept. of Physics Ohio
- X * State University V1.1 playtesting by: Hanan Baddar Ken Bloch John Davis
- X * Robert Jones Menelaos Kafkaladis Brett Lowry Paul Murphy Garrett van Cleef
- X * Wolfgang Wenzel and tons of people at U.C. Santa Cruz
- X *
- X *
- X * Major amounts of help in v2.0-current by Brian Scearce (bls@u02.svl.cdc.com).
- X */
- X
- X/*
- X * Fri Dec 11 01:59:53 EST 1992
- X *
- X * Started major rework of code. See the file doc/CHANGES for information.
- X *
- X * Work on GB is now for the most part solely conducted by the GBDT which
- X * consists of:
- X *
- X * John Paul Deragon (deragon@jethro.nyu.edu)
- X * Chris Fodor (cfodor@ucsd.edu)
- X * Evan Koffleva (koffleva@darkwing.uoregon.edu)
- X * Roger Lewis (rlewis@isi.edu)
- X * Jonathan Roy (ninja@halcyon.com)
- X *
- X */
- X
- X#include "TinyMUD_copyright.h"
- X/*
- X * Copyright for the original TinyMUD interface which was used for the
- X * networking
- X */
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/time.h>
- X#include <signal.h>
- X#include <sys/ioctl.h>
- X#include <sys/wait.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X#include <sys/errno.h>
- X#include <ctype.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <csp.h>
- X
- X#include <curses.h>
- X#include <strings.h>
- X#include <pwd.h>
- X
- X#include <sys/uio.h>
- X#include <sys/timeb.h>
- X
- X/* GB headers */
- X#define EXTERN
- X#include "vars.h"
- X#include "ships.h"
- X#include "races.h"
- X#include "power.h"
- X#include "doturn.h"
- X
- X#include "interface.h"
- X#include "buffers.h"
- X
- X/* datafile descriptors */
- Xint commoddata, pdata, racedata, sectdata, shdata, stdata;
- X
- Xstruct descriptor_data *descriptor_list;
- Xextern long Shipdata[NUMSTYPES][NUMABILS];
- Xextern int errno;
- Xtime_t clk;
- Xint shutdown_flag = 0;
- Xint update_flag = 0;
- X
- Xint port; /* port selection */
- Xstruct tm *current_tm; /* for watching for next update */
- Xchar start_buf[128];
- Xchar update_buf[128];
- Xchar segment_buf[128];
- X
- Xstatic char *flushed_message = "<Output Flushed>\n";
- Xstatic char *shutdown_message = "Shutdown ordered by deity - Bye\n";
- X/*
- X * DO NOT change these two lines.... they are client specific
- X * and are used in the login procedure according to the CLIENT
- X * PROTOCOL file
- X * -- JPD --
- X */
- Xstatic char *client_login = "Enter Password <race> <gov>:\n";
- Xstatic char *client_invalid = "Invalid: ";
- Xstatic char *already_on = "Player already logged on!\n";
- Xstatic char *bad_password = "Bad Password.\n";
- X
- Xint errno;
- Xint sig_null();
- X
- X
- Xstatic int sock;
- Xstatic int ndescriptors = 0;
- X
- Xvoid set_signals(void);
- Xvoid notify_race(int, char *);
- Xint notify(int, int, char *);
- Xvoid d_think(int, int, char *);
- Xvoid d_broadcast(int, int, char *, int);
- Xvoid d_shout(int, int, char *);
- Xvoid d_announce(int, int, int, char *);
- Xstruct timeval timeval(struct timeval, struct timeval);
- Xint msec_diff(struct timeval, struct timeval);
- Xstruct timeval msec_add(struct timeval, int);
- Xvoid shovechars(int);
- Xvoid do_next_thing(void);
- Xvoid shutdownsock(struct descriptor_data *);
- Xint make_socket(int);
- Xstruct timeval update_quotas(struct timeval, struct timeval);
- Xstruct descriptor_data *new_connection(int);
- Xchar *addrout(long);
- Xvoid clearstrings(struct descriptor_data *);
- Xvoid shutdown_sock(struct descriptor_data *);
- Xstruct descriptor_data *initializesock(int);
- Xstruct text_block *make_text_block(char *, int);
- Xvoid free_text_block(struct text_block *);
- Xvoid add_to_queue(struct text_queue *, char *, int);
- Xint flush_queue(struct text_queue *, int);
- Xvoid queue_write(struct descriptor_data *, char *, int);
- Xvoid queue_string(struct descriptor_data * d, char *message);
- Xint process_output(struct descriptor_data *);
- Xint process_string(struct descriptor_data *);
- Xvoid force_output(void);
- Xvoid make_nonblocking(int);
- Xvoid freeqs(struct descriptor_data *);
- Xvoid welcome_user(struct descriptor_data *);
- Xvoid goodbye_user(struct descriptor_data *);
- Xchar *strsave(char *);
- Xvoid save_command(struct descriptor_data *, char *);
- Xint process_input(struct descriptor_data *);
- Xvoid set_userstring(char **, char *);
- Xvoid process_commands(void);
- Xint do_command(struct descriptor_data *, char *);
- Xvoid check_connect(struct descriptor_data *, char *);
- Xvoid do_update(int);
- Xvoid do_segment(int, int);
- Xvoid parse_connect(char *, char *, char *);
- Xvoid close_sockets(void);
- Xvoid dump_users(struct descriptor_data *);
- Xvoid process_command(int, int, char *);
- Xvoid GB_time(int, int);
- Xvoid kill_ship(int, shiptype *);
- Xvoid compute_power_blocks(void);
- Xvoid insert_sh_univ(struct stardata *, shiptype *);
- Xvoid insert_sh_star(startype *, shiptype *);
- Xvoid insert_sh_plan(planettype *, shiptype *);
- Xvoid insert_sh_ship(shiptype *, shiptype *);
- Xvoid remove_sh_star(shiptype *);
- Xvoid remove_sh_plan(shiptype *);
- Xvoid remove_sh_ship(shiptype *, shiptype *);
- Xdouble GetComplexity(int);
- Xint ShipCompare(int *, int *);
- Xvoid SortShips(void);
- Xvoid warn_race(int, char *);
- Xvoid warn(int, int, char *);
- Xvoid warn_star(int, int, int, char *);
- Xvoid notify_star(int, int, int, int, char *);
- Xvoid post_star(char *, int, int);
- Xint send_special_string(int, int);
- X
- X#include "proto.h"
- X
- X#ifdef DEBUG
- Xvoid DEBUG_check(int, int);
- Xvoid DEBUG_reset(int, int);
- X#endif
- X
- Xchar *Desnames[] = {
- X "ocean", "land", "mountainous", "gaseous", "ice", "forest", "desert",
- X"plated", "wasted"};
- X
- Xchar Dessymbols[] = {
- X CHAR_SEA, CHAR_LAND, CHAR_MOUNT, CHAR_GAS, CHAR_ICE, CHAR_FOREST,
- XCHAR_DESERT, CHAR_PLATED, CHAR_WASTED};
- X
- X
- Xvoid
- Xmain(int argc, char **argv)
- X{
- X int i;
- X struct stat stbuf;
- X FILE *sfile;
- X
- X
- X clearlog(TRUE);
- X loginfo(ERRORLOG, NOERRNO, "GB server started");
- X
- X open_data_files();
- X clk = time(0);
- X switch (argc) {
- X case 2:
- X port = atoi(argv[1]);
- X update_time = DEFAULT_UPDATE_TIME;
- X segments = MOVES_PER_UPDATE;
- X break;
- X case 3:
- X port = atoi(argv[1]);
- X update_time = atoi(argv[2]);
- X segments = MOVES_PER_UPDATE;
- X break;
- X case 4:
- X port = atoi(argv[1]);
- X update_time = atoi(argv[2]);
- X segments = atoi(argv[3]);
- X break;
- X default:
- X port = GB_PORT;
- X update_time = DEFAULT_UPDATE_TIME;
- X segments = MOVES_PER_UPDATE;
- X break;
- X }
- X loginfo(ERRORLOG, NOERRNO, "Running on Port %d\n", port);
- X loginfo(UPDATELOG, NOERRNO, "%d minutes between updates", update_time);
- X loginfo(UPDATELOG, NOERRNO, "%d segments/update", segments);
- X
- X next_update_time = clk + (update_time * 60);
- X if (stat(UPDATEFL, &stbuf) >= 0) {
- X if (sfile = fopen(UPDATEFL, "r")) {
- X char dum[32];
- X if (fgets(dum, sizeof dum, sfile))
- X nupdates_done = atoi(dum);
- X if (fgets(dum, sizeof dum, sfile))
- X last_update_time = atol(dum);
- X if (fgets(dum, sizeof dum, sfile))
- X next_update_time = atol(dum);
- X fclose(sfile);
- X }
- X loginfo(UPDATELOG, NOERRNO, "Last update %3d : %s", nupdates_done,
- X ctime(&last_update_time));
- X }
- X if (segments <= 1)
- X next_segment_time += (144 * 3600);
- X else {
- X next_segment_time = clk + (update_time * 60 / segments);
- X if (stat(SEGMENTFL, &stbuf) >= 0) {
- X if (sfile = fopen(SEGMENTFL, "r")) {
- X char dum[32];
- X if (fgets(dum, sizeof dum, sfile))
- X nsegments_done = atoi(dum);
- X if (fgets(dum, sizeof dum, sfile))
- X last_segment_time = atol(dum);
- X if (fgets(dum, sizeof dum, sfile))
- X next_segment_time = atol(dum);
- X fclose(sfile);
- X }
- X }
- X if (next_segment_time < clk) { /* gvc */
- X next_segment_time = next_update_time;
- X nsegments_done = segments;
- X }
- X }
- X loginfo(UPDATELOG, NOERRNO, "Last Segment %2d : %s", nsegments_done,
- X ctime(&last_segment_time));
- X
- X loginfo(UPDATELOG, NOERRNO, "Next Update %d : %s",
- X nupdates_done + 1, ctime(&next_update_time));
- X loginfo(UPDATELOG, NOERRNO, "Next Segment : %s", ctime(&next_segment_time));
- X
- X srandom(getpid());
- X
- X
- X load_race_data(); /* make sure you do this first */
- X load_star_data(); /* get star data */
- X Getpower(Power); /* get power report from disk */
- X Getblock(Blocks); /* get alliance block data */
- X SortShips(); /* Sort the ship list by tech for "build ?" */
- X for (i = 1; i <= MAXPLAYERS; i++) {
- X setbit(Blocks[i - 1].invite, i);
- X setbit(Blocks[i - 1].pledge, i);
- X }
- X Putblock(Blocks);
- X compute_power_blocks();
- X set_signals();
- X shovechars(port);
- X close_sockets();
- X close_data_files();
- X loginfo(ERRORLOG, NOERRNO, "Going down.");
- X exit(1);
- X}
- X
- Xvoid
- Xset_signals(void)
- X{
- X signal(SIGPIPE, SIG_IGN);
- X}
- X
- Xvoid
- Xnotify_race(int race, char *message)
- X{
- X struct descriptor_data *d;
- X if (update_flag)
- X return;
- X for (d = descriptor_list; d; d = d->next) {
- X if (d->connected && d->Playernum == race) {
- X queue_string(d, message);
- X }
- X }
- X}
- X
- Xint
- Xsend_special_string(int player, int what)
- X{
- X struct descriptor_data *d;
- X char message[24];
- X
- X for (d = descriptor_list; d; d = d->next)
- X if (d->connected && d->Playernum == player &&
- X races[d->Playernum -1]->governor[d->Governor].CSP_client_info.csp_user) {
- X switch (what) {
- X case UPDATE_START:
- X sprintf(message, "%c %d\n", CSP_CLIENT, CSP_UPDATE_START);
- X break;
- X case UPDATE_END:
- X sprintf(message, "%c %d %d\n", CSP_CLIENT, CSP_UPDATE_END,
- X nupdates_done);
- X break;
- X case SEGMENT_START:
- X sprintf(message, "%c %d\n", CSP_CLIENT, CSP_SEGMENT_START);
- X break;
- X case SEGMENT_END:
- X sprintf(message, "%c %d\n", CSP_CLIENT, CSP_SEGMENT_END);
- X break;
- X case RESET_START:
- X sprintf(message, "%c %d\n", CSP_CLIENT, CSP_RESET_START);
- X break;
- X case RESET_END:
- X sprintf(message, "%c %d\n", CSP_CLIENT, CSP_RESET_END);
- X break;
- X }
- X queue_string(d, message);
- X return(1);
- X }
- X return(0);
- X}
- X
- Xint
- Xnotify(int race, int gov, char *message)
- X{
- X struct descriptor_data *d;
- X reg int ok;
- X
- X if (update_flag)
- X return 0;
- X ok = 0;
- X for (d = descriptor_list; d; d = d->next)
- X if (d->connected && d->Playernum == race && d->Governor == gov) {
- X queue_string(d, message);
- X ok = 1;
- X }
- X return ok;
- X}
- X
- Xvoid
- Xd_think(int Playernum, int Governor, char *message)
- X{
- X struct descriptor_data *d;
- X for (d = descriptor_list; d; d = d->next) {
- X if (d->connected && d->Playernum == Playernum && d->Governor != Governor &&
- X !races[d->Playernum - 1]->governor[d->Governor].toggle.gag) {
- X queue_string(d, message);
- X }
- X }
- X}
- X
- Xvoid
- Xd_broadcast(int Playernum, int Governor, char *message, int channel_wanted)
- X{
- X struct descriptor_data *d;
- X for (d = descriptor_list; d; d = d->next) {
- X#ifdef MULTIPLE_COMM_CHANNELS
- X if (d->connected && !(d->Playernum == Playernum && d->Governor == Governor) &&
- X !races[d->Playernum - 1]->governor[d->Governor].toggle.gag &&
- X isset(races[d->Playernum -1]->governor[d->Governor].channel,
- X channel_wanted)) {
- X#else
- X if (d->connected && !(d->Playernum == Playernum && d->Governor == Governor) &&
- X !races[d->Playernum - 1]->governor[d->Governor].toggle.gag) {
- X#endif
- X queue_string(d, message);
- X }
- X }
- X}
- X
- Xvoid
- Xd_shout(int Playernum, int Governor, char *message)
- X{
- X struct descriptor_data *d;
- X for (d = descriptor_list; d; d = d->next) {
- X if (d->connected && !(d->Playernum == Playernum && d->Governor == Governor)) {
- X queue_string(d, message);
- X }
- X }
- X}
- X
- Xvoid
- Xd_announce(int Playernum, int Governor, int star, char *message)
- X{
- X struct descriptor_data *d;
- X for (d = descriptor_list; d; d = d->next) {
- X if (d->connected && !(d->Playernum == Playernum && d->Governor == Governor) &&
- X (isset(Stars[star]->inhabited, d->Playernum) ||
- X races[d->Playernum - 1]->God) &&
- X Dir[d->Playernum - 1][d->Governor].snum == star &&
- X !races[d->Playernum - 1]->governor[d->Governor].toggle.gag) {
- X queue_string(d, message);
- X }
- X }
- X}
- X
- Xstruct timeval
- Xtimeval_sub(struct timeval now, struct timeval then)
- X{
- X now.tv_sec -= then.tv_sec;
- X now.tv_usec -= then.tv_usec;
- X if (now.tv_usec < 0) {
- X now.tv_usec += 1000000;
- X now.tv_sec--;
- X }
- X return now;
- X}
- X
- Xint
- Xmsec_diff(struct timeval now, struct timeval then)
- X{
- X return ((now.tv_sec - then.tv_sec) * 1000
- X + (now.tv_usec - then.tv_usec) / 1000);
- X}
- X
- Xstruct timeval
- Xmsec_add(struct timeval t, int x)
- X{
- X t.tv_sec += x / 1000;
- X t.tv_usec += (x % 1000) * 1000;
- X if (t.tv_usec >= 1000000) {
- X t.tv_sec += t.tv_usec / 1000000;
- X t.tv_usec = t.tv_usec % 1000000;
- X }
- X return t;
- X}
- X
- Xvoid
- Xshovechars(int port)
- X{
- X fd_set input_set, output_set;
- X time_t now, go_time;
- X struct timeval last_slice, current_time;
- X struct timeval next_slice;
- X struct timeval timeout, slice_timeout;
- X int maxd, i;
- X struct descriptor_data *d, *dnext;
- X struct descriptor_data *newd;
- X int avail_descriptors;
- X
- X go_time = 0;
- X sock = make_socket(port);
- X maxd = sock + 1;
- X gettimeofday(&last_slice, (struct timezone *) 0);
- X
- X avail_descriptors = getdtablesize() - 4;
- X
- X if (!shutdown_flag)
- X post("Server started\n", ANNOUNCE);
- X for (i = 0; i <= ANNOUNCE; i++)
- X newslength[i] = Newslength(i);
- X
- X while (!shutdown_flag) {
- X fflush(stdout);
- X gettimeofday(¤t_time, (struct timezone *) 0);
- X last_slice = update_quotas(last_slice, current_time);
- X
- X process_commands();
- X
- X if (shutdown_flag)
- X break;
- X timeout.tv_sec = 30;
- X timeout.tv_usec = 0;
- X next_slice = msec_add(last_slice, COMMAND_TIME_MSEC);
- X slice_timeout = timeval_sub(next_slice, current_time);
- X
- X FD_ZERO(&input_set);
- X FD_ZERO(&output_set);
- X if (ndescriptors < avail_descriptors)
- X FD_SET(sock, &input_set);
- X for (d = descriptor_list; d; d = d->next) {
- X if (d->input.head)
- X timeout = slice_timeout;
- X else
- X FD_SET(d->descriptor, &input_set);
- X if (d->output.head)
- X FD_SET(d->descriptor, &output_set);
- X }
- X
- X if (select(maxd, &input_set, &output_set,
- X (fd_set *) 0, &timeout) < 0) {
- X if (errno != EINTR) {
- X perror("select");
- X return;
- X }
- X (void) time(&now);
- X } else {
- X
- X (void) time(&now);
- X
- X if (FD_ISSET(sock, &input_set)) {
- X if (!(newd = new_connection(sock))) {
- X if (errno && errno != EINTR && errno != EMFILE) {
- X perror("new_connection");
- X return;
- X }
- X } else {
- X if (newd->descriptor >= maxd)
- X maxd = newd->descriptor + 1;
- X }
- X }
- X for (d = descriptor_list; d; d = dnext) {
- X dnext = d->next;
- X if (FD_ISSET(d->descriptor, &input_set)) {
- X /* d->last_time = now; */
- X if (!process_input(d)) {
- X shutdownsock(d);
- X continue;
- X }
- X }
- X if (FD_ISSET(d->descriptor, &output_set)) {
- X if (!process_output(d)) {
- X shutdownsock(d);
- X }
- X }
- X }
- X
- X }
- X if (go_time == 0) {
- X if (now >= next_update_time) {
- X go_time = now + (int_rand(0, DEFAULT_RANDOM_UPDATE_RANGE) * 60);
- X }
- X if (now >= next_segment_time && nsegments_done < segments) {
- X go_time = now + (int_rand(0, DEFAULT_RANDOM_SEGMENT_RANGE) * 60);
- X }
- X }
- X if (go_time > 0 && now >= go_time) {
- X (void) do_next_thing();
- X go_time = 0;
- X }
- X }
- X}
- X
- Xvoid
- Xdo_next_thing(void)
- X{
- X clk = time(0);
- X if (nsegments_done < segments)
- X do_segment(0, 1);
- X else
- X do_update(0);
- X}
- X
- Xint
- Xmake_socket(int port)
- X{
- X int s;
- X struct sockaddr_in server;
- X int opt;
- X
- X s = socket(AF_INET, SOCK_STREAM, 0);
- X if (s < 0) {
- X perror("creating stream socket");
- X exit(3);
- X }
- X opt = 1;
- X if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- X (char *) &opt, sizeof(opt)) < 0) {
- X perror("setsockopt");
- X exit(1);
- X }
- X if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, /* GVC */
- X (char *) &opt, sizeof(opt)) < 0) {
- X perror("setsockopt");
- X exit(1);
- X }
- X server.sin_family = AF_INET;
- X server.sin_addr.s_addr = INADDR_ANY;
- X server.sin_port = htons(port);
- X if (bind(s, (struct sockaddr *) & server, sizeof(server))) {
- X perror("binding stream socket");
- X close(s);
- X exit(4);
- X }
- X listen(s, 5);
- X return s;
- X}
- X
- Xstruct timeval
- Xupdate_quotas(struct timeval last, struct timeval current)
- X{
- X int nslices;
- X struct descriptor_data *d;
- X
- X nslices = msec_diff(current, last) / COMMAND_TIME_MSEC;
- X
- X if (nslices > 0) {
- X for (d = descriptor_list; d; d = d->next) {
- X d->quota += COMMANDS_PER_TIME * nslices;
- X if (d->quota > COMMAND_BURST_SIZE)
- X d->quota = COMMAND_BURST_SIZE;
- X }
- X }
- X return msec_add(last, nslices * COMMAND_TIME_MSEC);
- X}
- X
- Xstruct descriptor_data *
- Xnew_connection(int sock)
- X{
- X int newsock;
- X struct sockaddr_in addr;
- X int addr_len;
- X
- X addr_len = sizeof(addr);
- X newsock = accept(sock, (struct sockaddr *) & addr, &addr_len);
- X if (newsock <= 0) {
- X return 0;
- X } else {
- X#ifdef ACCESS_CHECK
- X if (address_ok(&addr)) {
- X loginfo(USERLOG, NOERRNO, "ACCEPT from %s(%d) on descriptor %d\n",
- X addrout(ntohl(addr.sin_addr.s_addr)),
- X ntohs(addr.sin_port), newsock);
- X return initializesock(newsock);
- X } else {
- X write(newsock, "Unauthorized Access.\n", 21);
- X loginfo(USERLOG, NOERRNO, "REJECT from %s(%d) on descriptor %d\n",
- X addrout(ntohl(addr.sin_addr.s_addr)),
- X ntohs(addr.sin_port),
- X newsock);
- X shutdown(newsock, 2);
- X close(newsock);
- X errno = 0;
- X return 0;
- X }
- X#else
- X loginfo(USERLOG, NOERRNO, "ACCEPT from %s(%d) on descriptor %d\n",
- X addrout(ntohl(addr.sin_addr.s_addr)),
- X ntohs(addr.sin_port), newsock);
- X return initializesock(newsock);
- X#endif
- X }
- X}
- X
- Xchar *
- Xaddrout(long a)
- X{
- X static char outbuf[1024];
- X
- X sprintf(outbuf, "%d.%d.%d.%d", (a >> 24) & 0xff, (a >> 16) & 0xff,
- X (a >> 8) & 0xff, a & 0xff);
- X return outbuf;
- X}
- X
- Xvoid
- Xclearstrings(struct descriptor_data * d)
- X{
- X if (d->output_prefix) {
- X free(d->output_prefix);
- X d->output_prefix = 0;
- X }
- X if (d->output_suffix) {
- X free(d->output_suffix);
- X d->output_suffix = 0;
- X }
- X}
- X
- Xvoid
- Xshutdownsock(struct descriptor_data * d)
- X{
- X racetype *r;
- X
- X
- X if (d->connected) {
- X r = races[d->Playernum -1];
- X loginfo(USERLOG, NOERRNO, "DISCONNECT: %d Race=%d Governor=%d",
- X d->descriptor, d->Playernum, d->Governor);
- X sprintf(buf, "\n%s \"%s\" [%d,%d] logged off.\n", r->name,
- X r->governor[d->Governor].name, d->Playernum, d->Governor);
- X notify_race(d->Playernum, buf);
- X } else {
- X loginfo(USERLOG, NOERRNO, "DISCONNECT: %d Never Connected.",
- X d->descriptor);
- X }
- X clearstrings(d);
- X shutdown(d->descriptor, 2);
- X close(d->descriptor);
- X freeqs(d);
- X *d->prev = d->next;
- X if (d->next)
- X d->next->prev = d->prev;
- X free(d);
- X ndescriptors--;
- X}
- X
- Xstruct descriptor_data *
- Xinitializesock(int s)
- X{
- X struct descriptor_data *d;
- X
- X ndescriptors++;
- X d = (struct descriptor_data *) malloc(sizeof(struct descriptor_data));
- X d->descriptor = s;
- X d->connected = 0;
- X make_nonblocking(s);
- X d->output_prefix = 0;
- X d->output_suffix = 0;
- X d->output_size = 0;
- X d->output.head = 0;
- X d->output.tail = &d->output.head;
- X d->input.head = 0;
- X d->input.tail = &d->input.head;
- X d->raw_input = 0;
- X d->raw_input_at = 0;
- X d->quota = COMMAND_BURST_SIZE;
- X d->last_time = 0;
- X if (descriptor_list)
- X descriptor_list->prev = &d->next;
- X d->next = descriptor_list;
- X d->prev = &descriptor_list;
- X descriptor_list = d;
- X
- X welcome_user(d);
- X queue_string(d, client_login);
- X return d;
- X}
- X
- Xstruct text_block *
- Xmake_text_block(char *s, int n)
- X{
- X struct text_block *p;
- X
- X p = (struct text_block *) malloc(sizeof(struct text_block));
- X p->buf = (char *) malloc(n * sizeof(char));
- X bcopy(s, p->buf, n);
- X p->nchars = n;
- X p->start = p->buf;
- X p->nxt = 0;
- X return p;
- X}
- X
- Xvoid
- Xfree_text_block(struct text_block * t)
- X{
- X free(t->buf);
- X free((char *) t);
- X}
- X
- Xvoid
- Xadd_to_queue(struct text_queue * q, char *b, int n)
- X{
- X struct text_block *p;
- X
- X if (n == 0)
- X return;
- X
- X p = make_text_block(b, n);
- X p->nxt = 0;
- X *q->tail = p;
- X q->tail = &p->nxt;
- X}
- X
- Xint
- Xflush_queue(struct text_queue * q, int n)
- X{
- X struct text_block *p;
- X int really_flushed = 0;
- X
- X n += strlen(flushed_message);
- X
- X while (n > 0 && (p = q->head)) {
- X n -= p->nchars;
- X really_flushed += p->nchars;
- X q->head = p->nxt;
- X free_text_block(p);
- X }
- X p = make_text_block(flushed_message, strlen(flushed_message));
- X p->nxt = q->head;
- X q->head = p;
- X if (!p->nxt)
- X q->tail = &p->nxt;
- X really_flushed -= p->nchars;
- X return really_flushed;
- X}
- X
- Xvoid
- Xqueue_write(struct descriptor_data * d, char *b, int n)
- X{
- X int space;
- X
- X space = MAX_OUTPUT - d->output_size - n;
- X if (space < 0)
- X d->output_size -= flush_queue(&d->output, -space);
- X add_to_queue(&d->output, b, n);
- X d->output_size += n;
- X}
- X
- Xvoid
- Xqueue_string(struct descriptor_data * d, char *s)
- X{
- X queue_write(d, s, strlen(s));
- X}
- X
- Xint
- Xprocess_output(struct descriptor_data * d)
- X{
- X struct text_block **qp, *cur;
- X int cnt;
- X
- X for (qp = &d->output.head; cur = *qp;) {
- X cnt = write(d->descriptor, cur->start, cur->nchars);
- X if (cnt < 0) {
- X if (errno == EWOULDBLOCK)
- X return 1;
- X d->connected = 0; /* added this */
- X return 0;
- X }
- X d->output_size -= cnt;
- X if (cnt == cur->nchars) {
- X if (!cur->nxt)
- X d->output.tail = qp;
- X *qp = cur->nxt;
- X free_text_block(cur);
- X continue; /* do not adv ptr */
- X }
- X cur->nchars -= cnt;
- X cur->start += cnt;
- X break;
- X }
- X return 1;
- X}
- X
- Xvoid
- Xforce_output(void)
- X{
- X struct descriptor_data *d;
- X
- X for (d = descriptor_list; d; d = d->next)
- X if (d->connected)
- X (void) process_output(d);
- X}
- X
- Xvoid
- Xmake_nonblocking(int s)
- X{
- X if (fcntl(s, F_SETFL, FNDELAY) == -1) {
- X perror("make_nonblocking: fcntl");
- X exit(0);
- X }
- X}
- X
- Xvoid
- Xfreeqs(struct descriptor_data * d)
- X{
- X struct text_block *cur, *next;
- X
- X cur = d->output.head;
- X while (cur) {
- X next = cur->nxt;
- X free_text_block(cur);
- X cur = next;
- X }
- X d->output.head = 0;
- X d->output.tail = &d->output.head;
- X
- X cur = d->input.head;
- X while (cur) {
- X next = cur->nxt;
- X free_text_block(cur);
- X cur = next;
- X }
- X d->input.head = 0;
- X d->input.tail = &d->input.head;
- X
- X if (d->raw_input)
- X free(d->raw_input);
- X d->raw_input = 0;
- X d->raw_input_at = 0;
- X}
- X
- Xvoid
- Xgoodbye_user(struct descriptor_data * d)
- X{
- X if (d->connected) /* this can happen, especially after updates */
- X write(d->descriptor, LEAVE_MESSAGE, strlen(LEAVE_MESSAGE));
- X}
- X
- Xchar *
- Xstrsave(char *s)
- X{
- X char *p;
- X
- X p = (char *) malloc((strlen(s) + 1) * sizeof(char));
- X
- X if (p)
- X strcpy(p, s);
- X return p;
- X}
- X
- Xvoid
- Xsave_command(struct descriptor_data * d, char *command)
- X{
- X add_to_queue(&d->input, command, strlen(command) + 1);
- X}
- X
- Xint
- Xprocess_input(struct descriptor_data * d)
- X{
- X int got;
- X char *p, *pend, *q, *qend;
- X
- X got = read(d->descriptor, buf, sizeof buf);
- X if (got <= 0)
- X return 0;
- X if (!d->raw_input) {
- X d->raw_input = (char *) malloc(MAX_COMMAND_LEN * sizeof(char));
- X d->raw_input_at = d->raw_input;
- X }
- X p = d->raw_input_at;
- X pend = d->raw_input + MAX_COMMAND_LEN - 1;
- X for (q = buf, qend = buf + got; q < qend; q++) {
- X if (*q == '\n') {
- X *p = '\0';
- X if (p > d->raw_input)
- X save_command(d, d->raw_input);
- X p = d->raw_input;
- X } else if (p < pend && isascii(*q) && isprint(*q)) {
- X *p++ = *q;
- X }
- X }
- X if (p > d->raw_input) {
- X d->raw_input_at = p;
- X } else {
- X free(d->raw_input);
- X d->raw_input = 0;
- X d->raw_input_at = 0;
- X }
- X return 1;
- X}
- X
- Xvoid
- Xset_userstring(char **userstring, char *comm)
- X{
- X if (*userstring) {
- X free(*userstring);
- X *userstring = 0;
- X }
- X while (*comm && isascii(*comm) && isspace(*comm))
- X comm++;
- X if (*comm)
- X *userstring = strsave(comm);
- X}
- X
- Xvoid
- Xprocess_commands(void)
- X{
- X int nprocessed;
- X long now;
- X struct descriptor_data *d, *dnext;
- X struct text_block *t;
- X
- X
- X (void) time(&now);
- X
- X do {
- X nprocessed = 0;
- X for (d = descriptor_list; d; d = dnext) {
- X dnext = d->next;
- X if (d->quota > 0 && (t = d->input.head)) {
- X d->quota--;
- X nprocessed++;
- X
- X if (!do_command(d, t->start)) {
- X shutdownsock(d);
- X } else {
- X d->last_time = now; /* experimental code */
- X d->input.head = t->nxt;
- X if (!d->input.head)
- X d->input.tail = &d->input.head;
- X free_text_block(t);
- X d->last_time = now; /* experimental code */
- X }
- X
- X }
- X }
- X } while (nprocessed > 0);
- X
- X}
- X
- Xint
- Xdo_command(struct descriptor_data * d, char *comm)
- X{
- X char *string;
- X int parse_exit = 0, i;
- X
- X argn = 0;
- X /*
- X * Main processing loop. When command strings are sent from the
- X * client, they are processed here. Responses are sent back to the
- X * client via notify. The client will then process the strings in
- X * whatever manner is expected.
- X */
- X
- X /*
- X * check to see if there are a few words typed out, usually for the
- X * help command
- X */
- X string = comm;
- X while (!parse_exit) {
- X i = 0;
- X while (!isspace(*string) && (*string != '\0') && (i < COMMANDSIZE))
- X args[argn][i++] = (*string++);
- X args[argn][i] = '\0';
- X while ((*string) == ' ')
- X string++;
- X if ((*string == '\0') || (argn >= MAXARGS))
- X parse_exit = 1;
- X argn++;
- X }
- X for (i = argn; i < MAXARGS; i++)
- X args[i][0] = '\0';
- X
- X if (!strcmp(args[0], QUIT_COMMAND)) {
- X goodbye_user(d);
- X return 0;
- X } else if (d->connected && !strcmp(args[0], WHO_COMMAND)) {
- X dump_users(d);
- X } else if (!strcmp(args[0], HELP_COMMAND)) {
- X help(d);
- X } else if (d->connected && d->God && !strcmp(args[0], EMULATE_COMMAND)) {
- X d->Playernum = atoi(args[1]);
- X d->Governor = atoi(args[2]);
- X sprintf(buf, "Emulating %s \"%s\" [%d,%d]\n", races[d->Playernum - 1]->name,
- X races[d->Playernum - 1]->governor[d->Governor].name,
- X d->Playernum, d->Governor);
- X queue_string(d, buf);
- X } else {
- X if (d->connected) {
- X /* GB command parser */
- X process_command(d->Playernum, d->Governor, comm);
- X } else {
- X check_connect(d, comm); /* Logs player into the game,
- X * connects if the password
- X * given by *command is a
- X * player's */
- X if (!d->connected) {
- X goodbye_user(d);
- X } else {
- X check_for_telegrams(d->Playernum, d->Governor);
- X /* set the scope to home upon login */
- X argn = 1;
- X strcpy(args[0], "cs");
- X process_command(d->Playernum, d->Governor, "cs");
- X }
- X }
- X }
- X return 1;
- X}
- X
- Xvoid
- Xcheck_connect(struct descriptor_data * d, char *message)
- X{
- X char race_password[MAX_COMMAND_LEN];
- X char gov_password[MAX_COMMAND_LEN];
- X int i, j;
- X int Playernum, Governor;
- X racetype *r;
- X struct descriptor_data *d0, *dnext;
- X
- X
- X parse_connect(message, race_password, gov_password);
- X
- X#ifdef EXTERNAL_TRIGGER
- X if (!strcmp(password, SEGMENT_PASSWORD)) {
- X do_segment(1, 0);
- X return;
- X } else if (!strcmp(password, UPDATE_PASSWORD)) {
- X do_update(1);
- X return;
- X }
- X#endif
- X
- X Getracenum(race_password, gov_password, &i, &j);
- X
- X if (!i) {
- X sprintf(buf, "%s %s\n", client_invalid, bad_password);
- X queue_string(d, buf);
- X loginfo(USERLOG, NOERRNO, "FAILED CONNECT: %s,%s on descriptor %d",
- X race_password, gov_password, d->descriptor);
- X queue_string(d, client_login);
- X } else {
- X Playernum = i;
- X Governor = j;
- X r = races[i - 1];
- X /*
- X * check to see if this player is already connect, if so,
- X * nuke the descriptor
- X */
- X for (d0 = descriptor_list; d0; d0 = dnext) {
- X dnext = d0->next;
- X if (d0->connected && d0->Playernum == Playernum &&
- X d0->Governor == Governor) {
- X sprintf(buf, "%s %s\n", client_invalid, already_on);
- X queue_string(d, buf);
- X queue_string(d, client_login);
- X return;
- X }
- X }
- X
- X loginfo(USERLOG, NOERRNO, "CONNECTED: %s \"%s\" [%d,%d] on descriptor %d",
- X r->name, r->governor[j].name, Playernum, Governor, d->descriptor);
- X d->connected = 1;
- X
- X d->God = r->God;
- X d->Playernum = Playernum;
- X d->Governor = Governor;
- X
- X sprintf(buf, "\n%s \"%s\" [%d,%d] logged on.\n", r->name,
- X r->governor[j].name, Playernum, Governor);
- X notify_race(Playernum, buf);
- X sprintf(buf, "You are %s.\n",
- X r->governor[j].toggle.invisible ? "invisible" : "visible");
- X notify(Playernum, Governor, buf);
- X
- X GB_time(Playernum, Governor);
- X sprintf(buf, "\nLast login : %s", ctime(&(r->governor[j].login)));
- X notify(Playernum, Governor, buf);
- X r->governor[j].login = time(0);
- X#ifdef MULTIPLE_COMM_CHANNELS
- X setbit(races[Playernum -1]->governor[Governor].channel,
- X COMM_CHANNEL1);
- X setbit(races[Playernum -1]->governor[Governor].channel,
- X COMM_DEF_CHANNEL1);
- X clrbit(races[Playernum -1]->governor[Governor].channel,
- X COMM_DEF_CHANNEL2);
- X clrbit(races[Playernum -1]->governor[Governor].channel,
- X COMM_DEF_CHANNEL3);
- X#endif
- X putrace(r);
- X if (!r->Gov_ship) {
- X strcat(buf, "You have no Governmental Center. No action points will be produced\nuntil you build one and designate a capital.\n");
- X notify(Playernum, Governor, buf);
- X } else {
- X sprintf(buf, "Government Center #%d is active.\n", r->Gov_ship);
- X notify(Playernum, Governor, buf);
- X }
- X sprintf(buf, " Morale: %d\n", r->morale);
- X notify(Playernum, Governor, buf);
- X treasury(Playernum, Governor);
- X }
- X}
- X
- Xvoid
- Xdo_update(int override)
- X{
- X register int i;
- X FILE *sfile;
- X struct stat stbuf;
- X int fakeit;
- X int client;
- X
- X fakeit = (!override && stat(NOGOFL, &stbuf) >= 0);
- X
- X sprintf(buf, "%sDOING UPDATE...\n", ctime(&clk));
- X if (!fakeit) {
- X for (i = 1; i <= Num_races; i++)
- X if (!send_special_string(i, UPDATE_START))
- X notify_race(i, buf);
- X force_output();
- X }
- X if (segments <= 1) {
- X /* Disables movement segments. */
- X next_segment_time = clk + (144 * 3600);
- X nsegments_done = segments;
- X } else {
- X if (override)
- X next_segment_time = clk + update_time * 60 / segments;
- X else
- X next_segment_time = next_update_time + update_time * 60 / segments;
- X nsegments_done = 1;
- X }
- X if (override)
- X next_update_time = clk + update_time * 60;
- X else
- X next_update_time += update_time * 60;
- X
- X if (!fakeit)
- X nupdates_done++;
- X
- X sprintf(Power_blocks.time, "%s", ctime(&clk));
- X sprintf(update_buf, "Last Update %3d : %s", nupdates_done, ctime(&clk));
- X sprintf(segment_buf, "Last Segment %2d : %s", nsegments_done, ctime(&clk));
- X
- X loginfo(UPDATELOG, NOERRNO, "Next Update %3d : %s",
- X nupdates_done + 1, ctime(&next_update_time));
- X loginfo(UPDATELOG, NOERRNO, "Next Segment %2d : %s",
- X nsegments_done == segments ? 1 : nsegments_done + 1,
- X ctime(&next_segment_time));
- X
- X unlink(UPDATEFL);
- X if (sfile = fopen(UPDATEFL, "w")) {
- X fprintf(sfile, "%d\n", nupdates_done);
- X fprintf(sfile, "%ld\n", clk);
- X fprintf(sfile, "%ld\n", next_update_time);
- X fflush(sfile);
- X fclose(sfile);
- X }
- X unlink(SEGMENTFL);
- X if (sfile = fopen(SEGMENTFL, "w")) {
- X fprintf(sfile, "%d\n", nsegments_done);
- X fprintf(sfile, "%ld\n", clk);
- X fprintf(sfile, "%ld\n", next_segment_time);
- X fflush(sfile);
- X fclose(sfile);
- X }
- X update_flag = 1;
- X if (!fakeit)
- X do_turn(1);
- X update_flag = 0;
- X clk = time(0);
- X sprintf(buf, "%sUpdate %d finished\n", ctime(&clk), nupdates_done);
- X if (!fakeit) {
- X for (i = 1; i <= Num_races; i++)
- X if (!send_special_string(i, UPDATE_END))
- X notify_race(i, buf);
- X force_output();
- X }
- X}
- X
- Xvoid
- Xdo_segment(int override, int segment)
- X{
- X register int i;
- X FILE *sfile;
- X struct stat stbuf;
- X int fakeit;
- X
- X fakeit = (!override && stat(NOGOFL, &stbuf) >= 0);
- X
- X if (!override && segments <= 1)
- X return;
- X
- X sprintf(buf, "%sDOING MOVEMENT...\n", ctime(&clk));
- X if (!fakeit) {
- X for (i = 1; i <= Num_races; i++)
- X if (!send_special_string(i, SEGMENT_START))
- X notify_race(i, buf);
- X force_output();
- X }
- X if (override) {
- X next_segment_time = clk + update_time * 60 / segments;
- X if (segment) {
- X nsegments_done = segment;
- X next_update_time = clk + update_time * 60 *
- X (segments - segment + 1) / segments;
- X } else {
- X nsegments_done++;
- X }
- X } else {
- X next_segment_time += update_time * 60 / segments;
- X nsegments_done++;
- X }
- X
- X update_flag = 1;
- X if (!fakeit)
- X do_turn(0);
- X update_flag = 0;
- X unlink(SEGMENTFL);
- X if (sfile = fopen(SEGMENTFL, "w")) {
- X fprintf(sfile, "%d\n", nsegments_done);
- X fprintf(sfile, "%ld\n", clk);
- X fprintf(sfile, "%ld\n", next_segment_time);
- X fflush(sfile);
- X fclose(sfile);
- X }
- X sprintf(segment_buf, "Last Segment %2d : %s",
- X nsegments_done, ctime(&clk));
- X loginfo(UPDATELOG, NOERRNO, "Next Segment %2d : %s",
- X nsegments_done, ctime(&next_segment_time));
- X clk = time(0);
- X sprintf(buf, "%sSegment finished\n", ctime(&clk));
- X if (!fakeit) {
- X for (i = 1; i <= Num_races; i++)
- X if (!send_special_string(i, SEGMENT_END))
- X notify_race(i, buf);
- X force_output();
- X }
- X}
- X
- Xvoid
- Xparse_connect(char *message, char *race_pass, char *gov_pass)
- X{
- X char *p;
- X char *q;
- X /* race password */
- X while (*message && isascii(*message) && isspace(*message))
- X message++;
- X p = race_pass;
- X while (*message && isascii(*message) && !isspace(*message))
- X *p++ = *message++;
- X *p = '\0';
- X /* governor password */
- X while (*message && isascii(*message) && isspace(*message))
- X message++;
- X q = gov_pass;
- X while (*message && isascii(*message) && !isspace(*message))
- X *q++ = *message++;
- X *q = '\0';
- X}
- X
- Xvoid
- Xclose_sockets(void)
- X{
- X struct descriptor_data *d, *dnext;
- X /* post message into news file */
- X post(shutdown_message, ANNOUNCE);
- X
- X for (d = descriptor_list; d; d = dnext) {
- X dnext = d->next;
- X write(d->descriptor, shutdown_message, strlen(shutdown_message));
- X if (shutdown(d->descriptor, 2) < 0)
- X perror("shutdown");
- X close(d->descriptor);
- X }
- X close(sock);
- X}
- X
- Xvoid
- Xdump_users(struct descriptor_data * e)
- X{
- X struct descriptor_data *d;
- X time_t now;
- X racetype *r;
- X int God = 0;
- X int coward_count = 0;
- X
- X (void) time(&now);
- X sprintf(buf, "Current Players: %s", ctime(&now));
- X queue_string(e, buf);
- X if (e->Playernum) {
- X r = races[e->Playernum - 1];
- X God = r->God;
- X } else
- X return;
- X
- X for (d = descriptor_list; d; d = d->next) {
- X if (d->connected) {
- X r = races[d->Playernum - 1];
- X if (!r->governor[d->Governor].toggle.invisible ||
- X e->Playernum == d->Playernum || God) {
- X sprintf(temp, "\"%s\"", r->governor[d->Governor].name);
- X sprintf(buf, "%20.20s %20.20s [%2d,%2d] %4ds idle %-4.4s %s %s\n",
- X r->name, temp, d->Playernum, d->Governor,
- X now - d->last_time,
- X God ? Stars[Dir[d->Playernum - 1][d->Governor].snum]->name : " ",
- X (r->governor[d->Governor].toggle.gag ? "GAG" : " "),
- X (r->governor[d->Governor].toggle.invisible ? "INVISIBLE" : ""));
- X queue_string(e, buf);
- X } else if (!God) /* deity lurks around */
- X coward_count++;
- X
- X if ((now - d->last_time) > DISCONNECT_TIME)
- X d->connected = 0;
- X }
- X }
- X#ifdef SHOW_COWARDS
- X sprintf(buf, "And %d coward%s.\n", coward_count, (coward_count == 1) ? "" : "s");
- X queue_string(e, buf);
- X#endif
- X queue_string(e, "Finished.\n");
- X}
- X
- Xvoid
- Xprocess_command(int Playernum, int Governor, char *comm)
- X{
- X int j, God, Guest;
- X char *string;
- X racetype *r;
- X
- X /* determine which routine to go to and what action to take */
- X /*
- X * target routine is specified by the first substring, other options
- X * are the substrings which follow
- X */
- X
- X r = races[Playernum - 1];
- X God = r->God;
- X Guest = r->Guest;
- X
- X string = comm;
- X while (*string && *string != ' ')
- X string++;
- X
- X if (match(args[0], "announce")) /* keep this at the front */
- X announce(Playernum, Governor, string, ANN, 0);
- X else if (match(args[0], CSP_SERVER))
- X CSP_process_command(Playernum, Governor);
- X else if (match(args[0], "client_survey"))
- X survey(Playernum, Governor, 0, 1);
- X else if (match(args[0], "allocate"))
- X allocateAPs(Playernum, Governor, 0);
- X else if (match(args[0], "analysis"))
- X analysis(Playernum, Governor, 0);
- X else if (match(args[0], "arm"))
- X arm(Playernum, Governor, 0, 1);
- X else if (match(args[0], "disarm"))
- X arm(Playernum, Governor, 0, 0);
- X else if (match(args[0], "assault"))
- X dock(Playernum, Governor, 1, 1);
- X else if (match(args[0], "autoreport"))
- X autoreport(Playernum, Governor, 0);
- X else if (match(args[0], "build"))
- X build(Playernum, Governor, 1);
- X#ifdef MARKET
- X else if (match(args[0], "bid"))
- X bid(Playernum, Governor, 0);
- X else if (match(args[0], "sell"))
- X sell(Playernum, Governor, 20);
- X#endif
- X else if (match(args[0], "bless") && God)
- X bless(Playernum, Governor, 0);
- X else if (match(args[0], "'") || match(args[0], "broadcast"))
- X announce(Playernum, Governor, string, BROADCAST, 0);
- X else if (match(args[0], "shout") && God)
- X announce(Playernum, Governor, string, SHOUT, 0);
- X else if (match(args[0], "think"))
- X announce(Playernum, Governor, string, THINK, 0);
- X else if (match(args[0], "block"))
- X block(Playernum, Governor, 0);
- X else if (match(args[0], "bombard") && !Guest)
- X bombard(Playernum, Governor, 1);
- X else if (match(args[0], "cs"))
- X cs(Playernum, Governor, 0);
- X else if (match(args[0], "capital"))
- X capital(Playernum, Governor, 50);
- X else if (match(args[0], "capture"))
- X capture(Playernum, Governor, 1);
- X else if (match(args[0], "center"))
- X center(Playernum, Governor, 0);
- X#ifdef MULTIPLE_COMM_CHANNELS
- X else if (match(args[0], "channel"))
- X channel(Playernum, Governor, 0, 0);
- X else if (match(args[0], "1"))
- X announce(Playernum, Governor, string, BROADCAST, 1);
- X else if (match(args[0], "2"))
- X announce(Playernum, Governor, string, BROADCAST, 2);
- X else if (match(args[0], "3"))
- X announce(Playernum, Governor, string, BROADCAST, 3);
- X#endif
- X else if (match(args[0], "declare"))
- X declare(Playernum, Governor, 1);
- X#ifdef DEFENSE
- X else if (match(args[0], "defend"))
- X defend(Playernum, Governor, 1);
- X#endif
- X else if (match(args[0], "detonate") && !Guest)
- X detonate(Playernum, Governor, 0);
- X else if (match(args[0], "distance"))
- X distance(Playernum, Governor, 0);
- X else if (match(args[0], "dismount"))
- X mount(Playernum, Governor, 0, 0);
- X else if (match(args[0], "dissolve") && !Guest)
- X dissolve(Playernum, Governor);
- X else if (match(args[0], "dock"))
- X dock(Playernum, Governor, 0, 0);
- X else if (match(args[0], "dump") && !Guest)
- X dump(Playernum, Governor, 10);
- X else if (match(args[0], "enslave"))
- X enslave(Playernum, Governor, 2);
- X else if (match(args[0], "examine"))
- X examine(Playernum, Governor, 0);
- X else if (match(args[0], "explore"))
- X exploration(Playernum, Governor, 0);
- X else if (match(args[0], "cew"))
- X fire(Playernum, Governor, 1, 1);
- X else if (match(args[0], "fire") && !Guest)
- X fire(Playernum, Governor, 1, 0);
- X else if (match(args[0], "fuel"))
- X proj_fuel(Playernum, Governor, 0);
- X else if (match(args[0], "governors") || match(args[0], "appoint")
- X || match(args[0], "revoke"))
- X governors(Playernum, Governor, 0);
- X else if (match(args[0], "grant"))
- X grant(Playernum, Governor, 0);
- X else if (match(args[0], "give") && !Guest)
- X give(Playernum, Governor, 5);
- X else if (match(args[0], "highlight"))
- X highlight(Playernum, Governor);
- X else if (match(args[0], "identify") || match(args[0], "whois"))
- X whois(Playernum, Governor, 0);
- X#ifdef MARKET
- X else if (match(args[0], "insurgency"))
- X insurgency(Playernum, Governor, 10);
- X#endif
- X else if (match(args[0], "invite"))
- X invite(Playernum, Governor, 0, 1);
- X else if (match(args[0], "jettison"))
- X jettison(Playernum, Governor, 0);
- X else if (match(args[0], "land"))
- X land(Playernum, Governor, 1);
- X else if (match(args[0], "launch"))
- X launch(Playernum, Governor, 0);
- X else if (match(args[0], "load"))
- X load(Playernum, Governor, 0, 0);
- X else if (match(args[0], "list"))
- X list(Playernum, Governor);
- X else if (match(args[0], "map"))
- X map(Playernum, Governor, 0);
- X else if (match(args[0], "mobilize"))
- X mobilize(Playernum, Governor, 1);
- X else if (match(args[0], "move"))
- X move_popn(Playernum, Governor, CIV);
- X else if (match(args[0], "deploy"))
- X move_popn(Playernum, Governor, MIL);
- X else if (match(args[0], "make"))
- X make_mod(Playernum, Governor, 0, 0);
- X#ifdef DEBUG
- X else if (match(args[0], "memcheck") && God)
- X DEBUGcheck(Playernum, Governor);
- X else if (match(args[0], "memreset") && God)
- X DEBUGreset(Playernum, Governor);
- X#endif
- X else if (match(args[0], "modify"))
- X make_mod(Playernum, Governor, 0, 1);
- X else if (match(args[0], "mount"))
- X mount(Playernum, Governor, 0, 1);
- X else if (match(args[0], "motto"))
- X motto(Playernum, Governor, 0, comm);
- X else if (match(args[0], "name"))
- X name(Playernum, Governor, 0);
- X else if (match(args[0], "orbit"))
- X orbit(Playernum, Governor, 0);
- X else if (match(args[0], "order"))
- X order(Playernum, Governor, 1);
- X else if (match(args[0], "page"))
- X page(Playernum, Governor, !God);
- X else if (match(args[0], "pay") && !Guest)
- X pay(Playernum, Governor, 0);
- X else if (match(args[0], "colonies"))
- X colonies(Playernum, Governor, 0, 0);
- X else if (match(args[0], "personal"))
- X personal(Playernum, Governor, string);
- X else if (match(args[0], "pledge"))
- X pledge(Playernum, Governor, 0, 1);
- X else if (match(args[0], "power"))
- X power(Playernum, Governor, 0);
- X else if (match(args[0], "post"))
- X send_message(Playernum, Governor, 0, 1);
- X else if (match(args[0], "profile"))
- X profile(Playernum, Governor, 0);
- X else if (match(args[0], "production"))
- X colonies(Playernum, Governor, 0, 1);
- X else if (match(args[0], "purge") && God)
- X purge();
- X else if (match(args[0], "fix") && God)
- X fix(Playernum, Governor);
- X else if (match(args[0], "relation"))
- X relation(Playernum, Governor, 0);
- X else if (match(args[0], "read"))
- X read_messages(Playernum, Governor, 0);
- X else if (match(args[0], "@@reset") && God) {
- X for (j = 1; j <= Num_races; j++)
- X if (!send_special_string(j, RESET_START))
- X notify_race(j, "DOING RESET...\n");
- X force_output();
- X load_race_data();
- X load_star_data();
- X do_reset(1);
- X } else if (match(args[0], "report"))
- X rst(Playernum, Governor, 0, 0);
- X else if (match(args[0], "factories"))
- X rst(Playernum, Governor, 0, 6);
- X else if (match(args[0], "repair"))
- X repair(Playernum, Governor, 0);
- X else if (match(args[0], "route"))
- X route(Playernum, Governor, 0);
- X else if (match(args[0], "@@shutdown") && God) {
- X shutdown_flag = 1;
- X notify(Playernum, Governor, "Doing shutdown.\n");
- X } else if (match(args[0], "@@update") && God)
- X do_update(1);
- X else if (match(args[0], "@@segment") && God)
- X do_segment(1, atoi(args[1]));
- X else if (match(args[0], "stock"))
- X rst(Playernum, Governor, 0, 1);
- X else if (match(args[0], "stats"))
- X rst(Playernum, Governor, 0, 4);
- X else if (match(args[0], "ship"))
- X rst(Playernum, Governor, 0, 3);
- X else if (match(args[0], "survey"))
- X survey(Playernum, Governor, 0, 0);
- X else if (match(args[0], "client_survey"))
- X survey(Playernum, Governor, 0, 1);
- X else if (match(args[0], "send"))
- X send_message(Playernum, Governor, !God, 0);
- X else if (match(args[0], "scrap") && (argn > 1))
- X scrap(Playernum, Governor, 1);
- X else if (match(args[0], "stars"))
- X star_locations(Playernum, Governor, 0);
- X else if (match(args[0], "status"))
- X tech_status(Playernum, Governor, 0);
- X else if (match(args[0], "tactical"))
- X rst(Playernum, Governor, 0, 2);
- X#ifdef MARKET
- X else if (match(args[0], "tax"))
- X tax(Playernum, Governor, 0);
- X#endif
- X else if (match(args[0], "technology"))
- X technology(Playernum, Governor, 1);
- X else if (match(args[0], "toggle"))
- X toggle(Playernum, Governor, 0);
- X else if (match(args[0], "toxicity"))
- X toxicity(Playernum, Governor, 1);
- X#ifdef MARKET
- X else if (match(args[0], "treasury"))
- X treasury(Playernum, Governor);
- X#endif
- X else if (match(args[0], "transfer") && !Guest)
- X transfer(Playernum, Governor, 1);
- X else if (match(args[0], "unload"))
- X load(Playernum, Governor, 0, 1);
- X else if (match(args[0], "undock"))
- X launch(Playernum, Governor, 1);
- X else if (match(args[0], "uninvite"))
- X invite(Playernum, Governor, 0, 0);
- X else if (match(args[0], "unpledge"))
- X pledge(Playernum, Governor, 0, 0);
- X else if (match(args[0], "upgrade"))
- X upgrade(Playernum, Governor, 1);
- X else if (match(args[0], "victory"))
- X victory(Playernum, Governor);
- X else if (match(args[0], "walk"))
- X walk(Playernum, Governor, 1);
- X else if (match(args[0], "weapons"))
- X rst(Playernum, Governor, 0, 5);
- X else if (match(args[0], "time"))
- X GB_time(Playernum, Governor);
- X else if (match(args[0], "schedule"))
- X GB_schedule(Playernum, Governor);
- X#ifdef VOTING
- X else if (match(args[0], "vote"))
- X vote(Playernum, Governor, 0);
- X#endif
- X else if (match(args[0], "zoom"))
- X zoom(Playernum, Governor);
- X else {
- X sprintf(buf, "'%s':illegal command error(%d).\n", args[0], *args[0]);
- X notify(Playernum, Governor, buf);
- X }
- X
- X /* compute the prompt and send to the player */
- X do_prompt(Playernum, Governor);
- X sprintf(buf, "%s", Dir[Playernum - 1][Governor].prompt);
- X notify(Playernum, Governor, buf);
- X}
- X
- X
- Xvoid
- XGB_time(int Playernum, int Governor)
- X{ /* report back the update status */
- X clk = time(0);
- X notify(Playernum, Governor, start_buf);
- X notify(Playernum, Governor, update_buf);
- X notify(Playernum, Governor, segment_buf);
- X sprintf(buf, "Current time : %s", ctime(&clk));
- X notify(Playernum, Governor, buf);
- X}
- X
- Xvoid
- Xkill_ship(int Playernum, shiptype * ship)
- X{
- X planettype *planet;
- X racetype *killer, *victim;
- X shiptype *s;
- X int sh;
- X
- X ship->alive = 0;
- X ship->notified = 0; /* prepare the ship for recycling */
- X
- X if (ship->type != STYPE_POD && ship->type != OTYPE_FACTORY) {
- X /* pods don't do things to morale, ditto for factories */
- X victim = races[ship->owner - 1];
- X if (victim->Gov_ship == ship->number)
- X victim->Gov_ship = 0;
- X if (!victim->God && Playernum != ship->owner) {
- X killer = races[Playernum - 1];
- X adjust_morale(killer, victim, (int) ship->build_cost);
- X putrace(killer);
- X } else if (ship->owner == Playernum && !ship->docked && Max_crew(ship)) {
- X victim->morale -= 2 * ship->build_cost; /* scuttle/scrap */
- X }
- X putrace(victim);
- X }
- X if (ship->type == OTYPE_TOXWC && ship->whatorbits == LEVEL_PLAN) {
- X getplanet(&planet, (int) ship->storbits, (int) ship->pnumorbits);
- X planet->conditions[TOXIC] = MIN(100, planet->conditions[TOXIC] +
- X ship->special.waste.toxic);
- X putplanet(planet, (int) ship->storbits, (int) ship->pnumorbits);
- X }
- X /* undock the stuff docked with it */
- X if (ship->docked && ship->whatorbits != LEVEL_SHIP
- X && ship->whatdest == LEVEL_SHIP) {
- X (void) getship(&s, (int) ship->destshipno);
- X s->docked = 0;
- X s->whatdest = LEVEL_UNIV;
- X putship(s);
- X free(s);
- X }
- X /* landed ships are killed */
- X if (ship->ships) {
- X sh = ship->ships;
- X while (sh) {
- X (void) getship(&s, sh);
- X kill_ship(Playernum, s);
- X putship(s);
- X sh = s->nextship;
- X free(s);
- X }
- X }
- X}
- X
- Xvoid
- Xcompute_power_blocks(void)
- X{
- X int i, j, dummy[2];
- X /* compute alliance block power */
- X sprintf(Power_blocks.time, "%s", ctime(&clk));
- X for (i = 1; i <= Num_races; i++) {
- X dummy[0] = (Blocks[i - 1].invite[0] & Blocks[i - 1].pledge[0]);
- X dummy[1] = (Blocks[i - 1].invite[1] & Blocks[i - 1].pledge[1]);
- X Power_blocks.members[i - 1] = 0;
- X Power_blocks.sectors_owned[i - 1] = 0;
- X Power_blocks.popn[i - 1] = 0;
- X Power_blocks.ships_owned[i - 1] = 0;
- X Power_blocks.resource[i - 1] = 0;
- X Power_blocks.fuel[i - 1] = 0;
- X Power_blocks.destruct[i - 1] = 0;
- X Power_blocks.money[i - 1] = 0;
- X Power_blocks.systems_owned[i - 1] = Blocks[i - 1].systems_owned;
- X Power_blocks.VPs[i - 1] = Blocks[i - 1].VPs;
- X for (j = 1; j <= Num_races; j++)
- X if (isset(dummy, j)) {
- X Power_blocks.members[i - 1] += 1;
- X Power_blocks.sectors_owned[i - 1] += Power[j - 1].sectors_owned;
- X Power_blocks.money[i - 1] += Power[j - 1].money;
- X Power_blocks.popn[i - 1] += Power[j - 1].popn;
- X Power_blocks.ships_owned[i - 1] += Power[j - 1].ships_owned;
- X Power_blocks.resource[i - 1] += Power[j - 1].resource;
- X Power_blocks.fuel[i - 1] += Power[j - 1].fuel;
- X Power_blocks.destruct[i - 1] += Power[j - 1].destruct;
- X }
- X }
- X}
- X
- X
- Xvoid
- Xwarn_race(int who, char *message)
- X{
- X reg int i;
- X
- X for (i = 0; i <= MAXGOVERNORS; i++)
- X if (races[who - 1]->governor[i].active)
- X warn(who, i, message);
- X}
- X
- Xvoid
- Xwarn(int who, int governor, char *message)
- X{
- X if (!notify(who, governor, message) && !notify(who, 0, message))
- X push_telegram(who, governor, message);
- X}
- X
- Xvoid
- Xwarn_star(int a, int b, int star, char *message)
- X{
- X int i;
- X
- X for (i = 1; i <= Num_races; i++)
- X if (i != a && i != b && isset(Stars[star]->inhabited, i))
- X warn_race(i, message);
- X}
- X
- Xvoid
- Xnotify_star(int a, int g, int b, int star, char *message)
- X{
- X struct descriptor_data *d;
- X racetype *Race;
- X
- X#ifdef MONITOR
- X Race = races[0]; /* deity */
- X if (Race->monitor || (a != 1 && b != 1))
- X notify_race(1, message);
- X#endif
- X for (d = descriptor_list; d; d = d->next)
- X if (d->connected && (d->Playernum != a || d->Governor != g) &&
- X isset(Stars[star]->inhabited, d->Playernum)) {
- X queue_string(d, message);
- X }
- X}
- END_OF_FILE
- if test 48398 -ne `wc -c <'server/GB_server.c'`; then
- echo shar: \"'server/GB_server.c'\" unpacked with wrong size!
- fi
- # end of 'server/GB_server.c'
- fi
- if test -f 'server/access.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'server/access.c'\"
- else
- echo shar: Extracting \"'server/access.c'\" \(2956 characters\)
- sed "s/^X//" >'server/access.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/time.h>
- X#include <signal.h>
- X#include <sys/ioctl.h>
- X#include <sys/wait.h>
- X#include <fcntl.h>
- X#include <sys/errno.h>
- X#include <ctype.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X
- X#include <curses.h>
- X#include <strings.h>
- X#include <pwd.h>
- X
- X#include <sys/uio.h>
- X#include <sys/timeb.h>
- X
- X#include "interface.h"
- X#include "files.h"
- X
- X/*
- X * Prototypes
- X */
- Xint address_ok(struct sockaddr_in *);
- Xint address_match(struct in_addr *, struct in_addr *);
- Xvoid add_address(unsigned long, int);
- X
- Xstatic int naddresses = 0;
- Xtypedef struct access {
- X struct in_addr ac_addr;
- X int access_value;
- X} ac_t;
- Xstatic ac_t *ac_tab = (ac_t *) NULL;
- X
- Xint
- Xaddress_ok(struct sockaddr_in * ap)
- X{
- X register int i;
- X register ac_t *acp;
- X static int ainit = 0;
- X FILE *afile;
- X char *cp, ibuf[64];
- X int aval;
- X unsigned long ina;
- X
- X if (!ainit) {
- X ainit = 1;
- X if ((afile = fopen(ADDRESSFL, "r"))) {
- X while (fgets(ibuf, sizeof ibuf, afile)) {
- X cp = ibuf;
- X aval = 1;
- X if (*cp == '#' || *cp == '\n' || *cp == '\r')
- X continue;
- X if (*cp == '!') {
- X cp++;
- X aval = 0;
- X }
- X ina = inet_addr(cp);
- X if (ina != -1)
- X add_address(ina, aval);
- X }
- X fclose(afile);
- X /* Always allow localhost. */
- X add_address(inet_addr("127"), 1);
- X } else {
- X /* Allow anything. */
- X add_address(inet_addr("0"), 1);
- X }
- X }
- X acp = ac_tab;
- X for (i = 0; i < naddresses; i++, acp++) {
- X if (address_match((struct in_addr *)&ap->sin_addr.s_addr, &acp->ac_addr))
- X return acp->access_value;
- X }
- X return 0;
- X}
- X
- Xaddress_match(struct in_addr * addr, struct in_addr * apat)
- X{
- X /* Ugh! There HAS to be a better way... */
- X
- X if (!apat->S_un.S_un_b.s_b1) {
- X if (apat->S_un.S_un_b.s_b4 &&
- X apat->S_un.S_un_b.s_b4 != addr->S_un.S_un_b.s_b1)
- X return 0;
- X return 1;
- X } else {
- X if (apat->S_un.S_un_b.s_b1 != addr->S_un.S_un_b.s_b1)
- X return 0;
- X }
- X if (!apat->S_un.S_un_b.s_b2) {
- X if (apat->S_un.S_un_b.s_b4 &&
- X apat->S_un.S_un_b.s_b4 != addr->S_un.S_un_b.s_b2)
- X return 0;
- X return 1;
- X } else {
- X if (apat->S_un.S_un_b.s_b2 != addr->S_un.S_un_b.s_b2)
- X return 0;
- X }
- X if (!apat->S_un.S_un_b.s_b3) {
- X if (apat->S_un.S_un_b.s_b4 &&
- X apat->S_un.S_un_b.s_b4 != addr->S_un.S_un_b.s_b3)
- X return 0;
- X return 1;
- X } else {
- X if (apat->S_un.S_un_b.s_b3 != addr->S_un.S_un_b.s_b3)
- X return 0;
- X }
- X if (apat->S_un.S_un_b.s_b4 != addr->S_un.S_un_b.s_b4)
- X return 0;
- X return 1;
- X}
- X
- Xvoid
- Xadd_address(unsigned long ina, int aval)
- X{
- X register ac_t *nac_t;
- X
- X if (naddresses > 0)
- X nac_t = (ac_t *) realloc(ac_tab, sizeof(ac_t) * (naddresses + 1));
- X else
- X nac_t = (ac_t *) calloc(1, sizeof(ac_t));
- X if (!nac_t) {
- X printf("add_address: Out of memory.\n");
- X return;
- X }
- X ac_tab = nac_t;
- X nac_t = &ac_tab[naddresses++];
- X nac_t->ac_addr.s_addr = ina;
- X nac_t->access_value = aval;
- X}
- END_OF_FILE
- if test 2956 -ne `wc -c <'server/access.c'`; then
- echo shar: \"'server/access.c'\" unpacked with wrong size!
- fi
- # end of 'server/access.c'
- fi
- echo shar: End of archive 3 \(of 21\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 21 archives.
- echo "Now type './buildfiles.sh'"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-