diff -upPr -x *.o ../stk/act.social.c ./act.social.c
--- ../stk/act.social.c	Fri Apr 12 23:39:21 1996
+++ ./act.social.c	Mon Oct 20 15:07:01 1997
@@ -180,7 +180,7 @@ char *fread_action(FILE * fl, int nr)
 
   fgets(buf, MAX_STRING_LENGTH, fl);
   if (feof(fl)) {
-    fprintf(stderr, "fread_action - unexpected EOF near action #%d", nr);
+    fprintf(logfile, "fread_action - unexpected EOF near action #%d", nr);
     exit(1);
   }
   if (*buf == '#')
@@ -225,7 +225,7 @@ void boot_social_messages(void)
       log(buf);
     }
     if (fscanf(fl, " %d %d \n", &hide, &min_pos) != 2) {
-      fprintf(stderr, "Format error in social file near social '%s'\n",
+      fprintf(logfile, "Format error in social file near social '%s'\n",
 	      next_soc);
       exit(1);
     }
diff -upPr -x *.o ../stk/comm.c ./comm.c
--- ../stk/comm.c	Sun Apr 14 14:28:46 1996
+++ ./comm.c	Mon Oct 20 15:07:44 1997
@@ -50,6 +50,7 @@ extern int no_rent_check;
 extern FILE *player_fl;
 extern int DFLT_PORT;
 extern char *DFLT_DIR;
+extern char *LOGFILE;
 extern int MAX_PLAYERS;
 extern int MAX_DESCRIPTORS_AVAILABLE;
 
@@ -74,6 +75,7 @@ extern int nameserver_is_slow;	/* see co
 extern int auto_save;		/* see config.c */
 extern int autosave_time;	/* see config.c */
 struct timeval null_time;	/* zero-valued time structure */
+FILE *logfile = stderr;		/* Where to log messages. */
 
 /* functions in this file */
 int get_from_q(struct txt_q *queue, char *dest, int *aliased);
@@ -141,6 +143,12 @@ int main(int argc, char **argv)
   port = DFLT_PORT;
   dir = DFLT_DIR;
 
+  /* Be nice to make this a command line option but the parser uses log() */
+  if (*LOGFILE != '\0' && !(logfile = fopen(LOGFILE, "w"))) {
+    fprintf(stdout, "Error opening log file!\n");
+    exit(1);
+  }
+
   while ((pos < argc) && (*(argv[pos]) == '-')) {
     switch (*(argv[pos] + 1)) {
     case 'd':
@@ -184,10 +192,10 @@ int main(int argc, char **argv)
 
   if (pos < argc) {
     if (!isdigit(*argv[pos])) {
-      fprintf(stderr, "Usage: %s [-c] [-m] [-q] [-r] [-s] [-d pathname] [port #]\n", argv[0]);
+      fprintf(logfile, "Usage: %s [-c] [-m] [-q] [-r] [-s] [-d pathname] [port #]\n", argv[0]);
       exit(1);
     } else if ((port = atoi(argv[pos])) <= 1024) {
-      fprintf(stderr, "Illegal port number.\n");
+      fprintf(logfile, "Illegal port number.\n");
       exit(1);
     }
   }
@@ -295,7 +303,7 @@ int init_socket(int port)
     log(buf);
 
     if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
-      fprintf(stderr, "Error opening network connection: Winsock err #%d\n", WSAGetLastError());
+      fprintf(logfile, "Error opening network connection: Winsock err #%d\n", WSAGetLastError());
       exit(1);
     }
   }
diff -upPr -x *.o ../stk/comm.h ./comm.h
--- ../stk/comm.h	Fri Apr 12 23:39:21 1996
+++ ./comm.h	Mon Oct 20 15:08:31 1997
@@ -42,6 +42,9 @@ void	page_string(struct descriptor_data 
 
 typedef RETSIGTYPE sigfunc(int);
 
+#if !defined(__COMM_C__)
+extern FILE *logfile;	/* Where to send messages from log() */
+#endif
 
 /* Function prototypes for brain-dead OS's */
 
diff -upPr -x *.o ../stk/config.c ./config.c
--- ../stk/config.c	Sat Apr 13 00:08:21 1996
+++ ./config.c	Mon Oct 20 15:17:19 1997
@@ -158,6 +158,9 @@ int DFLT_PORT = 4000;
 /* default directory to use as data directory */
 char *DFLT_DIR = "lib";
 
+/* What file to log messages to (ex: "log/syslog").  "" == stderr */
+char *LOGFILE = "";
+
 /* maximum number of players allowed before game starts to turn people away */
 int MAX_PLAYERS = 300;
 
diff -upPr -x *.o ../stk/db.c ./db.c
--- ../stk/db.c	Sun Apr 14 03:08:21 1996
+++ ./db.c	Mon Oct 20 15:06:11 1997
@@ -393,7 +393,7 @@ void build_player_index(void)
   size = ftell(player_fl);
   rewind(player_fl);
   if (size % sizeof(struct char_file_u))
-    fprintf(stderr, "\aWARNING:  PLAYERFILE IS PROBABLY CORRUPT!\n");
+    fprintf(logfile, "\aWARNING:  PLAYERFILE IS PROBABLY CORRUPT!\n");
   recs = size / sizeof(struct char_file_u);
   if (recs) {
     sprintf(buf, "   %ld players in database.", recs);
@@ -582,7 +582,7 @@ void discrete_load(FILE * fl, int mode)
      */
     if (mode != DB_BOOT_OBJ || nr < 0)
       if (!get_line(fl, line)) {
-	fprintf(stderr, "Format error after %s #%d\n", modes[mode], nr);
+	fprintf(logfile, "Format error after %s #%d\n", modes[mode], nr);
 	exit(1);
       }
     if (*line == '$')
@@ -591,7 +591,7 @@ void discrete_load(FILE * fl, int mode)
     if (*line == '#') {
       last = nr;
       if (sscanf(line, "#%d", &nr) != 1) {
-	fprintf(stderr, "Format error after %s #%d\n", modes[mode], last);
+	fprintf(logfile, "Format error after %s #%d\n", modes[mode], last);
 	exit(1);
       }
       if (nr >= 99999)
@@ -609,9 +609,9 @@ void discrete_load(FILE * fl, int mode)
 	  break;
 	}
     } else {
-      fprintf(stderr, "Format error in %s file near %s #%d\n",
+      fprintf(logfile, "Format error in %s file near %s #%d\n",
 	      modes[mode], modes[mode], nr);
-      fprintf(stderr, "Offending line: '%s'\n", line);
+      fprintf(logfile, "Offending line: '%s'\n", line);
       exit(1);
     }
   }
@@ -652,12 +652,12 @@ void parse_room(FILE * fl, int virtual_n
   sprintf(buf2, "room #%d", virtual_nr);
 
   if (virtual_nr <= (zone ? zone_table[zone - 1].top : -1)) {
-    fprintf(stderr, "Room #%d is below zone %d.\n", virtual_nr, zone);
+    fprintf(logfile, "Room #%d is below zone %d.\n", virtual_nr, zone);
     exit(1);
   }
   while (virtual_nr > zone_table[zone].top)
     if (++zone > top_of_zone_table) {
-      fprintf(stderr, "Room %d is outside of any zone.\n", virtual_nr);
+      fprintf(logfile, "Room %d is outside of any zone.\n", virtual_nr);
       exit(1);
     }
   world[room_nr].zone = zone;
@@ -666,7 +666,7 @@ void parse_room(FILE * fl, int virtual_n
   world[room_nr].description = fread_string(fl, buf2);
 
   if (!get_line(fl, line) || sscanf(line, " %d %s %d ", t, flags, t + 2) != 3) {
-    fprintf(stderr, "Format error in room #%d\n", virtual_nr);
+    fprintf(logfile, "Format error in room #%d\n", virtual_nr);
     exit(1);
   }
   /* t[0] is the zone number; ignored with the zone-file system */
@@ -687,7 +687,7 @@ void parse_room(FILE * fl, int virtual_n
 
   for (;;) {
     if (!get_line(fl, line)) {
-      fprintf(stderr, "%s\n", buf);
+      fprintf(logfile, "%s\n", buf);
       exit(1);
     }
     switch (*line) {
@@ -706,7 +706,7 @@ void parse_room(FILE * fl, int virtual_n
       return;
       break;
     default:
-      fprintf(stderr, "%s\n", buf);
+      fprintf(logfile, "%s\n", buf);
       exit(1);
       break;
     }
@@ -728,11 +728,11 @@ void setup_dir(FILE * fl, int room, int 
   world[room].dir_option[dir]->keyword = fread_string(fl, buf2);
 
   if (!get_line(fl, line)) {
-    fprintf(stderr, "Format error, %s\n", buf2);
+    fprintf(logfile, "Format error, %s\n", buf2);
     exit(1);
   }
   if (sscanf(line, " %d %d %d ", t, t + 1, t + 2) != 3) {
-    fprintf(stderr, "Format error, %s\n", buf2);
+    fprintf(logfile, "Format error, %s\n", buf2);
     exit(1);
   }
   if (t[0] == 1)
@@ -848,7 +848,7 @@ void parse_simple_mob(FILE *mob_f, int i
     get_line(mob_f, line);
     if (sscanf(line, " %d %d %d %dd%d+%d %dd%d+%d ",
 	  t, t + 1, t + 2, t + 3, t + 4, t + 5, t + 6, t + 7, t + 8) != 9) {
-      fprintf(stderr, "Format error in mob #%d, first line after S flag\n"
+      fprintf(logfile, "Format error in mob #%d, first line after S flag\n"
 	      "...expecting line of form '# # # #d#+# #d#+#'\n", nr);
       exit(1);
     }
@@ -876,7 +876,7 @@ void parse_simple_mob(FILE *mob_f, int i
 
     get_line(mob_f, line);
     if (sscanf(line, " %d %d %d %d ", t, t + 1, t + 2, t + 3) != 3) {
-      fprintf(stderr, "Format error in mob #%d, second line after S flag\n"
+      fprintf(logfile, "Format error in mob #%d, second line after S flag\n"
 	      "...expecting line of form '# # #'\n", nr);
     }
 
@@ -957,7 +957,7 @@ void interpret_espec(char *keyword, char
   }
 
   if (!matched) {
-    fprintf(stderr, "Warning: unrecognized espec keyword %s in mob #%d\n",
+    fprintf(logfile, "Warning: unrecognized espec keyword %s in mob #%d\n",
 	    keyword, nr);
   }    
 }
@@ -990,13 +990,13 @@ void parse_enhanced_mob(FILE *mob_f, int
     if (!strcmp(line, "E"))	/* end of the ehanced section */
       return;
     else if (*line == '#') {	/* we've hit the next mob, maybe? */
-      fprintf(stderr, "Unterminated E section in mob #%d\n", nr);
+      fprintf(logfile, "Unterminated E section in mob #%d\n", nr);
       exit(1);
     } else
       parse_espec(line, i, nr);
   }
 
-  fprintf(stderr, "Unexpected end of file reached after mob #%d\n", nr);
+  fprintf(logfile, "Unexpected end of file reached after mob #%d\n", nr);
   exit(1);
 }
 
@@ -1045,7 +1045,7 @@ void parse_mobile(FILE * mob_f, int nr)
     break;
   /* add new mob types here.. */
   default:
-    fprintf(stderr, "Unsupported mob type '%c' in mob #%d\n", letter, nr);
+    fprintf(logfile, "Unsupported mob type '%c' in mob #%d\n", letter, nr);
     exit(1);
     break;
   }
@@ -1086,7 +1086,7 @@ char *parse_object(FILE * obj_f, int nr)
 
   /* *** string data *** */
   if ((obj_proto[i].name = fread_string(obj_f, buf2)) == NULL) {
-    fprintf(stderr, "Null obj name or format error at or near %s\n", buf2);
+    fprintf(logfile, "Null obj name or format error at or near %s\n", buf2);
     exit(1);
   }
   tmpptr = obj_proto[i].short_description = fread_string(obj_f, buf2);
@@ -1103,7 +1103,7 @@ char *parse_object(FILE * obj_f, int nr)
   /* *** numeric data *** */
   if (!get_line(obj_f, line) ||
       (retval = sscanf(line, " %d %s %s", t, f1, f2)) != 3) {
-    fprintf(stderr, "Format error in first numeric line (expecting 3 args, got %d), %s\n", retval, buf2);
+    fprintf(logfile, "Format error in first numeric line (expecting 3 args, got %d), %s\n", retval, buf2);
     exit(1);
   }
   obj_proto[i].obj_flags.type_flag = t[0];
@@ -1112,7 +1112,7 @@ char *parse_object(FILE * obj_f, int nr)
 
   if (!get_line(obj_f, line) ||
       (retval = sscanf(line, "%d %d %d %d", t, t + 1, t + 2, t + 3)) != 4) {
-    fprintf(stderr, "Format error in second numeric line (expecting 4 args, got %d), %s\n", retval, buf2);
+    fprintf(logfile, "Format error in second numeric line (expecting 4 args, got %d), %s\n", retval, buf2);
     exit(1);
   }
   obj_proto[i].obj_flags.value[0] = t[0];
@@ -1122,7 +1122,7 @@ char *parse_object(FILE * obj_f, int nr)
 
   if (!get_line(obj_f, line) ||
       (retval = sscanf(line, "%d %d %d", t, t + 1, t + 2)) != 3) {
-    fprintf(stderr, "Format error in third numeric line (expecting 3 args, got %d), %s\n", retval, buf2);
+    fprintf(logfile, "Format error in third numeric line (expecting 3 args, got %d), %s\n", retval, buf2);
     exit(1);
   }
   obj_proto[i].obj_flags.weight = t[0];
@@ -1148,7 +1148,7 @@ char *parse_object(FILE * obj_f, int nr)
 
   for (;;) {
     if (!get_line(obj_f, line)) {
-      fprintf(stderr, "Format error in %s\n", buf2);
+      fprintf(logfile, "Format error in %s\n", buf2);
       exit(1);
     }
     switch (*line) {
@@ -1161,7 +1161,7 @@ char *parse_object(FILE * obj_f, int nr)
       break;
     case 'A':
       if (j >= MAX_OBJ_AFFECT) {
-	fprintf(stderr, "Too many A fields (%d max), %s\n", MAX_OBJ_AFFECT, buf2);
+	fprintf(logfile, "Too many A fields (%d max), %s\n", MAX_OBJ_AFFECT, buf2);
 	exit(1);
       }
       get_line(obj_f, line);
@@ -1176,7 +1176,7 @@ char *parse_object(FILE * obj_f, int nr)
       return line;
       break;
     default:
-      fprintf(stderr, "Format error in %s\n", buf2);
+      fprintf(logfile, "Format error in %s\n", buf2);
       exit(1);
       break;
     }
@@ -1200,7 +1200,7 @@ void load_zones(FILE * fl, char *zonenam
   rewind(fl);
 
   if (num_of_cmds == 0) {
-    fprintf(stderr, "%s is empty!\n", zname);
+    fprintf(logfile, "%s is empty!\n", zname);
     exit(0);
   } else
     CREATE(Z.cmd, struct reset_com, num_of_cmds);
@@ -1208,7 +1208,7 @@ void load_zones(FILE * fl, char *zonenam
   line_num += get_line(fl, buf);
 
   if (sscanf(buf, "#%d", &Z.number) != 1) {
-    fprintf(stderr, "Format error in %s, line %d\n", zname, line_num);
+    fprintf(logfile, "Format error in %s, line %d\n", zname, line_num);
     exit(0);
   }
   sprintf(buf2, "beginning of zone #%d", Z.number);
@@ -1220,14 +1220,14 @@ void load_zones(FILE * fl, char *zonenam
 
   line_num += get_line(fl, buf);
   if (sscanf(buf, " %d %d %d ", &Z.top, &Z.lifespan, &Z.reset_mode) != 3) {
-    fprintf(stderr, "Format error in 3-constant line of %s", zname);
+    fprintf(logfile, "Format error in 3-constant line of %s", zname);
     exit(0);
   }
   cmd_no = 0;
 
   for (;;) {
     if ((tmp = get_line(fl, buf)) == 0) {
-      fprintf(stderr, "Format error in %s - premature end of file\n", zname);
+      fprintf(logfile, "Format error in %s - premature end of file\n", zname);
       exit(0);
     }
     line_num += tmp;
@@ -1256,7 +1256,7 @@ void load_zones(FILE * fl, char *zonenam
     ZCMD.if_flag = tmp;
 
     if (error) {
-      fprintf(stderr, "Format error in %s, line %d: '%s'\n", zname, line_num, buf);
+      fprintf(logfile, "Format error in %s, line %d: '%s'\n", zname, line_num, buf);
       exit(0);
     }
     ZCMD.line = line_num;
@@ -1997,7 +1997,7 @@ char *fread_string(FILE * fl, char *erro
 
   do {
     if (!fgets(tmp, 512, fl)) {
-      fprintf(stderr, "SYSERR: fread_string: format error at or near %s\n",
+      fprintf(logfile, "SYSERR: fread_string: format error at or near %s\n",
 	      error);
       exit(1);
     }
diff -upPr -x *.o ../stk/fight.c ./fight.c
--- ../stk/fight.c	Fri Apr 12 23:39:21 1996
+++ ./fight.c	Mon Oct 20 15:06:43 1997
@@ -112,7 +112,7 @@ void load_messages(void)
     for (i = 0; (i < MAX_MESSAGES) && (fight_messages[i].a_type != type) &&
 	 (fight_messages[i].a_type); i++);
     if (i >= MAX_MESSAGES) {
-      fprintf(stderr, "Too many combat messages.  Increase MAX_MESSAGES and recompile.");
+      fprintf(logfile, "Too many combat messages.  Increase MAX_MESSAGES and recompile.");
       exit(1);
     }
     CREATE(messages, struct message_type, 1);
diff -upPr -x *.o ../stk/shop.c ./shop.c
--- ../stk/shop.c	Fri Apr 12 23:39:21 1996
+++ ./shop.c	Mon Oct 20 15:07:15 1997
@@ -905,7 +905,7 @@ int end_read_list(struct shop_buy_data *
 void read_line(FILE * shop_f, char *string, void *data)
 {
   if (!get_line(shop_f, buf) || !sscanf(buf, string, data)) {
-    fprintf(stderr, "Error in shop #%d\n", SHOP_NUM(top_shop));
+    fprintf(logfile, "Error in shop #%d\n", SHOP_NUM(top_shop));
     exit(1);
   }
 }
diff -upPr -x *.o ../stk/utils.c ./utils.c
--- ../stk/utils.c	Sat Apr 13 19:59:59 1996
+++ ./utils.c	Mon Oct 20 15:06:30 1997
@@ -132,7 +132,7 @@ void log(char *str)
   ct = time(0);
   tmstr = asctime(localtime(&ct));
   *(tmstr + strlen(tmstr) - 1) = '\0';
-  fprintf(stderr, "%-19.19s :: %s\n", tmstr, str);
+  fprintf(logfile, "%-19.19s :: %s\n", tmstr, str);
 }
 
 
@@ -167,7 +167,7 @@ void mudlog(char *str, char type, int le
   tmp = asctime(localtime(&ct));
 
   if (file)
-    fprintf(stderr, "%-19.19s :: %s\n", tmp, str);
+    fprintf(logfile, "%-19.19s :: %s\n", tmp, str);
   if (level < 0)
     return;
 
