00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include "plDevs.h"
00064 #include "plConfig.h"
00065
00066 #if defined ( PLD_tk ) || defined ( ENABLE_tk )
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #ifdef _POSIX_SOURCE
00082 #undef _POSIX_SOURCE
00083 #endif
00084 #ifdef caddr_t
00085 #undef caddr_t
00086 #endif
00087 #define PLARGS( a ) ( )
00088
00089 #include <stdio.h>
00090 #include <stdlib.h>
00091 #include <math.h>
00092 #include <string.h>
00093 #if defined ( __sgi ) && !defined ( SVR3 )
00094 #include <sys/select.h>
00095 #endif
00096 #ifdef PL_HAVE_UNISTD_H
00097 #include <unistd.h>
00098 #endif
00099
00100 #include "tcpip.h"
00101 #include <tcl.h>
00102 #include <tk.h>
00103
00104 #include <sys/stat.h>
00105 #include <sys/types.h>
00106 #include <fcntl.h>
00107 #include <ctype.h>
00108 #include <sys/uio.h>
00109 #include <errno.h>
00110
00111 extern int errno;
00112
00113 #ifndef MIN
00114 #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
00115 #endif
00116
00117
00118
00119
00120
00121 #define PACKET_MAGIC 0x6feeddcc
00122
00123
00124
00125
00126
00127
00128
00129
00130 typedef struct PartialRead
00131 {
00132 char *buffer;
00133 int bufSize;
00134 int offset;
00135 struct PartialRead *next;
00136 } PartialRead;
00137
00138 #define MAX_OPEN_FILES 128
00139
00140 static PartialRead *partial[MAX_OPEN_FILES];
00141
00142 static void pl_FreeReadBuffer PLARGS( (int fd) );
00143 static void pl_Unread PLARGS( ( int fd, char *buffer,
00144 int numBytes, int copy ) );
00145 static int pl_Read PLARGS( ( int fd, char *buffer, int numReq ) );
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 static void
00165 pl_FreeReadBuffer( fd )
00166 int fd;
00167 {
00168 PartialRead *readList;
00169
00170 while ( partial[fd] != NULL )
00171 {
00172 readList = partial[fd];
00173 partial[fd] = readList->next;
00174 free( readList->buffer );
00175 free( readList );
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 static void
00197 pl_Unread( fd, buffer, numBytes, copy )
00198 int fd;
00199 char *buffer;
00200 int numBytes;
00201 int copy;
00202
00203 {
00204 PartialRead *new;
00205
00206 new = (PartialRead *) malloc( sizeof ( PartialRead ) );
00207 if ( copy )
00208 {
00209 new->buffer = (char *) malloc( numBytes );
00210 memcpy( new->buffer, buffer, numBytes );
00211 }
00212 else
00213 {
00214 new->buffer = buffer;
00215 }
00216 new->bufSize = numBytes;
00217 new->offset = 0;
00218 new->next = partial[fd];
00219 partial[fd] = new;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 static int
00241 pl_Read( fd, buffer, numReq )
00242 int fd;
00243 char *buffer;
00244 int numReq;
00245 {
00246 PartialRead *readList;
00247 PartialRead *tmp;
00248 int numRead;
00249 int numToCopy;
00250
00251 readList = partial[fd];
00252
00253
00254
00255
00256
00257 if ( readList == NULL )
00258 {
00259 numRead = read( fd, buffer, numReq );
00260 #ifdef DEBUG
00261 {
00262 int j;
00263 fprintf( stderr, "received %d bytes starting with:", numRead );
00264 for ( j = 0; j < MIN( 8, numRead ); j++ )
00265 fprintf( stderr, " %x", 0x000000FF & (unsigned long) buffer[j] );
00266 fprintf( stderr, "\n" );
00267 }
00268 #endif
00269 return numRead;
00270 }
00271
00272
00273
00274
00275
00276
00277 numRead = 0;
00278 while ( ( readList != NULL ) && ( numRead < numReq ) )
00279 {
00280 numToCopy = readList->bufSize - readList->offset;
00281 if ( numToCopy + numRead > numReq )
00282 {
00283 numToCopy = numReq - numRead;
00284 }
00285 memcpy( buffer + numRead, readList->buffer + readList->offset, numToCopy );
00286
00287
00288
00289
00290 tmp = readList;
00291 readList = readList->next;
00292 tmp->offset += numToCopy;
00293 if ( tmp->offset == tmp->bufSize )
00294 {
00295 free( tmp->buffer );
00296 free( tmp );
00297 partial[fd] = readList;
00298 }
00299 numRead += numToCopy;
00300 }
00301
00302
00303
00304
00305 if ( ( numRead < numReq ) )
00306 {
00307 numToCopy = numReq - numRead;
00308 numRead += read( fd, buffer + numRead, numToCopy );
00309 }
00310
00311 return numRead;
00312 }
00313
00314
00315
00316
00317
00318 #ifdef PLD_dp
00319
00320 #include <dp.h>
00321
00322 #include <arpa/inet.h>
00323 #include <netdb.h>
00324 #include <netinet/in.h>
00325 #include <sys/socket.h>
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 static char *
00337 get_inet( listptr, length )
00338 char **listptr;
00339 int length;
00340 {
00341 struct in_addr *ptr;
00342
00343 while ( ( ptr = (struct in_addr *) *listptr++ ) == NULL )
00344 continue;
00345
00346 return inet_ntoa( *ptr );
00347 }
00348
00349 int
00350 plHost_ID( clientData, interp, argc, argv )
00351 ClientData clientData;
00352 Tcl_Interp *interp;
00353 int argc;
00354 char **argv;
00355 {
00356 register struct hostent *hostptr;
00357 char hostname[100];
00358
00359 if ( gethostname( hostname, 100 ) )
00360 {
00361 Tcl_AppendResult( interp, "Error -- cannot get host name",
00362 (char *) NULL );
00363 return TCL_ERROR;
00364 }
00365
00366 if ( ( hostptr = gethostbyname( hostname ) ) == NULL )
00367 {
00368 Tcl_AppendResult( interp, "Error -- cannot get host info for node ",
00369 hostname, (char *) NULL );
00370 return TCL_ERROR;
00371 }
00372
00373 Tcl_SetResult( interp,
00374 get_inet( hostptr->h_addr_list, hostptr->h_length ),
00375 TCL_VOLATILE );
00376
00377 return TCL_OK;
00378 }
00379
00380 #endif // PLD_dp
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 int
00406 pl_PacketReceive( interp, iodev, pdfs )
00407 Tcl_Interp * interp;
00408 PLiodev *iodev;
00409 PDFstrm *pdfs;
00410 {
00411 int j, numRead;
00412 unsigned int packetLen, header[2];
00413 int headerSize;
00414 unsigned char hbuf[8];
00415 char *errMsg;
00416
00417 pdfs->bp = 0;
00418
00419
00420
00421
00422 headerSize = 8;
00423 numRead = pl_Read( iodev->fd, (char *) hbuf, headerSize );
00424
00425 if ( numRead <= 0 )
00426 {
00427 #ifdef DEBUG
00428 fprintf( stderr, "Incorrect header read, numRead = %d\n", numRead );
00429 #endif
00430 goto readError;
00431 }
00432
00433
00434
00435
00436 if ( numRead < headerSize )
00437 {
00438 #ifdef DEBUG
00439 fprintf( stderr, "Incomplete header read, numRead = %d\n", numRead );
00440 #endif
00441 pl_Unread( iodev->fd, (char *) hbuf, numRead, 1 );
00442 Tcl_ResetResult( interp );
00443 return TCL_OK;
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453 j = 0;
00454
00455 header[0] = 0;
00456 header[0] |= hbuf[j++] << 24;
00457 header[0] |= hbuf[j++] << 16;
00458 header[0] |= hbuf[j++] << 8;
00459 header[0] |= hbuf[j++];
00460
00461 header[1] = 0;
00462 header[1] |= hbuf[j++] << 24;
00463 header[1] |= hbuf[j++] << 16;
00464 header[1] |= hbuf[j++] << 8;
00465 header[1] |= hbuf[j++];
00466
00467
00468
00469
00470
00471
00472
00473
00474 if ( header[0] != PACKET_MAGIC )
00475 {
00476 fprintf( stderr, "Badly formatted packet, numRead = %d\n", numRead );
00477 Tcl_AppendResult( interp, "Error reading from ", iodev->typeName,
00478 ": badly formatted packet", (char *) NULL );
00479 return TCL_ERROR;
00480 }
00481 packetLen = header[1] - headerSize;
00482
00483
00484
00485
00486
00487 if ( header[1] > (unsigned) pdfs->bufmax )
00488 {
00489 free( (void *) pdfs->buffer );
00490 pdfs->bufmax = header[1] + 32;
00491 pdfs->buffer = (unsigned char *) malloc( pdfs->bufmax );
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 if ( iodev->type == 0 )
00503 {
00504 numRead = pl_Read( iodev->fd, (char *) pdfs->buffer, packetLen );
00505 }
00506 else
00507 {
00508 #ifdef PLD_dp
00509 if ( Tdp_FDIsReady( iodev->fd ) & TCL_FILE_READABLE )
00510 {
00511 numRead = pl_Read( iodev->fd, (char *) pdfs->buffer, packetLen );
00512 }
00513 else
00514 {
00515 #ifdef DEBUG
00516 fprintf( stderr, "Packet not ready, putting back header\n" );
00517 #endif
00518 pl_Unread( iodev->fd, (char *) hbuf, headerSize, 1 );
00519 Tcl_ResetResult( interp );
00520 return TCL_OK;
00521 }
00522 #endif
00523 }
00524
00525 if ( numRead <= 0 )
00526 {
00527 goto readError;
00528 }
00529
00530 if ( (unsigned) numRead != packetLen )
00531 {
00532 #ifdef DEBUG
00533 fprintf( stderr, "Incomplete packet read, numRead = %d\n", numRead );
00534 #endif
00535 pl_Unread( iodev->fd, (char *) pdfs->buffer, numRead, 1 );
00536 pl_Unread( iodev->fd, (char *) hbuf, headerSize, 1 );
00537 return TCL_OK;
00538 }
00539
00540 pdfs->bp = numRead;
00541 #ifdef DEBUG
00542 fprintf( stderr, "received %d byte packet starting with:", numRead );
00543 for ( j = 0; j < 4; j++ )
00544 {
00545 fprintf( stderr, " %x", 0x000000FF & (unsigned long) pdfs->buffer[j] );
00546 }
00547 fprintf( stderr, "\n" );
00548 #endif
00549
00550 return TCL_OK;
00551
00552 readError:
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 if ( errno == EWOULDBLOCK || errno == EAGAIN )
00564 {
00565 Tcl_ResetResult( interp );
00566 return TCL_OK;
00567 }
00568
00569
00570 if ( numRead != 0 )
00571 {
00572 errMsg = (char *) Tcl_PosixError( interp );
00573 }
00574 else
00575 {
00576 errMsg = NULL;
00577 }
00578
00579
00580
00581
00582 if ( iodev->type == 0 )
00583 {
00584
00585 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ ) && !defined ( __CYGWIN__ )
00586 Tk_DeleteFileHandler( iodev->fd );
00587 #endif
00588 close( iodev->fd );
00589 }
00590 pl_FreeReadBuffer( iodev->fd );
00591
00592 Tcl_ResetResult( interp );
00593 if ( numRead == 0 )
00594 {
00595 return TCL_OK;
00596 }
00597 else
00598 {
00599 Tcl_AppendResult( interp, "pl_PacketReceive -- error reading from ",
00600 iodev->typeName, ": ", errMsg, (char *) NULL );
00601 return TCL_ERROR;
00602 }
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 int
00625 pl_PacketSend( interp, iodev, pdfs )
00626 Tcl_Interp * interp;
00627 PLiodev *iodev;
00628 PDFstrm *pdfs;
00629 {
00630 int j, numSent;
00631 unsigned char hbuf[8];
00632 unsigned int packetLen, header[2];
00633 int len;
00634 char *buffer, tmp[256];
00635
00636
00637
00638
00639
00640
00641
00642
00643 packetLen = pdfs->bp + 8;
00644
00645 header[0] = PACKET_MAGIC;
00646 header[1] = packetLen;
00647
00648
00649
00650
00651
00652
00653 j = 0;
00654
00655 hbuf[j++] = ( header[0] & (unsigned long) 0xFF000000 ) >> 24;
00656 hbuf[j++] = ( header[0] & (unsigned long) 0x00FF0000 ) >> 16;
00657 hbuf[j++] = ( header[0] & (unsigned long) 0x0000FF00 ) >> 8;
00658 hbuf[j++] = ( header[0] & (unsigned long) 0x000000FF );
00659
00660 hbuf[j++] = ( header[1] & (unsigned long) 0xFF000000 ) >> 24;
00661 hbuf[j++] = ( header[1] & (unsigned long) 0x00FF0000 ) >> 16;
00662 hbuf[j++] = ( header[1] & (unsigned long) 0x0000FF00 ) >> 8;
00663 hbuf[j++] = ( header[1] & (unsigned long) 0x000000FF );
00664
00665
00666
00667
00668
00669
00670
00671 len = pdfs->bp + 8;
00672 buffer = (char *) malloc( len );
00673
00674 memcpy( buffer, (char *) hbuf, 8 );
00675 memcpy( buffer + 8, (char *) pdfs->buffer, pdfs->bp );
00676
00677 #ifdef DEBUG
00678 fprintf( stderr, "sending %d byte packet starting with:", len );
00679 for ( j = 0; j < 12; j++ )
00680 {
00681 fprintf( stderr, " %x", 0x000000FF & (unsigned long) buffer[j] );
00682 }
00683 fprintf( stderr, "\n" );
00684 #endif
00685 numSent = write( iodev->fd, buffer, len );
00686
00687 free( buffer );
00688
00689 if ( (unsigned) numSent != packetLen )
00690 {
00691 if ( ( errno == 0 ) || ( errno == EWOULDBLOCK || errno == EAGAIN ) )
00692 {
00693
00694
00695
00696 Tcl_ResetResult( interp );
00697 sprintf( tmp, "%d", numSent - 8 );
00698 Tcl_SetResult( interp, tmp, TCL_VOLATILE );
00699 return TCL_OK;
00700 }
00701 else if ( errno == EPIPE )
00702 {
00703
00704
00705
00706
00707 if ( iodev->type == 0 )
00708 {
00709 close( iodev->fd );
00710 }
00711 sprintf( tmp, "0" );
00712 Tcl_SetResult( interp, tmp, TCL_VOLATILE );
00713 return TCL_OK;
00714 }
00715 else
00716 {
00717 Tcl_AppendResult( interp, "pl_PacketSend -- error writing to ",
00718 iodev->typeName, ": ",
00719 Tcl_PosixError( interp ), (char *) NULL );
00720 }
00721
00722 return TCL_ERROR;
00723 }
00724
00725
00726
00727
00728 sprintf( tmp, "%d", numSent - 8 );
00729 Tcl_SetResult( interp, tmp, TCL_VOLATILE );
00730 return TCL_OK;
00731 }
00732
00733 #else
00734 int
00735 pldummy_tcpip()
00736 {
00737 return 0;
00738 }
00739
00740 #endif // defined(PLD_tk) || defined (ENABLE_tk)