00001 00002 /* 00003 * THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE 00004 * CHECKED IT OUT USING THE COMMAND CHECKOUT. 00005 * 00006 * $Id: wave__client_8c-source.html 2161 2006-05-19 16:55:03Z paulf $ 00007 * 00008 * Revision history: 00009 * $Log$ 00009 * Revision 1.1 2006/05/19 16:55:02 paulf 00009 * first inclusion 00009 * 00010 * Revision 1.2 2001/04/17 17:30:42 davidk 00011 * added an explicit typecast to get rid of a compiler warning on NT. 00012 * 00013 * Revision 1.1 2000/02/14 18:51:48 lucky 00014 * Initial revision 00015 * 00016 * 00017 */ 00018 00019 /* 00020 wave_client.c 00021 00022 Contains functions for connecting to a wave_server's socket, making 00023 a request for a time-chunk of waveforms, and writing the requested 00024 data to a disk file. 00025 Library routines for talking to the original "wave_server". 00026 00027 Returns the number of waveform messages received. 00028 */ 00029 00030 #include <stdlib.h> 00031 #include <errno.h> 00032 #include <stdio.h> 00033 #include <string.h> 00034 #include <earthworm.h> 00035 #include <kom.h> 00036 #include "wave_client.h" 00037 00038 #define MAX_MSG_LEN 126 00039 00040 /* Global variables 00041 ******************/ 00042 static int Config_Init = 0; /* 1=config file has been read */ 00043 static struct hostent *Host; /* Contains host ip address */ 00044 static struct sockaddr_in Sin; /* Server's socket address stucture */ 00045 static unsigned long Addr; /* binary form of server's ip address */ 00046 00047 /********************************************************* 00048 * wave_request * 00049 * Connects to socket, requests data, writes file * 00050 *********************************************************/ 00051 int wave_request( double ton, /* start-time of requested waveforms */ 00052 double toff, /* end-time of requested waveforms */ 00053 char *pathfile ) /* where to write file of waveforms */ 00054 { 00055 char request[MAX_MSG_LEN]; 00056 char *buf, *bufptr; 00057 FILE *fp; 00058 long maxbuflen; 00059 long databuflen; 00060 long ntoget; 00061 long getatonce; 00062 int sd; /* Socket descriptor */ 00063 int ir, nr; 00064 int ndatabuf, nbufrec; 00065 int length; 00066 int ret; 00067 unsigned char inst, module, type; /* logo of incoming waveform messages */ 00068 char c; 00069 int i, m, t; 00070 00071 /* Make sure configuration file has been read 00072 ********************************************/ 00073 if ( !Config_Init ) 00074 { 00075 /*printf("wave_request: Config file has not been read.\n" );*/ /*DEBUG*/ 00076 return( ERR_NOCONFIG ); 00077 } 00078 00079 /* Open the file that will contain the trace data 00080 ************************************************/ 00081 fp = fopen( pathfile, "wb" ); 00082 if ( fp == NULL ) 00083 { 00084 /*printf("wave_request: Error opening output file <%s>\n", 00085 pathfile );*/ /*DEBUG*/ 00086 return( ERR_FILEIO ); 00087 } 00088 00089 /* Set up socket connection here 00090 *******************************/ 00091 if ( (sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) 00092 { 00093 logit( "t", "wave_request: Socket call failed.\n" ); 00094 SocketPerror( "wave_request: Socket call failed" ); 00095 fclose( fp ); 00096 return( ERR_SOCKET ); 00097 } 00098 00099 if ( connect( sd, (struct sockaddr *)&Sin, sizeof(Sin) ) == -1 ) 00100 { 00101 logit( "t", "wave_request: Connect to wave_server host failed.\n" ); 00102 SocketPerror( "wave_request: Connect to wave_server host failed" ); 00103 ret = ERR_SOCKET; 00104 goto done; 00105 } 00106 00107 /* Build and send a request to the wave_server 00108 *********************************************/ 00109 sprintf( request, "REQ: %15.2f %15.2f\n", ton, toff ); 00110 length = (int) strlen(request); 00111 if ( send( sd, request, length, 0 ) == -1 ) 00112 { 00113 logit( "t", "wave_request: Error sending waveform request.\n" ); 00114 SocketPerror( "wave_request: Error sending waveform request" ); 00115 ret = ERR_SOCKET; 00116 goto done; 00117 } 00118 00119 /* Start reading the socket, one character at a time 00120 ***************************************************/ 00121 ir = 0; 00122 do 00123 { 00124 if ( ir == MAX_MSG_LEN ) { /* stop if there's no more room */ 00125 /*printf("wave_request: wave_server reply too long.\n ");*/ /*DEBUG*/ 00126 ret = ERR_OVRFLW; 00127 goto done; 00128 } 00129 nr = recv( sd, &c, 1, 0 ); /* try to get a char from socket*/ 00130 if ( nr == 1 ) { /* got a character; save it */ 00131 request[ir++] = c; 00132 } 00133 else if ( nr == -1 ) { /* trouble reading socket */ 00134 logit( "e", "wave_request: Error on socket recv\n" ); 00135 ret = ERR_SOCKET; 00136 goto done; 00137 } 00138 } while( c != '\n' ); /* last char of reply */ 00139 request[ir] = '\0'; /* null-terminate the reply */ 00140 00141 /* Process inquiry reply from wave_server 00142 ****************************************/ 00143 if( sscanf( request, "%d %d %d %ld %d", 00144 &i, &m, &t, &maxbuflen, &ndatabuf ) < 5 ) 00145 { 00146 logit("e","wave_request: error decoding wave_server reply:\n%s\n", 00147 request ); 00148 inst = 0; 00149 module = 0; 00150 type = 0; 00151 ndatabuf = 0; 00152 ret = ERR_STRIO; 00153 goto done; 00154 } 00155 if ( i<256 && i>0 ) { 00156 inst = (unsigned char) i; 00157 } 00158 else { 00159 logit( "e", "wave_request: invalid installation id <%d>\n", i ); 00160 inst = 0; 00161 } 00162 if ( m<256 && m>0 ) { 00163 module = (unsigned char) m; 00164 } 00165 else { 00166 logit( "e", "wave_request: invalid module id <%d>\n", m ); 00167 module = 0; 00168 } 00169 if ( t<256 && t>0 ) { 00170 type = (unsigned char) t; 00171 } 00172 else { 00173 logit( "e", "wave_request: invalid msg type <%d>\n", t ); 00174 type = 0; 00175 } 00176 /*printf("wave_request: accepting %d msg(s) of logo Inst:%d Mod:%d Type:%d\n", 00177 ndatabuf, (int) inst, (int) module, (int) type );*/ /*DEBUG*/ 00178 00179 /* Bail out if there's no data coming 00180 ************************************/ 00181 if ( ndatabuf == 0 ) 00182 { 00183 /*printf("wave_request: Requested time period not in tank\n");*/ /*DEBUG*/ 00184 ret = ERR_NODATA; 00185 goto done; 00186 } 00187 00188 /* Allocate memory for incoming messages 00189 ***************************************/ 00190 buf = (char *) malloc( (size_t) maxbuflen ); 00191 if ( buf == (char *)NULL ) 00192 { 00193 /*printf("wave_request: Error allocating memory buffer.\n");*/ /*DEBUG*/ 00194 ret = ERR_ALLOC; 00195 goto done; 00196 } 00197 00198 /* Loop reading messages from socket 00199 ***********************************/ 00200 nbufrec = 0; 00201 do 00202 { 00203 00204 /* Read the size of the next message from the socket 00205 ***************************************************/ 00206 ir = 0; 00207 do 00208 { 00209 if ( ir == maxbuflen ) { /* stop if there's no more room */ 00210 ret = ERR_OVRFLW; 00211 goto almostdone; 00212 } 00213 nr = recv( sd, &c, 1, 0 ); /* try to get a char from socket*/ 00214 if ( nr == 1 ) { /* got a character; save it */ 00215 buf[ir++] = c; 00216 } 00217 else if ( nr == -1 ) { /* trouble reading socket */ 00218 logit( "e", "wave_request: Error on socket recv\n" ); 00219 ret = ERR_SOCKET; 00220 goto almostdone; 00221 } 00222 } while( c != '\n' ); /* last char of reply */ 00223 buf[ir] = '\0'; /* null-terminate the reply */ 00224 00225 sscanf( buf, "%ld", &databuflen ); 00226 /*printf( "wave_request: incoming msg[%ld]\n", databuflen );*/ /*DEBUG*/ 00227 00228 if( databuflen > maxbuflen ) 00229 { 00230 logit( "e", 00231 "wave_request: Data_buffer:%ld bytes > max_size:%ld\n", 00232 databuflen, maxbuflen ); 00233 ret = ERR_OVRFLW; 00234 goto almostdone; 00235 } 00236 00237 /* Read one waveform message from the server 00238 *******************************************/ 00239 ntoget = databuflen; 00240 bufptr = buf; 00241 while ( ntoget > 0 ) 00242 { 00243 /* warning: trouble trying to recv 32 kbytes or more at once */ 00244 /* (recv dies with an "invalid argument" error) */ 00245 getatonce = ( (ntoget<32000) ? ntoget : 32000 ); 00246 nr = recv( sd, bufptr, getatonce, 0 ); 00247 if ( nr == -1 ) 00248 { 00249 logit( "t", "wave_request: Error reading socket.\n" ); 00250 SocketPerror( "wave_request: Error reading socket" ); 00251 ret = ERR_SOCKET; 00252 goto almostdone; 00253 } 00254 bufptr += nr; 00255 ntoget -= nr; 00256 } 00257 00258 /* Get end-of-message flag; make sure it's a newline! 00259 ****************************************************/ 00260 nr = recv( sd, &c, 1, 0 ); 00261 if ( nr != 1 || c != '\n' ) 00262 { 00263 logit( "e", "wave_request: Error on recv end-of-message flag\n" ); 00264 ret = ERR_SOCKET; 00265 goto almostdone; 00266 } 00267 00268 /* Write this data buffer to the disk file 00269 *****************************************/ 00270 if ( fwrite( buf, sizeof(char), databuflen, fp ) != (size_t)databuflen ) 00271 { 00272 /*printf("wave_request: Error writing to file.\n");*/ /*DEBUG*/ 00273 ret = ERR_FILEIO; 00274 goto almostdone; 00275 } 00276 00277 } while ( ++nbufrec < ndatabuf ); 00278 00279 /* Received all the data we requested 00280 ************************************/ 00281 ret = nbufrec; 00282 00283 almostdone: 00284 free( buf ); 00285 00286 done: 00287 SocketClose( sd ); 00288 fclose( fp ); 00289 return( ret ); 00290 } 00291 00292 00293 /******************************************************** 00294 * wave_inquire * 00295 * Asks the wave_server for the time range and * 00296 * and the logo (installation, module and message * 00297 * type) of the data that's stored in the tank * 00298 ********************************************************/ 00299 int wave_inquire( double *tstart, /* start-time of first buffer in tank */ 00300 double *tend, /* start-time of last buffer in tank */ 00301 unsigned char *inst, /* source installation of served data */ 00302 unsigned char *module, /* source module of served waveforms */ 00303 unsigned char *type ) /* type of waveform msg being served */ 00304 { 00305 int sd; /* Socket descriptor */ 00306 int i, m, t; 00307 char msg[MAX_MSG_LEN]; 00308 char c; 00309 int length, nrec; 00310 int ir; 00311 00312 /* Make sure configuration file has been read 00313 ********************************************/ 00314 if ( !Config_Init ) 00315 { 00316 /*printf("wave_inquire: Configuration file has not been read.\n");*/ /*DEBUG*/ 00317 return( ERR_NOCONFIG ); 00318 } 00319 00320 /* Set up socket connection here 00321 *******************************/ 00322 if ( (sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) 00323 { 00324 logit( "t", "wave_inquire: Socket call failed.\n" ); 00325 SocketPerror( "wave_inquire: Socket call failed" ); 00326 return( ERR_SOCKET ); 00327 } 00328 00329 if ( connect( sd, (struct sockaddr *)&Sin, sizeof(Sin) ) == -1 ) 00330 { 00331 logit( "t", "wave_inquire: Connect to wave_server host failed.\n" ); 00332 SocketPerror( "wave_inquire: Connect to wave_server host failed" ); 00333 SocketClose( sd ); 00334 return( ERR_SOCKET ); 00335 } 00336 00337 /* Send an inquiry to the wave_server 00338 ************************************/ 00339 sprintf( msg, "INQ:\n\0" ); 00340 length = (int) strlen( msg ); 00341 if ( send( sd, msg, length, 0 ) == -1 ) 00342 { 00343 logit( "t", "wave_inquire: Error sending inquiry.\n" ); 00344 SocketPerror( "wave_inquire: Error sending inquiry" ); 00345 SocketClose( sd ); 00346 return( ERR_SOCKET ); 00347 } 00348 00349 /* Start reading the socket. 00350 ***************************/ 00351 nrec = 0; 00352 do 00353 { 00354 if ( nrec == MAX_MSG_LEN ) { /* stop if there's no more room */ 00355 logit( "e", "wave_inquire: wave_server reply too long.\n " ); 00356 SocketClose( sd ); 00357 return( ERR_OVRFLW ); 00358 } 00359 ir = recv( sd, &c, 1, 0 ); /* try to get a char from socket*/ 00360 if ( ir == 1 ) { /* got a character; save it */ 00361 msg[nrec++] = c; 00362 } 00363 else if ( ir == -1 ) { /* trouble reading socket */ 00364 logit( "t", "wave_inquire: Error on socket recv\n" ); 00365 SocketPerror( "wave_inquire: Error on socket recv" ); 00366 SocketClose( sd ); 00367 return( ERR_SOCKET ); 00368 } 00369 } while( c != '\n' ); /* last char of reply */ 00370 msg[nrec] = '\0'; /* null-terminate reply */ 00371 00372 /* Process inquiry reply from wave_server 00373 ****************************************/ 00374 if( sscanf( msg, "%lf %lf %d %d %d", tstart, tend, &i, &m, &t ) < 5 ) 00375 { 00376 logit( "e", "wave_inquire: error decoding wave_server reply:\n%s\n", 00377 msg ); 00378 *tstart = 0.; 00379 *tend = 0.; 00380 *inst = 0; 00381 *module = 0; 00382 *type = 0; 00383 SocketClose( sd ); 00384 return( ERR_STRIO ); 00385 } 00386 if ( i<256 && i>0 ) { 00387 *inst = (unsigned char) i; 00388 } 00389 else { 00390 logit( "e", "wave_inquire: invalid installation id <%d>\n", i ); 00391 *inst = 0; 00392 } 00393 if ( m<256 && m>0 ) { 00394 *module = (unsigned char) m; 00395 } 00396 else { 00397 logit( "e", "wave_inquire: invalid module id <%d>\n", m ); 00398 *module = 0; 00399 } 00400 if ( t<256 && t>0 ) { 00401 *type = (unsigned char) t; 00402 } 00403 else { 00404 logit( "e", "wave_inquire: invalid msg type <%d>\n", t ); 00405 *type = 0; 00406 } 00407 SocketClose( sd ); 00408 return( 0 ); 00409 } 00410 00411 00412 /*********************************************************************** 00413 * wave_client_config() processes command file using kom.c functions * 00414 * exits if any errors are encountered * 00415 ***********************************************************************/ 00416 void wave_client_config( char *configfile ) 00417 { 00418 int ncommand; /* # of required commands you expect to process */ 00419 char init[10]; /* init flags, one byte for each required command */ 00420 int nmiss; /* number of required commands that were missed */ 00421 char *com; 00422 char *str; 00423 int nfiles; 00424 int success; 00425 int i; 00426 00427 /* Set to zero one init flag for each required command 00428 *****************************************************/ 00429 ncommand = 2; 00430 for( i=0; i<ncommand; i++ ) init[i] = 0; 00431 00432 /* Open the main configuration file 00433 **********************************/ 00434 nfiles = k_open( configfile ); 00435 if ( nfiles == 0 ) { 00436 fprintf( stderr, 00437 "wave_client: Error opening command file <%s>; exitting!\n", 00438 configfile ); 00439 exit( -1 ); 00440 } 00441 00442 /* Process all command files 00443 ***************************/ 00444 while(nfiles > 0) /* While there are command files open */ 00445 { 00446 while(k_rd()) /* Read next line from active file */ 00447 { 00448 com = k_str(); /* Get the first token from line */ 00449 00450 /* Ignore blank lines & comments 00451 *******************************/ 00452 if( !com ) continue; 00453 if( com[0] == '#' ) continue; 00454 00455 /* Open a nested configuration file 00456 **********************************/ 00457 if( com[0] == '@' ) { 00458 success = nfiles+1; 00459 nfiles = k_open(&com[1]); 00460 if ( nfiles != success ) { 00461 fprintf( stderr, 00462 "wave_client: Error opening command file <%s>; exitting!\n", 00463 &com[1] ); 00464 exit( -1 ); 00465 } 00466 continue; 00467 } 00468 00469 /* Process anything else as a command 00470 ************************************/ 00471 /* Read the wave_server's host name 00472 **********************************/ 00473 /*0*/ if( k_its( "ServerIPAdr" ) ) 00474 { 00475 str = k_str(); 00476 if(str) strcpy( ServerIPAdr, str ); 00477 init[0] = 1; 00478 } 00479 /* Read the port number to find waveform data on 00480 ***********************************************/ 00481 /*1*/ else if( k_its( "ServerPort" ) ) 00482 { 00483 ServerPort = k_int(); 00484 init[1] = 1; 00485 } 00486 /* Command not recognized 00487 ************************/ 00488 else 00489 { 00490 fprintf(stderr, 00491 "wave_client: <%s> unknown command in <%s>.\n", 00492 com, configfile ); 00493 continue; 00494 } 00495 00496 /* See if there were any errors processing the command 00497 *****************************************************/ 00498 if( k_err() ) { 00499 fprintf( stderr, 00500 "wave_client: Bad <%s> command in <%s>; exitting!\n", 00501 com, configfile ); 00502 exit( -1 ); 00503 } 00504 } 00505 nfiles = k_close(); 00506 } 00507 00508 /* After all files are closed, check init flags for missed commands 00509 ******************************************************************/ 00510 nmiss = 0; 00511 for ( i=0; i<ncommand; i++ ) if( !init[i] ) nmiss++; 00512 if ( nmiss ) { 00513 fprintf( stderr, "wave_client: ERROR, no " ); 00514 if ( !init[0] ) fprintf( stderr, "<ServerIPAdr> " ); 00515 if ( !init[1] ) fprintf( stderr, "<ServerPort> " ); 00516 fprintf( stderr, "command(s) in <%s>; exitting!\n", configfile ); 00517 exit( -1 ); 00518 } 00519 00520 /* Set up socket address structure for wave_server's machine 00521 ***********************************************************/ 00522 if((int)(Addr = inet_addr(ServerIPAdr)) == -1) 00523 { 00524 fprintf( stderr, 00525 "wave_client: inet_addr failed for ServerIPAdr <%s>\n", 00526 ServerIPAdr ); 00527 exit( -1 ); 00528 } 00529 00530 Host = gethostbyaddr((char *)&Addr, sizeof(Addr), AF_INET); 00531 if(Host == NULL) 00532 { 00533 fprintf( stderr, 00534 "wave_client: gethostbyaddr failed for ServerIPAdr <%s>\n", 00535 ServerIPAdr ); 00536 exit( -1 ); 00537 } 00538 memset( (char *) &Sin, '\0', sizeof(Sin) ); 00539 memcpy( (char *) &Sin.sin_addr, Host->h_addr, Host->h_length ); 00540 Sin.sin_family = AF_INET; 00541 Sin.sin_port = htons( (short)ServerPort ); 00542 00543 /* Set configuration flag 00544 ************************/ 00545 Config_Init = 1; 00546 00547 return; 00548 } 00549 00550 /*********************************************************************** 00551 * wave_client_setup() Initializes or resets the global variables * 00552 * ServerIPAdr & ServerPort used by wave_client * 00553 * routines to connect to a wave_server * 00554 ***********************************************************************/ 00555 int wave_client_setup( char *ipadr, /* server's IP address */ 00556 int port ) /* server's port number */ 00557 { 00558 /* Transfer arguments to wave_client globals 00559 *******************************************/ 00560 strcpy( ServerIPAdr, ipadr ); 00561 ServerPort = port; 00562 00563 /* Set up socket address structure for wave_server's machine 00564 ***********************************************************/ 00565 if((int)(Addr = inet_addr(ServerIPAdr)) == -1) 00566 { 00567 logit( "et", 00568 "wave_client: inet_addr failed for ServerIPAdr <%s>\n", 00569 ServerIPAdr ); 00570 return( -1 ); 00571 } 00572 00573 Host = gethostbyaddr((char *)&Addr, sizeof(Addr), AF_INET); 00574 if(Host == NULL) 00575 { 00576 logit( "et", 00577 "wave_client: gethostbyaddr failed for ServerIPAdr <%s>\n", 00578 ServerIPAdr ); 00579 return( -1 ); 00580 } 00581 memset( (char *) &Sin, '\0', sizeof(Sin) ); 00582 memcpy( (char *) &Sin.sin_addr, Host->h_addr, Host->h_length ); 00583 Sin.sin_family = AF_INET; 00584 Sin.sin_port = htons( (short)ServerPort ); 00585 00586 /* Set configuration flag 00587 ************************/ 00588 Config_Init = 1; 00589 00590 return( 0 ); 00591 }