0
|
1 // $Id$
|
|
2 //
|
|
3
|
|
4 /*----------------------------------------------------------------------
|
|
5 インクルードファイル読み込み
|
|
6 ----------------------------------------------------------------------*/
|
|
7 #include <sys/file.h>
|
|
8 #include <stdio.h>
|
|
9 #include <stdlib.h>
|
|
10 #include <string.h>
|
|
11 #include <unistd.h>
|
|
12 #include <fcntl.h>
|
|
13 #include <sys/uio.h>
|
|
14 #include <sys/time.h>
|
|
15 #include <sys/select.h>
|
|
16 #include <sys/stat.h>
|
|
17 #include <sys/types.h>
|
|
18 #include <sys/socket.h>
|
|
19 #include <sys/un.h>
|
|
20 #include <netinet/in.h>
|
|
21 #include <netinet/tcp.h>
|
|
22 #include <signal.h>
|
|
23 #include <termios.h>
|
|
24 #include <netdb.h>
|
|
25 #include <errno.h>
|
|
26 #include <sys/select.h>
|
|
27
|
|
28 #include "lindaapi.h"
|
|
29
|
|
30 #define TIMEDELTA 10
|
|
31 #if 0
|
|
32 #define PSX_Debug(deb) (putchar(PS_DEB)),\
|
|
33 (printf deb ),\
|
|
34 (putchar(PS_DEB))
|
|
35 #define DEB(a)
|
|
36 #else
|
|
37 #define PSX_Debug(deb)
|
|
38 #define DEB(a) /* a */
|
|
39 #endif
|
|
40
|
|
41 COMMAND *q_top, *q_end;
|
|
42 REPLY *reply, *r_end;
|
|
43
|
|
44 int qsize, ps;
|
|
45 unsigned short seq;
|
|
46
|
|
47 #ifdef COUNT_PACKET
|
|
48 // print packet count message per PRINT_INTERVAL sec
|
|
49 #define PRINT_INTERVAL 4
|
|
50
|
|
51 /*-------------------------------------------------------------------/
|
|
52 void
|
|
53 count_packet (char type):
|
|
54 パケットの送受信カウントする
|
|
55
|
|
56 引き数:
|
|
57 type - 送信、受信 (char型: s,r)
|
|
58 /-------------------------------------------------------------------*/
|
|
59 void count_packet(char type)
|
|
60 {
|
|
61 static int send_packet=-1,receive_packet=0;
|
|
62 static struct timeval start,now,previous;
|
|
63
|
|
64 if (out_packet == -1) {
|
|
65 gettimeofday(&start,NULL);
|
|
66 gettimeofday(&previous,NULL);
|
|
67 send_packet = 0;
|
|
68 printf("packet\tout\tread\t\ttime\n");
|
|
69 }
|
|
70
|
|
71 if (type == 's') {
|
|
72 send_packet++;
|
|
73 } else if (type == 'r') {
|
|
74 receive_packet++;
|
|
75 } else {
|
|
76 fprintf(stderr,"No type in count_packet function\n");
|
|
77 return;
|
|
78 }
|
|
79
|
|
80 gettimeofday(&now,NULL);
|
|
81 if ((now.tv_sec-previous.tv_sec) > PRINT_INTERVAL) {
|
|
82 printf("log\t%d\t%d\t%ld\n",
|
|
83 send_packet,receive_packet,now.tv_sec-start.tv_sec);
|
|
84 fflush(stdout);
|
|
85
|
|
86 previous.tv_sec = now.tv_sec;
|
|
87 send_packet = receive_packet = 0;
|
|
88 }
|
|
89 }
|
|
90 #endif
|
|
91
|
|
92
|
|
93 #define unix_open open
|
|
94 #define unix_read_w read
|
|
95 /*-------------------------------------------------------------------/
|
|
96 int
|
|
97 unix_read (int fd, char *buf, unsigned int size):
|
|
98 サーバからTUPLEを読みこむ。
|
|
99 現在は使われていない。
|
|
100
|
|
101 引き数:
|
|
102 fd - サーバのファイルディスクリプタ
|
|
103 buf - 受け取るデータの格納場所(TUPLEヘッダ含む)
|
|
104 size - bufのbyte数
|
|
105 返り値:
|
|
106 読みこんだbyte数
|
|
107 /-------------------------------------------------------------------*/
|
|
108 int
|
|
109 unix_read(int fd,char *buf,unsigned int size) {
|
|
110 int len,a,i;
|
|
111 if(read(fd,buf,INT_SIZE)!=INT_SIZE) { // INT_SIZE is sizeof(int)
|
|
112 fprintf(stderr, "read error! on fd:%d len=%d %s\n", fd,
|
|
113 *(unsigned int*)&buf[0],
|
|
114 strerror(errno));
|
|
115 exit(1);
|
|
116 }
|
|
117 len = ntohl(*(unsigned int*)&buf[0]);
|
|
118 if(len>size) len=size;
|
|
119 for(a=0;a<len;a+=i) {
|
|
120 if((i=read(fd,buf+a,len-a))<0) {
|
|
121 fprintf(stderr, "ldserv: client read error! on i=%d len= %d %s\n",
|
|
122 i, len, strerror(errno));
|
|
123 exit(1);
|
|
124 }
|
|
125 }
|
|
126 return len;
|
|
127 }
|
|
128
|
|
129 /*-------------------------------------------------------------------/
|
|
130 int
|
|
131 unix_write (int fd, unsigned char *buf, unsigned int size):
|
|
132 サーバへTUPLEを送る。
|
|
133
|
|
134 引き数:
|
|
135 fd - サーバのファイルディスクリプタ
|
|
136 buf - サーバへ送るデータ(TUPLEヘッダ含む)
|
|
137 size - bufのbyte数
|
|
138 返り値:
|
|
139 送った(書きこんだ)データのbyte数
|
|
140 /-------------------------------------------------------------------*/
|
|
141 int
|
|
142 unix_write(int fd,unsigned char *buf,unsigned int size) {
|
|
143 int i,nsize;
|
|
144 nsize = htonl(size);
|
|
145 i = write(fd,&nsize,INT_SIZE);
|
|
146 i += write(fd,buf,size); // size == datasize + LINDA_HEADER_SIZE
|
|
147 #ifdef COUNT_PACKET
|
|
148 count_packet('s');
|
|
149 #endif
|
|
150 return(i);
|
|
151 }
|
|
152
|
|
153 #define unix_write_w unix_write
|
|
154
|
|
155 #define SERV_NAME unix_port
|
|
156 #define PROTO_NAME "tcp"
|
|
157 #define SERVER_NAME hostname
|
|
158 #define MAX_REQ 16
|
|
159
|
|
160 int fd,paddrlen;
|
|
161 struct hostent *hoste;
|
|
162 struct sockaddr_in serv_addr;
|
|
163 struct sockaddr_un serv_addr_un;
|
|
164 unsigned char ipaddr[4];
|
|
165
|
|
166
|
|
167 /*-------------------------------------------------------------------/
|
|
168 int
|
|
169 start_linda (char * hostname):
|
|
170 サーバとのコネクションを確立し、COMMANDキューとREPLYキューの
|
|
171 初期化を行なう。
|
|
172
|
|
173 引き数:
|
|
174 hostname - サーバのホスト名
|
|
175 返り値:
|
|
176 コネクション確立が成功するとそのファイルディスクリプタを返す。
|
|
177 失敗すると -1 を返す。
|
|
178 /-------------------------------------------------------------------*/
|
|
179 int
|
|
180 start_linda(char * hostname){
|
|
181 char *p;
|
|
182
|
|
183 if (! hostname) {
|
|
184 hostname = "/tmp/ldserv";
|
|
185 }
|
|
186 if (hostname[0]=='/') {
|
|
187 /* Unix domain */
|
|
188 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == FAIL){
|
|
189 fprintf(stderr, "socket open error! errno :%d %s\n", errno,
|
|
190 strerror(errno));
|
|
191 return(-1);
|
|
192 }
|
|
193 serv_addr_un.sun_family = AF_UNIX;
|
|
194 strcpy(serv_addr_un.sun_path, hostname);
|
|
195 fprintf(stdout,"connecting ... %d\n", serv_addr.sin_port);
|
|
196 if (connect(fd, (struct sockaddr *)&serv_addr_un,sizeof(serv_addr_un)) == FAIL){
|
|
197 fprintf(stderr,"connection error! errno :%d %s\n", errno,
|
|
198 strerror(errno));
|
|
199 close(fd);
|
|
200 return(-1);
|
|
201 }
|
|
202
|
|
203 } else {
|
|
204 /* INET domain */
|
|
205 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == FAIL){
|
|
206 fprintf(stderr, "socket open error! errno :%d %s\n", errno,
|
|
207 strerror(errno));
|
|
208 return(-1);
|
|
209 }
|
|
210 /* check optional port number */
|
|
211 serv_addr.sin_port = 11511;
|
|
212 p = (char *)malloc(strlen(hostname));
|
|
213 strcpy(p,hostname);
|
|
214 hostname = p;
|
|
215 while(*p) {
|
|
216 if (*p==':') {
|
|
217 serv_addr.sin_port = atoi(p+1);
|
|
218 *p = 0;
|
|
219 break;
|
|
220 }
|
|
221 p++;
|
|
222 }
|
|
223 if ((hoste = gethostbyname(hostname)) == NULL){
|
|
224 fprintf(stderr,"hostname error\n");
|
|
225 close(fd);
|
|
226 return(-1);
|
|
227 }
|
|
228 free(hostname); hostname=0;
|
|
229 serv_addr.sin_family = AF_INET;
|
|
230 serv_addr.sin_addr.s_addr = ((struct in_addr *)(hoste->h_addr))->s_addr;
|
|
231 if (serv_addr.sin_family == AF_INET) {
|
|
232 int tmp = 1;
|
|
233 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY,
|
|
234 (char *) &tmp, sizeof (int));
|
|
235 }
|
|
236 fprintf(stdout,"connecting ... %d\n", serv_addr.sin_port);
|
|
237 if (connect(fd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) == FAIL){
|
|
238 fprintf(stderr,"connection error! errno :%d %s\n", errno,
|
|
239 strerror(errno));
|
|
240 close(fd);
|
|
241 return(-1);
|
|
242 }
|
|
243 }
|
|
244
|
|
245 ps = fd;
|
|
246 fprintf(stdout," connect middle server %d\n", fd);
|
|
247 q_end = q_top = NULL;
|
|
248 r_end = reply = NULL;
|
|
249 qsize = seq = 0;
|
|
250 seq = 120;
|
|
251 return ps;
|
|
252 }
|
|
253
|
|
254 /*-------------------------------------------------------------------/
|
|
255 int
|
|
256 psx_out (unsigned int id, unsigned char *data, unsigned int size):
|
|
257 outコマンドをCOMMANDキューへ溜める。
|
|
258
|
|
259 引き数:
|
|
260 id - TUPLE SpaceのID
|
|
261 data - 送信するデータ
|
|
262 size - dataのサイズ
|
|
263 返り値:
|
|
264 シーケンス番号
|
|
265 /-------------------------------------------------------------------*/
|
|
266 int
|
|
267 psx_out(unsigned int id, unsigned char *data, unsigned int size){
|
|
268 if (psx_queue(id, size, data, 'o', NULL, NULL) == FAIL){
|
|
269 return(FAIL);
|
|
270 }
|
|
271 DEB( fprintf(stdout, "psx_out: size = %d, command = %s\n",
|
|
272 q_end->size, q_end->command+LINDA_HEADER_SIZE));
|
|
273 return(seq);
|
|
274 }
|
|
275
|
|
276 /*-------------------------------------------------------------------/
|
|
277 int
|
|
278 psx_ld (unsigned int id, char mode, void(*callback)(char*,void*),
|
|
279 void * obj):
|
|
280 in,read,waitなどの受信コマンドをCOMMANDキューへ溜める。
|
|
281 psx_in,psx_rd,psx_wait_rdなどに置き換えられている。
|
|
282
|
|
283 引き数:
|
|
284 id - TUPLE SpaceのID
|
|
285 mode - i,r,w の文字を取り、各々in,read,waitを表している。
|
|
286 callback - コールバックを使用する場合の関数へのポインタ。
|
|
287 使用しない場合はNULLをいれる。
|
|
288 obj - コールバックで用いる関数の引き数。
|
|
289 返り値:
|
|
290 psx_queue内でmallocされたREPLY構造体へのポインタ
|
|
291 /-------------------------------------------------------------------*/
|
|
292 int
|
|
293 psx_ld(unsigned int id, char mode,void(*callback)(char *,void *),void * obj){
|
|
294 int r;
|
|
295 if ((r=psx_queue(id, 0, NULL, mode, callback, obj)) == FAIL){
|
|
296 return(FAIL);
|
|
297 }
|
|
298 return(r);
|
|
299 }
|
|
300
|
|
301 /*-------------------------------------------------------------------/
|
|
302 unsigned char *
|
|
303 psx_reply (int seq):
|
|
304 サーバから答えが来たデータを返す。
|
|
305
|
|
306 引き数:
|
|
307 seq - psx_ld()が返した値。
|
|
308 返り値:
|
|
309 seqに対応したデータを返す。データをまだ受信していない場合は
|
|
310 NULLを返す。
|
|
311 /-------------------------------------------------------------------*/
|
|
312 unsigned char *
|
|
313 psx_reply(int seq){
|
|
314 REPLY *p, *q;
|
|
315 char *ans;
|
|
316
|
|
317 DEB(fprintf(stdout, "psx_reply: search of seq = %d\n", seq));
|
|
318 PSX_Debug(("psx_reply: seq %d", seq));
|
|
319 for(q = NULL,p = reply;p;q = p,p = p->next){
|
|
320 if (p->seq == seq){
|
|
321 DEB(fprintf(stdout, "psx_reply: match of seq = %d\n", seq));
|
|
322 if (p->mode == '!'){
|
|
323 ans = p->answer;
|
|
324 if (q == NULL){
|
|
325 reply = p->next;
|
|
326 if(p==r_end) {
|
|
327 r_end = p->next;
|
|
328 }
|
|
329 } else {
|
|
330 q->next = p->next;
|
|
331 if(p==r_end) {
|
|
332 r_end = q;
|
|
333 }
|
|
334 }
|
|
335 PSX_Debug(("psx_reply: reply %x r_end %x p %x q %x",reply,r_end,p,q));
|
|
336 free(p);
|
|
337 DEB( for(p=reply;p;p=p->next) { PSX_Debug(("psx_queue dump: seq %d mode %c %x %x",p->seq,p->mode,p,p->next))});
|
|
338 DEB( fprintf(stdout, "psx_reply: returned answer = %s\n", ans));
|
|
339 PSX_Debug(("psx_reply: answer %s",ans));
|
|
340 return(ans);
|
|
341 } else {
|
|
342 if (p->mode == '?'){
|
|
343 DEB(fprintf(stdout, "psx_reply: don't accept anser\n"));
|
|
344 return(NULL);
|
|
345 }
|
|
346 }
|
|
347 }
|
|
348
|
|
349 }
|
|
350 PSX_Debug(("psx_reply: no match seq %d",seq));
|
|
351 DEB(fprintf(stdout, "psx_reply: no match of seq\n"));
|
|
352 return(NULL);
|
|
353 }
|
|
354
|
|
355 /*-------------------------------------------------------------------/
|
|
356 void
|
|
357 psx_sync_n ():
|
|
358 サーバとデータの送受信をする。COMMANDキューに溜まったデータを
|
|
359 送信し、サーバから送られて来たデータを対応するREPLYへいれる。
|
|
360 /-------------------------------------------------------------------*/
|
|
361 void
|
|
362 psx_sync_n(){
|
|
363 int acount;
|
|
364 COMMAND *c, *t;
|
|
365
|
|
366 fd_set tmp, fds;
|
|
367 struct timeval timeout;
|
|
368 timeout.tv_sec=0;
|
|
369 timeout.tv_usec=TIMEDELTA * 1000;
|
|
370
|
|
371 acount = 0;
|
|
372 while (q_top != NULL){
|
|
373 c = q_top;
|
|
374 unix_write_w(ps, c->command, c->size);
|
|
375 free(c->command);
|
|
376 t = c->next;
|
|
377 free(c);
|
|
378 q_top = c = t;qsize--;
|
|
379 }
|
|
380 FD_ZERO(&fds);
|
|
381 FD_SET(ps, &fds);
|
|
382 tmp = fds;
|
|
383 while(select(32, &tmp, NULL, NULL, &timeout) > 0) {
|
|
384 if(FD_ISSET(ps, &tmp)) {
|
|
385 unix_chkserv();
|
|
386 }
|
|
387 }
|
|
388 }
|
|
389
|
|
390 /*-------------------------------------------------------------------/
|
|
391 int
|
|
392 psx_queue (unsigned int id, unsigned int size, unsigned char *data,
|
|
393 char mode, void(*callback)(char*,void*), void * obj):
|
|
394 out,in,read,waitなどのコマンドをCOMMANDキューに溜める。データを
|
|
395 受信するコマンド(in,read,wait)のときは受け取ったときにデータを
|
|
396 格納するREPLY構造体を作る。
|
|
397
|
|
398 引き数:
|
|
399 id - アクセスするTUPLE SpaceのID
|
|
400 size - dataのサイズ
|
|
401 data - 送信するデータ。受信時はNULL。
|
|
402 mode - コマンドのモード(out,in,read,wait は各々char型: o,i,r,w)
|
|
403 callback - コールバックを使用する場合の関数へのポインタ。
|
|
404 使用しない場合はNULL。
|
|
405 obj - コールバックで用いる関数に引き渡すデータ。
|
|
406 返り値:
|
|
407 成功した場合 - mallocしたREPLY構造体へのポインタ。outの場合は
|
|
408 0が返る。
|
|
409 失敗した場合 - FAIL(-1)が返る。
|
|
410 /-------------------------------------------------------------------*/
|
|
411 int
|
|
412 psx_queue(unsigned int id, unsigned int size, unsigned char *data, char mode,
|
|
413 void(*callback)(char *,void *), void * obj){
|
|
414 REPLY *p;
|
|
415 COMMAND *c;
|
|
416
|
|
417 seq++;
|
|
418 if (qsize >= MAX_QUEUE){
|
|
419 // PSX_Debug(("max queue: qsize=%d",qsize));
|
|
420 psx_sync_n();
|
|
421 }
|
|
422
|
|
423 for(p=reply;p;p=p->next){
|
|
424 if(p->seq == seq){
|
|
425 printf("same seq number: %d\n",seq);
|
|
426 }
|
|
427 }
|
|
428
|
|
429 if (q_top == NULL){
|
|
430 if ((q_top = (COMMAND *) malloc (sizeof(COMMAND))) == NULL){
|
|
431 return(FAIL);
|
|
432 }
|
|
433 c = q_end = q_top;
|
|
434 } else {
|
|
435 if ((q_end->next = (COMMAND *) malloc (sizeof(COMMAND))) == NULL){
|
|
436 return(FAIL);
|
|
437 }
|
|
438 c = q_end;
|
|
439 q_end = q_end->next;
|
|
440 }
|
|
441
|
|
442 // size は DATASIZE
|
|
443 if ((q_end->command = (unsigned char *) malloc(size+LINDA_HEADER_SIZE)) == NULL){
|
|
444 free(q_end);
|
|
445 c->next = NULL;
|
|
446 return(FAIL);
|
|
447 }
|
|
448
|
|
449 if (mode != 'o'){
|
|
450 if (reply == NULL){
|
|
451 if ((reply = (REPLY *) malloc (sizeof(REPLY))) == NULL){
|
|
452 return(FAIL);
|
|
453 }
|
|
454 p = r_end = reply; p->next = NULL;
|
|
455 } else {
|
|
456 if ((r_end->next = (REPLY *) malloc (sizeof(REPLY))) == NULL){
|
|
457 return(FAIL);
|
|
458 }
|
|
459 p = r_end->next; r_end = p; p->next = NULL;
|
|
460 }
|
|
461 p->mode = '?';
|
|
462 p->seq = (int)p; // 構造体のアドレスで識別
|
|
463 p->callback = callback;
|
|
464 p->obj = obj;
|
|
465 PSX_Debug(("psx_queue: seq %d reply %x p %x r_end %x",seq,reply,p,r_end));
|
|
466 }else{
|
|
467 p=0;
|
|
468 }
|
|
469 q_end->command[LINDA_MODE_OFFSET] = mode;
|
|
470
|
|
471 q_end->command[LINDA_ID_OFFSET] = id >> 8;
|
|
472 q_end->command[LINDA_ID_OFFSET+1] = id & 0xff;
|
|
473
|
|
474 q_end->command[LINDA_SEQ_OFFSET] = ((int)p>>24) & 0xff;
|
|
475 q_end->command[LINDA_SEQ_OFFSET+1] = ((int)p>>16) & 0xff;
|
|
476 q_end->command[LINDA_SEQ_OFFSET+2] = ((int)p>>8) & 0xff;
|
|
477 q_end->command[LINDA_SEQ_OFFSET+3] = ((int)p) & 0xff;
|
|
478
|
|
479 q_end->command[LINDA_DATA_LENGTH_OFFSET] = (size>>24) & 0xff;
|
|
480 q_end->command[LINDA_DATA_LENGTH_OFFSET+1] = (size>>16) & 0xff;
|
|
481 q_end->command[LINDA_DATA_LENGTH_OFFSET+2] = (size>>8) & 0xff;
|
|
482 q_end->command[LINDA_DATA_LENGTH_OFFSET+3] = (size) & 0xff;
|
|
483
|
|
484 q_end->size = size+LINDA_HEADER_SIZE; /* command size */
|
|
485 q_end->next = NULL; qsize++;
|
|
486 if (data && size>0) memcpy(q_end->command+LINDA_HEADER_SIZE, data, size);
|
|
487 return((int)p);
|
|
488 }
|
|
489
|
|
490 /*-------------------------------------------------------------------/
|
|
491 void
|
|
492 unix_chkserv ():
|
|
493 サーバからデータ(TUPLE)を受け取る。REPLY構造体にコールバック関数
|
|
494 が指定されていればその関数を実行し、REPLY構造体をキューから取り
|
|
495 除く。コールバック関数が指定されていなければREPLY構造体にデータ
|
|
496 を引き渡す。
|
|
497 /-------------------------------------------------------------------*/
|
|
498 void
|
|
499 unix_chkserv(){
|
|
500 int i,k,pkt,npkt;
|
|
501 REPLY *r,*prev;
|
|
502 int a;
|
|
503 unsigned char * tuple = 0;
|
|
504
|
|
505 if((i=read(ps,&npkt,INT_SIZE))<0) {
|
|
506 fprintf(stderr, "size read error! on fd:%d %s\n", ps,
|
|
507 strerror(errno));
|
|
508 exit(1);
|
|
509 }
|
|
510 pkt = ntohl(npkt);
|
|
511 DEB(printf("pkt: %d\n",pkt));
|
|
512 DEB(fprintf(stdout, "psx_chkserv: queue number: %d , size = %d\n", i, pkt));
|
|
513 if((tuple = (unsigned char *)malloc(pkt))==NULL){
|
|
514 fprintf(stderr,"allocate error! errno :%d %s",errno,strerror(errno));
|
|
515 exit(1);
|
|
516 }
|
|
517 for(a=0;a<pkt;a+=i) {
|
|
518 if((i=unix_read_w(ps,tuple+a,pkt-a))<0) {
|
|
519 fprintf(stderr, "psx_chkserv: read error! on i=%d pkt=%d %s\n",
|
|
520 i, pkt, strerror(errno));
|
|
521 exit(1);//close(ps);
|
|
522 }
|
|
523 }
|
|
524
|
|
525 #ifdef COUNT_PACKET
|
|
526 count_packet('r');
|
|
527 #endif
|
|
528
|
|
529 i = tuple[LINDA_ID_OFFSET] * 256 + tuple[LINDA_ID_OFFSET+1]; /* id */
|
|
530 k = (tuple[LINDA_SEQ_OFFSET] <<24) +
|
|
531 (tuple[LINDA_SEQ_OFFSET+1]<<16) +
|
|
532 (tuple[LINDA_SEQ_OFFSET+2]<<8) +
|
|
533 (tuple[LINDA_SEQ_OFFSET+3]); /* seq */
|
|
534 PSX_Debug(("psx_chkserv: anser packet size = %d id %d seq %d", pkt,i,k));
|
|
535 DEB(fprintf(stdout, "psx_chkserv: data from server: %s id=%d seq = %d\n", tuple, i, k));
|
|
536 DEB (
|
|
537 for(p=reply;p;p=p->next) {
|
|
538 PSX_Debug(printf("psx_queue dump: seq %d mode %c %x %x",p->seq,p->mode,p,p->next));
|
|
539 })
|
|
540
|
|
541 for(prev = NULL,r = reply; r; prev = r,r = r->next){
|
|
542 DEB(fprintf(stdout,"seq: %d\n",r->seq);)
|
|
543 if (r->seq == k){
|
|
544 if(r->callback){ // call callback function
|
|
545 (*r->callback)(tuple,r->obj);
|
|
546 if (prev == NULL){
|
|
547 reply = r->next;
|
|
548 if(r == r_end) {
|
|
549 r_end = r->next;
|
|
550 }
|
|
551 } else {
|
|
552 prev->next = r->next;
|
|
553 if(r == r_end) {
|
|
554 r_end = prev;
|
|
555 }
|
|
556 }
|
|
557 free(r);
|
|
558 }else{ // normal reply
|
|
559 PSX_Debug(("psx_chkserv: copy answer r %x seq %d",r,k));
|
|
560 r->answer = tuple;
|
|
561 r->mode = '!';
|
|
562 }
|
|
563 break;
|
|
564 }
|
|
565 }
|
|
566 tuple = 0;
|
|
567 if (!r){
|
|
568 DEB(fprintf(stdout, "unix_chkserv: accepted seq %d does not match. \n",k));
|
|
569 }
|
|
570 }
|
|
571
|
|
572 void psx_free(unsigned char * tuple)
|
|
573 {
|
|
574 // free(tuple - LINDA_HEADER_SIZE);
|
|
575 free(tuple);
|
|
576 }
|
|
577
|
|
578 /*-------------------------------------------------------------------/
|
|
579 int
|
|
580 get_int(unsigned char * tuple, int offset):
|
|
581 TUPLEのヘッダに格納された int型 のデータを得るための関数
|
|
582 psx_get_datalength() と psx_get_seq() から呼ばれる。
|
|
583
|
|
584 引き数:
|
|
585 tuple - ヘッダ情報も含んだTUPLE。psx_reply()で得たものでもいい。
|
|
586 offset - 取りだすデータのオフセット。LINDA_DATA_LENGTH_OFFSET
|
|
587 か LINDA_SEQ_OFFSET。
|
|
588
|
|
589 返り値:
|
|
590 指定したオフセットに格納されていた数値(int型)
|
|
591 /-------------------------------------------------------------------*/
|
|
592 static
|
|
593 int get_int(unsigned char * tuple, int offset){
|
|
594 int i;
|
|
595 i = (tuple[offset] <<24) +
|
|
596 (tuple[offset+1]<<16) +
|
|
597 (tuple[offset+2]<<8) +
|
|
598 (tuple[offset+3]);
|
|
599 return i;
|
|
600 }
|
|
601
|
|
602 int psx_get_datalength(unsigned char * tuple){
|
|
603 return get_int(tuple,LINDA_DATA_LENGTH_OFFSET);
|
|
604 }
|
|
605
|
|
606 unsigned char *psx_get_data(unsigned char * tuple){
|
|
607 return tuple+LINDA_HEADER_SIZE;
|
|
608 }
|
|
609
|
|
610 int psx_get_seq(unsigned char * tuple){
|
|
611 return get_int(tuple,LINDA_SEQ_OFFSET);
|
|
612 }
|
|
613
|
|
614 short psx_get_id(unsigned char * tuple){
|
|
615 short s;
|
|
616 s = tuple[LINDA_ID_OFFSET] * 256 +
|
|
617 tuple[LINDA_ID_OFFSET+1];
|
|
618 return s;
|
|
619 }
|
|
620
|
|
621 char psx_get_mode(unsigned char * tuple){
|
|
622 return tuple[LINDA_MODE_OFFSET];
|
|
623 }
|
|
624
|
|
625
|
|
626 /* end */
|