diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/extra/dumpOSC.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/extra/dumpOSC.c | 1998 |
1 files changed, 999 insertions, 999 deletions
diff --git a/apps/plugins/pdbox/PDa/extra/dumpOSC.c b/apps/plugins/pdbox/PDa/extra/dumpOSC.c index 28b0d8223e..4e80de18a0 100644 --- a/apps/plugins/pdbox/PDa/extra/dumpOSC.c +++ b/apps/plugins/pdbox/PDa/extra/dumpOSC.c | |||
@@ -1,1000 +1,1000 @@ | |||
1 | /* | 1 | /* |
2 | Written by Matt Wright and Adrian Freed, The Center for New Music and | 2 | Written by Matt Wright and Adrian Freed, The Center for New Music and |
3 | Audio Technologies, University of California, Berkeley. Copyright (c) | 3 | Audio Technologies, University of California, Berkeley. Copyright (c) |
4 | 1992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of | 4 | 1992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of |
5 | California (Regents). | 5 | California (Regents). |
6 | 6 | ||
7 | Permission to use, copy, modify, distribute, and distribute modified versions | 7 | Permission to use, copy, modify, distribute, and distribute modified versions |
8 | of this software and its documentation without fee and without a signed | 8 | of this software and its documentation without fee and without a signed |
9 | licensing agreement, is hereby granted, provided that the above copyright | 9 | licensing agreement, is hereby granted, provided that the above copyright |
10 | notice, this paragraph and the following two paragraphs appear in all copies, | 10 | notice, this paragraph and the following two paragraphs appear in all copies, |
11 | modifications, and distributions. | 11 | modifications, and distributions. |
12 | 12 | ||
13 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | 13 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, |
14 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING | 14 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING |
15 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS | 15 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS |
16 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 16 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
17 | 17 | ||
18 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 18 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
20 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED | 20 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED |
21 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE | 21 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE |
22 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 22 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
23 | 23 | ||
24 | 24 | ||
25 | The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl | 25 | The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl |
26 | */ | 26 | */ |
27 | 27 | ||
28 | 28 | ||
29 | /* | 29 | /* |
30 | 30 | ||
31 | dumpOSC.c | 31 | dumpOSC.c |
32 | server that displays OpenSoundControl messages sent to it | 32 | server that displays OpenSoundControl messages sent to it |
33 | for debugging client udp and UNIX protocol | 33 | for debugging client udp and UNIX protocol |
34 | 34 | ||
35 | by Matt Wright, 6/3/97 | 35 | by Matt Wright, 6/3/97 |
36 | modified from dumpSC.c, by Matt Wright and Adrian Freed | 36 | modified from dumpSC.c, by Matt Wright and Adrian Freed |
37 | 37 | ||
38 | version 0.2: Added "-silent" option a.k.a. "-quiet" | 38 | version 0.2: Added "-silent" option a.k.a. "-quiet" |
39 | 39 | ||
40 | version 0.3: Incorporated patches from Nicola Bernardini to make | 40 | version 0.3: Incorporated patches from Nicola Bernardini to make |
41 | things Linux-friendly. Also added ntohl() in the right places | 41 | things Linux-friendly. Also added ntohl() in the right places |
42 | to support little-endian architectures. | 42 | to support little-endian architectures. |
43 | 43 | ||
44 | 44 | ||
45 | 45 | ||
46 | compile: | 46 | compile: |
47 | cc -o dumpOSC dumpOSC.c | 47 | cc -o dumpOSC dumpOSC.c |
48 | 48 | ||
49 | to-do: | 49 | to-do: |
50 | 50 | ||
51 | More robustness in saying exactly what's wrong with ill-formed | 51 | More robustness in saying exactly what's wrong with ill-formed |
52 | messages. (If they don't make sense, show exactly what was | 52 | messages. (If they don't make sense, show exactly what was |
53 | received.) | 53 | received.) |
54 | 54 | ||
55 | Time-based features: print time-received for each packet | 55 | Time-based features: print time-received for each packet |
56 | 56 | ||
57 | Clean up to separate OSC parsing code from socket/select stuff | 57 | Clean up to separate OSC parsing code from socket/select stuff |
58 | 58 | ||
59 | pd: branched from http://www.cnmat.berkeley.edu/OpenSoundControl/src/dumpOSC/dumpOSC.c | 59 | pd: branched from http://www.cnmat.berkeley.edu/OpenSoundControl/src/dumpOSC/dumpOSC.c |
60 | ------------- | 60 | ------------- |
61 | -- added pd functions | 61 | -- added pd functions |
62 | -- socket is made differently than original via pd mechanisms | 62 | -- socket is made differently than original via pd mechanisms |
63 | -- tweaks for Win32 www.zeggz.com/raf 13-April-2002 | 63 | -- tweaks for Win32 www.zeggz.com/raf 13-April-2002 |
64 | -- the OSX changes from cnmat didnt make it here yet but this compiles | 64 | -- the OSX changes from cnmat didnt make it here yet but this compiles |
65 | on OSX anyway. | 65 | on OSX anyway. |
66 | 66 | ||
67 | */ | 67 | */ |
68 | 68 | ||
69 | #if HAVE_CONFIG_H | 69 | #if HAVE_CONFIG_H |
70 | #include <config.h> | 70 | #include <config.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #include "m_pd.h" | 73 | #include "m_pd.h" |
74 | //#include "m_imp.h" | 74 | //#include "m_imp.h" |
75 | #include "s_stuff.h" | 75 | #include "s_stuff.h" |
76 | 76 | ||
77 | /* declarations */ | 77 | /* declarations */ |
78 | 78 | ||
79 | // typedef void (*t_fdpollfn)(void *ptr, int fd); | 79 | // typedef void (*t_fdpollfn)(void *ptr, int fd); |
80 | void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr); | 80 | void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr); |
81 | 81 | ||
82 | 82 | ||
83 | #if defined(__sgi) || defined(__linux) || defined(WIN32) || defined(__APPLE__) | 83 | #if defined(__sgi) || defined(__linux) || defined(WIN32) || defined(__APPLE__) |
84 | 84 | ||
85 | #ifdef WIN32 | 85 | #ifdef WIN32 |
86 | #include "OSC-common.h" | 86 | #include "OSC-common.h" |
87 | #include <winsock2.h> | 87 | #include <winsock2.h> |
88 | #include <string.h> | 88 | #include <string.h> |
89 | #include <stdlib.h> | 89 | #include <stdlib.h> |
90 | #include <fcntl.h> | 90 | #include <fcntl.h> |
91 | #include <sys/types.h> | 91 | #include <sys/types.h> |
92 | #include <sys/stat.h> | 92 | #include <sys/stat.h> |
93 | #include <ctype.h> | 93 | #include <ctype.h> |
94 | #include <signal.h> | 94 | #include <signal.h> |
95 | #else | 95 | #else |
96 | #include <stdio.h> | 96 | #include <stdio.h> |
97 | #include <string.h> | 97 | #include <string.h> |
98 | #include <stdlib.h> | 98 | #include <stdlib.h> |
99 | #include <unistd.h> | 99 | #include <unistd.h> |
100 | #include <fcntl.h> | 100 | #include <fcntl.h> |
101 | #include <sys/types.h> | 101 | #include <sys/types.h> |
102 | #include <sys/stat.h> | 102 | #include <sys/stat.h> |
103 | #include <netinet/in.h> | 103 | #include <netinet/in.h> |
104 | #include <rpc/rpc.h> | 104 | #include <rpc/rpc.h> |
105 | #include <sys/socket.h> | 105 | #include <sys/socket.h> |
106 | #include <sys/un.h> | 106 | #include <sys/un.h> |
107 | #include <sys/times.h> | 107 | #include <sys/times.h> |
108 | #include <sys/param.h> | 108 | #include <sys/param.h> |
109 | #include <sys/time.h> | 109 | #include <sys/time.h> |
110 | #include <sys/ioctl.h> | 110 | #include <sys/ioctl.h> |
111 | #include <ctype.h> | 111 | #include <ctype.h> |
112 | #include <arpa/inet.h> | 112 | #include <arpa/inet.h> |
113 | #include <netdb.h> | 113 | #include <netdb.h> |
114 | #include <pwd.h> | 114 | #include <pwd.h> |
115 | #include <signal.h> | 115 | #include <signal.h> |
116 | #include <grp.h> | 116 | #include <grp.h> |
117 | #include <sys/file.h> | 117 | #include <sys/file.h> |
118 | //#include <sys/prctl.h> | 118 | //#include <sys/prctl.h> |
119 | 119 | ||
120 | #ifdef NEED_SCHEDCTL_AND_LOCK | 120 | #ifdef NEED_SCHEDCTL_AND_LOCK |
121 | #include <sys/schedctl.h> | 121 | #include <sys/schedctl.h> |
122 | #include <sys/lock.h> | 122 | #include <sys/lock.h> |
123 | #endif | 123 | #endif |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | 126 | ||
127 | char *htm_error_string; | 127 | char *htm_error_string; |
128 | typedef int Boolean; | 128 | typedef int Boolean; |
129 | typedef void *OBJ; | 129 | typedef void *OBJ; |
130 | 130 | ||
131 | typedef struct ClientAddressStruct { | 131 | typedef struct ClientAddressStruct { |
132 | struct sockaddr_in cl_addr; | 132 | struct sockaddr_in cl_addr; |
133 | int clilen; | 133 | int clilen; |
134 | int sockfd; | 134 | int sockfd; |
135 | } *ClientAddr; | 135 | } *ClientAddr; |
136 | 136 | ||
137 | typedef unsigned long long osc_time_t; | 137 | typedef unsigned long long osc_time_t; |
138 | 138 | ||
139 | Boolean ShowBytes = FALSE; | 139 | Boolean ShowBytes = FALSE; |
140 | Boolean Silent = FALSE; | 140 | Boolean Silent = FALSE; |
141 | 141 | ||
142 | /* Declarations */ | 142 | /* Declarations */ |
143 | #ifndef WIN32 | 143 | #ifndef WIN32 |
144 | static int unixinitudp(int chan); | 144 | static int unixinitudp(int chan); |
145 | #endif | 145 | #endif |
146 | 146 | ||
147 | static int initudp(int chan); | 147 | static int initudp(int chan); |
148 | static void closeudp(int sockfd); | 148 | static void closeudp(int sockfd); |
149 | Boolean ClientReply(int packetsize, void *packet, int socketfd, | 149 | Boolean ClientReply(int packetsize, void *packet, int socketfd, |
150 | void *clientaddresspointer, int clientaddressbufferlength); | 150 | void *clientaddresspointer, int clientaddressbufferlength); |
151 | void sgi_CleanExit(void); | 151 | void sgi_CleanExit(void); |
152 | Boolean sgi_HaveToQuit(void); | 152 | Boolean sgi_HaveToQuit(void); |
153 | int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy); | 153 | int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy); |
154 | static void catch_sigint(); | 154 | static void catch_sigint(); |
155 | static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ; | 155 | static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ; |
156 | char *DataAfterAlignedString(char *string, char *boundary) ; | 156 | char *DataAfterAlignedString(char *string, char *boundary) ; |
157 | Boolean IsNiceString(char *string, char *boundary) ; | 157 | Boolean IsNiceString(char *string, char *boundary) ; |
158 | void complain(char *s, ...); | 158 | void complain(char *s, ...); |
159 | 159 | ||
160 | #define MAXMESG 32768 | 160 | #define MAXMESG 32768 |
161 | static char mbuf[MAXMESG]; | 161 | static char mbuf[MAXMESG]; |
162 | 162 | ||
163 | /* ----------------------------- dumpOSC ------------------------- */ | 163 | /* ----------------------------- dumpOSC ------------------------- */ |
164 | 164 | ||
165 | #define MAXOUTAT 50 | 165 | #define MAXOUTAT 50 |
166 | 166 | ||
167 | static t_class *dumpOSC_class; | 167 | static t_class *dumpOSC_class; |
168 | 168 | ||
169 | typedef struct _dumpOSC | 169 | typedef struct _dumpOSC |
170 | { | 170 | { |
171 | t_object x_obj; | 171 | t_object x_obj; |
172 | t_outlet *x_msgout; | 172 | t_outlet *x_msgout; |
173 | t_outlet *x_connectout; | 173 | t_outlet *x_connectout; |
174 | t_atom x_outat[MAXOUTAT]; | 174 | t_atom x_outat[MAXOUTAT]; |
175 | int x_outatc; | 175 | int x_outatc; |
176 | t_binbuf *x_b; | 176 | t_binbuf *x_b; |
177 | int x_connectsocket; | 177 | int x_connectsocket; |
178 | int x_nconnections; | 178 | int x_nconnections; |
179 | int x_udp; | 179 | int x_udp; |
180 | struct sockaddr_in x_server; | 180 | struct sockaddr_in x_server; |
181 | int x_clilen; | 181 | int x_clilen; |
182 | } t_dumpOSC; | 182 | } t_dumpOSC; |
183 | 183 | ||
184 | void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr); | 184 | void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr); |
185 | Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd); | 185 | Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd); |
186 | static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr); | 186 | static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr); |
187 | static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n); | 187 | static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n); |
188 | static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma); | 188 | static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma); |
189 | 189 | ||
190 | static void dumpOSC_read(t_dumpOSC *x, int sockfd) { | 190 | static void dumpOSC_read(t_dumpOSC *x, int sockfd) { |
191 | int clilen = x->x_clilen; | 191 | int clilen = x->x_clilen; |
192 | int n; | 192 | int n; |
193 | struct ClientAddressStruct ras; | 193 | struct ClientAddressStruct ras; |
194 | ClientAddr ra = &ras; | 194 | ClientAddr ra = &ras; |
195 | 195 | ||
196 | //catchupflag= FALSE; | 196 | //catchupflag= FALSE; |
197 | 197 | ||
198 | /* if (ShowBytes) { */ | 198 | /* if (ShowBytes) { */ |
199 | /* int i; */ | 199 | /* int i; */ |
200 | /* printf("%d byte message:\n", n); */ | 200 | /* printf("%d byte message:\n", n); */ |
201 | /* for (i = 0; i < n; ++i) { */ | 201 | /* for (i = 0; i < n; ++i) { */ |
202 | /* printf(" %x (%c)\t", m[i], m[i]); */ | 202 | /* printf(" %x (%c)\t", m[i], m[i]); */ |
203 | /* if (i%4 == 3) printf("\n"); */ | 203 | /* if (i%4 == 3) printf("\n"); */ |
204 | /* } */ | 204 | /* } */ |
205 | /* printf("\n"); */ | 205 | /* printf("\n"); */ |
206 | /* } */ | 206 | /* } */ |
207 | 207 | ||
208 | // return catchupflag; | 208 | // return catchupflag; |
209 | //struct sockaddr_in x->x_server; | 209 | //struct sockaddr_in x->x_server; |
210 | //while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0) | 210 | //while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0) |
211 | // while(( | 211 | // while(( |
212 | 212 | ||
213 | #ifdef WIN32 | 213 | #ifdef WIN32 |
214 | if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (SOCKADDR*)&x->x_server, &clilen)) >0) | 214 | if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (SOCKADDR*)&x->x_server, &clilen)) >0) |
215 | #else | 215 | #else |
216 | if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (struct sockaddr *)&x->x_server, &clilen)) >0) | 216 | if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (struct sockaddr *)&x->x_server, &clilen)) >0) |
217 | #endif | 217 | #endif |
218 | { | 218 | { |
219 | //int r; | 219 | //int r; |
220 | ras.cl_addr = *((struct sockaddr_in *) &x->x_server); | 220 | ras.cl_addr = *((struct sockaddr_in *) &x->x_server); |
221 | ras.clilen = x->x_clilen; | 221 | ras.clilen = x->x_clilen; |
222 | ras.sockfd = x->x_connectsocket; | 222 | ras.sockfd = x->x_connectsocket; |
223 | 223 | ||
224 | #ifdef DEBUG | 224 | #ifdef DEBUG |
225 | printf("dumpOSC_read: received UDP packet of length %d\n", n); | 225 | printf("dumpOSC_read: received UDP packet of length %d\n", n); |
226 | #endif | 226 | #endif |
227 | 227 | ||
228 | if(!dumpOSC_SendReply(mbuf, n, &x->x_server, clilen, sockfd)) | 228 | if(!dumpOSC_SendReply(mbuf, n, &x->x_server, clilen, sockfd)) |
229 | { | 229 | { |
230 | dumpOSC_ParsePacket(x, mbuf, n, ra); | 230 | dumpOSC_ParsePacket(x, mbuf, n, ra); |
231 | } | 231 | } |
232 | //r = Synthmessage(mbuf, n, &x->x_server, clilen, sockfd); | 232 | //r = Synthmessage(mbuf, n, &x->x_server, clilen, sockfd); |
233 | //post ("%d", r); | 233 | //post ("%d", r); |
234 | //outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, | 234 | //outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, |
235 | // emsg-msg-1, at + msg + 1); | 235 | // emsg-msg-1, at + msg + 1); |
236 | // outlet_list(x->x_msgout, 0, n, mbuf); | 236 | // outlet_list(x->x_msgout, 0, n, mbuf); |
237 | //if( sgi_HaveToQuit()) goto out; | 237 | //if( sgi_HaveToQuit()) goto out; |
238 | //if(r>0) goto back; | 238 | //if(r>0) goto back; |
239 | //clilen = maxclilen; | 239 | //clilen = maxclilen; |
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
243 | static void *dumpOSC_new(t_symbol *compatflag, | 243 | static void *dumpOSC_new(t_symbol *compatflag, |
244 | t_floatarg fportno) { | 244 | t_floatarg fportno) { |
245 | t_dumpOSC *x; | 245 | t_dumpOSC *x; |
246 | struct sockaddr_in server; | 246 | struct sockaddr_in server; |
247 | int clilen=sizeof(server); | 247 | int clilen=sizeof(server); |
248 | int sockfd; | 248 | int sockfd; |
249 | int portno=fportno; | 249 | int portno=fportno; |
250 | int udp = 1; | 250 | int udp = 1; |
251 | 251 | ||
252 | //x->x_b = binbuf_new(); | 252 | //x->x_b = binbuf_new(); |
253 | //x->x_outat = binbuf_getvec(x->x_b); | 253 | //x->x_outat = binbuf_getvec(x->x_b); |
254 | 254 | ||
255 | //{{raf}} pointer not valid yet...moving this down | 255 | //{{raf}} pointer not valid yet...moving this down |
256 | //x->x_outatc = 0; {{raf}} | 256 | //x->x_outatc = 0; {{raf}} |
257 | 257 | ||
258 | /* create a socket */ | 258 | /* create a socket */ |
259 | if ((sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1) | 259 | if ((sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1) |
260 | { | 260 | { |
261 | sys_sockerror("socket"); | 261 | sys_sockerror("socket"); |
262 | return (0); | 262 | return (0); |
263 | } | 263 | } |
264 | 264 | ||
265 | server.sin_family = AF_INET; | 265 | server.sin_family = AF_INET; |
266 | server.sin_addr.s_addr = INADDR_ANY; | 266 | server.sin_addr.s_addr = INADDR_ANY; |
267 | /* assign server port number */ | 267 | /* assign server port number */ |
268 | server.sin_port = htons((u_short)portno); | 268 | server.sin_port = htons((u_short)portno); |
269 | /* name the socket */ | 269 | /* name the socket */ |
270 | if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) | 270 | if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) |
271 | { | 271 | { |
272 | sys_sockerror("bind"); | 272 | sys_sockerror("bind"); |
273 | sys_closesocket(sockfd); | 273 | sys_closesocket(sockfd); |
274 | return (0); | 274 | return (0); |
275 | } | 275 | } |
276 | 276 | ||
277 | x = (t_dumpOSC *)pd_new(dumpOSC_class); | 277 | x = (t_dumpOSC *)pd_new(dumpOSC_class); |
278 | x->x_outatc = 0; // {{raf}} now pointer is valid (less invalid) | 278 | x->x_outatc = 0; // {{raf}} now pointer is valid (less invalid) |
279 | 279 | ||
280 | x->x_msgout = outlet_new(&x->x_obj, &s_anything); | 280 | x->x_msgout = outlet_new(&x->x_obj, &s_anything); |
281 | 281 | ||
282 | // if (udp) /* datagram protocol */ | 282 | // if (udp) /* datagram protocol */ |
283 | { | 283 | { |
284 | 284 | ||
285 | sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_read, x); | 285 | sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_read, x); |
286 | x->x_connectout = 0; | 286 | x->x_connectout = 0; |
287 | } | 287 | } |
288 | // else /* streaming protocol */ | 288 | // else /* streaming protocol */ |
289 | /* { */ | 289 | /* { */ |
290 | /* if (listen(sockfd, 5) < 0) */ | 290 | /* if (listen(sockfd, 5) < 0) */ |
291 | /* { */ | 291 | /* { */ |
292 | /* sys_sockerror("listen"); */ | 292 | /* sys_sockerror("listen"); */ |
293 | /* sys_closesocket(sockfd); */ | 293 | /* sys_closesocket(sockfd); */ |
294 | /* sockfd = -1; */ | 294 | /* sockfd = -1; */ |
295 | /* } */ | 295 | /* } */ |
296 | /* else */ | 296 | /* else */ |
297 | /* { */ | 297 | /* { */ |
298 | /* sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_connectpoll, x); */ | 298 | /* sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_connectpoll, x); */ |
299 | /* x->x_connectout = outlet_new(&x->x_obj, &s_float); */ | 299 | /* x->x_connectout = outlet_new(&x->x_obj, &s_float); */ |
300 | /* } */ | 300 | /* } */ |
301 | /* } */ | 301 | /* } */ |
302 | 302 | ||
303 | x->x_connectsocket = sockfd; | 303 | x->x_connectsocket = sockfd; |
304 | x->x_server = server; | 304 | x->x_server = server; |
305 | x->x_clilen = clilen; | 305 | x->x_clilen = clilen; |
306 | x->x_nconnections = 0; | 306 | x->x_nconnections = 0; |
307 | x->x_udp = udp; | 307 | x->x_udp = udp; |
308 | 308 | ||
309 | return (x); | 309 | return (x); |
310 | } | 310 | } |
311 | 311 | ||
312 | static void dumpOSC_free(t_dumpOSC *x) | 312 | static void dumpOSC_free(t_dumpOSC *x) |
313 | { | 313 | { |
314 | /* LATER make me clean up open connections */ | 314 | /* LATER make me clean up open connections */ |
315 | if (x->x_connectsocket >= 0) | 315 | if (x->x_connectsocket >= 0) |
316 | { | 316 | { |
317 | sys_rmpollfn(x->x_connectsocket); | 317 | sys_rmpollfn(x->x_connectsocket); |
318 | sys_closesocket(x->x_connectsocket); | 318 | sys_closesocket(x->x_connectsocket); |
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | #ifdef WIN32 | 322 | #ifdef WIN32 |
323 | OSC_API void dumpOSC_setup(void) | 323 | OSC_API void dumpOSC_setup(void) |
324 | #else | 324 | #else |
325 | void dumpOSC_setup(void) | 325 | void dumpOSC_setup(void) |
326 | #endif | 326 | #endif |
327 | { | 327 | { |
328 | dumpOSC_class = class_new(gensym("dumpOSC"), | 328 | dumpOSC_class = class_new(gensym("dumpOSC"), |
329 | (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free, | 329 | (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free, |
330 | sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT, | 330 | sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT, |
331 | A_DEFSYM, 0); | 331 | A_DEFSYM, 0); |
332 | class_sethelpsymbol(dumpOSC_class, gensym("dumpOSC-help.pd")); | 332 | class_sethelpsymbol(dumpOSC_class, gensym("dumpOSC-help.pd")); |
333 | } | 333 | } |
334 | 334 | ||
335 | 335 | ||
336 | #ifndef WIN32 | 336 | #ifndef WIN32 |
337 | #define UNIXDG_PATH "/tmp/htm" | 337 | #define UNIXDG_PATH "/tmp/htm" |
338 | #define UNIXDG_TMP "/tmp/htm.XXXXXX" | 338 | #define UNIXDG_TMP "/tmp/htm.XXXXXX" |
339 | static int unixinitudp(int chan) | 339 | static int unixinitudp(int chan) |
340 | { | 340 | { |
341 | struct sockaddr_un serv_addr; | 341 | struct sockaddr_un serv_addr; |
342 | int sockfd; | 342 | int sockfd; |
343 | 343 | ||
344 | if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) | 344 | if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) |
345 | return sockfd; | 345 | return sockfd; |
346 | 346 | ||
347 | bzero((char *)&serv_addr, sizeof(serv_addr)); | 347 | bzero((char *)&serv_addr, sizeof(serv_addr)); |
348 | serv_addr.sun_family = AF_UNIX; | 348 | serv_addr.sun_family = AF_UNIX; |
349 | strcpy(serv_addr.sun_path, UNIXDG_PATH); | 349 | strcpy(serv_addr.sun_path, UNIXDG_PATH); |
350 | sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan); | 350 | sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan); |
351 | unlink(serv_addr.sun_path); | 351 | unlink(serv_addr.sun_path); |
352 | if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0) | 352 | if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0) |
353 | { | 353 | { |
354 | perror("unable to bind\n"); | 354 | perror("unable to bind\n"); |
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | 357 | ||
358 | fcntl(sockfd, F_SETFL, FNDELAY); | 358 | fcntl(sockfd, F_SETFL, FNDELAY); |
359 | return sockfd; | 359 | return sockfd; |
360 | } | 360 | } |
361 | #endif // #ifndef WIN32 | 361 | #endif // #ifndef WIN32 |
362 | 362 | ||
363 | 363 | ||
364 | 364 | ||
365 | static int initudp(int chan) | 365 | static int initudp(int chan) |
366 | { | 366 | { |
367 | 367 | ||
368 | #ifdef WIN32 | 368 | #ifdef WIN32 |
369 | struct sockaddr_in serv_addr; | 369 | struct sockaddr_in serv_addr; |
370 | unsigned int sockfd; | 370 | unsigned int sockfd; |
371 | ULONG nonBlocking = (ULONG) TRUE; | 371 | ULONG nonBlocking = (ULONG) TRUE; |
372 | 372 | ||
373 | if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET ) { | 373 | if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET ) { |
374 | ZeroMemory((char *)&serv_addr, sizeof(serv_addr)); | 374 | ZeroMemory((char *)&serv_addr, sizeof(serv_addr)); |
375 | serv_addr.sin_family = AF_INET; | 375 | serv_addr.sin_family = AF_INET; |
376 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | 376 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
377 | serv_addr.sin_port = htons(chan); | 377 | serv_addr.sin_port = htons(chan); |
378 | if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) { | 378 | if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) { |
379 | // set for non-blocking mode | 379 | // set for non-blocking mode |
380 | if(ioctlsocket(sockfd, FIONBIO, &nonBlocking) == SOCKET_ERROR) { | 380 | if(ioctlsocket(sockfd, FIONBIO, &nonBlocking) == SOCKET_ERROR) { |
381 | perror("unable to set non-blocking\n"); | 381 | perror("unable to set non-blocking\n"); |
382 | return -1; | 382 | return -1; |
383 | } | 383 | } |
384 | } | 384 | } |
385 | else { perror("unable to bind\n"); return -1; } | 385 | else { perror("unable to bind\n"); return -1; } |
386 | } | 386 | } |
387 | return (sockfd == INVALID_SOCKET ? -1 : (int)sockfd); | 387 | return (sockfd == INVALID_SOCKET ? -1 : (int)sockfd); |
388 | #else | 388 | #else |
389 | struct sockaddr_in serv_addr; | 389 | struct sockaddr_in serv_addr; |
390 | int sockfd; | 390 | int sockfd; |
391 | 391 | ||
392 | if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) | 392 | if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) |
393 | return sockfd; | 393 | return sockfd; |
394 | 394 | ||
395 | bzero((char *)&serv_addr, sizeof(serv_addr)); | 395 | bzero((char *)&serv_addr, sizeof(serv_addr)); |
396 | serv_addr.sin_family = AF_INET; | 396 | serv_addr.sin_family = AF_INET; |
397 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | 397 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
398 | serv_addr.sin_port = htons(chan); | 398 | serv_addr.sin_port = htons(chan); |
399 | 399 | ||
400 | if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) | 400 | if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) |
401 | { | 401 | { |
402 | perror("unable to bind\n"); | 402 | perror("unable to bind\n"); |
403 | return -1; | 403 | return -1; |
404 | } | 404 | } |
405 | 405 | ||
406 | fcntl(sockfd, F_SETFL, FNDELAY); | 406 | fcntl(sockfd, F_SETFL, FNDELAY); |
407 | return sockfd; | 407 | return sockfd; |
408 | #endif | 408 | #endif |
409 | } | 409 | } |
410 | 410 | ||
411 | 411 | ||
412 | 412 | ||
413 | 413 | ||
414 | 414 | ||
415 | 415 | ||
416 | 416 | ||
417 | 417 | ||
418 | static void closeudp(int sockfd) { | 418 | static void closeudp(int sockfd) { |
419 | #ifdef WIN32 | 419 | #ifdef WIN32 |
420 | closesocket(sockfd); | 420 | closesocket(sockfd); |
421 | #else | 421 | #else |
422 | close(sockfd); | 422 | close(sockfd); |
423 | #endif | 423 | #endif |
424 | } | 424 | } |
425 | 425 | ||
426 | static Boolean catchupflag=FALSE; | 426 | static Boolean catchupflag=FALSE; |
427 | Boolean ClientReply(int packetsize, void *packet, int socketfd, | 427 | Boolean ClientReply(int packetsize, void *packet, int socketfd, |
428 | void *clientaddresspointer, int clientaddressbufferlength) | 428 | void *clientaddresspointer, int clientaddressbufferlength) |
429 | { | 429 | { |
430 | if(!clientaddresspointer) return FALSE; | 430 | if(!clientaddresspointer) return FALSE; |
431 | catchupflag= TRUE; | 431 | catchupflag= TRUE; |
432 | return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength); | 432 | return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength); |
433 | } | 433 | } |
434 | 434 | ||
435 | static Boolean exitflag= FALSE; | 435 | static Boolean exitflag= FALSE; |
436 | void sgi_CleanExit(void) { | 436 | void sgi_CleanExit(void) { |
437 | exitflag = TRUE; | 437 | exitflag = TRUE; |
438 | } | 438 | } |
439 | 439 | ||
440 | Boolean sgi_HaveToQuit(void) { | 440 | Boolean sgi_HaveToQuit(void) { |
441 | return exitflag; | 441 | return exitflag; |
442 | } | 442 | } |
443 | 443 | ||
444 | 444 | ||
445 | /* file descriptor poll table */ | 445 | /* file descriptor poll table */ |
446 | static int npolldevs =0; | 446 | static int npolldevs =0; |
447 | typedef struct polldev | 447 | typedef struct polldev |
448 | { | 448 | { |
449 | int fd; | 449 | int fd; |
450 | void (*callbackfunction)(int , void *); | 450 | void (*callbackfunction)(int , void *); |
451 | void *dummy; | 451 | void *dummy; |
452 | } polldev; | 452 | } polldev; |
453 | #define TABMAX 8 | 453 | #define TABMAX 8 |
454 | static polldev polldevs[TABMAX]; | 454 | static polldev polldevs[TABMAX]; |
455 | 455 | ||
456 | 456 | ||
457 | /* Register a device (referred to by a file descriptor that the caller | 457 | /* Register a device (referred to by a file descriptor that the caller |
458 | should have already successfully obtained from a system call) to be | 458 | should have already successfully obtained from a system call) to be |
459 | polled as real-time constraints allowed. | 459 | polled as real-time constraints allowed. |
460 | 460 | ||
461 | When a select(2) call indicates activity on the file descriptor, the | 461 | When a select(2) call indicates activity on the file descriptor, the |
462 | callback function is called with the file descripter as first | 462 | callback function is called with the file descripter as first |
463 | argument and the given dummy argument (presumably a pointer to the | 463 | argument and the given dummy argument (presumably a pointer to the |
464 | instance variables associated with the device). | 464 | instance variables associated with the device). |
465 | */ | 465 | */ |
466 | int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy) | 466 | int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy) |
467 | { | 467 | { |
468 | if(npolldevs<TABMAX) | 468 | if(npolldevs<TABMAX) |
469 | { | 469 | { |
470 | polldevs[npolldevs].fd = fd; | 470 | polldevs[npolldevs].fd = fd; |
471 | polldevs[npolldevs].callbackfunction = callbackfunction; | 471 | polldevs[npolldevs].callbackfunction = callbackfunction; |
472 | polldevs[npolldevs].dummy = dummy; | 472 | polldevs[npolldevs].dummy = dummy; |
473 | } | 473 | } |
474 | else return -1; | 474 | else return -1; |
475 | return npolldevs++; | 475 | return npolldevs++; |
476 | } | 476 | } |
477 | 477 | ||
478 | static int caught_sigint; | 478 | static int caught_sigint; |
479 | 479 | ||
480 | static void catch_sigint() { | 480 | static void catch_sigint() { |
481 | caught_sigint = 1; | 481 | caught_sigint = 1; |
482 | } | 482 | } |
483 | static int sockfd, usockfd; | 483 | static int sockfd, usockfd; |
484 | 484 | ||
485 | 485 | ||
486 | void PrintClientAddr(ClientAddr CA) { | 486 | void PrintClientAddr(ClientAddr CA) { |
487 | unsigned long addr = CA->cl_addr.sin_addr.s_addr; | 487 | unsigned long addr = CA->cl_addr.sin_addr.s_addr; |
488 | printf("Client address %p:\n", CA); | 488 | printf("Client address %p:\n", CA); |
489 | printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd); | 489 | printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd); |
490 | printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family, | 490 | printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family, |
491 | CA->cl_addr.sin_port); | 491 | CA->cl_addr.sin_port); |
492 | printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr)); | 492 | printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr)); |
493 | 493 | ||
494 | printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n", | 494 | printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n", |
495 | CA->cl_addr.sin_zero[0], | 495 | CA->cl_addr.sin_zero[0], |
496 | CA->cl_addr.sin_zero[1], | 496 | CA->cl_addr.sin_zero[1], |
497 | CA->cl_addr.sin_zero[2], | 497 | CA->cl_addr.sin_zero[2], |
498 | CA->cl_addr.sin_zero[3], | 498 | CA->cl_addr.sin_zero[3], |
499 | CA->cl_addr.sin_zero[4], | 499 | CA->cl_addr.sin_zero[4], |
500 | CA->cl_addr.sin_zero[5], | 500 | CA->cl_addr.sin_zero[5], |
501 | CA->cl_addr.sin_zero[6], | 501 | CA->cl_addr.sin_zero[6], |
502 | CA->cl_addr.sin_zero[7]); | 502 | CA->cl_addr.sin_zero[7]); |
503 | 503 | ||
504 | printf("\n"); | 504 | printf("\n"); |
505 | } | 505 | } |
506 | 506 | ||
507 | //******************* | 507 | //******************* |
508 | 508 | ||
509 | void WriteTime(char* dst, osc_time_t osctime) | 509 | void WriteTime(char* dst, osc_time_t osctime) |
510 | { | 510 | { |
511 | *(int32_t*)dst = htonl((int32_t)(osctime >> 32)); | 511 | *(int32_t*)dst = htonl((int32_t)(osctime >> 32)); |
512 | *(int32_t*)(dst+4) = htonl((int32_t)osctime); | 512 | *(int32_t*)(dst+4) = htonl((int32_t)osctime); |
513 | } | 513 | } |
514 | 514 | ||
515 | void WriteMode(char* dst) | 515 | void WriteMode(char* dst) |
516 | { | 516 | { |
517 | *(int32_t*)dst = htonl(0); | 517 | *(int32_t*)dst = htonl(0); |
518 | } | 518 | } |
519 | 519 | ||
520 | osc_time_t ReadTime(const char* src) | 520 | osc_time_t ReadTime(const char* src) |
521 | { | 521 | { |
522 | osc_time_t osctime = ntohl(*(int32_t*)src); | 522 | osc_time_t osctime = ntohl(*(int32_t*)src); |
523 | return (osctime << 32) + ntohl(*(int32_t*)(src+4)); | 523 | return (osctime << 32) + ntohl(*(int32_t*)(src+4)); |
524 | } | 524 | } |
525 | 525 | ||
526 | double TimeToSeconds(osc_time_t osctime) | 526 | double TimeToSeconds(osc_time_t osctime) |
527 | { | 527 | { |
528 | return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */; | 528 | return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */; |
529 | } | 529 | } |
530 | 530 | ||
531 | int timeRound(double x) | 531 | int timeRound(double x) |
532 | { | 532 | { |
533 | return x >= 0.0 ? x+0.5 : x-0.5; | 533 | return x >= 0.0 ? x+0.5 : x-0.5; |
534 | } | 534 | } |
535 | /* | 535 | /* |
536 | void WriteLogicalTime(char* dst) | 536 | void WriteLogicalTime(char* dst) |
537 | { | 537 | { |
538 | static double startTime = -1.0; | 538 | static double startTime = -1.0; |
539 | double sTime; | 539 | double sTime; |
540 | 540 | ||
541 | // Initialisierung der Startzeit. | 541 | // Initialisierung der Startzeit. |
542 | // Knnte effizienter (ohne 'if') auch irgendwo vorher passieren. | 542 | // Knnte effizienter (ohne 'if') auch irgendwo vorher passieren. |
543 | // Knnte wahrscheinlich auch 0.0 sein. | 543 | // Knnte wahrscheinlich auch 0.0 sein. |
544 | if (startTime < 0.0) { | 544 | if (startTime < 0.0) { |
545 | startTime = clock_getlogicaltime(); | 545 | startTime = clock_getlogicaltime(); |
546 | } | 546 | } |
547 | 547 | ||
548 | sTime = clock_gettimesince(startTime) * 0.001; | 548 | sTime = clock_gettimesince(startTime) * 0.001; |
549 | *(int32_t*)dst = hton'K l((int32_t)sTime); | 549 | *(int32_t*)dst = hton'K l((int32_t)sTime); |
550 | *(int32_t*)(dst+4) = htonl((int32_t)(4294967296.0 * sTime)); | 550 | *(int32_t*)(dst+4) = htonl((int32_t)(4294967296.0 * sTime)); |
551 | } | 551 | } |
552 | */ | 552 | */ |
553 | 553 | ||
554 | void WriteLogicalTime(char* dst) | 554 | void WriteLogicalTime(char* dst) |
555 | { | 555 | { |
556 | double sTime = clock_gettimesince(19230720) / 1000.0; | 556 | double sTime = clock_gettimesince(19230720) / 1000.0; |
557 | double tau = sTime - timeRound(sTime); | 557 | double tau = sTime - timeRound(sTime); |
558 | 558 | ||
559 | //fprintf(stderr, "sSec = %f tau = %f\n", sTime, tau); | 559 | //fprintf(stderr, "sSec = %f tau = %f\n", sTime, tau); |
560 | 560 | ||
561 | *(int32_t*)dst = htonl((int32_t)(sTime)); | 561 | *(int32_t*)dst = htonl((int32_t)(sTime)); |
562 | *(int32_t*)(dst+4) = htonl((int32_t)(4294967296 * tau)); | 562 | *(int32_t*)(dst+4) = htonl((int32_t)(4294967296 * tau)); |
563 | } | 563 | } |
564 | 564 | ||
565 | Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd) | 565 | Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd) |
566 | { | 566 | { |
567 | if((n == 24) && (strcmp(buf, "#time") == 0)) | 567 | if((n == 24) && (strcmp(buf, "#time") == 0)) |
568 | { | 568 | { |
569 | osc_time_t t0, t1, t2; | 569 | osc_time_t t0, t1, t2; |
570 | double dt0, dt1, dt2; | 570 | double dt0, dt1, dt2; |
571 | 571 | ||
572 | WriteMode(buf+6); | 572 | WriteMode(buf+6); |
573 | 573 | ||
574 | t0 = ReadTime(buf+8); | 574 | t0 = ReadTime(buf+8); |
575 | 575 | ||
576 | WriteLogicalTime(buf+16); | 576 | WriteLogicalTime(buf+16); |
577 | t1 = ReadTime(buf+16); // reverse | 577 | t1 = ReadTime(buf+16); // reverse |
578 | dt0 = TimeToSeconds(t0); // client time | 578 | dt0 = TimeToSeconds(t0); // client time |
579 | dt1 = TimeToSeconds(t1); // server time | 579 | dt1 = TimeToSeconds(t1); // server time |
580 | 580 | ||
581 | // fprintf(stderr, "%f\t%f\t%f\n", dt0, dt1, dt0 - dt1); | 581 | // fprintf(stderr, "%f\t%f\t%f\n", dt0, dt1, dt0 - dt1); |
582 | 582 | ||
583 | sendto(fd, buf, n, 0, (struct sockaddr *)clientDesc, clientDescLenght); | 583 | sendto(fd, buf, n, 0, (struct sockaddr *)clientDesc, clientDescLenght); |
584 | return TRUE; | 584 | return TRUE; |
585 | } | 585 | } |
586 | else | 586 | else |
587 | { | 587 | { |
588 | return FALSE; | 588 | return FALSE; |
589 | } | 589 | } |
590 | } | 590 | } |
591 | 591 | ||
592 | //********************** | 592 | //********************** |
593 | 593 | ||
594 | void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr) { | 594 | void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr) { |
595 | // t_dumpOSC *x; | 595 | // t_dumpOSC *x; |
596 | int size, messageLen, i; | 596 | int size, messageLen, i; |
597 | char *messageName; | 597 | char *messageName; |
598 | char *args; | 598 | char *args; |
599 | 599 | ||
600 | //#ifdef PRINTADDRS | 600 | //#ifdef PRINTADDRS |
601 | #ifdef DEBUG | 601 | #ifdef DEBUG |
602 | //PrintClientAddr(returnAddr); | 602 | //PrintClientAddr(returnAddr); |
603 | #endif | 603 | #endif |
604 | 604 | ||
605 | 605 | ||
606 | if ((n%4) != 0) { | 606 | if ((n%4) != 0) { |
607 | complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", n); | 607 | complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", n); |
608 | return; | 608 | return; |
609 | } | 609 | } |
610 | 610 | ||
611 | if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) { | 611 | if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) { |
612 | /* This is a bundle message. */ | 612 | /* This is a bundle message. */ |
613 | #ifdef DEBUG | 613 | #ifdef DEBUG |
614 | printf("dumpOSC_ParsePacket: bundle msg: bundles not yet supported\n"); | 614 | printf("dumpOSC_ParsePacket: bundle msg: bundles not yet supported\n"); |
615 | #endif | 615 | #endif |
616 | 616 | ||
617 | if (n < 16) { | 617 | if (n < 16) { |
618 | complain("Bundle message too small (%d bytes) for time tag", n); | 618 | complain("Bundle message too small (%d bytes) for time tag", n); |
619 | return; | 619 | return; |
620 | } | 620 | } |
621 | 621 | ||
622 | /* Print the time tag */ | 622 | /* Print the time tag */ |
623 | #ifdef DEBUG | 623 | #ifdef DEBUG |
624 | printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), ntohl(*((unsigned long *)(buf+12)))); | 624 | printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), ntohl(*((unsigned long *)(buf+12)))); |
625 | #endif | 625 | #endif |
626 | 626 | ||
627 | /* Note: if we wanted to actually use the time tag as a little-endian | 627 | /* Note: if we wanted to actually use the time tag as a little-endian |
628 | 64-bit int, we'd have to word-swap the two 32-bit halves of it */ | 628 | 64-bit int, we'd have to word-swap the two 32-bit halves of it */ |
629 | 629 | ||
630 | i = 16; /* Skip "#group\0" and time tag */ | 630 | i = 16; /* Skip "#group\0" and time tag */ |
631 | 631 | ||
632 | while(i<n) { | 632 | while(i<n) { |
633 | size = ntohl(*((int *) (buf + i))); | 633 | size = ntohl(*((int *) (buf + i))); |
634 | if ((size % 4) != 0) { | 634 | if ((size % 4) != 0) { |
635 | complain("Bad size count %d in bundle (not a multiple of 4)", size); | 635 | complain("Bad size count %d in bundle (not a multiple of 4)", size); |
636 | return; | 636 | return; |
637 | } | 637 | } |
638 | if ((size + i + 4) > n) { | 638 | if ((size + i + 4) > n) { |
639 | complain("Bad size count %d in bundle (only %d bytes left in entire bundle)", | 639 | complain("Bad size count %d in bundle (only %d bytes left in entire bundle)", |
640 | size, n-i-4); | 640 | size, n-i-4); |
641 | return; | 641 | return; |
642 | } | 642 | } |
643 | 643 | ||
644 | /* Recursively handle element of bundle */ | 644 | /* Recursively handle element of bundle */ |
645 | dumpOSC_ParsePacket(x, buf+i+4, size, returnAddr); | 645 | dumpOSC_ParsePacket(x, buf+i+4, size, returnAddr); |
646 | i += 4 + size; | 646 | i += 4 + size; |
647 | } | 647 | } |
648 | 648 | ||
649 | if (i != n) { | 649 | if (i != n) { |
650 | complain("This can't happen"); | 650 | complain("This can't happen"); |
651 | } | 651 | } |
652 | #ifdef DEBUG | 652 | #ifdef DEBUG |
653 | printf("]\n"); | 653 | printf("]\n"); |
654 | #endif | 654 | #endif |
655 | 655 | ||
656 | } | 656 | } |
657 | else if ((n == 24) && (strcmp(buf, "#time") == 0)) | 657 | else if ((n == 24) && (strcmp(buf, "#time") == 0)) |
658 | { | 658 | { |
659 | complain("Time message: %s\n :).\n", htm_error_string); | 659 | complain("Time message: %s\n :).\n", htm_error_string); |
660 | return; | 660 | return; |
661 | 661 | ||
662 | } | 662 | } |
663 | else | 663 | else |
664 | { | 664 | { |
665 | /* This is not a bundle message */ | 665 | /* This is not a bundle message */ |
666 | 666 | ||
667 | messageName = buf; | 667 | messageName = buf; |
668 | args = DataAfterAlignedString(messageName, buf+n); | 668 | args = DataAfterAlignedString(messageName, buf+n); |
669 | if (args == 0) { | 669 | if (args == 0) { |
670 | complain("Bad message name string: %s\nDropping entire message.\n", | 670 | complain("Bad message name string: %s\nDropping entire message.\n", |
671 | htm_error_string); | 671 | htm_error_string); |
672 | return; | 672 | return; |
673 | } | 673 | } |
674 | messageLen = args-messageName; | 674 | messageLen = args-messageName; |
675 | dumpOSC_Smessage(x, messageName, (void *)args, n-messageLen, returnAddr); | 675 | dumpOSC_Smessage(x, messageName, (void *)args, n-messageLen, returnAddr); |
676 | } | 676 | } |
677 | } | 677 | } |
678 | 678 | ||
679 | #define SMALLEST_POSITIVE_FLOAT 0.000001f | 679 | #define SMALLEST_POSITIVE_FLOAT 0.000001f |
680 | 680 | ||
681 | static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr) { | 681 | static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr) { |
682 | char *chars = v; | 682 | char *chars = v; |
683 | t_atom at; | 683 | t_atom at; |
684 | //t_atom myargv[50]; | 684 | //t_atom myargv[50]; |
685 | 685 | ||
686 | int myargc = x->x_outatc; | 686 | int myargc = x->x_outatc; |
687 | t_atom* mya = x->x_outat; | 687 | t_atom* mya = x->x_outat; |
688 | int myi; | 688 | int myi; |
689 | 689 | ||
690 | #ifdef DEBUG | 690 | #ifdef DEBUG |
691 | printf("%s ", address); | 691 | printf("%s ", address); |
692 | #endif | 692 | #endif |
693 | 693 | ||
694 | // ztoln+cvt from envgen.c, ggee-0.18 .. | 694 | // ztoln+cvt from envgen.c, ggee-0.18 .. |
695 | // outlet_anything's 'symbol' gets set to address | 695 | // outlet_anything's 'symbol' gets set to address |
696 | // so we dont need to append address to the atomlist | 696 | // so we dont need to append address to the atomlist |
697 | /* | 697 | /* |
698 | SETSYMBOL(mya,gensym(address));myargc++; | 698 | SETSYMBOL(mya,gensym(address));myargc++; |
699 | x->x_outatc = myargc; | 699 | x->x_outatc = myargc; |
700 | */ | 700 | */ |
701 | 701 | ||
702 | if (n != 0) { | 702 | if (n != 0) { |
703 | if (chars[0] == ',') { | 703 | if (chars[0] == ',') { |
704 | if (chars[1] != ',') { | 704 | if (chars[1] != ',') { |
705 | /* This message begins with a type-tag string */ | 705 | /* This message begins with a type-tag string */ |
706 | dumpOSC_PrintTypeTaggedArgs(x, v, n); | 706 | dumpOSC_PrintTypeTaggedArgs(x, v, n); |
707 | } else { | 707 | } else { |
708 | /* Double comma means an escaped real comma, not a type string */ | 708 | /* Double comma means an escaped real comma, not a type string */ |
709 | dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 1); | 709 | dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 1); |
710 | } | 710 | } |
711 | } else { | 711 | } else { |
712 | dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0); | 712 | dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0); |
713 | } | 713 | } |
714 | } | 714 | } |
715 | 715 | ||
716 | outlet_anything(x->x_msgout,gensym(address),x->x_outatc,(t_atom*)&x->x_outat); | 716 | outlet_anything(x->x_msgout,gensym(address),x->x_outatc,(t_atom*)&x->x_outat); |
717 | x->x_outatc = 0; | 717 | x->x_outatc = 0; |
718 | #ifdef DEBUG | 718 | #ifdef DEBUG |
719 | printf("\n"); | 719 | printf("\n"); |
720 | #endif | 720 | #endif |
721 | fflush(stdout); /* Added for Sami 5/21/98 */ | 721 | fflush(stdout); /* Added for Sami 5/21/98 */ |
722 | } | 722 | } |
723 | 723 | ||
724 | static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n) { | 724 | static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n) { |
725 | char *typeTags, *thisType; | 725 | char *typeTags, *thisType; |
726 | char *p; | 726 | char *p; |
727 | 727 | ||
728 | int myargc = x->x_outatc; | 728 | int myargc = x->x_outatc; |
729 | t_atom* mya = x->x_outat; | 729 | t_atom* mya = x->x_outat; |
730 | int myi; | 730 | int myi; |
731 | 731 | ||
732 | typeTags = v; | 732 | typeTags = v; |
733 | 733 | ||
734 | if (!IsNiceString(typeTags, typeTags+n)) { | 734 | if (!IsNiceString(typeTags, typeTags+n)) { |
735 | /* No null-termination, so maybe it wasn't a type tag | 735 | /* No null-termination, so maybe it wasn't a type tag |
736 | string after all */ | 736 | string after all */ |
737 | dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0); | 737 | dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0); |
738 | return; | 738 | return; |
739 | } | 739 | } |
740 | 740 | ||
741 | p = DataAfterAlignedString(typeTags, typeTags+n); | 741 | p = DataAfterAlignedString(typeTags, typeTags+n); |
742 | 742 | ||
743 | 743 | ||
744 | for (thisType = typeTags + 1; *thisType != 0; ++thisType) { | 744 | for (thisType = typeTags + 1; *thisType != 0; ++thisType) { |
745 | switch (*thisType) { | 745 | switch (*thisType) { |
746 | case 'i': case 'r': case 'm': case 'c': | 746 | case 'i': case 'r': case 'm': case 'c': |
747 | #ifdef DEBUG | 747 | #ifdef DEBUG |
748 | //post("integer: %d", ntohl(*((int *) p))); | 748 | //post("integer: %d", ntohl(*((int *) p))); |
749 | #endif | 749 | #endif |
750 | /* Martin Peach fix for negative floats: | 750 | /* Martin Peach fix for negative floats: |
751 | * was: SETFLOAT(mya+myargc,ntohl(*((int *) p))); | 751 | * was: SETFLOAT(mya+myargc,ntohl(*((int *) p))); |
752 | * now is: | 752 | * now is: |
753 | */ | 753 | */ |
754 | SETFLOAT(mya+myargc,(signed)ntohl(*((int *) p))); | 754 | SETFLOAT(mya+myargc,(signed)ntohl(*((int *) p))); |
755 | myargc++; | 755 | myargc++; |
756 | 756 | ||
757 | p += 4; | 757 | p += 4; |
758 | break; | 758 | break; |
759 | 759 | ||
760 | case 'f': { | 760 | case 'f': { |
761 | int i = ntohl(*((int *) p)); | 761 | int i = ntohl(*((int *) p)); |
762 | float *floatp = ((float *) (&i)); | 762 | float *floatp = ((float *) (&i)); |
763 | #ifdef DEBUG | 763 | #ifdef DEBUG |
764 | post("float: %f", *floatp); | 764 | post("float: %f", *floatp); |
765 | #endif | 765 | #endif |
766 | SETFLOAT(mya+myargc,*floatp); | 766 | SETFLOAT(mya+myargc,*floatp); |
767 | myargc++; | 767 | myargc++; |
768 | 768 | ||
769 | p += 4; | 769 | p += 4; |
770 | } | 770 | } |
771 | break; | 771 | break; |
772 | 772 | ||
773 | case 'h': case 't': | 773 | case 'h': case 't': |
774 | #ifdef DEBUG | 774 | #ifdef DEBUG |
775 | printf("[A 64-bit int] "); | 775 | printf("[A 64-bit int] "); |
776 | #endif | 776 | #endif |
777 | post("[A 64-bit int] not implemented"); | 777 | post("[A 64-bit int] not implemented"); |
778 | 778 | ||
779 | p += 8; | 779 | p += 8; |
780 | break; | 780 | break; |
781 | 781 | ||
782 | case 'd': | 782 | case 'd': |
783 | #ifdef DEBUG | 783 | #ifdef DEBUG |
784 | printf("[A 64-bit float] "); | 784 | printf("[A 64-bit float] "); |
785 | #endif | 785 | #endif |
786 | post("[A 64-bit float] not implemented"); | 786 | post("[A 64-bit float] not implemented"); |
787 | 787 | ||
788 | p += 8; | 788 | p += 8; |
789 | break; | 789 | break; |
790 | 790 | ||
791 | case 's': case 'S': | 791 | case 's': case 'S': |
792 | if (!IsNiceString(p, typeTags+n)) { | 792 | if (!IsNiceString(p, typeTags+n)) { |
793 | post("Type tag said this arg is a string but it's not!\n"); | 793 | post("Type tag said this arg is a string but it's not!\n"); |
794 | return; | 794 | return; |
795 | } else { | 795 | } else { |
796 | #ifdef DEBUG | 796 | #ifdef DEBUG |
797 | post("string: \"%s\"", p); | 797 | post("string: \"%s\"", p); |
798 | #endif | 798 | #endif |
799 | SETSYMBOL(mya+myargc,gensym(p)); | 799 | SETSYMBOL(mya+myargc,gensym(p)); |
800 | myargc++; | 800 | myargc++; |
801 | //outlet_list(x->x_msgout, 0,sizeof(p), p); | 801 | //outlet_list(x->x_msgout, 0,sizeof(p), p); |
802 | //outlet_anything(x->x_msgout, 0, sizeof(p), p); | 802 | //outlet_anything(x->x_msgout, 0, sizeof(p), p); |
803 | p = DataAfterAlignedString(p, typeTags+n); | 803 | p = DataAfterAlignedString(p, typeTags+n); |
804 | // append to output vector .. | 804 | // append to output vector .. |
805 | } | 805 | } |
806 | break; | 806 | break; |
807 | 807 | ||
808 | case 'T': | 808 | case 'T': |
809 | #ifdef DEBUG | 809 | #ifdef DEBUG |
810 | printf("[True] "); | 810 | printf("[True] "); |
811 | #endif | 811 | #endif |
812 | SETFLOAT(mya+myargc,1.); | 812 | SETFLOAT(mya+myargc,1.); |
813 | myargc++; | 813 | myargc++; |
814 | break; | 814 | break; |
815 | case 'F': | 815 | case 'F': |
816 | #ifdef DEBUG | 816 | #ifdef DEBUG |
817 | printf("[False] "); | 817 | printf("[False] "); |
818 | #endif | 818 | #endif |
819 | SETFLOAT(mya+myargc,0.); | 819 | SETFLOAT(mya+myargc,0.); |
820 | myargc++; | 820 | myargc++; |
821 | break; | 821 | break; |
822 | case 'N': | 822 | case 'N': |
823 | #ifdef DEBUG | 823 | #ifdef DEBUG |
824 | printf("[Nil]"); | 824 | printf("[Nil]"); |
825 | #endif | 825 | #endif |
826 | post("sendOSC: [Nil] not implemented"); | 826 | post("sendOSC: [Nil] not implemented"); |
827 | break; | 827 | break; |
828 | case 'I': | 828 | case 'I': |
829 | #ifdef DEBUG | 829 | #ifdef DEBUG |
830 | printf("[Infinitum]"); | 830 | printf("[Infinitum]"); |
831 | #endif | 831 | #endif |
832 | post("sendOSC: [Infinitum] not implemented"); | 832 | post("sendOSC: [Infinitum] not implemented"); |
833 | break; | 833 | break; |
834 | 834 | ||
835 | default: | 835 | default: |
836 | post("sendOSC: [Unrecognized type tag %c]", *thisType); | 836 | post("sendOSC: [Unrecognized type tag %c]", *thisType); |
837 | // return; | 837 | // return; |
838 | } | 838 | } |
839 | } | 839 | } |
840 | x->x_outatc = myargc; | 840 | x->x_outatc = myargc; |
841 | } | 841 | } |
842 | 842 | ||
843 | static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma) { | 843 | static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma) { |
844 | int i, thisi; | 844 | int i, thisi; |
845 | float thisf; | 845 | float thisf; |
846 | int *ints; | 846 | int *ints; |
847 | char *chars; | 847 | char *chars; |
848 | char *string, *nextString; | 848 | char *string, *nextString; |
849 | 849 | ||
850 | int myargc= x->x_outatc; | 850 | int myargc= x->x_outatc; |
851 | t_atom* mya = x->x_outat; | 851 | t_atom* mya = x->x_outat; |
852 | int myi; | 852 | int myi; |
853 | 853 | ||
854 | 854 | ||
855 | /* Go through the arguments 32 bits at a time */ | 855 | /* Go through the arguments 32 bits at a time */ |
856 | ints = v; | 856 | ints = v; |
857 | chars = v; | 857 | chars = v; |
858 | 858 | ||
859 | for (i = 0; i<n/4; ) { | 859 | for (i = 0; i<n/4; ) { |
860 | string = &chars[i*4]; | 860 | string = &chars[i*4]; |
861 | thisi = ntohl(ints[i]); | 861 | thisi = ntohl(ints[i]); |
862 | /* Reinterpret the (potentially byte-reversed) thisi as a float */ | 862 | /* Reinterpret the (potentially byte-reversed) thisi as a float */ |
863 | thisf = *(((float *) (&thisi))); | 863 | thisf = *(((float *) (&thisi))); |
864 | 864 | ||
865 | if (thisi >= -1000 && thisi <= 1000000) { | 865 | if (thisi >= -1000 && thisi <= 1000000) { |
866 | #ifdef DEBUG | 866 | #ifdef DEBUG |
867 | printf("%d ", thisi); | 867 | printf("%d ", thisi); |
868 | #endif | 868 | #endif |
869 | // append to output vector .. | 869 | // append to output vector .. |
870 | SETFLOAT(mya+myargc,(t_float) (thisi)); | 870 | SETFLOAT(mya+myargc,(t_float) (thisi)); |
871 | myargc++; | 871 | myargc++; |
872 | // outlet_float(x->x_msgout, thisi); | 872 | // outlet_float(x->x_msgout, thisi); |
873 | i++; | 873 | i++; |
874 | } else if (thisf >= -1000.f && thisf <= 1000000.f && | 874 | } else if (thisf >= -1000.f && thisf <= 1000000.f && |
875 | (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) { | 875 | (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) { |
876 | #ifdef DEBUG | 876 | #ifdef DEBUG |
877 | printf("%f ", thisf); | 877 | printf("%f ", thisf); |
878 | #endif | 878 | #endif |
879 | // append to output vector .. | 879 | // append to output vector .. |
880 | SETFLOAT(mya+myargc,thisf); | 880 | SETFLOAT(mya+myargc,thisf); |
881 | myargc++; | 881 | myargc++; |
882 | //outlet_float(x->x_msgout, thisf); | 882 | //outlet_float(x->x_msgout, thisf); |
883 | i++; | 883 | i++; |
884 | } else if (IsNiceString(string, chars+n)) { | 884 | } else if (IsNiceString(string, chars+n)) { |
885 | nextString = DataAfterAlignedString(string, chars+n); | 885 | nextString = DataAfterAlignedString(string, chars+n); |
886 | #ifdef DEBUG | 886 | #ifdef DEBUG |
887 | printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string); | 887 | printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string); |
888 | #endif | 888 | #endif |
889 | // append to output vector .. | 889 | // append to output vector .. |
890 | SETSYMBOL(mya+myargc,gensym(string)); | 890 | SETSYMBOL(mya+myargc,gensym(string)); |
891 | myargc++; | 891 | myargc++; |
892 | //outlet_symbol(x->x_msgout, gensym((i == 0 && skipComma) ? string +1 : string)); | 892 | //outlet_symbol(x->x_msgout, gensym((i == 0 && skipComma) ? string +1 : string)); |
893 | i += (nextString-string) / 4; | 893 | i += (nextString-string) / 4; |
894 | } else { | 894 | } else { |
895 | // unhandled .. ;) | 895 | // unhandled .. ;) |
896 | #ifdef DEBUG | 896 | #ifdef DEBUG |
897 | printf("0x%x xx", ints[i]); | 897 | printf("0x%x xx", ints[i]); |
898 | #endif | 898 | #endif |
899 | i++; | 899 | i++; |
900 | } | 900 | } |
901 | x->x_outatc = myargc; | 901 | x->x_outatc = myargc; |
902 | } | 902 | } |
903 | } | 903 | } |
904 | 904 | ||
905 | 905 | ||
906 | #define STRING_ALIGN_PAD 4 | 906 | #define STRING_ALIGN_PAD 4 |
907 | 907 | ||
908 | char *DataAfterAlignedString(char *string, char *boundary) | 908 | char *DataAfterAlignedString(char *string, char *boundary) |
909 | { | 909 | { |
910 | /* The argument is a block of data beginning with a string. The | 910 | /* The argument is a block of data beginning with a string. The |
911 | string has (presumably) been padded with extra null characters | 911 | string has (presumably) been padded with extra null characters |
912 | so that the overall length is a multiple of STRING_ALIGN_PAD | 912 | so that the overall length is a multiple of STRING_ALIGN_PAD |
913 | bytes. Return a pointer to the next byte after the null | 913 | bytes. Return a pointer to the next byte after the null |
914 | byte(s). The boundary argument points to the character after | 914 | byte(s). The boundary argument points to the character after |
915 | the last valid character in the buffer---if the string hasn't | 915 | the last valid character in the buffer---if the string hasn't |
916 | ended by there, something's wrong. | 916 | ended by there, something's wrong. |
917 | 917 | ||
918 | If the data looks wrong, return 0, and set htm_error_string */ | 918 | If the data looks wrong, return 0, and set htm_error_string */ |
919 | 919 | ||
920 | int i; | 920 | int i; |
921 | 921 | ||
922 | if ((boundary - string) %4 != 0) { | 922 | if ((boundary - string) %4 != 0) { |
923 | fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n"); | 923 | fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n"); |
924 | return 0; | 924 | return 0; |
925 | } | 925 | } |
926 | 926 | ||
927 | for (i = 0; string[i] != '\0'; i++) { | 927 | for (i = 0; string[i] != '\0'; i++) { |
928 | if (string + i >= boundary) { | 928 | if (string + i >= boundary) { |
929 | htm_error_string = "DataAfterAlignedString: Unreasonably long string"; | 929 | htm_error_string = "DataAfterAlignedString: Unreasonably long string"; |
930 | return 0; | 930 | return 0; |
931 | } | 931 | } |
932 | } | 932 | } |
933 | 933 | ||
934 | /* Now string[i] is the first null character */ | 934 | /* Now string[i] is the first null character */ |
935 | i++; | 935 | i++; |
936 | 936 | ||
937 | for (; (i % STRING_ALIGN_PAD) != 0; i++) { | 937 | for (; (i % STRING_ALIGN_PAD) != 0; i++) { |
938 | if (string + i >= boundary) { | 938 | if (string + i >= boundary) { |
939 | htm_error_string = "DataAfterAlignedString: Unreasonably long string"; | 939 | htm_error_string = "DataAfterAlignedString: Unreasonably long string"; |
940 | return 0; | 940 | return 0; |
941 | } | 941 | } |
942 | if (string[i] != '\0') { | 942 | if (string[i] != '\0') { |
943 | htm_error_string = "DataAfterAlignedString: Incorrectly padded string."; | 943 | htm_error_string = "DataAfterAlignedString: Incorrectly padded string."; |
944 | return 0; | 944 | return 0; |
945 | } | 945 | } |
946 | } | 946 | } |
947 | 947 | ||
948 | return string+i; | 948 | return string+i; |
949 | } | 949 | } |
950 | 950 | ||
951 | Boolean IsNiceString(char *string, char *boundary) | 951 | Boolean IsNiceString(char *string, char *boundary) |
952 | { | 952 | { |
953 | /* Arguments same as DataAfterAlignedString(). Is the given "string" | 953 | /* Arguments same as DataAfterAlignedString(). Is the given "string" |
954 | really a string? I.e., is it a sequence of isprint() characters | 954 | really a string? I.e., is it a sequence of isprint() characters |
955 | terminated with 1-4 null characters to align on a 4-byte boundary? */ | 955 | terminated with 1-4 null characters to align on a 4-byte boundary? */ |
956 | 956 | ||
957 | int i; | 957 | int i; |
958 | 958 | ||
959 | if ((boundary - string) %4 != 0) { | 959 | if ((boundary - string) %4 != 0) { |
960 | fprintf(stderr, "Internal error: IsNiceString: bad boundary\n"); | 960 | fprintf(stderr, "Internal error: IsNiceString: bad boundary\n"); |
961 | return 0; | 961 | return 0; |
962 | } | 962 | } |
963 | 963 | ||
964 | for (i = 0; string[i] != '\0'; i++) { | 964 | for (i = 0; string[i] != '\0'; i++) { |
965 | if (!isprint(string[i])) return FALSE; | 965 | if (!isprint(string[i])) return FALSE; |
966 | if (string + i >= boundary) return FALSE; | 966 | if (string + i >= boundary) return FALSE; |
967 | } | 967 | } |
968 | 968 | ||
969 | /* If we made it this far, it's a null-terminated sequence of printing characters | 969 | /* If we made it this far, it's a null-terminated sequence of printing characters |
970 | in the given boundary. Now we just make sure it's null padded... */ | 970 | in the given boundary. Now we just make sure it's null padded... */ |
971 | 971 | ||
972 | /* Now string[i] is the first null character */ | 972 | /* Now string[i] is the first null character */ |
973 | i++; | 973 | i++; |
974 | for (; (i % STRING_ALIGN_PAD) != 0; i++) { | 974 | for (; (i % STRING_ALIGN_PAD) != 0; i++) { |
975 | if (string[i] != '\0') return FALSE; | 975 | if (string[i] != '\0') return FALSE; |
976 | } | 976 | } |
977 | 977 | ||
978 | return TRUE; | 978 | return TRUE; |
979 | } | 979 | } |
980 | 980 | ||
981 | 981 | ||
982 | 982 | ||
983 | 983 | ||
984 | 984 | ||
985 | 985 | ||
986 | 986 | ||
987 | 987 | ||
988 | 988 | ||
989 | #include <stdarg.h> | 989 | #include <stdarg.h> |
990 | void complain(char *s, ...) { | 990 | void complain(char *s, ...) { |
991 | va_list ap; | 991 | va_list ap; |
992 | va_start(ap, s); | 992 | va_start(ap, s); |
993 | fprintf(stderr, "*** ERROR: "); | 993 | fprintf(stderr, "*** ERROR: "); |
994 | vfprintf(stderr, s, ap); | 994 | vfprintf(stderr, s, ap); |
995 | fprintf(stderr, "\n"); | 995 | fprintf(stderr, "\n"); |
996 | va_end(ap); | 996 | va_end(ap); |
997 | } | 997 | } |
998 | 998 | ||
999 | #endif /* __sgi or LINUX or WIN32 */ | 999 | #endif /* __sgi or LINUX or WIN32 */ |
1000 | 1000 | ||