/************************************************/ /* */ /* File : spy_inet.c */ /* Description : Internet spy library */ /* */ /* Author: Sfiligoi Igor */ /* */ /* Created : 14.12.1998 */ /* Last modified: 15.12.1998 */ /* */ /************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #include <unistd.h> #include <errno.h> #include <Error.h> /* FARM */ #include <farmprog_defs.h> #include "spy_inet.h" int spy_open_inet(char *raddr, /* IN : address of the farm (can be a.b.c.d or 1.2.3.4) */ int rport, /* IN : port of the farm */ SPY_ext_id *sid) /* OUT: SPY_id */ { struct sockaddr_in sin_me; int sock_remote; sock_remote = socket(AF_INET,SOCK_STREAM,0); if (sock_remote<0) { ErrorSetF(0,"spy_open_inet","Error in socket."); return(SPY_ERROR_UNKNOWN); } if (atoi(raddr) > 0 ) /* node given as 1.2.3.4 ? */ { sin_me.sin_family = AF_INET; sin_me.sin_addr.s_addr = inet_addr(raddr); } else /* ... or as a.b.c.d */ { struct hostent *addr; unsigned int addr_tmp; if ( (addr=gethostbyname(raddr)) == NULL ) { ErrorSetF(0,"spy_open_inet", "%s is a bad hostname",raddr); close(sock_remote); return(SPY_ERROR_UNKNOWN); } sin_me.sin_family = addr->h_addrtype; memcpy((char*)&addr_tmp, addr->h_addr, addr->h_length); sin_me.sin_addr.s_addr = addr_tmp; } sin_me.sin_port = htons(rport); if (connect(sock_remote, (struct sockaddr *) &sin_me, sizeof(struct sockaddr_in))<0) { ErrorSetF(0,"spy_open_inet","Error in connect"); close(sock_remote); return(SPY_ERROR_UNKNOWN); } *sid = (SPY_ext_id) malloc(sizeof(SPY_ext_id_base)); (*sid)->spy_type = SPY_TYPE_INET; (*sid)->last_event_nr = 0; (*sid)->cid = sock_remote; return SPY_ERROR_OK; } int spy_close_inet(SPY_ext_id sid) { close(sid->cid); free(sid); return SPY_ERROR_OK; } /* read the requested len */ static int spy_read(int stream_id,char *buf,int len) { int index,count; index = 0; for (index=0; index<len;) { count = read(stream_id,&(buf[index]),len-index); if (((count<0) && (errno != EINTR)) || (count==0)) break; /* connection closed */ /* do not exit if a new command arrives */ if (count<0) count = 0; /* probably a new command arrived */ index+=count; } return index; } /* EINTR safe write */ static int spy_write(int stream_id,void *buf,int len) { int count; /* if new command arrives, retry */ do count = write(stream_id,buf,len); while ((count<0) && (errno==EINTR)); return count; } int spy_get_inet(SPY_ext_id sid,/* IN : SPY_id returned by spy_open_inet */ char **buf, /* OUT: pointer to the data */ /* Should be disposed by the caller */ int *bufsize) /* OUT: buffer size */ { int sock_remote; int buffer_size; char *abuf; /* Ask for a buffer */ { int data[3]; int count; ((unsigned int *) data)[0] = FARMSPYD_MAGIC_NUMBER; data[1] = sid->last_event_nr; data[2] = -1; count = spy_write(sock_remote,data,3*sizeof(int)); if (count!=3*sizeof(int)) { /* connection closed */ ErrorSetF(SPY_ERROR_UNKNOWN,"spy_get_inet","Write header failed, connection closed."); return SPY_ERROR_UNKNOWN; } } /* Read the received header */ { int count; int msg[3]; count = spy_read(sock_remote,(char *) msg, 3*sizeof(int)); if (count<3*sizeof(int)) { /* connection closed */ ErrorSetF(SPY_ERROR_UNKNOWN,"spy_get_inet","Read header failed, connection closed."); return SPY_ERROR_UNKNOWN; } if (((unsigned int *) msg)[0]!=FARMSPYD_MAGIC_NUMBER) { ErrorSetF(0,"spy_get_inet", "Invalid magic number received from farm daemon (%x,%x), closing connection.", ((unsigned int *) msg)[0],FARMSPYD_MAGIC_NUMBER); return(Error_YES); } buffer_size = msg[2]; if (buffer_size==0) { *buf = NULL; *bufsize = 0; return SPY_ERROR_EMPTY; } sid->last_event_nr = msg[1]; } /* Allocate space */ { abuf = (char *) malloc(buffer_size); } /* Read the data in the buffer */ { int count; count = spy_read(sock_remote,abuf, buffer_size); if (count<buffer_size) { /* connection closed */ free(abuf); ErrorSetF(SPY_ERROR_UNKNOWN,"spy_get_inet","Read data failed, connection closed."); return SPY_ERROR_UNKNOWN; } } /* Fill the structures */ *buf = abuf; *bufsize = buffer_size; return SPY_ERROR_OK; }