27ed571aca68eb360f5267d8aaff33d27ee55720
[fw/altos] / s51 / s51-main.c
1 /*
2  * Copyright © 2008 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include "s51.h"
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <signal.h>
25 #include <stdarg.h>
26 #include <poll.h>
27
28 static int s51_port = 0;
29 static char *cpu = "8051";
30 static double freq = 11059200;
31 char *s51_prompt = "> ";
32 struct ccdbg *s51_dbg;
33 int s51_interrupted = 0;
34
35 static FILE *s51_input;
36 static FILE *s51_output;
37
38 static void
39 usage(void)
40 {
41         fprintf(stderr, "You're doing it wrong.\n");
42         exit(1);
43 }
44
45 void s51_sigint()
46 {
47         s51_interrupted = 1;
48 }
49
50 int
51 main(int argc, char **argv)
52 {
53         int flags, opt;
54         char *endptr;
55         struct sigvec vec, ovec;
56
57         while ((opt = getopt(argc, argv, "PVvHht:X:c:r:Z:s:S:p:")) != -1) {
58                 switch (opt) {
59                 case 't':
60                         cpu = optarg;
61                         break;
62                 case 'X':
63                         freq = strtod(optarg, &endptr);
64                         if (endptr == optarg)
65                                 usage();
66                         if (endptr[0] != '\0') {
67                                 if (!strcmp(endptr, "k"))
68                                         freq *= 1000;
69                                 else if (!strcmp(endptr, "M") )
70                                         freq *= 1000000;
71                                 else
72                                         usage ();
73                         }
74                         break;
75                 case 'c':
76                         break;
77                 case 'r':
78                 case 'Z':
79                         s51_port = strtol(optarg, &endptr, 0);
80                         if (endptr == optarg || strlen(endptr) != 0)
81                                 usage();
82                         break;
83                 case 's':
84                         break;
85                 case 'S':
86                         break;
87                 case 'p':
88                         s51_prompt = optarg;
89                         break;
90                 case 'P':
91                         s51_prompt = NULL;
92                         break;
93                 case 'V':
94                         break;
95                 case 'v':
96                         break;
97                 case 'H':
98                         exit (0);
99                         break;
100                 case 'h':
101                         usage ();
102                         break;
103                 }
104         }
105         if (s51_port) {
106                 int l, r, one = 1;
107                 int s;
108                 struct sockaddr_in in;
109
110                 l = socket(AF_INET, SOCK_STREAM, 0);
111                 if (l < 0) {
112                         perror ("socket");
113                         exit(1);
114                 }
115                 r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
116                 if (r) {
117                         perror("setsockopt");
118                         exit(1);
119                 }
120                 in.sin_family = AF_INET;
121                 in.sin_port = htons(s51_port);
122                 in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
123                 r = bind(l, (struct sockaddr *) &in, sizeof (in));
124                 if (r) {
125                         perror("bind");
126                         exit(1);
127                 }
128                 r = listen(l, 5);
129                 if (r) {
130                         perror("listen");
131                         exit(1);
132                 }
133                 for (;;) {
134                         struct sockaddr_in client_addr;
135                         socklen_t client_len = sizeof (struct sockaddr_in);
136                         
137                         s = accept(l, (struct sockaddr *)
138                                    &client_addr, &client_len);
139                         if (s < 0) {
140                                 perror("accept");
141                                 exit(1);
142                         }
143                         s51_input = fdopen(s, "r");
144                         s51_output = fdopen(s, "w");
145                         if (!s51_input || !s51_output) {
146                                 perror("fdopen");
147                                 exit(1);
148                         }
149                         vec.sv_handler = s51_sigint;
150                         vec.sv_mask = 0;
151                         vec.sv_flags = 0;
152                         sigvec(SIGINT, &vec, &ovec);
153                         command_read();
154                         sigvec(SIGINT, &ovec, NULL);
155                         fclose(s51_input);
156                         fclose(s51_output);
157                 }
158         } else {
159                 s51_input = stdin;
160                 s51_output = stdout;
161                 vec.sv_handler = s51_sigint;
162                 vec.sv_mask = 0;
163                 vec.sv_flags = 0;
164                 sigvec(SIGINT, &vec, &ovec);
165                 command_read();
166         }
167         exit(0);
168 }
169
170 void
171 s51_printf(char *format, ...)
172 {
173         va_list ap;
174
175         va_start(ap, format);
176         vfprintf(s51_output, format, ap);
177 #if 1
178         if (s51_port)
179                 vfprintf(stdout, format, ap);
180 #endif
181         va_end(ap);
182 }
183
184 void
185 s51_putc(int c)
186 {
187         putc(c, s51_output);
188 }
189
190 int
191 s51_read_line(char *line, int len)
192 {
193         int ret;
194         if (s51_prompt)
195                 s51_printf("%s", s51_prompt);
196         else
197                 s51_putc('\0');
198         fflush(s51_output);
199         ret = fgets(line, len, s51_input) != NULL;
200 #if 1
201         if (s51_port)
202                 printf("> %s", line);
203 #endif
204         fflush(stdout);
205         return ret;
206 }
207
208 int
209 s51_check_input(void)
210 {
211         struct pollfd   input;
212         int r;
213         int c;
214
215         input.fd = fileno(s51_input);
216         input.events = POLLIN;
217         r = poll(&input, 1, 0);
218         if (r > 0) {
219                 char line[256];
220                 (void) s51_read_line(line, sizeof (line));
221                 return 1; 
222         }
223         return 0;
224 }
225