2009-04-01 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
CommitLineData
c906108c 1/* Remote utility routines for the remote server for GDB.
6aba47ca 2 Copyright (C) 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
0fb0cc75 3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
9b254dd1 4 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "server.h"
22#include "terminal.h"
5b1c542e 23#include "target.h"
c906108c
SS
24#include <stdio.h>
25#include <string.h>
b80864fb 26#if HAVE_SYS_IOCTL_H
c906108c 27#include <sys/ioctl.h>
b80864fb 28#endif
68070c10 29#if HAVE_SYS_FILE_H
c906108c 30#include <sys/file.h>
68070c10 31#endif
b80864fb 32#if HAVE_NETINET_IN_H
c906108c 33#include <netinet/in.h>
b80864fb
DJ
34#endif
35#if HAVE_SYS_SOCKET_H
c906108c 36#include <sys/socket.h>
b80864fb
DJ
37#endif
38#if HAVE_NETDB_H
c906108c 39#include <netdb.h>
b80864fb
DJ
40#endif
41#if HAVE_NETINET_TCP_H
c906108c 42#include <netinet/tcp.h>
b80864fb
DJ
43#endif
44#if HAVE_SYS_IOCTL_H
c906108c 45#include <sys/ioctl.h>
b80864fb 46#endif
68070c10 47#if HAVE_SIGNAL_H
c906108c 48#include <signal.h>
68070c10
PA
49#endif
50#if HAVE_FCNTL_H
c906108c 51#include <fcntl.h>
68070c10 52#endif
cf30a8e1 53#include <sys/time.h>
68070c10 54#if HAVE_UNISTD_H
cf30a8e1 55#include <unistd.h>
68070c10 56#endif
b80864fb 57#if HAVE_ARPA_INET_H
0729219d 58#include <arpa/inet.h>
b80864fb 59#endif
8264bb58 60#include <sys/stat.h>
68070c10 61#if HAVE_ERRNO_H
8264bb58 62#include <errno.h>
68070c10 63#endif
b80864fb
DJ
64
65#if USE_WIN32API
66#include <winsock.h>
67#endif
c906108c 68
f450004a
DJ
69#ifndef HAVE_SOCKLEN_T
70typedef int socklen_t;
71#endif
72
7390519e
PA
73#if USE_WIN32API
74# define INVALID_DESCRIPTOR INVALID_SOCKET
75#else
76# define INVALID_DESCRIPTOR -1
77#endif
78
fd500816
DJ
79/* A cache entry for a successfully looked-up symbol. */
80struct sym_cache
81{
95954743 82 char *name;
fd500816
DJ
83 CORE_ADDR addr;
84 struct sym_cache *next;
85};
86
c906108c 87int remote_debug = 0;
03863182 88struct ui_file *gdb_stdlog;
c906108c 89
7390519e 90static int remote_desc = INVALID_DESCRIPTOR;
c906108c 91
0d62e5e8
DJ
92/* FIXME headerize? */
93extern int using_threads;
94extern int debug_threads;
95
a6f3e723
SL
96/* If true, then GDB has requested noack mode. */
97int noack_mode = 0;
98/* If true, then we tell GDB to use noack mode by default. */
99int transport_is_reliable = 0;
100
0f48aa01 101#ifdef USE_WIN32API
68070c10
PA
102# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
103# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
0f48aa01
DJ
104#endif
105
c906108c
SS
106/* Open a connection to a remote debugger.
107 NAME is the filename used for communication. */
108
109void
fba45db2 110remote_open (char *name)
c906108c 111{
b80864fb 112#if defined(F_SETFL) && defined (FASYNC)
c906108c 113 int save_fcntl_flags;
b80864fb 114#endif
8264bb58
DJ
115 char *port_str;
116
117 port_str = strchr (name, ':');
118 if (port_str == NULL)
c906108c 119 {
b80864fb
DJ
120#ifdef USE_WIN32API
121 error ("Only <host>:<port> is supported on this platform.");
122#else
8264bb58
DJ
123 struct stat statbuf;
124
125 if (stat (name, &statbuf) == 0
126 && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)))
127 remote_desc = open (name, O_RDWR);
128 else
129 {
130 errno = EINVAL;
131 remote_desc = -1;
132 }
133
c906108c
SS
134 if (remote_desc < 0)
135 perror_with_name ("Could not open remote device");
136
137#ifdef HAVE_TERMIOS
138 {
139 struct termios termios;
c5aa993b 140 tcgetattr (remote_desc, &termios);
c906108c
SS
141
142 termios.c_iflag = 0;
143 termios.c_oflag = 0;
144 termios.c_lflag = 0;
c5aa993b 145 termios.c_cflag &= ~(CSIZE | PARENB);
c906108c 146 termios.c_cflag |= CLOCAL | CS8;
d0608e50 147 termios.c_cc[VMIN] = 1;
c906108c
SS
148 termios.c_cc[VTIME] = 0;
149
c5aa993b 150 tcsetattr (remote_desc, TCSANOW, &termios);
c906108c
SS
151 }
152#endif
153
154#ifdef HAVE_TERMIO
155 {
156 struct termio termio;
157 ioctl (remote_desc, TCGETA, &termio);
158
159 termio.c_iflag = 0;
160 termio.c_oflag = 0;
161 termio.c_lflag = 0;
c5aa993b 162 termio.c_cflag &= ~(CSIZE | PARENB);
c906108c 163 termio.c_cflag |= CLOCAL | CS8;
d0608e50 164 termio.c_cc[VMIN] = 1;
c906108c
SS
165 termio.c_cc[VTIME] = 0;
166
167 ioctl (remote_desc, TCSETA, &termio);
168 }
169#endif
170
171#ifdef HAVE_SGTTY
172 {
173 struct sgttyb sg;
174
175 ioctl (remote_desc, TIOCGETP, &sg);
176 sg.sg_flags = RAW;
177 ioctl (remote_desc, TIOCSETP, &sg);
178 }
179#endif
180
e641a1ca 181 fprintf (stderr, "Remote debugging using %s\n", name);
b80864fb 182#endif /* USE_WIN32API */
a6f3e723
SL
183
184 transport_is_reliable = 0;
c906108c
SS
185 }
186 else
187 {
b80864fb
DJ
188#ifdef USE_WIN32API
189 static int winsock_initialized;
190#endif
c906108c
SS
191 int port;
192 struct sockaddr_in sockaddr;
f450004a 193 socklen_t tmp;
c906108c 194 int tmp_desc;
2d717e4f 195 char *port_end;
c906108c 196
2d717e4f
DJ
197 port = strtoul (port_str + 1, &port_end, 10);
198 if (port_str[1] == '\0' || *port_end != '\0')
199 fatal ("Bad port argument: %s", name);
c906108c 200
b80864fb
DJ
201#ifdef USE_WIN32API
202 if (!winsock_initialized)
203 {
204 WSADATA wsad;
205
206 WSAStartup (MAKEWORD (1, 0), &wsad);
207 winsock_initialized = 1;
208 }
209#endif
210
211 tmp_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
c906108c
SS
212 if (tmp_desc < 0)
213 perror_with_name ("Can't open socket");
214
215 /* Allow rapid reuse of this port. */
216 tmp = 1;
c5aa993b
JM
217 setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
218 sizeof (tmp));
c906108c
SS
219
220 sockaddr.sin_family = PF_INET;
c5aa993b 221 sockaddr.sin_port = htons (port);
c906108c
SS
222 sockaddr.sin_addr.s_addr = INADDR_ANY;
223
c5aa993b 224 if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
c906108c
SS
225 || listen (tmp_desc, 1))
226 perror_with_name ("Can't bind address");
227
6f8486da
DJ
228 /* If port is zero, a random port will be selected, and the
229 fprintf below needs to know what port was selected. */
230 if (port == 0)
231 {
232 socklen_t len = sizeof (sockaddr);
233 if (getsockname (tmp_desc, (struct sockaddr *) &sockaddr, &len) < 0
234 || len < sizeof (sockaddr))
235 perror_with_name ("Can't determine port");
236 port = ntohs (sockaddr.sin_port);
237 }
238
6910d122 239 fprintf (stderr, "Listening on port %d\n", port);
b80864fb 240 fflush (stderr);
6910d122 241
c906108c 242 tmp = sizeof (sockaddr);
c5aa993b 243 remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
c906108c
SS
244 if (remote_desc == -1)
245 perror_with_name ("Accept failed");
246
c906108c
SS
247 /* Enable TCP keep alive process. */
248 tmp = 1;
aa0403d9
PA
249 setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
250 (char *) &tmp, sizeof (tmp));
c906108c
SS
251
252 /* Tell TCP not to delay small packets. This greatly speeds up
1b3f6016 253 interactive response. */
c906108c 254 tmp = 1;
373fe97f 255 setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
c5aa993b 256 (char *) &tmp, sizeof (tmp));
c906108c 257
b80864fb
DJ
258
259#ifndef USE_WIN32API
c906108c
SS
260 close (tmp_desc); /* No longer need this */
261
c5aa993b
JM
262 signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
263 exits when the remote side dies. */
b80864fb
DJ
264#else
265 closesocket (tmp_desc); /* No longer need this */
266#endif
e641a1ca
ML
267
268 /* Convert IP address to string. */
1b3f6016
PA
269 fprintf (stderr, "Remote debugging from host %s\n",
270 inet_ntoa (sockaddr.sin_addr));
a6f3e723
SL
271
272 transport_is_reliable = 1;
c906108c
SS
273 }
274
275#if defined(F_SETFL) && defined (FASYNC)
276 save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
277 fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
cf30a8e1
C
278#if defined (F_SETOWN)
279 fcntl (remote_desc, F_SETOWN, getpid ());
94dfea5d 280#endif
cf30a8e1 281#endif
bd99dc85
PA
282
283 /* Register the event loop handler. */
284 add_file_handler (remote_desc, handle_serial_event, NULL);
c906108c
SS
285}
286
287void
fba45db2 288remote_close (void)
c906108c 289{
bd99dc85
PA
290 delete_file_handler (remote_desc);
291
b80864fb
DJ
292#ifdef USE_WIN32API
293 closesocket (remote_desc);
294#else
c906108c 295 close (remote_desc);
b80864fb 296#endif
c906108c
SS
297}
298
299/* Convert hex digit A to a number. */
300
301static int
fba45db2 302fromhex (int a)
c906108c
SS
303{
304 if (a >= '0' && a <= '9')
305 return a - '0';
306 else if (a >= 'a' && a <= 'f')
307 return a - 'a' + 10;
308 else
309 error ("Reply contains invalid hex digit");
0a30fbc4 310 return 0;
c906108c
SS
311}
312
95954743
PA
313static const char hexchars[] = "0123456789abcdef";
314
315static int
316ishex (int ch, int *val)
317{
318 if ((ch >= 'a') && (ch <= 'f'))
319 {
320 *val = ch - 'a' + 10;
321 return 1;
322 }
323 if ((ch >= 'A') && (ch <= 'F'))
324 {
325 *val = ch - 'A' + 10;
326 return 1;
327 }
328 if ((ch >= '0') && (ch <= '9'))
329 {
330 *val = ch - '0';
331 return 1;
332 }
333 return 0;
334}
335
ce3a066d
DJ
336int
337unhexify (char *bin, const char *hex, int count)
338{
339 int i;
340
341 for (i = 0; i < count; i++)
342 {
343 if (hex[0] == 0 || hex[1] == 0)
1b3f6016
PA
344 {
345 /* Hex string is short, or of uneven length.
346 Return the count that has been converted so far. */
347 return i;
348 }
ce3a066d
DJ
349 *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
350 hex += 2;
351 }
352 return i;
353}
354
dae5f5cf 355void
2f2893d9
DJ
356decode_address (CORE_ADDR *addrp, const char *start, int len)
357{
358 CORE_ADDR addr;
359 char ch;
360 int i;
361
362 addr = 0;
363 for (i = 0; i < len; i++)
364 {
365 ch = start[i];
366 addr = addr << 4;
367 addr = addr | (fromhex (ch) & 0x0f);
368 }
369 *addrp = addr;
370}
371
89be2091
DJ
372const char *
373decode_address_to_semicolon (CORE_ADDR *addrp, const char *start)
374{
375 const char *end;
376
377 end = start;
378 while (*end != '\0' && *end != ';')
379 end++;
380
381 decode_address (addrp, start, end - start);
382
383 if (*end == ';')
384 end++;
385 return end;
386}
387
c906108c
SS
388/* Convert number NIB to a hex digit. */
389
390static int
fba45db2 391tohex (int nib)
c906108c
SS
392{
393 if (nib < 10)
394 return '0' + nib;
395 else
396 return 'a' + nib - 10;
397}
398
ce3a066d
DJ
399int
400hexify (char *hex, const char *bin, int count)
401{
402 int i;
403
404 /* May use a length, or a nul-terminated string as input. */
405 if (count == 0)
406 count = strlen (bin);
407
408 for (i = 0; i < count; i++)
409 {
410 *hex++ = tohex ((*bin >> 4) & 0xf);
411 *hex++ = tohex (*bin++ & 0xf);
412 }
413 *hex = 0;
414 return i;
415}
416
01f9e8fa
DJ
417/* Convert BUFFER, binary data at least LEN bytes long, into escaped
418 binary data in OUT_BUF. Set *OUT_LEN to the length of the data
419 encoded in OUT_BUF, and return the number of bytes in OUT_BUF
420 (which may be more than *OUT_LEN due to escape characters). The
421 total number of bytes in the output buffer will be at most
422 OUT_MAXLEN. */
423
424int
425remote_escape_output (const gdb_byte *buffer, int len,
426 gdb_byte *out_buf, int *out_len,
427 int out_maxlen)
428{
429 int input_index, output_index;
430
431 output_index = 0;
432 for (input_index = 0; input_index < len; input_index++)
433 {
434 gdb_byte b = buffer[input_index];
435
436 if (b == '$' || b == '#' || b == '}' || b == '*')
437 {
438 /* These must be escaped. */
439 if (output_index + 2 > out_maxlen)
440 break;
441 out_buf[output_index++] = '}';
442 out_buf[output_index++] = b ^ 0x20;
443 }
444 else
445 {
446 if (output_index + 1 > out_maxlen)
447 break;
448 out_buf[output_index++] = b;
449 }
450 }
451
452 *out_len = input_index;
453 return output_index;
454}
455
456/* Convert BUFFER, escaped data LEN bytes long, into binary data
457 in OUT_BUF. Return the number of bytes written to OUT_BUF.
458 Raise an error if the total number of bytes exceeds OUT_MAXLEN.
459
460 This function reverses remote_escape_output. It allows more
461 escaped characters than that function does, in particular because
462 '*' must be escaped to avoid the run-length encoding processing
463 in reading packets. */
464
465static int
466remote_unescape_input (const gdb_byte *buffer, int len,
467 gdb_byte *out_buf, int out_maxlen)
468{
469 int input_index, output_index;
470 int escaped;
471
472 output_index = 0;
473 escaped = 0;
474 for (input_index = 0; input_index < len; input_index++)
475 {
476 gdb_byte b = buffer[input_index];
477
478 if (output_index + 1 > out_maxlen)
479 error ("Received too much data from the target.");
480
481 if (escaped)
482 {
483 out_buf[output_index++] = b ^ 0x20;
484 escaped = 0;
485 }
486 else if (b == '}')
487 escaped = 1;
488 else
489 out_buf[output_index++] = b;
490 }
491
492 if (escaped)
493 error ("Unmatched escape character in target response.");
494
495 return output_index;
496}
497
5ffff7c1
DJ
498/* Look for a sequence of characters which can be run-length encoded.
499 If there are any, update *CSUM and *P. Otherwise, output the
500 single character. Return the number of characters consumed. */
501
502static int
503try_rle (char *buf, int remaining, unsigned char *csum, char **p)
504{
505 int n;
506
507 /* Always output the character. */
508 *csum += buf[0];
509 *(*p)++ = buf[0];
510
511 /* Don't go past '~'. */
512 if (remaining > 97)
513 remaining = 97;
514
515 for (n = 1; n < remaining; n++)
516 if (buf[n] != buf[0])
517 break;
518
519 /* N is the index of the first character not the same as buf[0].
520 buf[0] is counted twice, so by decrementing N, we get the number
521 of characters the RLE sequence will replace. */
522 n--;
523
524 if (n < 3)
525 return 1;
526
527 /* Skip the frame characters. The manual says to skip '+' and '-'
528 also, but there's no reason to. Unfortunately these two unusable
529 characters double the encoded length of a four byte zero
530 value. */
531 while (n + 29 == '$' || n + 29 == '#')
532 n--;
533
534 *csum += '*';
535 *(*p)++ = '*';
536 *csum += n + 29;
537 *(*p)++ = n + 29;
538
539 return n + 1;
540}
541
95954743
PA
542char *
543unpack_varlen_hex (char *buff, /* packet to parse */
544 ULONGEST *result)
545{
546 int nibble;
547 ULONGEST retval = 0;
548
549 while (ishex (*buff, &nibble))
550 {
551 buff++;
552 retval = retval << 4;
553 retval |= nibble & 0x0f;
554 }
555 *result = retval;
556 return buff;
557}
558
559/* Write a PTID to BUF. Returns BUF+CHARACTERS_WRITTEN. */
560
561char *
562write_ptid (char *buf, ptid_t ptid)
563{
564 int pid, tid;
565
566 if (multi_process)
567 {
568 pid = ptid_get_pid (ptid);
569 if (pid < 0)
570 buf += sprintf (buf, "p-%x.", -pid);
571 else
572 buf += sprintf (buf, "p%x.", pid);
573 }
574 tid = ptid_get_lwp (ptid);
575 if (tid < 0)
576 buf += sprintf (buf, "-%x", -tid);
577 else
578 buf += sprintf (buf, "%x", tid);
579
580 return buf;
581}
582
583ULONGEST
584hex_or_minus_one (char *buf, char **obuf)
585{
586 ULONGEST ret;
587
588 if (strncmp (buf, "-1", 2) == 0)
589 {
590 ret = (ULONGEST) -1;
591 buf += 2;
592 }
593 else
594 buf = unpack_varlen_hex (buf, &ret);
595
596 if (obuf)
597 *obuf = buf;
598
599 return ret;
600}
601
602/* Extract a PTID from BUF. If non-null, OBUF is set to the to one
603 passed the last parsed char. Returns null_ptid on error. */
604ptid_t
605read_ptid (char *buf, char **obuf)
606{
607 char *p = buf;
608 char *pp;
609 ULONGEST pid = 0, tid = 0;
610
611 if (*p == 'p')
612 {
613 /* Multi-process ptid. */
614 pp = unpack_varlen_hex (p + 1, &pid);
615 if (*pp != '.')
616 error ("invalid remote ptid: %s\n", p);
617
618 p = pp + 1;
619
620 tid = hex_or_minus_one (p, &pp);
621
622 if (obuf)
623 *obuf = pp;
624 return ptid_build (pid, tid, 0);
625 }
626
627 /* No multi-process. Just a tid. */
628 tid = hex_or_minus_one (p, &pp);
629
630 /* Since the stub is not sending a process id, then default to
631 what's in the current inferior. */
632 pid = ptid_get_pid (((struct inferior_list_entry *) current_inferior)->id);
633
634 if (obuf)
635 *obuf = pp;
636 return ptid_build (pid, tid, 0);
637}
638
c906108c 639/* Send a packet to the remote machine, with error checking.
01f9e8fa
DJ
640 The data of the packet is in BUF, and the length of the
641 packet is in CNT. Returns >= 0 on success, -1 otherwise. */
c906108c 642
bd99dc85
PA
643static int
644putpkt_binary_1 (char *buf, int cnt, int is_notif)
c906108c
SS
645{
646 int i;
647 unsigned char csum = 0;
0a30fbc4 648 char *buf2;
c906108c 649 char buf3[1];
c906108c
SS
650 char *p;
651
bca929d3 652 buf2 = xmalloc (PBUFSIZ);
0a30fbc4 653
c906108c
SS
654 /* Copy the packet into buffer BUF2, encapsulating it
655 and giving it a checksum. */
656
657 p = buf2;
bd99dc85
PA
658 if (is_notif)
659 *p++ = '%';
660 else
661 *p++ = '$';
c906108c 662
5ffff7c1
DJ
663 for (i = 0; i < cnt;)
664 i += try_rle (buf + i, cnt - i, &csum, &p);
665
c906108c
SS
666 *p++ = '#';
667 *p++ = tohex ((csum >> 4) & 0xf);
668 *p++ = tohex (csum & 0xf);
669
670 *p = '\0';
671
672 /* Send it over and over until we get a positive ack. */
673
674 do
675 {
676 int cc;
677
0f48aa01 678 if (write (remote_desc, buf2, p - buf2) != p - buf2)
c906108c
SS
679 {
680 perror ("putpkt(write)");
f88c79e6 681 free (buf2);
c906108c
SS
682 return -1;
683 }
684
bd99dc85 685 if (noack_mode || is_notif)
a6f3e723
SL
686 {
687 /* Don't expect an ack then. */
688 if (remote_debug)
689 {
bd99dc85
PA
690 if (is_notif)
691 fprintf (stderr, "putpkt (\"%s\"); [notif]\n", buf2);
692 else
693 fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2);
a6f3e723
SL
694 fflush (stderr);
695 }
696 break;
697 }
698
c906108c 699 if (remote_debug)
0d62e5e8
DJ
700 {
701 fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
702 fflush (stderr);
703 }
0f48aa01 704 cc = read (remote_desc, buf3, 1);
c906108c 705 if (remote_debug)
0d62e5e8
DJ
706 {
707 fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
708 fflush (stderr);
709 }
710
c906108c
SS
711 if (cc <= 0)
712 {
713 if (cc == 0)
714 fprintf (stderr, "putpkt(read): Got EOF\n");
715 else
716 perror ("putpkt(read)");
717
0a30fbc4 718 free (buf2);
c906108c
SS
719 return -1;
720 }
0d62e5e8
DJ
721
722 /* Check for an input interrupt while we're here. */
2d717e4f 723 if (buf3[0] == '\003' && current_inferior != NULL)
ef57601b 724 (*the_target->request_interrupt) ();
c906108c
SS
725 }
726 while (buf3[0] != '+');
727
0a30fbc4 728 free (buf2);
c906108c
SS
729 return 1; /* Success! */
730}
731
bd99dc85
PA
732int
733putpkt_binary (char *buf, int cnt)
734{
735 return putpkt_binary_1 (buf, cnt, 0);
736}
737
01f9e8fa
DJ
738/* Send a packet to the remote machine, with error checking. The data
739 of the packet is in BUF, and the packet should be a NUL-terminated
740 string. Returns >= 0 on success, -1 otherwise. */
741
742int
743putpkt (char *buf)
744{
745 return putpkt_binary (buf, strlen (buf));
746}
747
bd99dc85
PA
748int
749putpkt_notif (char *buf)
750{
751 return putpkt_binary_1 (buf, strlen (buf), 1);
752}
753
c906108c
SS
754/* Come here when we get an input interrupt from the remote side. This
755 interrupt should only be active while we are waiting for the child to do
756 something. About the only thing that should come through is a ^C, which
ef57601b 757 will cause us to request child interruption. */
c906108c
SS
758
759static void
0a30fbc4 760input_interrupt (int unused)
c906108c 761{
cf30a8e1
C
762 fd_set readset;
763 struct timeval immediate = { 0, 0 };
c906108c 764
cf30a8e1
C
765 /* Protect against spurious interrupts. This has been observed to
766 be a problem under NetBSD 1.4 and 1.5. */
c906108c 767
cf30a8e1
C
768 FD_ZERO (&readset);
769 FD_SET (remote_desc, &readset);
770 if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
c906108c 771 {
cf30a8e1 772 int cc;
fd500816 773 char c = 0;
7390519e 774
0f48aa01 775 cc = read (remote_desc, &c, 1);
c906108c 776
2d717e4f 777 if (cc != 1 || c != '\003' || current_inferior == NULL)
cf30a8e1 778 {
fd500816
DJ
779 fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
780 cc, c, c);
cf30a8e1
C
781 return;
782 }
7390519e 783
ef57601b 784 (*the_target->request_interrupt) ();
cf30a8e1 785 }
c906108c 786}
7390519e
PA
787
788/* Check if the remote side sent us an interrupt request (^C). */
789void
790check_remote_input_interrupt_request (void)
791{
792 /* This function may be called before establishing communications,
793 therefore we need to validate the remote descriptor. */
794
795 if (remote_desc == INVALID_DESCRIPTOR)
796 return;
797
798 input_interrupt (0);
799}
b80864fb
DJ
800
801/* Asynchronous I/O support. SIGIO must be enabled when waiting, in order to
802 accept Control-C from the client, and must be disabled when talking to
803 the client. */
c906108c 804
a20d5e98 805static void
62ea82f5
DJ
806unblock_async_io (void)
807{
b80864fb 808#ifndef USE_WIN32API
62ea82f5 809 sigset_t sigio_set;
a20d5e98 810
62ea82f5
DJ
811 sigemptyset (&sigio_set);
812 sigaddset (&sigio_set, SIGIO);
813 sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);
b80864fb 814#endif
62ea82f5
DJ
815}
816
fd500816
DJ
817/* Current state of asynchronous I/O. */
818static int async_io_enabled;
819
820/* Enable asynchronous I/O. */
c906108c 821void
fba45db2 822enable_async_io (void)
c906108c 823{
fd500816
DJ
824 if (async_io_enabled)
825 return;
826
b80864fb 827#ifndef USE_WIN32API
c906108c 828 signal (SIGIO, input_interrupt);
b80864fb 829#endif
fd500816 830 async_io_enabled = 1;
c906108c
SS
831}
832
fd500816 833/* Disable asynchronous I/O. */
c906108c 834void
fba45db2 835disable_async_io (void)
c906108c 836{
fd500816
DJ
837 if (!async_io_enabled)
838 return;
839
b80864fb 840#ifndef USE_WIN32API
c906108c 841 signal (SIGIO, SIG_IGN);
b80864fb 842#endif
fd500816 843 async_io_enabled = 0;
c906108c
SS
844}
845
a20d5e98
DJ
846void
847initialize_async_io (void)
848{
849 /* Make sure that async I/O starts disabled. */
850 async_io_enabled = 1;
851 disable_async_io ();
852
853 /* Make sure the signal is unblocked. */
854 unblock_async_io ();
855}
856
c906108c
SS
857/* Returns next char from remote GDB. -1 if error. */
858
859static int
fba45db2 860readchar (void)
c906108c 861{
01f9e8fa 862 static unsigned char buf[BUFSIZ];
c906108c 863 static int bufcnt = 0;
01f9e8fa 864 static unsigned char *bufp;
c906108c
SS
865
866 if (bufcnt-- > 0)
01f9e8fa 867 return *bufp++;
c906108c 868
0f48aa01 869 bufcnt = read (remote_desc, buf, sizeof (buf));
c906108c
SS
870
871 if (bufcnt <= 0)
872 {
873 if (bufcnt == 0)
874 fprintf (stderr, "readchar: Got EOF\n");
875 else
876 perror ("readchar");
877
878 return -1;
879 }
880
881 bufp = buf;
882 bufcnt--;
b79d787e 883 return *bufp++;
c906108c
SS
884}
885
886/* Read a packet from the remote machine, with error checking,
887 and store it in BUF. Returns length of packet, or negative if error. */
888
889int
fba45db2 890getpkt (char *buf)
c906108c
SS
891{
892 char *bp;
893 unsigned char csum, c1, c2;
894 int c;
895
896 while (1)
897 {
898 csum = 0;
899
900 while (1)
901 {
902 c = readchar ();
903 if (c == '$')
904 break;
905 if (remote_debug)
0d62e5e8
DJ
906 {
907 fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
908 fflush (stderr);
909 }
910
c906108c
SS
911 if (c < 0)
912 return -1;
913 }
914
915 bp = buf;
916 while (1)
917 {
918 c = readchar ();
919 if (c < 0)
920 return -1;
921 if (c == '#')
922 break;
923 *bp++ = c;
924 csum += c;
925 }
926 *bp = 0;
927
928 c1 = fromhex (readchar ());
929 c2 = fromhex (readchar ());
c5aa993b 930
c906108c
SS
931 if (csum == (c1 << 4) + c2)
932 break;
933
a6f3e723
SL
934 if (noack_mode)
935 {
936 fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s [no-ack-mode, Bad medium?]\n",
937 (c1 << 4) + c2, csum, buf);
938 /* Not much we can do, GDB wasn't expecting an ack/nac. */
939 break;
940 }
941
c906108c
SS
942 fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
943 (c1 << 4) + c2, csum, buf);
0f48aa01 944 write (remote_desc, "-", 1);
c906108c
SS
945 }
946
a6f3e723 947 if (!noack_mode)
0d62e5e8 948 {
a6f3e723
SL
949 if (remote_debug)
950 {
951 fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf);
952 fflush (stderr);
953 }
c906108c 954
a6f3e723 955 write (remote_desc, "+", 1);
c906108c 956
a6f3e723
SL
957 if (remote_debug)
958 {
959 fprintf (stderr, "[sent ack]\n");
960 fflush (stderr);
961 }
0d62e5e8 962 }
86b1f9c5
PM
963 else
964 {
965 if (remote_debug)
966 {
967 fprintf (stderr, "getpkt (\"%s\"); [no ack sent] \n", buf);
968 fflush (stderr);
969 }
970 }
0d62e5e8 971
c906108c
SS
972 return bp - buf;
973}
974
975void
fba45db2 976write_ok (char *buf)
c906108c
SS
977{
978 buf[0] = 'O';
979 buf[1] = 'K';
980 buf[2] = '\0';
981}
982
983void
fba45db2 984write_enn (char *buf)
c906108c 985{
c89dc5d4 986 /* Some day, we should define the meanings of the error codes... */
c906108c 987 buf[0] = 'E';
c89dc5d4
DJ
988 buf[1] = '0';
989 buf[2] = '1';
c906108c
SS
990 buf[3] = '\0';
991}
992
993void
f450004a 994convert_int_to_ascii (unsigned char *from, char *to, int n)
c906108c
SS
995{
996 int nib;
f450004a 997 int ch;
c906108c
SS
998 while (n--)
999 {
1000 ch = *from++;
1001 nib = ((ch & 0xf0) >> 4) & 0x0f;
1002 *to++ = tohex (nib);
1003 nib = ch & 0x0f;
1004 *to++ = tohex (nib);
1005 }
1006 *to++ = 0;
1007}
1008
1009
1010void
f450004a 1011convert_ascii_to_int (char *from, unsigned char *to, int n)
c906108c
SS
1012{
1013 int nib1, nib2;
1014 while (n--)
1015 {
1016 nib1 = fromhex (*from++);
1017 nib2 = fromhex (*from++);
1018 *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
1019 }
1020}
1021
1022static char *
fba45db2 1023outreg (int regno, char *buf)
c906108c 1024{
5c44784c
JM
1025 if ((regno >> 12) != 0)
1026 *buf++ = tohex ((regno >> 12) & 0xf);
1027 if ((regno >> 8) != 0)
1028 *buf++ = tohex ((regno >> 8) & 0xf);
1029 *buf++ = tohex ((regno >> 4) & 0xf);
c906108c
SS
1030 *buf++ = tohex (regno & 0xf);
1031 *buf++ = ':';
0d62e5e8
DJ
1032 collect_register_as_string (regno, buf);
1033 buf += 2 * register_size (regno);
c906108c
SS
1034 *buf++ = ';';
1035
1036 return buf;
1037}
1038
0d62e5e8
DJ
1039void
1040new_thread_notify (int id)
1041{
1042 char own_buf[256];
1043
1044 /* The `n' response is not yet part of the remote protocol. Do nothing. */
1045 if (1)
1046 return;
1047
1048 if (server_waiting == 0)
1049 return;
1050
1051 sprintf (own_buf, "n%x", id);
1052 disable_async_io ();
1053 putpkt (own_buf);
1054 enable_async_io ();
1055}
1056
1057void
1058dead_thread_notify (int id)
1059{
1060 char own_buf[256];
1061
1062 /* The `x' response is not yet part of the remote protocol. Do nothing. */
1063 if (1)
1064 return;
1065
1066 sprintf (own_buf, "x%x", id);
1067 disable_async_io ();
1068 putpkt (own_buf);
1069 enable_async_io ();
1070}
1071
c906108c 1072void
95954743 1073prepare_resume_reply (char *buf, ptid_t ptid,
5b1c542e 1074 struct target_waitstatus *status)
c906108c 1075{
5b1c542e 1076 if (debug_threads)
95954743
PA
1077 fprintf (stderr, "Writing resume reply for %s:%d\n\n",
1078 target_pid_to_str (ptid), status->kind);
c906108c 1079
5b1c542e 1080 switch (status->kind)
c906108c 1081 {
5b1c542e
PA
1082 case TARGET_WAITKIND_STOPPED:
1083 {
1084 struct thread_info *saved_inferior;
1085 const char **regp;
e013ee27 1086
5b1c542e
PA
1087 sprintf (buf, "T%02x", status->value.sig);
1088 buf += strlen (buf);
e013ee27 1089
5b1c542e 1090 regp = gdbserver_expedite_regs;
e013ee27 1091
5b1c542e 1092 saved_inferior = current_inferior;
e013ee27 1093
95954743 1094 current_inferior = find_thread_pid (ptid);
e013ee27 1095
5b1c542e
PA
1096 if (the_target->stopped_by_watchpoint != NULL
1097 && (*the_target->stopped_by_watchpoint) ())
1098 {
1099 CORE_ADDR addr;
1100 int i;
c906108c 1101
5b1c542e
PA
1102 strncpy (buf, "watch:", 6);
1103 buf += 6;
0d62e5e8 1104
5b1c542e 1105 addr = (*the_target->stopped_data_address) ();
255e7678 1106
5b1c542e
PA
1107 /* Convert each byte of the address into two hexadecimal
1108 chars. Note that we take sizeof (void *) instead of
1109 sizeof (addr); this is to avoid sending a 64-bit
1110 address to a 32-bit GDB. */
1111 for (i = sizeof (void *) * 2; i > 0; i--)
1112 *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
1113 *buf++ = ';';
1114 }
1115
1116 while (*regp)
1117 {
1118 buf = outreg (find_regno (*regp), buf);
1119 regp ++;
1120 }
1121
1122 /* Formerly, if the debugger had not used any thread features
1123 we would not burden it with a thread status response. This
1124 was for the benefit of GDB 4.13 and older. However, in
1125 recent GDB versions the check (``if (cont_thread != 0)'')
1126 does not have the desired effect because of sillyness in
1127 the way that the remote protocol handles specifying a
1128 thread. Since thread support relies on qSymbol support
1129 anyway, assume GDB can handle threads. */
1130
1131 if (using_threads && !disable_packet_Tthread)
1132 {
1133 /* This if (1) ought to be unnecessary. But remote_wait
1134 in GDB will claim this event belongs to inferior_ptid
1135 if we do not specify a thread, and there's no way for
1136 gdbserver to know what inferior_ptid is. */
95954743 1137 if (1 || !ptid_equal (general_thread, ptid))
5b1c542e 1138 {
bd99dc85
PA
1139 /* In non-stop, don't change the general thread behind
1140 GDB's back. */
1141 if (!non_stop)
1142 general_thread = ptid;
95954743
PA
1143 sprintf (buf, "thread:");
1144 buf += strlen (buf);
1145 buf = write_ptid (buf, ptid);
1146 strcat (buf, ";");
5b1c542e
PA
1147 buf += strlen (buf);
1148 }
1149 }
1150
1151 if (dlls_changed)
1152 {
1153 strcpy (buf, "library:;");
1154 buf += strlen (buf);
1155 dlls_changed = 0;
1156 }
1157
1158 current_inferior = saved_inferior;
1159 }
1160 break;
1161 case TARGET_WAITKIND_EXITED:
95954743
PA
1162 if (multi_process)
1163 sprintf (buf, "W%x;process:%x",
1164 status->value.integer, ptid_get_pid (ptid));
1165 else
1166 sprintf (buf, "W%02x", status->value.integer);
5b1c542e
PA
1167 break;
1168 case TARGET_WAITKIND_SIGNALLED:
95954743
PA
1169 if (multi_process)
1170 sprintf (buf, "X%x;process:%x",
1171 status->value.sig, ptid_get_pid (ptid));
1172 else
1173 sprintf (buf, "X%02x", status->value.sig);
5b1c542e
PA
1174 break;
1175 default:
1176 error ("unhandled waitkind");
1177 break;
c906108c 1178 }
c906108c
SS
1179}
1180
1181void
fba45db2 1182decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
c906108c
SS
1183{
1184 int i = 0, j = 0;
1185 char ch;
1186 *mem_addr_ptr = *len_ptr = 0;
1187
1188 while ((ch = from[i++]) != ',')
1189 {
1190 *mem_addr_ptr = *mem_addr_ptr << 4;
1191 *mem_addr_ptr |= fromhex (ch) & 0x0f;
1192 }
1193
1194 for (j = 0; j < 4; j++)
1195 {
1196 if ((ch = from[i++]) == 0)
1197 break;
1198 *len_ptr = *len_ptr << 4;
1199 *len_ptr |= fromhex (ch) & 0x0f;
1200 }
1201}
1202
1203void
fba45db2 1204decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
f450004a 1205 unsigned char *to)
c906108c
SS
1206{
1207 int i = 0;
1208 char ch;
1209 *mem_addr_ptr = *len_ptr = 0;
1210
1211 while ((ch = from[i++]) != ',')
1212 {
1213 *mem_addr_ptr = *mem_addr_ptr << 4;
1214 *mem_addr_ptr |= fromhex (ch) & 0x0f;
1215 }
1216
1217 while ((ch = from[i++]) != ':')
1218 {
1219 *len_ptr = *len_ptr << 4;
1220 *len_ptr |= fromhex (ch) & 0x0f;
1221 }
1222
1223 convert_ascii_to_int (&from[i++], to, *len_ptr);
1224}
2f2893d9 1225
01f9e8fa
DJ
1226int
1227decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
1228 unsigned int *len_ptr, unsigned char *to)
1229{
1230 int i = 0;
1231 char ch;
1232 *mem_addr_ptr = *len_ptr = 0;
1233
1234 while ((ch = from[i++]) != ',')
1235 {
1236 *mem_addr_ptr = *mem_addr_ptr << 4;
1237 *mem_addr_ptr |= fromhex (ch) & 0x0f;
1238 }
1239
1240 while ((ch = from[i++]) != ':')
1241 {
1242 *len_ptr = *len_ptr << 4;
1243 *len_ptr |= fromhex (ch) & 0x0f;
1244 }
1245
1246 if (remote_unescape_input ((const gdb_byte *) &from[i], packet_len - i,
1247 to, *len_ptr) != *len_ptr)
1248 return -1;
1249
1250 return 0;
1251}
1252
0e7f50da
UW
1253/* Decode a qXfer write request. */
1254int
1255decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset,
1256 unsigned int *len, unsigned char *data)
1257{
1258 char ch;
1259
1260 /* Extract and NUL-terminate the annex. */
1261 *annex = buf;
1262 while (*buf && *buf != ':')
1263 buf++;
1264 if (*buf == '\0')
1265 return -1;
1266 *buf++ = 0;
1267
1268 /* Extract the offset. */
1269 *offset = 0;
1270 while ((ch = *buf++) != ':')
1271 {
1272 *offset = *offset << 4;
1273 *offset |= fromhex (ch) & 0x0f;
1274 }
1275
1276 /* Get encoded data. */
1277 packet_len -= buf - *annex;
1278 *len = remote_unescape_input ((const gdb_byte *) buf, packet_len,
1279 data, packet_len);
1280 return 0;
1281}
1282
08388c79
DE
1283/* Decode the parameters of a qSearch:memory packet. */
1284
1285int
1286decode_search_memory_packet (const char *buf, int packet_len,
1287 CORE_ADDR *start_addrp,
1288 CORE_ADDR *search_space_lenp,
1289 gdb_byte *pattern, unsigned int *pattern_lenp)
1290{
1291 const char *p = buf;
1292
1293 p = decode_address_to_semicolon (start_addrp, p);
1294 p = decode_address_to_semicolon (search_space_lenp, p);
1295 packet_len -= p - buf;
1296 *pattern_lenp = remote_unescape_input ((const gdb_byte *) p, packet_len,
1297 pattern, packet_len);
1298 return 0;
1299}
1300
95954743
PA
1301static void
1302free_sym_cache (struct sym_cache *sym)
1303{
1304 if (sym != NULL)
1305 {
1306 free (sym->name);
1307 free (sym);
1308 }
1309}
1310
1311void
1312clear_symbol_cache (struct sym_cache **symcache_p)
1313{
1314 struct sym_cache *sym, *next;
1315
1316 /* Check the cache first. */
1317 for (sym = *symcache_p; sym; sym = next)
1318 {
1319 next = sym->next;
1320 free_sym_cache (sym);
1321 }
1322
1323 *symcache_p = NULL;
1324}
1325
fd500816
DJ
1326/* Ask GDB for the address of NAME, and return it in ADDRP if found.
1327 Returns 1 if the symbol is found, 0 if it is not, -1 on error. */
1328
2f2893d9
DJ
1329int
1330look_up_one_symbol (const char *name, CORE_ADDR *addrp)
1331{
1332 char own_buf[266], *p, *q;
1333 int len;
fd500816 1334 struct sym_cache *sym;
95954743
PA
1335 struct process_info *proc;
1336
1337 proc = current_process ();
fd500816
DJ
1338
1339 /* Check the cache first. */
95954743 1340 for (sym = proc->symbol_cache; sym; sym = sym->next)
fd500816
DJ
1341 if (strcmp (name, sym->name) == 0)
1342 {
1343 *addrp = sym->addr;
1344 return 1;
1345 }
2f2893d9 1346
ea025f5f
DJ
1347 /* If we've passed the call to thread_db_look_up_symbols, then
1348 anything not in the cache must not exist; we're not interested
1349 in any libraries loaded after that point, only in symbols in
1350 libpthread.so. It might not be an appropriate time to look
1351 up a symbol, e.g. while we're trying to fetch registers. */
95954743 1352 if (proc->all_symbols_looked_up)
ea025f5f
DJ
1353 return 0;
1354
2f2893d9
DJ
1355 /* Send the request. */
1356 strcpy (own_buf, "qSymbol:");
1357 hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
1358 if (putpkt (own_buf) < 0)
1359 return -1;
1360
1361 /* FIXME: Eventually add buffer overflow checking (to getpkt?) */
1362 len = getpkt (own_buf);
1363 if (len < 0)
1364 return -1;
1365
2bbe3cc1
DJ
1366 /* We ought to handle pretty much any packet at this point while we
1367 wait for the qSymbol "response". That requires re-entering the
1368 main loop. For now, this is an adequate approximation; allow
1369 GDB to read from memory while it figures out the address of the
1370 symbol. */
1371 while (own_buf[0] == 'm')
1372 {
1373 CORE_ADDR mem_addr;
1374 unsigned char *mem_buf;
1375 unsigned int mem_len;
1376
1377 decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
bca929d3 1378 mem_buf = xmalloc (mem_len);
2bbe3cc1
DJ
1379 if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
1380 convert_int_to_ascii (mem_buf, own_buf, mem_len);
1381 else
1382 write_enn (own_buf);
1383 free (mem_buf);
1384 if (putpkt (own_buf) < 0)
1385 return -1;
1386 len = getpkt (own_buf);
1387 if (len < 0)
1388 return -1;
1389 }
1b3f6016 1390
2f2893d9
DJ
1391 if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
1392 {
2bbe3cc1 1393 warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf);
2f2893d9
DJ
1394 return -1;
1395 }
1396
1397 p = own_buf + strlen ("qSymbol:");
1398 q = p;
1399 while (*q && *q != ':')
1400 q++;
1401
1402 /* Make sure we found a value for the symbol. */
1403 if (p == q || *q == '\0')
1404 return 0;
1405
1406 decode_address (addrp, p, q - p);
fd500816
DJ
1407
1408 /* Save the symbol in our cache. */
bca929d3
DE
1409 sym = xmalloc (sizeof (*sym));
1410 sym->name = xstrdup (name);
fd500816 1411 sym->addr = *addrp;
95954743
PA
1412 sym->next = proc->symbol_cache;
1413 proc->symbol_cache = sym;
fd500816 1414
2f2893d9
DJ
1415 return 1;
1416}
c74d0ad8
DJ
1417
1418void
bce7165d 1419monitor_output (const char *msg)
c74d0ad8 1420{
bca929d3 1421 char *buf = xmalloc (strlen (msg) * 2 + 2);
c74d0ad8
DJ
1422
1423 buf[0] = 'O';
1424 hexify (buf + 1, msg, 0);
1425
1426 putpkt (buf);
1427 free (buf);
1428}
255e7678
DJ
1429
1430/* Return a malloc allocated string with special characters from TEXT
1431 replaced by entity references. */
1432
1433char *
1434xml_escape_text (const char *text)
1435{
1436 char *result;
1437 int i, special;
1438
1439 /* Compute the length of the result. */
1440 for (i = 0, special = 0; text[i] != '\0'; i++)
1441 switch (text[i])
1442 {
1443 case '\'':
1444 case '\"':
1445 special += 5;
1446 break;
1447 case '&':
1448 special += 4;
1449 break;
1450 case '<':
1451 case '>':
1452 special += 3;
1453 break;
1454 default:
1455 break;
1456 }
1457
1458 /* Expand the result. */
bca929d3 1459 result = xmalloc (i + special + 1);
255e7678
DJ
1460 for (i = 0, special = 0; text[i] != '\0'; i++)
1461 switch (text[i])
1462 {
1463 case '\'':
1464 strcpy (result + i + special, "&apos;");
1465 special += 5;
1466 break;
1467 case '\"':
1468 strcpy (result + i + special, "&quot;");
1469 special += 5;
1470 break;
1471 case '&':
1472 strcpy (result + i + special, "&amp;");
1473 special += 4;
1474 break;
1475 case '<':
1476 strcpy (result + i + special, "&lt;");
1477 special += 3;
1478 break;
1479 case '>':
1480 strcpy (result + i + special, "&gt;");
1481 special += 3;
1482 break;
1483 default:
1484 result[i + special] = text[i];
1485 break;
1486 }
1487 result[i + special] = '\0';
1488
1489 return result;
1490}
07e059b5
VP
1491
1492void
1493buffer_grow (struct buffer *buffer, const char *data, size_t size)
1494{
1495 char *new_buffer;
1496 size_t new_buffer_size;
1497
1498 if (size == 0)
1499 return;
1500
1501 new_buffer_size = buffer->buffer_size;
1502
1503 if (new_buffer_size == 0)
1504 new_buffer_size = 1;
1505
1506 while (buffer->used_size + size > new_buffer_size)
1507 new_buffer_size *= 2;
1508 new_buffer = realloc (buffer->buffer, new_buffer_size);
1509 if (!new_buffer)
1510 abort ();
1511 memcpy (new_buffer + buffer->used_size, data, size);
1512 buffer->buffer = new_buffer;
1513 buffer->buffer_size = new_buffer_size;
1514 buffer->used_size += size;
1515}
1516
1517void
1518buffer_free (struct buffer *buffer)
1519{
1520 if (!buffer)
1521 return;
1522
1523 free (buffer->buffer);
1524 buffer->buffer = NULL;
1525 buffer->buffer_size = 0;
1526 buffer->used_size = 0;
1527}
1528
1529void
1530buffer_init (struct buffer *buffer)
1531{
1532 memset (buffer, 0, sizeof (*buffer));
1533}
1534
1535char*
1536buffer_finish (struct buffer *buffer)
1537{
1538 char *ret = buffer->buffer;
1539 buffer->buffer = NULL;
1540 buffer->buffer_size = 0;
1541 buffer->used_size = 0;
1542 return ret;
1543}
1544
1545void
1546buffer_xml_printf (struct buffer *buffer, const char *format, ...)
1547{
1548 va_list ap;
1549 const char *f;
1550 const char *prev;
1551 int percent = 0;
1552
1553 va_start (ap, format);
1554
1555 prev = format;
1556 for (f = format; *f; f++)
1557 {
1558 if (percent)
1559 {
1b3f6016
PA
1560 switch (*f)
1561 {
1562 case 's':
1563 {
1564 char *p;
1565 char *a = va_arg (ap, char *);
1566 buffer_grow (buffer, prev, f - prev - 1);
1567 p = xml_escape_text (a);
1568 buffer_grow_str (buffer, p);
1569 free (p);
1570 prev = f + 1;
1571 }
1572 break;
1573 }
1574 percent = 0;
07e059b5
VP
1575 }
1576 else if (*f == '%')
1577 percent = 1;
1578 }
1579
1580 buffer_grow_str (buffer, prev);
1581 va_end (ap);
1582}
This page took 1.655935 seconds and 4 git commands to generate.