TeleStern/ao-tools/ao-dbg/ao-dbg-main.c

257 lines
4.8 KiB
C

/*
* Copyright © 2008 Keith Packard <keithp@keithp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ao-dbg.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdarg.h>
#include <poll.h>
#include <getopt.h>
static int s51_port = 0;
static char *cpu = "8051";
static double freq = 11059200;
char *s51_prompt = "> ";
struct ccdbg *s51_dbg;
int s51_interrupted = 0;
int s51_monitor = 0;
char *s51_tty = NULL;
char *s51_device = NULL;
static FILE *s51_input;
static FILE *s51_output;
static void
usage(void)
{
fprintf(stderr, "You're doing it wrong.\n");
exit(1);
}
static void
s51_sigint(int signum)
{
s51_interrupted = 1;
}
static const struct option options[] = {
{ .name = "tty", .has_arg = 1, .val = 'T' },
{ .name = "device", .has_arg = 1, .val = 'D' },
{ 0, 0, 0, 0 },
};
int
main(int argc, char **argv)
{
int opt;
char *endptr;
while ((opt = getopt_long(argc, argv, "PVvHhmt:X:c:r:Z:s:S:p:T:", options, NULL)) != -1) {
switch (opt) {
case 't':
cpu = optarg;
break;
case 'X':
freq = strtod(optarg, &endptr);
if (endptr == optarg)
usage();
if (endptr[0] != '\0') {
if (!strcmp(endptr, "k"))
freq *= 1000;
else if (!strcmp(endptr, "M") )
freq *= 1000000;
else
usage ();
}
break;
case 'c':
break;
case 'r':
case 'Z':
s51_port = strtol(optarg, &endptr, 0);
if (endptr == optarg || strlen(endptr) != 0)
usage();
break;
case 's':
break;
case 'S':
break;
case 'p':
s51_prompt = optarg;
break;
case 'P':
s51_prompt = NULL;
break;
case 'V':
break;
case 'v':
break;
case 'H':
exit (0);
break;
case 'h':
usage ();
break;
case 'm':
s51_monitor = 1;
break;
case 'T':
s51_tty = optarg;
break;
case 'D':
s51_device = optarg;
break;
}
}
if (s51_port) {
int l, r, one = 1;
int s;
struct sockaddr_in in;
l = socket(AF_INET, SOCK_STREAM, 0);
if (l < 0) {
perror ("socket");
exit(1);
}
r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
if (r) {
perror("setsockopt");
exit(1);
}
in.sin_family = AF_INET;
in.sin_port = htons(s51_port);
in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
r = bind(l, (struct sockaddr *) &in, sizeof (in));
if (r) {
perror("bind");
exit(1);
}
r = listen(l, 5);
if (r) {
perror("listen");
exit(1);
}
for (;;) {
struct sockaddr_in client_addr;
socklen_t client_len = sizeof (struct sockaddr_in);
s = accept(l, (struct sockaddr *)
&client_addr, &client_len);
if (s < 0) {
perror("accept");
exit(1);
}
s51_input = fdopen(s, "r");
s51_output = fdopen(s, "w");
if (!s51_input || !s51_output) {
perror("fdopen");
exit(1);
}
signal(SIGINT, SIG_IGN);
command_read();
signal(SIGINT, SIG_DFL);
fclose(s51_input);
fclose(s51_output);
}
} else {
s51_input = stdin;
s51_output = stdout;
signal(SIGINT, s51_sigint);
command_read();
}
exit(0);
}
void
s51_printf(char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(s51_output, format, ap);
if (s51_monitor)
vfprintf(stdout, format, ap);
va_end(ap);
}
void
s51_putc(int c)
{
putc(c, s51_output);
}
#if HAVE_LIBREADLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif
int
s51_read_line(char *line, int len)
{
int ret;
#if HAVE_LIBREADLINE
if (s51_output == stdout && s51_input == stdin && s51_prompt) {
char *r;
r = readline(s51_prompt);
if (r == NULL)
return 0;
strncpy (line, r, len);
line[len-1] = '\0';
add_history(r);
return 1;
} else
#endif
{
if (s51_prompt)
s51_printf("%s", s51_prompt);
else
s51_putc('\0');
fflush(s51_output);
ret = fgets(line, len, s51_input) != NULL;
if (s51_monitor)
printf("> %s", line);
fflush(stdout);
}
return ret;
}
int
s51_check_input(void)
{
struct pollfd input;
int r;
input.fd = fileno(s51_input);
input.events = POLLIN;
r = poll(&input, 1, 0);
if (r > 0) {
char line[256];
(void) s51_read_line(line, sizeof (line));
return 1;
}
return 0;
}