/* From log.c */
extern void start_all_logs(void);
extern void end_all_logs(void);
-extern void redirect_stderr(void);
+extern void redirect_streams(void);
extern void WIN32_CDECL do_log
(int logtype, dbref player, dbref object, const char *fmt, ...)
__attribute__ ((__format__(__printf__, 4, 5)));
#ifndef MUSH_TYPES_H
#define MUSH_TYPES_H
#include "copyrite.h"
-#include "options.h"
-#include <stdio.h>
-#ifdef WIN32
-#include <windows.h>
-#endif
#ifdef HAS_OPENSSL
#include <openssl/ssl.h>
#endif
(set +e; for file in *.dst *.c ../hdrs/*.h ; do echo $$file; \
/usr/bin/expand $$file > tmpfile; mv -f tmpfile $$file; \
/usr/bin/indent -npro -kr -ci2 -ss -psl -ip4 -i2 -cs -l80 -lc75 \
- -T ATRALIAS -T DESC -T CNode -T CONF -T BQUE -T FUN \
+ -T atr_err -T ATRALIAS -T DESC -T CNode -T CONF -T BQUE -T FUN \
-T NVAL -T i_rec -T f_rec -T USERFN_ENTRY -T PRIV -T FLAG \
-T FLAGENT -T FLAG_ALIAS -T tlist -T u -T stat -T tcheck -T ATTR \
-T ALIST -T CHTAB -T FBLKHDR -T FBLOCK -T OPTTAB -T dbref \
test_compress: comp_h.c
$(CC) $(CFLAGS) -o test_compress -DSTANDALONE comp_h.c
-portmsg: portmsg.c
- $(CC) $(CFLAGS) -o portmsg portmsg.c $(LIBS)
+portmsg: portmsg.c mysocket.c sig.o
+ $(CC) $(CCFLAGS) -DINFOSLAVE -o portmsg portmsg.c mysocket.c sig.o \
+ $(LDFLAGS) $(LIBS)
# Some dependencies that make depend doesn't handle well
compress.o: comp_h.c comp_w.c comp_w8.c
if (ModTime(player))
notify_format(player, T("%ld failed connections since last login."),
- ModTime(player));
+ (long) ModTime(player));
ModTime(player) = (time_t) 0;
announce_connect(player, isnew, num); /* broadcast connect message */
check_last(player, d->addr, d->ip); /* set Last, Lastsite, give paycheck */
msg++;
p = (unsigned char *) user;
- if (PLAYER_NAME_SPACES && *msg == '\"') {
+ if (*msg == '\"') {
for (; *msg && ((*msg == '\"') || isspace(*msg)); msg++) ;
while (*msg && (*msg != '\"')) {
while (*msg && !isspace(*msg) && (*msg != '\"'))
}
static const char *
-time_format_1(long dt)
+time_format_1(time_t dt)
{
register struct tm *delta;
- time_t holder; /* A hack for 64bit SGI */
+
static char buf[64];
if (dt < 0)
dt = 0;
- holder = (time_t) dt;
- delta = gmtime(&holder);
+
+ delta = gmtime(&dt);
if (delta->tm_yday > 0) {
sprintf(buf, "%dd %02d:%02d",
delta->tm_yday, delta->tm_hour, delta->tm_min);
}
static const char *
-time_format_2(long dt)
+time_format_2(time_t dt)
{
register struct tm *delta;
static char buf[64];
if (dt < 0)
dt = 0;
- delta = gmtime((time_t *) & dt);
+ delta = gmtime(&dt);
if (delta->tm_yday > 0) {
sprintf(buf, "%dd", delta->tm_yday);
} else if (delta->tm_hour > 0) {
dbref ooref; /**< Used when doing twin checks */
dbref sem; /**< semaphore object to block on */
char *semattr; /**< semaphore attribute to block on */
- int left; /**< seconds left until execution */
+ time_t left; /**< seconds left until execution */
char *env[10]; /**< environment, from wild match */
char *rval[NUMQ]; /**< environment, from setq() */
char *comm; /**< command to be executed */
/* Wait queue is in sorted order so we only have to look at the first
item on it. Anything else is wasted time. */
if (qwait) {
- curr = qwait->left - mudtime;
+ curr = (int) difftime(qwait->left, mudtime);
if (curr <= 2)
return 1;
if (curr < min)
for (point = qsemfirst; point; point = point->next) {
if (point->left == 0) /* no timeout */
continue;
- curr = point->left - mudtime;
+ curr = (int) difftime(point->left, mudtime);
if (curr <= 2)
return 1;
if (curr < min) {
}
/* get timeout, default of -1 */
if (tcount && *tcount)
- waitfor = atol(tcount);
+ waitfor = parse_integer(tcount);
else
waitfor = -1;
add_to_sem(thing, 1, aname);
/* Now we make a list of keys */
for (i = 0; i < nptrs; i++) {
/* Build our %0 args */
- wenv[0] = (char *)ptrs[i];
+ wenv[0] = (char *) ptrs[i];
call_ufun(&ufun, wenv, 2, result, executor, enactor, pe_info);
keys[i] = mush_strdup(result, "sortkey");
}
safe_chr('a', buff, bp);
return;
}
- c = tolower(*p);
+ c = DOWNCASE(*p);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
safe_str("an", buff, bp);
else
safe_str(T("#-1 INVALID THIRD ARGUMENT"), buff, bp);
return;
} else if (nargs == 3) {
- type = toupper(*args[2]);
+ type = UPCASE(*args[2]);
}
switch (type) {
conf_default_set();
config_file_startup(conf, 0);
start_all_logs();
- redirect_stderr();
+ redirect_streams();
/* Initialize the attribute chunk storage */
chunk_init();
notify_format(player,
T
("Time until next database save: %ld minutes %ld seconds, at %s"),
- (options.dump_counter - mudtime) / 60,
- (options.dump_counter - mudtime) % 60, tbuf1);
+ ((long) difftime(options.dump_counter, mudtime)) / 60,
+ ((long) difftime(options.dump_counter, mudtime)) % 60, tbuf1);
when = localtime(&options.dbck_counter);
strftime(tbuf1, sizeof tbuf1, "%X", when);
notify_format(player,
T
(" Time until next dbck check: %ld minutes %ld seconds, at %s."),
- (options.dbck_counter - mudtime) / 60,
- (options.dbck_counter - mudtime) % 60, tbuf1);
+ ((long) difftime(options.dbck_counter, mudtime)) / 60,
+ ((long) difftime(options.dbck_counter, mudtime)) % 60, tbuf1);
when = localtime(&options.purge_counter);
strftime(tbuf1, sizeof tbuf1, "%X", when);
notify_format(player,
T
(" Time until next purge: %ld minutes %ld seconds, at %s."),
- (options.purge_counter - mudtime) / 60,
- (options.purge_counter - mudtime) % 60, tbuf1);
+ ((long) difftime(options.purge_counter, mudtime)) / 60,
+ ((long) difftime(options.purge_counter, mudtime)) % 60, tbuf1);
if (options.warn_interval) {
when = localtime(&options.warn_counter);
notify_format(player,
T
(" Time until next @warnings: %ld minutes %ld seconds, at %s."),
- (options.warn_counter - mudtime) / 60,
- (options.warn_counter - mudtime) % 60, tbuf1);
+ ((long) difftime(options.warn_counter, mudtime)) / 60,
+ ((long) difftime(options.warn_counter, mudtime)) % 60, tbuf1);
}
notify_format(player,
T
("PennMUSH Uptime: %ld days %ld hours %ld minutes %ld seconds"),
- (mudtime - globals.first_start_time) / 86400,
- ((mudtime - globals.first_start_time) % 86400) / 3600,
- (((mudtime - globals.first_start_time) % 86400) % 3600) / 60,
- (((mudtime - globals.first_start_time) % 86400) % 3600) % 60);
+ ((long) difftime(mudtime, globals.first_start_time)) / 86400,
+ ((long) difftime(mudtime, globals.first_start_time) % 86400) /
+ 3600,
+ (((long) difftime(mudtime, globals.first_start_time) % 86400) %
+ 3600) / 60,
+ (((long) difftime(mudtime, globals.first_start_time) % 86400) %
+ 3600) % 60);
/* Mortals, go no further! */
if (!Site(player) || mortal)
start_log(&cmdlog_fp, CMDLOG);
}
-/** Redirect stderr to a error log file.
+/** Redirect stderr to a error log file and close stdout and stdin.
* Should be called after start_all_logs().
* \param log name of logfile to redirect stderr to.
*/
void
-redirect_stderr(void)
+redirect_streams(void)
{
FILE *errlog_fp;
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
fclose(errlog_fp);
}
+#ifndef DEBUG_BYTECODE
+ fclose(stdout);
+#endif
+ fclose(stdin);
}
if (!nextc)
goto exit_sequence;
(*str)++;
- if (!isdigit(nextc)) {
+ if (!isdigit((unsigned char) nextc)) {
safe_str(T(e_int), buff, bp);
break;
}
* SUCH DAMAGE.
*
* This version extensively modified by Javelin (Alan Schwartz)
- * to conform to PennMUSH autoconfiguration standards.
+ * and Raevnos (Shawn Wagner) to conform to PennMUSH standards.
*/
/* If you have multiple IP addresses and want to bind to only one,
#include <sys/wait.h>
#endif
#include <fcntl.h>
+#include <string.h>
#include "conf.h"
#include "externs.h"
-#include "mymalloc.h"
+#include "mysocket.h"
#include "confmagic.h"
-/* What htons expects */
-typedef unsigned short Port_t;
-
#ifdef HAS_WAITPID
#define WAIT_TYPE int
#else
#endif
#endif
-static Signal_t wait_on_child(int sig);
-static Signal_t lostconn(int sig);
-static int how_many_fds(void);
+#ifndef SINGLE_IP_ADDR
+const char *host_ip = "";
+#else
+const char *host_ip = SINGLE_IP_ADDR
+#endif
+ static void wait_on_child(int sig);
+static void
+lostconn(int sig)
+ NORETURN;
+
+ enum { MAX_CONNECTIONS = 15 };
+ int connections = 0;
-static Signal_t
-wait_on_child(int sig __attribute__ ((__unused__)))
+ static void
+ wait_on_child(int sig __attribute__ ((__unused__)))
{
WAIT_TYPE status;
#ifdef HAS_WAITPID
- while (waitpid(-1, &status, WNOHANG) > 0) ;
+ while (waitpid(-1, &status, WNOHANG) > 0)
+ connections--;
#else
- while (wait3(&status, WNOHANG, 0) > 0) ;
+ while (wait3(&status, WNOHANG, NULL) > 0)
+ connections--;
#endif
-#ifndef SIGNALS_KEPT
- signal(SIGCLD, (Sigfunc) wait_on_child);
-#endif
-#ifndef VOIDSIG
- return 0;
-#endif
+ if (connections < 0)
+ connections = 0;
+
+ reload_sig_handler(SIGCHLD, wait_on_child);
}
-Signal_t
+void
lostconn(int sig __attribute__ ((__unused__)))
{
exit(1);
int
main(int argc, char **argv)
{
- int msgfd, fd, n;
+ int msgfd, fd;
struct stat statBuf;
Port_t port;
char *msg;
int sockfd, newsockfd;
- int addrlen;
- int opt;
- struct sockaddr_in tcp_srv_addr;
- struct sockaddr_in their_addr;
- int num_fds;
+ socklen_t addrlen = 0;
+ union sockaddr_u their_addr;
if (argc != 3) {
fprintf(stderr, "Usage: portmsg file port\n");
- exit(1);
+ return 1;
}
port = atoi(argv[2]);
if (port == 0) {
fprintf(stderr, "error: bad port number [%s]\n", argv[2]);
- exit(1);
+ return 1;
}
if ((msgfd = open(argv[1], O_RDONLY)) < 0) {
- fprintf(stderr, "error: cannot open message file [%s]\n", argv[1]);
- exit(1);
+ fprintf(stderr, "error: cannot open message file [%s]: %s\n", argv[1],
+ strerror(errno));
+ return 1;
}
/* read the message */
fstat(msgfd, &statBuf);
if (statBuf.st_size <= 0) {
fprintf(stderr, "error: message file [%s] is empty\n", argv[1]);
- exit(1);
+ return 1;
}
msg = (char *) malloc(statBuf.st_size);
if (read(msgfd, msg, statBuf.st_size) != statBuf.st_size) {
fprintf(stderr, "error: cannot read message file [%s]\n", argv[1]);
- exit(1);
+ return 1;
}
- num_fds = how_many_fds();
/* become a daemon */
switch (fork()) {
case -1:
- fprintf(stderr, "error: can't fork\n");
- exit(1);
+ perror("can't fork");
+ return 1;
case 0:
break;
default:
- exit(0);
+ return 0;
}
#ifdef HAS_SETPGRP
#ifdef USE_BSD_SETPGRP
#else
if (setpgrp() == -1) {
#endif
- fprintf(stderr, "error: can't change process group\n");
- exit(1);
+ perror("can't change process group");
+ return 1;
}
#endif
}
#endif
- signal(SIGCLD, (void *) wait_on_child);
- memset((char *) &tcp_srv_addr, 0, sizeof(tcp_srv_addr));
- tcp_srv_addr.sin_family = AF_INET;
-#ifdef SINGLE_IP_ADDR
- tcp_srv_addr.sin_addr.s_addr = inet_addr(MUSH_IP_ADDR);
-#else
- tcp_srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-#endif
- tcp_srv_addr.sin_port = htons(port);
+ install_sig_handler(SIGCHLD, wait_on_child);
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "can't create stream socket\n");
- exit(-1);
+ if ((sockfd = make_socket(port, NULL, NULL, host_ip)) < 0) {
+ perror("can't make socket");
+ return 1;
}
- opt = 1;
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
- (char *) &opt, sizeof(opt)) < 0) {
- perror("setsockopt");
- exit(1);
- }
- if (bind(sockfd, (struct sockaddr *) &tcp_srv_addr, sizeof(tcp_srv_addr)) < 0) {
- fprintf(stderr, "can't bind local address\n");
- exit(-1);
- }
- listen(sockfd, 5);
main_again:
+ if (connections > MAX_CONNECTIONS) {
+ sleep(1);
+ goto main_again;
+ }
addrlen = sizeof(their_addr);
- newsockfd = accept(sockfd, (struct sockaddr *) &their_addr, &addrlen);
+ newsockfd = accept(sockfd, &their_addr.addr, &addrlen);
if (newsockfd < 0) {
if (errno == EINTR)
goto main_again;
- fprintf(stderr, "accept error\n");
- exit(-1);
+ perror("Couldn't accept connection");
+ return 1;
}
+ connections++;
switch (fork()) {
case -1:
- fprintf(stderr, "server can't fork\n");
- exit(-1);
+ perror("server can't fork");
+ return 1;
case 0:
- dup2(newsockfd, 0);
- dup2(newsockfd, 1);
- for (n = 3; n < num_fds; n++)
- close(n);
+ /* child process */
+ install_sig_handler(SIGPIPE, lostconn);
+ ignore_signal(SIGCHLD);
+ send(newsockfd, msg, statBuf.st_size, 0);
+ sleep(5);
+ closesocket(newsockfd);
break;
default:
- close(newsockfd);
+ closesocket(newsockfd);
goto main_again;
}
- /* daemon child arrives here */
- signal(SIGPIPE, lostconn);
- signal(SIGCLD, SIG_IGN);
-
- fprintf(stdout, msg);
- fflush(stdout);
- sleep(5);
- exit(0);
-}
-
-static int
-how_many_fds(void)
-{
- /* Determine how many open file descriptors we're allowed
- * In order, we'll try:
- * 0. OPEN_MAX constant - POSIX.1 limits.h
- * 1. sysconf(_SC_OPEN_MAX) - POSIX.1
- * 2. getdtablesize - BSD
- * 3. NOFILE - in some sys/param.h
- * 4. _NFILE - in some stdio.h
- */
-#ifdef OPEN_MAX
- static int open_max = OPEN_MAX;
-#else
- static int open_max = 0;
-#endif
-
- if (open_max)
- return open_max;
-
-#ifdef HAS_SYSCONF
- errno = 0;
- if ((open_max = sysconf(_SC_OPEN_MAX)) < 0) {
- if (errno == 0) /* Value was indeterminate */
- open_max = 0;
- }
- if (open_max)
- return open_max;
-#endif
- /* Caching getdtablesize is dangerous, since it's affected by
- * getrlimit, so we don't.
- */
- open_max = 0;
- return getdtablesize();
+ return 0;
}
}
/* A USR1 does a shutdown/reboot */
if (usr1_triggered) {
+ do_rawlog(LT_ERR, T("SIGUSR1 received. Rebooting."));
do_reboot(NOTHING, 0); /* We don't return from this */
usr1_triggered = 0; /* But just in case */
}