Pull in even more rdesktop source.
[rdpsrv] / util.c
1 /* -*- c-basic-offset: 8 -*-
2    rdesktop: A Remote Desktop Protocol client.
3    Entrypoint and utility functions
4    Copyright (C) Matthew Chapman 1999-2004
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <stdarg.h>             /* va_list va_start va_end */
22 #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */
23 #include <fcntl.h>              /* open */
24 #include <pwd.h>                /* getpwuid */
25 #include <termios.h>            /* tcgetattr tcsetattr */
26 #include <sys/stat.h>           /* stat */
27 #include <sys/time.h>           /* gettimeofday */
28 #include <sys/times.h>          /* times */
29 #include <errno.h>
30 #include <X11/Xlib.h>           /* Window */
31 #include "rdesktop.h"
32
33 #ifdef EGD_SOCKET
34 #include <sys/socket.h>         /* socket connect */
35 #include <sys/un.h>             /* sockaddr_un */
36 #endif
37
38 #include <openssl/md5.h>
39
40 #ifdef EGD_SOCKET
41 /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
42 static BOOL
43 generate_random_egd(uint8 * buf)
44 {
45         struct sockaddr_un addr;
46         BOOL ret = False;
47         int fd;
48
49         fd = socket(AF_UNIX, SOCK_STREAM, 0);
50         if (fd == -1)
51                 return False;
52
53         addr.sun_family = AF_UNIX;
54         memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
55         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
56                 goto err;
57
58         /* PRNGD and EGD use a simple communications protocol */
59         buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
60         buf[1] = 32;            /* Number of requested random bytes */
61         if (write(fd, buf, 2) != 2)
62                 goto err;
63
64         if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
65                 goto err;
66
67         if (read(fd, buf, 32) != 32)
68                 goto err;
69
70         ret = True;
71
72       err:
73         close(fd);
74         return ret;
75 }
76 #endif
77
78 /* malloc; exit if out of memory */
79 void *
80 xmalloc(int size)
81 {
82         void *mem = malloc(size);
83         if (mem == NULL)
84         {
85                 error("xmalloc %d\n", size);
86                 exit(1);
87         }
88         return mem;
89 }
90
91 /* realloc; exit if out of memory */
92 void *
93 xrealloc(void *oldmem, int size)
94 {
95         void *mem = realloc(oldmem, size);
96         if (mem == NULL)
97         {
98                 error("xrealloc %d\n", size);
99                 exit(1);
100         }
101         return mem;
102 }
103
104 /* free */
105 void
106 xfree(void *mem)
107 {
108         free(mem);
109 }
110
111 /* report an error */
112 void
113 error(char *format, ...)
114 {
115         va_list ap;
116
117         fprintf(stderr, "ERROR: ");
118
119         va_start(ap, format);
120         vfprintf(stderr, format, ap);
121         va_end(ap);
122 }
123
124 /* report a warning */
125 void
126 warning(char *format, ...)
127 {
128         va_list ap;
129
130         fprintf(stderr, "WARNING: ");
131
132         va_start(ap, format);
133         vfprintf(stderr, format, ap);
134         va_end(ap);
135 }
136
137 /* report an unimplemented protocol feature */
138 void
139 unimpl(char *format, ...)
140 {
141         va_list ap;
142
143         fprintf(stderr, "NOT IMPLEMENTED: ");
144
145         va_start(ap, format);
146         vfprintf(stderr, format, ap);
147         va_end(ap);
148 }
149
150 /* produce a hex dump */
151 void
152 hexdump(unsigned char *p, int len)
153 {
154         unsigned char *line = p;
155         int i, thisline, offset = 0;
156
157         while (offset < len)
158         {
159                 printf("%04x ", offset);
160                 thisline = len - offset;
161                 if (thisline > 16)
162                         thisline = 16;
163
164                 for (i = 0; i < thisline; i++)
165                         printf("%02x ", line[i]);
166
167                 for (; i < 16; i++)
168                         printf("   ");
169
170                 for (i = 0; i < thisline; i++)
171                         printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
172
173                 printf("\n");
174                 offset += thisline;
175                 line += thisline;
176         }
177 }
178