* src/ttt-args.h:
* src/ttt-args.c: (ttt_args_help), (ttt_args_parse): Add support
for -h,--host, -p,--port, and --log-file command-line arguments.
* src/ttt-server.c: (main): Use host, port, and log-file
command-line arguments.
* src/ttt-client.c: (main): Track change in signature of
ttt_args_parse.
* src/x.h:
* src/x.c: (xfdopen), (xfreopen): More wrappers.
+2005-11-09 Carl Worth <cworth@cworth.org>
+
+ * src/ttt-args.h:
+ * src/ttt-args.c: (ttt_args_help), (ttt_args_parse): Add support
+ for -h,--host, -p,--port, and --log-file command-line arguments.
+
+ * src/ttt-server.c: (main): Use host, port, and log-file
+ command-line arguments.
+
+ * src/ttt-client.c: (main): Track change in signature of
+ ttt_args_parse.
+
+ * src/x.h:
+ * src/x.c: (xfdopen), (xfreopen): More wrappers.
+
2005-11-08 Carl Worth <cworth@cworth.org>
* src/ttt.h:
2005-11-08 Carl Worth <cworth@cworth.org>
* src/ttt.h:
static const char TTT_ARGS_PROGRAM_VERSION[] = VERSION;
static const char TTT_ARGS_PROGRAM_DESCRIPTION[] = "client-server tic-tac-toe game";
static const char TTT_ARGS_PROGRAM_VERSION[] = VERSION;
static const char TTT_ARGS_PROGRAM_DESCRIPTION[] = "client-server tic-tac-toe game";
-static const char TTT_ARGS_PROGRAM_BUG_ADDRESS[] = "<cworth@cworth.org>";
+static const char TTT_ARGS_PROGRAM_BUG_ADDRESS[] = "<carl@theworths.org>";
-/* XXX: SAMPLE: */
-static char TTT_ARGS_PROGRAM_ARGDOC[] = "<file>";
+static char TTT_ARGS_PROGRAM_ARGDOC[] = "";
/* XXX: getopt is rather annoying in that you must maintain a
* string-encoding of the options in addition to the table. For
/* XXX: getopt is rather annoying in that you must maintain a
* string-encoding of the options in addition to the table. For
* strings, so the args_help function below must also be maintained
* manually.
*/
* strings, so the args_help function below must also be maintained
* manually.
*/
-static char ttt_args_optstring[] = "hV";
+
+enum {
+ TTT_ARGS_VAL_LOG_FILE = 256,
+ TTT_ARGS_VAL_HELP,
+ TTT_ARGS_VAL_VERSION
+};
+
+static char ttt_args_optstring[] = "h:p:";
static struct option ttt_args_options[] = {
/* name, has_arg, flag, val */
static struct option ttt_args_options[] = {
/* name, has_arg, flag, val */
- /* XXX: SAMPLE:
- {"display", 1, 0, 'd'},
- */
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'V'},
+ {"host", 1, 0, 'h'},
+ {"port", 1, 0, 'p'},
+ {"log-file", 1, 0, TTT_ARGS_VAL_LOG_FILE},
+ {"help", 0, 0, TTT_ARGS_VAL_HELP},
+ {"version", 0, 0, TTT_ARGS_VAL_VERSION},
printf ("Usage: %s [OPTION] %s\n", argv0, TTT_ARGS_PROGRAM_ARGDOC);
printf ("%s - %s\n", argv0, TTT_ARGS_PROGRAM_DESCRIPTION);
puts ("");
printf ("Usage: %s [OPTION] %s\n", argv0, TTT_ARGS_PROGRAM_ARGDOC);
printf ("%s - %s\n", argv0, TTT_ARGS_PROGRAM_DESCRIPTION);
puts ("");
- printf (" -h, --help\t\tGive this help list\n");
- printf (" -V, --version\t\tPrint program version\n");
- /* XXX: SAMPLE:
- printf (" -d, --display=DISPLAY\tX server to connect to");
- */
+ printf ("Options that are common to both client and server:\n");
+ puts ("");
+ printf (" -h HOST, --host=HOST\tHost to connect/bind to\n");
+ printf (" -p PORT, --port=PORT\tPort to connect/bind to\n");
+ printf (" --help\tGive this help list\n");
+ printf (" --version\tPrint program version\n");
+ puts ("");
+ printf ("Options that are specific to the server:\n");
+ puts ("");
+ printf (" --log-file=FILE\tFile to use for logging\n");
-ttt_args_parse(ttt_args_t *args, int argc, char *argv[], int *args_first)
+ttt_args_parse(ttt_args_t *args, int argc, char *argv[])
{
char *argv0_copy = strdup (argv[0]);
char *argv0 = basename (argv0_copy);
int c;
{
char *argv0_copy = strdup (argv[0]);
char *argv0 = basename (argv0_copy);
int c;
- /* XXX: SAMPLE:
- args->display = NULL;
- */
+ args->host = TTT_ARGS_HOST_DEFAULT;
+ args->port = TTT_ARGS_PORT_DEFAULT;
+ args->log_file = TTT_ARGS_LOG_FILE_DEFAULT;
while (1) {
c = getopt_long (argc, argv, ttt_args_optstring, ttt_args_options, NULL);
while (1) {
c = getopt_long (argc, argv, ttt_args_optstring, ttt_args_options, NULL);
- /* XXX: SAMPLE:
- case 'd':
- args->display = optarg;
+ case 'h':
+ args->host = optarg;
+ case 'p':
+ args->port = optarg;
+ break;
+ case TTT_ARGS_VAL_LOG_FILE:
+ args->log_file = optarg;
+ break;
+ case TTT_ARGS_VAL_VERSION:
printf ("%s\n", VERSION);
exit (0);
break;
printf ("%s\n", VERSION);
exit (0);
break;
+ case TTT_ARGS_VAL_HELP:
ttt_args_help (argv0);
exit (0);
break;
ttt_args_help (argv0);
exit (0);
break;
- /* XXX: SAMPLE:
- if (argc - optind == 1) {
- args->file = argv[optind];
- } else {
- ttt_args_usage (argv0);
- }
- */
-
- if (args_first)
- *args_first = optind;
-
free (argv0_copy);
return 0;
free (argv0_copy);
return 0;
#include "config.h"
#endif
#include "config.h"
#endif
+#define TTT_ARGS_HOST_DEFAULT "localhost"
+#define TTT_ARGS_PORT_DEFAULT "5334"
+/* NULL means to just log to stderr. */
+#define TTT_ARGS_LOG_FILE_DEFAULT NULL
+
typedef struct ttt_args
{
typedef struct ttt_args
{
- /* XXX: SAMPLE:
- char *display;
- */
- char *file;
-
+ char *host;
+ char *port;
+ char *log_file;
-ttt_args_parse(ttt_args_t *args, int argc, char *argv[], int *args_first);
+ttt_args_parse(ttt_args_t *args, int argc, char *argv[]);
main (int argc, char **argv)
{
ttt_args_t args;
main (int argc, char **argv)
{
ttt_args_t args;
- ttt_args_parse (&args, argc, argv, &args_first);
+ ttt_args_parse (&args, argc, argv);
/* XXX: insert code here */
/* XXX: insert code here */
main (int argc, char **argv)
{
ttt_args_t args;
main (int argc, char **argv)
{
ttt_args_t args;
int listen_socket, connected_socket;
struct sockaddr_in addr;
int listen_socket, connected_socket;
struct sockaddr_in addr;
- ttt_args_parse (&args, argc, argv, &args_first);
+ ttt_args_parse (&args, argc, argv);
- listen_socket = xsocket (PF_INET, SOCK_STREAM, 0);
+ if (args.log_file)
+ stderr = xfreopen (args.log_file, "a", stderr);
-#define HOST "localhost"
-#define PORT "5534"
+ listen_socket = xsocket (PF_INET, SOCK_STREAM, 0);
- _sockaddr_init (&addr, HOST, PORT);
+ _sockaddr_init (&addr, args.host, args.port);
xlisten (listen_socket, SOMAXCONN);
xlisten (listen_socket, SOMAXCONN);
- printf (WELCOME_MESSAGE, HOST, PORT, HOST, PORT);
+ printf (WELCOME_MESSAGE, args.host, args.port, args.host, args.port);
connected_socket = _wait_for_connection (listen_socket);
connected_socket = _wait_for_connection (listen_socket);
ret = fdopen (filedes, mode);
if (ret == NULL) {
ret = fdopen (filedes, mode);
if (ret == NULL) {
- fprintf (stderr, "Error: fdopen failed: %s. Aborting.\n", strerror (errno));
+ fprintf (stderr, "Error: fdopen failed: %s. Aborting.\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ return ret;
+}
+
+FILE *
+xfreopen (const char *path, const char *mode, FILE *stream)
+{
+ FILE *ret;
+
+ ret = freopen (path, mode, stream);
+ if (ret == NULL) {
+ fprintf (stderr, "Error: freopen of %s failed: %s. Aborting.\n",
+ path, strerror (errno));
FILE *
xfdopen (int filedes, const char *mode);
FILE *
xfdopen (int filedes, const char *mode);
+FILE *
+xfreopen (const char *path, const char *mode, FILE *stream);
+
char *
xstrdup (const char *s);
char *
xstrdup (const char *s);