Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanFukusyaYa/DriveAccess/netaccess.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.23 - (show annotations) (download) (as text)
Mon Nov 1 14:34:11 2010 UTC (13 years, 5 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.22: +192 -192 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * @file netaccess.c
3 * @brief ネットワークアクセス
4 * @author BananaJinn
5 * @version $Id: netaccess.c,v 1.22 2009/12/27 16:27:13 bananajinn Exp $
6 * 円盤複写屋
7 * Copyright (C) 2004-2006 BananaJinn<banana@mxh.mesh.ne.jp>.
8 */
9 #include <stdio.h>
10 #if defined(__APPLE__) && defined(__MACH__)
11 # include <sys/time.h>
12 #endif
13 #if defined(linux) || defined(MACOSX)
14 # include <errno.h>
15 # include <stdlib.h>
16 # include <string.h>
17 # include <unistd.h>
18 # include <netinet/in.h>
19 # include <arpa/inet.h>
20 # include <netdb.h>
21 # define INVALID_SOCKET (-1)
22 # define SOCKET_ERROR (-1)
23 # define SD_SEND SHUT_WR
24 # define SD_RECEIVE SHUT_RD
25 # define SD_BOTH SHUT_RDWR
26 # define closesocket close
27 #endif
28 #if defined(__MINGW32__)
29 # include <errno.h>
30 #endif
31
32 #include "mem.h"
33 #include "cmd.h"
34 #include "netaccess.h"
35 #include "ui.h"
36 #include "text.h"
37 #include "ebstring.h"
38
39 static void SetErrorCode(SOCKCB *scb)
40 {
41 #if defined(WIN32)
42 scb->error_code = WSAGetLastError();
43 #else
44 scb->error_code = errno;
45 #endif
46 }
47
48 /**
49 * @brief ソケット待ち
50 * @param[out] read_fds 読み込み用
51 * @param[out] write_fds 書き込み用
52 * @param[out] except_fds 例外用
53 * @param[in] sd ソケットデスクリプタ
54 * @param[in] timeout タイムアウト(ミリ秒)
55 * @retval RET_OK ソケット入出力有り
56 * @retval RET_TIMEOUT タイムアウト
57 * @retval RET_NG エラー
58 */
59 static int WaitFDS(fd_set *read_fds, fd_set *write_fds, fd_set *except_fds,
60 SOCKET sd, DWORD timeout)
61 {
62 struct timeval timeout_val;
63 int ret;
64
65 if(read_fds != NULL){
66 FD_ZERO(read_fds);
67 }
68 if(write_fds != NULL){
69 FD_ZERO(write_fds);
70 }
71 if(except_fds != NULL){
72 FD_ZERO(except_fds);
73 }
74
75 if(read_fds != NULL){
76 FD_SET(sd, read_fds);
77 }
78 if(write_fds != NULL){
79 FD_SET(sd, write_fds);
80 }
81 if(except_fds != NULL){
82 FD_SET(sd, except_fds);
83 }
84
85 timeout_val.tv_sec = timeout/1000;
86 timeout_val.tv_usec = (timeout%1000)*1000;
87 ret = select(sd+1, read_fds, write_fds, except_fds, &timeout_val);
88 #if defined(WIN32)
89 if(ret == SOCKET_ERROR){
90 return RET_NG;
91 }
92 #else
93 if(ret < 0){
94 return RET_NG;
95 }
96 #endif
97 if(ret == 0){
98 return RET_TIMEOUT;
99 }
100 return RET_OK;
101 }
102
103
104 /**
105 * @brief ソケット制御ブロック初期化
106 * @param[out] scb 初期化するソケット制御ブロック
107 * @retval RET_OK 正常終了
108 * @retval RET_SOCKET ソケットエラー
109 */
110 int InitializeSOCKCB(SOCKCB *scb)
111 {
112 #if defined(WIN32)
113 WSADATA wsadata;
114 #endif
115
116 memset(scb, 0, sizeof(SOCKCB));
117
118 #if defined(WIN32)
119 if(WSAStartup(MAKEWORD(1,1), &wsadata) != 0){
120 SetErrorCode(scb);
121 return RET_SOCKET;
122 }
123 #endif
124
125 return RET_OK;
126 }
127
128 /**
129 * @brief ソケット制御ブロック解放
130 * @param[in] scb 解放するソケット制御ブロック
131 * @retval RET_OK 正常終了
132 */
133 int FreeSOCKCB(SOCKCB *scb)
134 {
135 NAClose(scb);
136 if(scb->remote_host != NULL){
137 MemFree(scb->remote_host);
138 scb->remote_host = NULL;
139 }
140 #if defined(linux) || defined(__MINGW32__)
141 if(scb->iconv_desc != NULL){
142 iconv_close(scb->iconv_desc);
143 }
144 #endif
145 memset(scb, 0, sizeof(SOCKCB));
146
147 #if defined(WIN32)
148 WSACleanup();
149 #endif
150
151 return RET_OK;
152 }
153
154
155 /**
156 * @brief サーバソケット作成
157 * @param[in,out] scb ソケット制御ブロック
158 * @retval RET_OK 正常終了
159 * @retval RET_SOCKET ソケットエラー
160 */
161 int NACreateServer(SOCKCB *scb)
162 {
163 int ret;
164 struct sockaddr_in sin;
165
166 scb->server_mode = TRUE;
167
168 /* Setup listener */
169 scb->u.server.listen_socket = socket(AF_INET, SOCK_STREAM, 0);
170 if(scb->u.server.listen_socket == INVALID_SOCKET){
171 SetErrorCode(scb);
172 return RET_SOCKET;
173 }
174 memset(&sin, 0, sizeof(sin));
175 sin.sin_family = AF_INET;
176 sin.sin_addr.s_addr = INADDR_ANY;
177 sin.sin_port = htons(scb->u.server.port);
178 ret = bind(scb->u.server.listen_socket,
179 (struct sockaddr *)&sin,
180 sizeof(struct sockaddr_in));
181 if(ret == SOCKET_ERROR){
182 SetErrorCode(scb);
183 return RET_SOCKET;
184 }
185
186 listen(scb->u.server.listen_socket, 1);
187
188 #if defined(__MINGW32__)
189 /* SJIS => UTF-8 */
190 scb->iconv_desc = iconv_open("UTF-8", "SJIS");
191 #elif defined(linux)
192 /* SJIS => local charset */
193 scb->iconv_desc = iconv_open("", "SJIS");
194 #endif
195
196 return RET_OK;
197 }
198
199 /**
200 * @brief ソケット接続要求待ち
201 * @param[in,out] scb ソケット制御ブロック
202 * @param[in] timeout タイムアウト時間(ミリ秒)
203 * @retval RET_OK 正常終了
204 * @retval RET_TIMEOUT タイムアウト発生
205 * @retval RET_SOCKET ソケットエラー
206 * @retval RET_NG その他のエラー
207 */
208 int NAWaitConnect(SOCKCB *scb, DWORD timeout)
209 {
210 struct sockaddr_in sin_remote;
211 #if defined(linux)
212 socklen_t addr_size;
213 #else
214 int addr_size;
215 #endif
216 fd_set read_fds;
217 int ret;
218 char *remote_host;
219
220 if(scb->server_mode == FALSE){
221 scb->error_code = 0;
222 return RET_NG;
223 }
224
225 ret = WaitFDS(&read_fds, NULL, NULL, scb->u.server.listen_socket, timeout);
226 if(ret != RET_OK){
227 if(ret==RET_TIMEOUT){
228 return ret;
229 }
230 SetErrorCode(scb);
231 return RET_SOCKET;
232 }
233
234 if(!FD_ISSET(scb->u.server.listen_socket, &read_fds)){
235 SetErrorCode(scb);
236 return RET_SOCKET;
237 }
238
239 /* Accept connection */
240 addr_size = sizeof(sin_remote);
241 scb->u.server.socket_desc = accept(scb->u.server.listen_socket,
242 (struct sockaddr *)&sin_remote,
243 &addr_size);
244 if(scb->u.server.socket_desc == INVALID_SOCKET){
245 SetErrorCode(scb);
246 return RET_SOCKET;
247 }
248
249 remote_host = inet_ntoa(sin_remote.sin_addr);
250 scb->remote_host = MemNew(strlen(remote_host)+1);
251 strncpy(scb->remote_host, remote_host, strlen(remote_host)+1);
252
253 return RET_OK;
254 }
255
256
257 /**
258 * @brief ソケット接続
259 * @param[in,out] scb ソケット制御ブロック
260 * @retval RET_OK 正常終了
261 * @retval RET_SOCKET ソケットエラー
262 * @retval RET_NG その他のエラー
263 */
264 int NAConnect(SOCKCB *scb)
265 {
266 DWORD remaddr;
267 struct hostent *hent;
268 struct sockaddr_in sin_remote;
269
270 if(scb->remote_host == NULL){
271 return RET_NG;
272 }
273
274 /* lookup remote address */
275 remaddr = inet_addr(scb->remote_host);
276 if(remaddr == INADDR_NONE){
277 hent = gethostbyname(scb->remote_host);
278 if(hent == NULL){
279 SetErrorCode(scb);
280 return RET_SOCKET;
281 }
282 remaddr = *((DWORD*)hent->h_addr_list[0]);
283 }
284 scb->u.client.remote_address = remaddr;
285
286 scb->u.client.socket_desc = socket(AF_INET, SOCK_STREAM, 0);
287 if(scb->u.client.socket_desc == INVALID_SOCKET){
288 SetErrorCode(scb);
289 return RET_SOCKET;
290 }
291
292 memset(&sin_remote, 0, sizeof(sin_remote));
293 sin_remote.sin_family = AF_INET;
294 sin_remote.sin_addr.s_addr = scb->u.client.remote_address;
295 sin_remote.sin_port = htons(scb->u.client.remote_port);
296 if(connect(scb->u.client.socket_desc,
297 (struct sockaddr*)&sin_remote,
298 sizeof(sin_remote)) == SOCKET_ERROR){
299 SetErrorCode(scb);
300 shutdown(scb->u.client.socket_desc, SD_BOTH);
301 closesocket(scb->u.client.socket_desc);
302 scb->u.client.socket_desc = 0;
303 return RET_SOCKET;
304 }
305
306 #if defined(__MINGW32__)
307 /* UTF-8 => SJIS */
308 scb->iconv_desc = iconv_open("SJIS", "UTF-8");
309 #elif defined(linux)
310 /* local charset => SJIS */
311 scb->iconv_desc = iconv_open("SJIS", "");
312 #endif
313
314 return RET_OK;
315 }
316
317
318 /**
319 * @brief ソケットクローズ
320 * @param[in,out] scb ソケット制御ブロック
321 * @retval RET_OK 正常終了
322 * @retval RET_SOCKET ソケットエラー
323 */
324 int NAClose(SOCKCB *scb)
325 {
326 SOCKET sd;
327 int read_bytes;
328 char buf[256];
329 fd_set read_fds;
330 int ret;
331
332 if(scb->server_mode){
333 sd = scb->u.server.socket_desc;
334 }
335 else{
336 sd = scb->u.client.socket_desc;
337 }
338
339 if(sd > 0){
340 shutdown(sd, SD_SEND);
341
342 while(1){
343 ret = WaitFDS(&read_fds, NULL, NULL, sd, 30*1000);
344 if(ret == RET_TIMEOUT){
345 continue;
346 }
347 else if(ret != RET_OK){
348 break;
349 }
350 read_bytes = recv(sd, buf, sizeof(buf), 0);
351 if(read_bytes == SOCKET_ERROR){
352 break;
353 }
354 else if(read_bytes == 0){
355 break;
356 }
357 }
358
359 shutdown(sd, SD_RECEIVE);
360
361 if(closesocket(sd) == SOCKET_ERROR){
362 SetErrorCode(scb);
363 return RET_SOCKET;
364 }
365 }
366
367 if(scb->server_mode){
368 closesocket(scb->u.server.listen_socket);
369 }
370
371 return RET_OK;
372 }
373
374
375 /**
376 * @brief ソケット送信
377 * @param[in,out] scb ソケット制御ブロック
378 * @param[in] buffer 送信データバッファ
379 * @param[in] length 送信データバイト数
380 * @param[in] tmieout タイムアウト(ミリ秒)
381 * @param[in] check_readfd READ用fdを監視するかどうか
382 * @retval RET_OK 正常終了
383 * @retval RET_READFD check_readfd指定時にREAD用のfdが読み取り可能となった
384 * @retval RET_SOCKET ソケットエラー
385 * @retval RET_ABORT 接続断念
386 * @retval RET_TIMEOUT タイムアウト発生
387 * @retval RET_NG その他のエラー
388 */
389 int NASend(SOCKCB *scb, const void *buffer, int length, DWORD timeout,
390 BOOL check_readfd)
391 {
392 fd_set read_fds;
393 fd_set write_fds;
394 int ret;
395 SOCKET sd;
396 int write_bytes;
397 const char *bufp = (const char *)buffer;
398
399 if(scb->server_mode){
400 sd = scb->u.server.socket_desc;
401 }
402 else{
403 sd = scb->u.client.socket_desc;
404 }
405
406 while(length > 0){
407 ret = WaitFDS(check_readfd ? &read_fds : NULL,
408 &write_fds, NULL, sd, timeout);
409 if(ret != RET_OK){
410 if(ret==RET_TIMEOUT){
411 return ret;
412 }
413 SetErrorCode(scb);
414 return RET_SOCKET;
415 }
416
417 if(check_readfd){
418 if(FD_ISSET(sd, &read_fds)){
419 return RET_READFD;
420 }
421 }
422 if(FD_ISSET(sd, &write_fds)){
423 write_bytes = send(sd, bufp, length, 0);
424 if(write_bytes == SOCKET_ERROR){
425 SetErrorCode(scb);
426 return RET_SOCKET;
427 }
428 else if(write_bytes == 0){
429 /* connection closed */
430 return RET_ABORT;
431 }
432 length -= write_bytes;
433 bufp += write_bytes;
434 }
435 }
436
437 return RET_OK;
438 }
439
440 /**
441 * @brief ソケットからデータ受信
442 * @param[in,out] scb ソケット制御ブロック
443 * @param[out] buffer 受信データ格納領域(NULL指定でデータを捨てる)
444 * @param[in] length 受信データ長
445 * @param[in] timeout タイムアウト(ミリ秒)
446 * @retval RET_OK 正常終了
447 * @retval RET_TIMEOUT タイムアウト
448 * @retval RET_ABORT 中断(相手側より切断された)
449 * @retval RET_SOCKET ソケットエラー
450 */
451 int NAReceive(SOCKCB *scb, void *buffer, int length, DWORD timeout)
452 {
453 fd_set read_fds;
454 int ret;
455 SOCKET sd;
456 int read_bytes;
457 char dummy_buffer[64];
458 int len;
459 char *bufp = (char *)buffer;
460
461 if(scb->server_mode){
462 sd = scb->u.server.socket_desc;
463 }
464 else{
465 sd = scb->u.client.socket_desc;
466 }
467
468 while(length > 0){
469 ret = WaitFDS(&read_fds, NULL, NULL, sd, timeout);
470 if(ret != RET_OK){
471 if(ret==RET_TIMEOUT){
472 return ret;
473 }
474 SetErrorCode(scb);
475 return RET_SOCKET;
476 }
477
478 if(FD_ISSET(sd, &read_fds)){
479 if(bufp==NULL){
480 len = (length < sizeof(dummy_buffer))
481 ? length : sizeof(dummy_buffer);
482 read_bytes = recv(sd, dummy_buffer, len, 0);
483 }
484 else{
485 read_bytes = recv(sd, bufp, length, 0);
486 }
487 if(read_bytes == SOCKET_ERROR){
488 SetErrorCode(scb);
489 return RET_SOCKET;
490 }
491 else if(read_bytes == 0){
492 /* connection closed */
493 return RET_ABORT;
494 }
495 length -= read_bytes;
496 bufp += read_bytes;
497 }
498 }
499
500 return RET_OK;
501 }
502
503
504 /**
505 * @brief コマンド応答を受信
506 * @param[in,out] scb ソケット制御ブロック
507 * @param[out] buf 応答データ格納バッファ
508 * @param[in] buflen バッファサイズ(バイト数)
509 * @param[out] sensedata センスデータ格納バッファ
510 * @param[in] senselen センスデータ格納バッファサイズ(バイト数)
511 * @param[in] reqflag 要求フラグ(REQ_NODATA/REQ_DATAIN/REQ_DATAOUT)
512 * @param[out] cmd_header コマンドヘッダー
513 * @retval RET_OK 正常終了
514 * @retval RET_ABORT 中断
515 * @retval RET_TIMEOUT タイムアウト発生
516 * @retval RET_SOCKET ソケットエラー
517 * @retval RET_NG その他のエラー
518 */
519 static int ReceiveCmdResponse(SOCKCB *scb, void *buf, DWORD buflen,
520 BYTE *sensedata, DWORD senselen,
521 int reqflag, NETCMDHEADER *cmd_header)
522 {
523 BYTE netdata_common[8];
524 NETCMDHEADER recv_header;
525 int ret;
526
527 memset(sensedata, 0, senselen);
528
529 if(cmd_header == NULL){
530 cmd_header = &recv_header;
531 }
532
533 /* 共通部(データ長とデータタイプ)を受信する */
534 ret = NAReceive(scb, (char *)netdata_common, 8, NETTIMEOUT);
535 if(ret != RET_OK){
536 return ret;
537 }
538
539 if(netdata_common[4]!=NETDATATYPE_RESPONSE){
540 return RET_ABORT;
541 }
542
543 /* receive command result */
544 ret = NAReceive(scb, (char *)cmd_header, sizeof(NETCMDHEADER), NETTIMEOUT);
545 if(ret != RET_OK){
546 return ret;
547 }
548 /* check command result */
549 if((cmd_header->sense_data[2]&0x0f) != 0x00 ||
550 cmd_header->sense_data[12] != 0x00 ||
551 cmd_header->sense_data[13] != 0x00){
552 memcpy(sensedata, cmd_header->sense_data, senselen);
553 return RET_NG;
554 }
555
556 if(reqflag==REQ_DATAIN){
557 /* receive_data */
558 ret = NAReceive(scb, buf, buflen, NETTIMEOUT);
559 if(ret != RET_OK){
560 return ret;
561 }
562 }
563
564 return RET_OK;
565 }
566
567
568 /**
569 * @brief コマンドデータ送信
570 * @param[in,out] scb ソケット制御ブロック
571 * @param[in] cdb コマンド列(12バイト)
572 * @param[in,out] buf 送信コマンドに付随するデータ / 受信データ
573 * @param[in] buflen バッファサイズ(バイト数)
574 * @param[out] sensedata センスデータ格納バッファ
575 * @param[in] senselen センスデータ格納バッファサイズ(バイト数)
576 * @param[in] reqflag 要求フラグ(REQ_NODATA/REQ_DATAIN/REQ_DATAOUT)
577 * @retval RET_OK 正常終了
578 * @retval RET_ABORT 中断
579 * @retval RET_TIMEOUT タイムアウト発生
580 * @retval RET_SOCKET ソケットエラー
581 * @retval RET_NG その他のエラー
582 */
583 int SendNetCmd(SOCKCB *scb, BYTE *cdb, void *buf, DWORD buflen,
584 BYTE *sensedata, DWORD senselen, int reqflag)
585 {
586 BYTE netdata_common[8];
587 NETCMDHEADER header;
588 int ret;
589 DWORD length;
590
591 length = sizeof(NETCMDHEADER);
592 if(reqflag==REQ_DATAOUT){
593 length += buflen;
594 }
595 Set4bytes(netdata_common, length);
596 netdata_common[4] = NETDATATYPE_COMMAND;
597 header.reqflag = reqflag;
598 memcpy(header.cdb, cdb, 12);
599 Set4bytes(header.data_length, buflen);
600
601 /* 共通部(データ長とデータタイプ)を送る */
602 ret = NASend(scb, netdata_common, 8, NETTIMEOUT, FALSE);
603 if(ret != RET_OK){
604 return ret;
605 }
606
607 /* 個別部を送る */
608 ret = NASend(scb, &header, sizeof(NETCMDHEADER), NETTIMEOUT, FALSE);
609 if(ret != RET_OK){
610 return ret;
611 }
612
613 if(reqflag==REQ_DATAOUT){
614 /* send data */
615 ret = NASend(scb, buf, buflen, NETTIMEOUT, FALSE);
616 if(ret != RET_OK){
617 return ret;
618 }
619 }
620
621 ret = ReceiveCmdResponse(scb, buf, buflen, sensedata, senselen, reqflag,
622 NULL);
623 if(ret != RET_OK){
624 return ret;
625 }
626
627 return RET_OK;
628 }
629
630 /**
631 * @brief Network経由でLONGREADを送信する。または、LONGREAD結果を受信する。
632 * total_blocksが0の場合に結果受信を行い、それ以外の場合は、送信を行う。
633 * @param[in,out] scb ソケット制御ブロック
634 * @param[in] cdb コマンド列(12バイト)
635 * @param[out] buf 受信バッファ
636 * @param[in] buflen 受信バッファサイズ(バイト数)
637 * @param[out] sensedata センスデータ格納バッファ
638 * @param[in] senselen センスデータ格納バッファサイズ(バイト数)
639 * @param[in] reqflag 要求フラグ(REQ_NODATA/REQ_DATAIN/REQ_DATAOUT)
640 * @param[in] total_blocks READブロック数
641 * @retval RET_OK 正常終了
642 * @retval RET_ABORT 中断
643 * @retval RET_TIMEOUT タイムアウト発生
644 * @retval RET_SOCKET ソケットエラー
645 * @retval RET_NG その他のエラー
646 */
647 int SendNetCmdLongRead(SOCKCB *scb, BYTE *cdb, void *buf, DWORD buflen,
648 BYTE *sensedata, DWORD senselen,
649 int reqflag, DWORD total_blocks)
650 {
651 BYTE netdata_common[8];
652 NETCMDHEADER header, recv_header;
653 BYTE total_blocks_data[4];
654 int ret;
655 DWORD length;
656
657 if(total_blocks == 0){
658 /* LONGREAD結果受信 */
659 ret = ReceiveCmdResponse(scb, buf, buflen, sensedata, senselen, reqflag,
660 &recv_header);
661 if(ret != RET_OK){
662 return ret;
663 }
664
665 if(memcmp(recv_header.cdb, cdb, 12)){
666 /* コマンド相違 */
667 return RET_NG;
668 }
669 }
670 else{
671 /* LONGREAD送信 */
672 length = sizeof(NETCMDHEADER);
673 if(reqflag==REQ_DATAOUT){
674 length += buflen;
675 }
676 Set4bytes(netdata_common, length);
677 netdata_common[4] = NETDATATYPE_LONGREAD;
678 header.reqflag = reqflag;
679 memcpy(header.cdb, cdb, 12);
680 Set4bytes(header.data_length, buflen);
681
682 /* 共通部(データ長とデータタイプ)を送る */
683 ret = NASend(scb, (char *)netdata_common, 8, NETTIMEOUT, FALSE);
684 if(ret != RET_OK){
685 return ret;
686 }
687
688 /* 個別部を送る */
689 ret = NASend(scb, (char *)&header, sizeof(NETCMDHEADER), NETTIMEOUT,
690 FALSE);
691 if(ret != RET_OK){
692 return ret;
693 }
694 Set4bytes(total_blocks_data, total_blocks);
695 ret = NASend(scb, (char *)total_blocks_data, 4, NETTIMEOUT, FALSE);
696 if(ret!=RET_OK){
697 return ret;
698 }
699 }
700
701 return RET_OK;
702 }
703
704
705 #if defined(linux) || defined(__MINGW32__)
706 /**
707 * @brief 文字コード変換
708 * @param[in] iconv_desc iconvディスクリプタ
709 * @param[in] in_string 変換文字列
710 * @return 変換結果の文字列。エラーが発生した場合は NULL を返す。
711 * @note 変換結果文字列は使用後 MemFree() が必要。
712 */
713 char *ConvertCharcode(iconv_t iconv_desc, const char *in_string)
714 {
715 char *out_string = NULL;
716 int bufsize = strlen(in_string)+1;
717 size_t inbytes = strlen(in_string);
718 size_t outbytes = strlen(in_string);
719 char *inbufp = (char *)in_string;
720 char *outbufp;
721 int out_offset = 0;
722 int iconv_ret;
723
724 out_string = (char *)MemNew(bufsize);
725
726 if(strlen(in_string)==0){
727 out_string[0] = '\0';
728 return out_string;
729 }
730
731 iconv(iconv_desc, NULL, NULL, NULL, NULL);
732 outbufp = out_string;
733 while(inbytes > 0){
734 iconv_ret = iconv(iconv_desc,
735 (char **)&inbufp, &inbytes,
736 &outbufp, &outbytes);
737 if(iconv_ret != (size_t)-1){
738 continue;
739 }
740 if(errno != E2BIG){
741 /* 変換失敗 */
742 MemFree(out_string);
743 return NULL;
744 }
745 /* 領域不足 */
746 out_offset = (int)(outbufp-out_string);
747 bufsize += 64;
748 outbytes += 64;
749 out_string = (char *)MemResize(out_string, bufsize);
750 if(out_string == NULL){
751 return NULL;
752 }
753 outbufp = out_string+out_offset;
754 }
755 *outbufp = '\0';
756
757 return out_string;
758 }
759 #endif
760
761
762 /**
763 * @brief 表示データ送信
764 * @param[in,out] scb ソケット制御ブロック
765 * @param[in] area 表示領域<br>
766 * 0:画面下メッセージ<br>
767 * 1:プログレスバー1<br>
768 * 2:プログレスバー2
769 * @param[in] percent パーセンテージ
770 * @param[in] message 表示メッセージ
771 * @retval RET_OK 正常終了
772 * @retval RET_SOCKET ソケットエラー
773 * @retval RET_ABORT 中断
774 * @retval RET_TIMEOUT タイムアウト発生
775 * @retval RET_NG その他のエラー
776 */
777 int NASendDispCmd(SOCKCB *scb, BYTE area, BYTE percent, const char *message)
778 {
779 int ret;
780 BYTE netdata_common[8];
781 NETDISPHEADER header;
782 DWORD length;
783 #if defined(linux) || defined(__MINGW32__)
784 char *message_sjis = NULL;
785 #endif
786
787 header.area = area;
788 header.percent = percent;
789
790 length = sizeof(header);
791 if(message != NULL){
792 #if defined(linux) || defined(__MINGW32__)
793 /* local charset => SJIS */
794 message_sjis = ConvertCharcode(scb->iconv_desc, message);
795 if(message_sjis == NULL){
796 return RET_MEMERR;
797 }
798 message = message_sjis;
799 #endif
800 length += strlen(message);
801 }
802
803 Set4bytes(netdata_common, length);
804 netdata_common[4] = NETDATATYPE_DISPLAY;
805 ret = NASend(scb, (char *)netdata_common, 8, NETTIMEOUT, FALSE);
806 if(ret != RET_OK){
807 #if defined(linux) || defined(__MINGW32__)
808 if(message_sjis != NULL){
809 MemFree(message_sjis);
810 }
811 #endif
812 return ret;
813 }
814 ret = NASend(scb, (char *)&header, sizeof(header), NETTIMEOUT, FALSE);
815 if(ret != RET_OK){
816 #if defined(linux) || defined(__MINGW32__)
817 if(message_sjis != NULL){
818 MemFree(message_sjis);
819 }
820 #endif
821 return ret;
822 }
823 if(message != NULL){
824 ret = NASend(scb, message, strlen(message), NETTIMEOUT, FALSE);
825 if(ret != RET_OK){
826 #if defined(linux) || defined(__MINGW32__)
827 if(message_sjis != NULL){
828 MemFree(message_sjis);
829 }
830 #endif
831 return ret;
832 }
833 }
834
835 #if defined(linux) || defined(__MINGW32__)
836 if(message_sjis != NULL){
837 MemFree(message_sjis);
838 }
839 #endif
840 return RET_OK;
841 }
842
843
844 /**
845 * @brief 中断を送信
846 * @param[in,out] scb ソケット制御ブロック
847 * @retval RET_OK 正常終了
848 * @retval RET_SOCKET ソケットエラー
849 * @retval RET_ABORT 中断
850 * @retval RET_TIMEOUT タイムアウト発生
851 * @retval RET_NG その他のエラー
852 */
853 int NASendAbort(SOCKCB *scb)
854 {
855 int ret;
856 BYTE netdata_common[8];
857
858 Set4bytes(netdata_common, 0);
859 netdata_common[4] = NETDATATYPE_ABORT;
860 ret = NASend(scb, (char *)netdata_common, 8, NETTIMEOUT, FALSE);
861 if(ret != RET_OK){
862 return ret;
863 }
864 return RET_OK;
865 }
866
867 /**
868 * @brief 完了を送信
869 * @param[in,out] scb ソケット制御ブロック
870 * @retval RET_OK 正常終了
871 * @retval RET_SOCKET ソケットエラー
872 * @retval RET_ABORT 中断
873 * @retval RET_TIMEOUT タイムアウト発生
874 * @retval RET_NG その他のエラー
875 */
876 int NASendComplete(SOCKCB *scb)
877 {
878 int ret;
879 BYTE netdata_common[8];
880
881 Set4bytes(netdata_common, 0);
882 netdata_common[4] = NETDATATYPE_COMPLETE;
883 ret = NASend(scb, (char *)netdata_common, 8, NETTIMEOUT, FALSE);
884 if(ret != RET_OK){
885 return ret;
886 }
887 return RET_OK;
888 }
889
890
891
892 /**
893 * @brief 情報表示データを送信
894 * @param[in,out] scb ソケット制御ブロック
895 * @param[in] message 表示メッセージ
896 * @retval RET_OK 正常終了
897 * @retval RET_SOCKET ソケットエラー
898 * @retval RET_ABORT 中断
899 * @retval RET_TIMEOUT タイムアウト発生
900 * @retval RET_NG その他のエラー
901 */
902 int NAUIDispInfo(SOCKCB *scb, const char *message)
903 {
904 return NASendDispCmd(scb, 0, 0, message);
905 }
906
907 /**
908 * @brief プログレスバー1の初期化を送信
909 * @param[in,out] scb ソケット制御ブロック
910 * @param[in] message 表示メッセージ
911 * @retval RET_OK 正常終了
912 * @retval RET_SOCKET ソケットエラー
913 * @retval RET_ABORT 中断
914 * @retval RET_TIMEOUT タイムアウト発生
915 * @retval RET_NG その他のエラー
916 */
917 int NAUIMeter1Initialize(SOCKCB *scb, const char *message)
918 {
919 return NASendDispCmd(scb, 1, 0, message);
920 }
921
922 /**
923 * @brief プログレスバー2の初期化を送信
924 * @param[in,out] scb ソケット制御ブロック
925 * @param[in] message 表示メッセージ
926 * @retval RET_OK 正常終了
927 * @retval RET_SOCKET ソケットエラー
928 * @retval RET_ABORT 中断
929 * @retval RET_TIMEOUT タイムアウト発生
930 * @retval RET_NG その他のエラー
931 */
932 int NAUIMeter2Initialize(SOCKCB *scb, const char *message)
933 {
934 return NASendDispCmd(scb, 2, 0, message);
935 }
936
937 /**
938 * @brief プログレスバー1の更新を送信
939 * @param[in,out] scb ソケット制御ブロック
940 * @param[in] message 表示メッセージ
941 * @retval RET_OK 正常終了
942 * @retval RET_SOCKET ソケットエラー
943 * @retval RET_ABORT 中断
944 * @retval RET_TIMEOUT タイムアウト発生
945 * @retval RET_NG その他のエラー
946 */
947 int NAUIMeter1Update(SOCKCB *scb, float percentage)
948 {
949 return NASendDispCmd(scb, 1, (BYTE)(percentage), NULL);
950 }
951
952 /**
953 * @brief プログレスバー2の更新を送信
954 * @param[in,out] scb ソケット制御ブロック
955 * @param[in] message 表示メッセージ
956 * @retval RET_OK 正常終了
957 * @retval RET_SOCKET ソケットエラー
958 * @retval RET_ABORT 中断
959 * @retval RET_TIMEOUT タイムアウト発生
960 * @retval RET_NG その他のエラー
961 */
962 int NAUIMeter2Update(SOCKCB *scb, float percentage)
963 {
964 return NASendDispCmd(scb, 2, (BYTE)(percentage), NULL);
965 }
966
967 #if defined(WIN32)
968 static const struct SOCKERRMESSAGE {
969 DWORD code;
970 char *message;
971 } g_ErrorMessage[] = {
972 { 0, "No error"},
973 { WSAEINTR, "Interrupted system call" },
974 { WSAEBADF, "Bad file number" },
975 { WSAEACCES, "Permission denied" },
976 { WSAEFAULT, "Bad address" },
977 { WSAEINVAL, "Invalid argument" },
978 { WSAEMFILE, "Too many open sockets" },
979 { WSAEWOULDBLOCK, "Operation would block" },
980 { WSAEINPROGRESS, "Operation now in progress" },
981 { WSAEALREADY, "Operation already in progress" },
982 { WSAENOTSOCK, "Socket operation on non-socket" },
983 { WSAEDESTADDRREQ, "Destination address required" },
984 { WSAEMSGSIZE, "Message too long" },
985 { WSAEPROTOTYPE, "Protocol wrong type for socket" },
986 { WSAENOPROTOOPT, "Bad protocol option" },
987 { WSAEPROTONOSUPPORT, "Protocol not supported" },
988 { WSAESOCKTNOSUPPORT, "Socket type not supported" },
989 { WSAEOPNOTSUPP, "Operation not supported on socket" },
990 { WSAEPFNOSUPPORT, "Protocol family not supported" },
991 { WSAEAFNOSUPPORT, "Address family not supported" },
992 { WSAEADDRINUSE, "Address already in use" },
993 { WSAEADDRNOTAVAIL, "Can't assign requested address" },
994 { WSAENETDOWN, "Network is down" },
995 { WSAENETUNREACH, "Network is unreachable" },
996 { WSAENETRESET, "Net connection reset" },
997 { WSAECONNABORTED, "Software caused connection abort" },
998 { WSAECONNRESET, "Connection reset by peer" },
999 { WSAENOBUFS, "No buffer space available" },
1000 { WSAEISCONN, "Socket is already connected" },
1001 { WSAENOTCONN, "Socket is not connected" },
1002 { WSAESHUTDOWN, "Can't send after socket shutdown" },
1003 { WSAETOOMANYREFS, "Too many references, can't splice" },
1004 { WSAETIMEDOUT, "Connection timed out" },
1005 { WSAECONNREFUSED, "Connection refused" },
1006 { WSAELOOP, "Too many levels of symbolic links" },
1007 { WSAENAMETOOLONG, "File name too long" },
1008 { WSAEHOSTDOWN, "Host is down" },
1009 { WSAEHOSTUNREACH, "No route to host" },
1010 { WSAENOTEMPTY, "Directory not empty" },
1011 { WSAEPROCLIM, "Too many processes" },
1012 { WSAEUSERS, "Too many users" },
1013 { WSAEDQUOT, "Disc quota exceeded" },
1014 { WSAESTALE, "Stale NFS file handle" },
1015 { WSAEREMOTE, "Too many levels of remote in path" },
1016 { WSASYSNOTREADY, "Network system is unavailable" },
1017 { WSAVERNOTSUPPORTED, "Winsock version out of range" },
1018 { WSANOTINITIALISED, "WSAStartup not yet called" },
1019 { WSAEDISCON, "Graceful shutdown in progress" },
1020 { WSAHOST_NOT_FOUND, "Host not found" },
1021 { WSANO_DATA, "No host data of that type was found" },
1022 };
1023 #endif /* WIN32 */
1024
1025 /**
1026 * @brief エラーコードに対応するメッセージを取得
1027 * @param[in] scb ソケット制御ブロック
1028 * @return 取得したメッセージを返す。エラーの場合はNULLを返す。
1029 * @note 取得したメッセージはメモリ解放する必要なし。
1030 */
1031 const char *NAGetErrorMessage(SOCKCB *scb)
1032 {
1033 const char *message = NULL;
1034
1035 #if defined(WIN32)
1036 int index;
1037 for(index=0; index<sizeof(g_ErrorMessage)/sizeof(struct SOCKERRMESSAGE); index++){
1038 if(g_ErrorMessage[index].code == scb->error_code){
1039 message = g_ErrorMessage[index].message;
1040 break;
1041 }
1042 }
1043 #else
1044 message = strerror(scb->error_code);
1045 #endif
1046
1047 return message;
1048 }
1049
1050 /**
1051 * ソケット関連エラーならエラーを表示
1052 * @param[in] drive 装置構造体
1053 * @param[in] ret_value 関数返却値
1054 * @return ソケット関連エラーかどうか
1055 */
1056 BOOL DispSocketError(SOCKCB *scb, int ret_value)
1057 {
1058 if(ret_value==RET_SOCKET){
1059 const char *message = NAGetErrorMessage(scb);
1060 if(message != NULL){
1061 char *net_err = EbStringNewWithFormat(
1062 MSG_NETWORK_ERROR_ /*"ネットワークエラー %ld : "*/,
1063 scb->error_code);
1064 net_err = EbStringAppend(net_err, message);
1065 UIDispMessage(message, UIDMT_ERROR);
1066 net_err = EbStringFree(net_err);
1067 return TRUE;
1068 }
1069 }
1070 return FALSE;
1071 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26