/* * Copyright © 2008 Keith Packard * * 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 #include #include #include #include #include #include #include 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 #include #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; }