--- /dev/null
+/* -*- c-basic-offset: 8 -*-
+ rdesktop: A Remote Desktop Protocol client.
+ Entrypoint and utility functions
+ Copyright (C) Matthew Chapman 1999-2004
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdarg.h> /* va_list va_start va_end */
+#include <unistd.h> /* read close getuid getgid getpid getppid gethostname */
+#include <fcntl.h> /* open */
+#include <pwd.h> /* getpwuid */
+#include <termios.h> /* tcgetattr tcsetattr */
+#include <sys/stat.h> /* stat */
+#include <sys/time.h> /* gettimeofday */
+#include <sys/times.h> /* times */
+#include <errno.h>
+#include <X11/Xlib.h> /* Window */
+#include "rdesktop.h"
+
+#ifdef EGD_SOCKET
+#include <sys/socket.h> /* socket connect */
+#include <sys/un.h> /* sockaddr_un */
+#endif
+
+#include <openssl/md5.h>
+
+#ifdef EGD_SOCKET
+/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
+static BOOL
+generate_random_egd(uint8 * buf)
+{
+ struct sockaddr_un addr;
+ BOOL ret = False;
+ int fd;
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ return False;
+
+ addr.sun_family = AF_UNIX;
+ memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
+ if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+ goto err;
+
+ /* PRNGD and EGD use a simple communications protocol */
+ buf[0] = 1; /* Non-blocking (similar to /dev/urandom) */
+ buf[1] = 32; /* Number of requested random bytes */
+ if (write(fd, buf, 2) != 2)
+ goto err;
+
+ if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */
+ goto err;
+
+ if (read(fd, buf, 32) != 32)
+ goto err;
+
+ ret = True;
+
+ err:
+ close(fd);
+ return ret;
+}
+#endif
+
+/* malloc; exit if out of memory */
+void *
+xmalloc(int size)
+{
+ void *mem = malloc(size);
+ if (mem == NULL)
+ {
+ error("xmalloc %d\n", size);
+ exit(1);
+ }
+ return mem;
+}
+
+/* realloc; exit if out of memory */
+void *
+xrealloc(void *oldmem, int size)
+{
+ void *mem = realloc(oldmem, size);
+ if (mem == NULL)
+ {
+ error("xrealloc %d\n", size);
+ exit(1);
+ }
+ return mem;
+}
+
+/* free */
+void
+xfree(void *mem)
+{
+ free(mem);
+}
+
+/* report an error */
+void
+error(char *format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "ERROR: ");
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+/* report a warning */
+void
+warning(char *format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "WARNING: ");
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+/* report an unimplemented protocol feature */
+void
+unimpl(char *format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "NOT IMPLEMENTED: ");
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+/* produce a hex dump */
+void
+hexdump(unsigned char *p, int len)
+{
+ unsigned char *line = p;
+ int i, thisline, offset = 0;
+
+ while (offset < len)
+ {
+ printf("%04x ", offset);
+ thisline = len - offset;
+ if (thisline > 16)
+ thisline = 16;
+
+ for (i = 0; i < thisline; i++)
+ printf("%02x ", line[i]);
+
+ for (; i < 16; i++)
+ printf(" ");
+
+ for (i = 0; i < thisline; i++)
+ printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+
+ printf("\n");
+ offset += thisline;
+ line += thisline;
+ }
+}
+