| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 1 | /*****************************************************************************/ | 
 | 2 | /* "NetPIPE" -- Network Protocol Independent Performance Evaluator.          */ | 
 | 3 | /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc.      */ | 
 | 4 | /*                                                                           */ | 
 | 5 | /* This program is free software; you can redistribute it and/or modify      */ | 
 | 6 | /* it under the terms of the GNU General Public License as published by      */ | 
 | 7 | /* the Free Software Foundation.  You should have received a copy of the     */ | 
 | 8 | /* GNU General Public License along with this program; if not, write to the  */ | 
 | 9 | /* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ | 
 | 10 | /*                                                                           */ | 
 | 11 | /*     * TCP.c              ---- TCP calls source                            */ | 
 | 12 | /*     * TCP.h              ---- Include file for TCP calls and data structs */ | 
 | 13 | /* 2002/03/18 --- Modified for IPv6 - Robbie Williamson (robbiew@us.ibm.com) */ | 
 | 14 | /*****************************************************************************/ | 
 | 15 | #include    "netpipe.h" | 
 | 16 |  | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 17 |  | 
 | 18 | int Setup(ArgStruct *p) | 
 | 19 | { | 
 | 20 |  | 
 | 21 |  int tr, one = 1;                 /* tr==1 if process is a transmitter */ | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 22 |  int sr = 0; | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 23 |  int sockfd; | 
 | 24 |  struct sockaddr *lsin1; | 
 | 25 |  char *host; | 
 | 26 |  char *server_host; | 
 | 27 |  struct addrinfo *addr; | 
 | 28 |  struct addrinfo *server_addr; | 
 | 29 |  struct addrinfo hints; | 
 | 30 |  struct protoent *proto; | 
 | 31 |  | 
 | 32 |  memset(&hints, 0, sizeof(hints)); | 
 | 33 |  hints.ai_family = AF_INET6; | 
 | 34 |  | 
 | 35 |  | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 36 |  host = p->host;                           /* copy ptr to hostname */ | 
 | 37 |  server_host = p->server_host;             /* copy ptr to server */ | 
 | 38 |  | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 39 |  tr = p->tr;                               /* copy tr indicator */ | 
 | 40 |  sr = p->sr; | 
 | 41 |  | 
 | 42 |  | 
 | 43 |  memset(&p->prot.sin1, 0, sizeof(p->prot.sin1)); | 
 | 44 |  memset(&p->prot.sin2, 0, sizeof(p->prot.sin2)); | 
 | 45 |  | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 46 |  if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 47 |    printf("NetPIPE: can't open stream socket! errno=%d\n", errno); | 
 | 48 |    exit(-4); | 
 | 49 |  } | 
 | 50 |  | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 51 |  if (!(proto = getprotobyname("tcp"))) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 52 |    printf("NetPIPE: protocol 'tcp' unknown!\n"); | 
 | 53 |    exit(555); | 
 | 54 |  } | 
 | 55 |  | 
 | 56 |  /* Attempt to set TCP_NODELAY */ | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 57 |  if (setsockopt(sockfd, proto->p_proto, TCP_NODELAY, &one, sizeof(one)) < 0) | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 58 |  { | 
 | 59 |    printf("NetPIPE: setsockopt: TCP_NODELAY failed! errno=%d\n", errno); | 
 | 60 |    exit(556); | 
 | 61 |  } | 
 | 62 |  | 
 | 63 |  /* If requested, set the send and receive buffer sizes */ | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 64 |  if (p->prot.sndbufsz > 0) | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 65 |  { | 
 | 66 |       printf("Send and Receive Buffers set to %d bytes\n", p->prot.sndbufsz); | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 67 |      if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 68 |                                        sizeof(p->prot.sndbufsz)) < 0) | 
 | 69 |      { | 
 | 70 |           printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno); | 
 | 71 |           exit(556); | 
 | 72 |      } | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 73 |      if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 74 |                                        sizeof(p->prot.rcvbufsz)) < 0) | 
 | 75 |      { | 
 | 76 |           printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno); | 
 | 77 |           exit(556); | 
 | 78 |      } | 
 | 79 |  } | 
 | 80 |  | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 81 |  if (tr) {                                  /* if client i.e., Sender */ | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 82 |  | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 83 |    if (host) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 84 |      getaddrinfo(host, NULL, &hints, &addr); | 
 | 85 |      memcpy(&p->prot.sin1, addr->ai_addr, addr->ai_addrlen); | 
 | 86 |    } else { | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 87 |      if ((getaddrinfo(host,NULL,&hints,&addr)) != 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 88 |        printf("NetPIPE: invalid hostname '%s'\n", host); | 
 | 89 |        exit(-5); | 
 | 90 |    } | 
 | 91 |  } | 
 | 92 |    p->prot.sin1.sin6_port = htons(p->port); | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 93 |  | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 94 | } else {                                 /* we are the receiver (server) */ | 
 | 95 |  | 
 | 96 |    memset(&p->prot.sin1, 0, sizeof(p->prot.sin1)); | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 97 |    if (sr==0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 98 |      p->prot.sin1.sin6_addr = in6addr_any; | 
 | 99 |      p->prot.sin1.sin6_port = htons(p->port); | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 100 |      lsin1=(struct sockaddr*)&p->prot.sin1; | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 101 |      if (bind(sockfd, (struct sockaddr*)lsin1, sizeof(p->prot.sin1)) < 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 102 |        printf("NetPIPE: server: bind on local address failed! errno=%d", errno); | 
 | 103 |        exit(-6); | 
 | 104 |      } | 
 | 105 |    } | 
 | 106 |    else{ | 
 | 107 |        getaddrinfo(server_host, NULL, NULL, &server_addr); | 
 | 108 |        memcpy(&p->prot.sin1, server_addr->ai_addr, server_addr->ai_addrlen); | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 109 |        if ((getaddrinfo(server_host, NULL, NULL, &server_addr)) != 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 110 |   	  printf("NetPIPE: invalid hostname '%s'\n", host); | 
 | 111 | 	  exit(-5); | 
 | 112 |        } | 
 | 113 |        memcpy(&p->prot.sin1, server_addr->ai_addr, server_addr->ai_addrlen); | 
 | 114 |        p->prot.sin1.sin6_port = htons(p->port); | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 115 |        lsin1=(struct sockaddr*)&p->prot.sin1; | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 116 |        if (bind(sockfd, (struct sockaddr*)lsin1, sizeof(p->prot.sin1)) < 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 117 |          printf("NetPIPE: server: bind on %s failed! errno=%d", server_host, errno); | 
 | 118 |          exit(-6); | 
 | 119 |        } | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 120 |    } | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 121 |  } | 
 | 122 |  | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 123 |  if (tr) | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 124 |    p->commfd = sockfd; | 
 | 125 |  else | 
 | 126 |    p->servicefd = sockfd; | 
 | 127 |  | 
 | 128 |  return(0); | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 129 |  | 
 | 130 | } | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 131 |  | 
 | 132 | static int | 
 | 133 | readFully(int fd, void *obuf, int len) | 
 | 134 | { | 
 | 135 |   int bytesLeft = len; | 
 | 136 |   char *buf = (char *) obuf; | 
 | 137 |   int bytesRead = 0; | 
 | 138 |  | 
 | 139 |   while (bytesLeft > 0 && | 
 | 140 | 	 (bytesRead = read(fd, (void *) buf, bytesLeft)) > 0) | 
 | 141 |     { | 
 | 142 |       bytesLeft -= bytesRead; | 
 | 143 |       buf += bytesRead; | 
 | 144 |     } | 
 | 145 |   if (bytesRead <= 0) | 
 | 146 |     return bytesRead; | 
 | 147 |   return len; | 
 | 148 | } | 
 | 149 |  | 
 | 150 | void Sync(ArgStruct *p) | 
 | 151 | { | 
 | 152 |     char s[] = "SyncMe"; | 
 | 153 |     char response[7]; | 
 | 154 |  | 
 | 155 |     if (write(p->commfd, s, strlen(s)) < 0 || | 
 | 156 | 	readFully(p->commfd, response, strlen(s)) < 0) | 
 | 157 |       { | 
 | 158 | 	perror("NetPIPE: error writing or reading synchronization string"); | 
 | 159 | 	exit(3); | 
 | 160 |       } | 
 | 161 |     if (strncmp(s, response, strlen(s))) | 
 | 162 |       { | 
 | 163 | 	fprintf(stderr, "NetPIPE: Synchronization string incorrect!\n"); | 
 | 164 | 	exit(3); | 
 | 165 |       } | 
 | 166 | } | 
 | 167 |  | 
 | 168 | void PrepareToReceive(ArgStruct *p) | 
 | 169 | { | 
 | 170 | 	/* | 
 | 171 | 	  The Berkeley sockets interface doesn't have a method to pre-post | 
 | 172 | 	  a buffer for reception of data. | 
 | 173 | 	*/ | 
 | 174 | } | 
 | 175 |  | 
 | 176 | void SendData(ArgStruct *p) | 
 | 177 | { | 
 | 178 |     int bytesWritten, bytesLeft; | 
 | 179 |     char *q; | 
 | 180 |  | 
 | 181 |     bytesLeft = p->bufflen; | 
 | 182 |     bytesWritten = 0; | 
 | 183 |     q = p->buff; | 
 | 184 |     while (bytesLeft > 0 && | 
 | 185 | 	   (bytesWritten = write(p->commfd, q, bytesLeft)) > 0) | 
 | 186 |       { | 
 | 187 | 	bytesLeft -= bytesWritten; | 
 | 188 | 	q += bytesWritten; | 
 | 189 |       } | 
 | 190 |     if (bytesWritten == -1) | 
 | 191 |       { | 
 | 192 | 	printf("NetPIPE: write: error encountered, errno=%d\n", errno); | 
 | 193 | 	exit(401); | 
 | 194 |       } | 
 | 195 | } | 
 | 196 |  | 
 | 197 | void RecvData(ArgStruct *p) | 
 | 198 | { | 
 | 199 |     int bytesLeft; | 
 | 200 |     int bytesRead; | 
 | 201 |     char *q; | 
 | 202 |  | 
 | 203 |     bytesLeft = p->bufflen; | 
 | 204 |     bytesRead = 0; | 
 | 205 |     q = p->buff1; | 
 | 206 |     while (bytesLeft > 0 && | 
 | 207 | 	   (bytesRead = read(p->commfd, q, bytesLeft)) > 0) | 
 | 208 |       { | 
 | 209 | 	bytesLeft -= bytesRead; | 
 | 210 | 	q += bytesRead; | 
 | 211 |       } | 
 | 212 |     if (bytesLeft > 0 && bytesRead == 0) | 
 | 213 |       { | 
 | 214 | 	printf("NetPIPE: \"end of file\" encountered on reading from socket\n"); | 
 | 215 |       } | 
 | 216 |     else if (bytesRead == -1) | 
 | 217 |       { | 
 | 218 | 	printf("NetPIPE: read: error encountered, errno=%d\n", errno); | 
 | 219 | 	exit(401); | 
 | 220 |       } | 
 | 221 | } | 
 | 222 |  | 
 | 223 | void SendTime(ArgStruct *p, double *t) | 
 | 224 | { | 
 | 225 |     unsigned int ltime, ntime; | 
 | 226 |  | 
 | 227 |     /* | 
 | 228 |       Multiply the number of seconds by 1e6 to get time in microseconds | 
 | 229 |       and convert value to an unsigned 32-bit integer. | 
 | 230 |       */ | 
 | 231 |     ltime = (unsigned int)(*t * 1.e6); | 
 | 232 |  | 
 | 233 |     /* Send time in network order */ | 
 | 234 |     ntime = htonl(ltime); | 
 | 235 |     if (write(p->commfd, (char *)&ntime, sizeof(unsigned int)) < 0) | 
 | 236 |       { | 
 | 237 | 	printf("NetPIPE: write failed in SendTime: errno=%d\n", errno); | 
 | 238 | 	exit(301); | 
 | 239 |       } | 
 | 240 | } | 
 | 241 |  | 
 | 242 | void RecvTime(ArgStruct *p, double *t) | 
 | 243 | { | 
 | 244 |     unsigned int ltime, ntime; | 
 | 245 |     int bytesRead; | 
 | 246 |  | 
 | 247 |     bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(unsigned int)); | 
 | 248 |     if (bytesRead < 0) | 
 | 249 |       { | 
 | 250 | 	printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno); | 
 | 251 | 	exit(302); | 
 | 252 |       } | 
 | 253 |     else if (bytesRead != sizeof(unsigned int)) | 
 | 254 |       { | 
 | 255 | 	fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n", | 
 | 256 | 		bytesRead); | 
 | 257 | 	exit(303); | 
 | 258 |       } | 
 | 259 |     ltime = ntohl(ntime); | 
 | 260 |  | 
 | 261 |     /* Result is ltime (in microseconds) divided by 1.0e6 to get seconds */ | 
 | 262 |     *t = (double)ltime / 1.0e6; | 
 | 263 | } | 
 | 264 |  | 
 | 265 | void SendRepeat(ArgStruct *p, int rpt) | 
 | 266 | { | 
 | 267 |   unsigned int lrpt, nrpt; | 
 | 268 |  | 
 | 269 |   lrpt = rpt; | 
 | 270 |   /* Send repeat count as an unsigned 32 bit integer in network order */ | 
 | 271 |   nrpt = htonl(lrpt); | 
 | 272 |   if (write(p->commfd, (void *) &nrpt, sizeof(unsigned int)) < 0) | 
 | 273 |     { | 
 | 274 |       printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno); | 
 | 275 |       exit(304); | 
 | 276 |     } | 
 | 277 | } | 
 | 278 |  | 
 | 279 | void RecvRepeat(ArgStruct *p, int *rpt) | 
 | 280 | { | 
 | 281 |   unsigned int lrpt, nrpt; | 
 | 282 |   int bytesRead; | 
 | 283 |  | 
 | 284 |   bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(unsigned int)); | 
 | 285 |   if (bytesRead < 0) | 
 | 286 |     { | 
 | 287 |       printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno); | 
 | 288 |       exit(305); | 
 | 289 |     } | 
 | 290 |   else if (bytesRead != sizeof(unsigned int)) | 
 | 291 |     { | 
 | 292 |       fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n", | 
 | 293 | 	      bytesRead); | 
 | 294 |       exit(306); | 
 | 295 |     } | 
 | 296 |   lrpt = ntohl(nrpt); | 
 | 297 |  | 
 | 298 |   *rpt = lrpt; | 
 | 299 | } | 
 | 300 |  | 
 | 301 | int Establish(ArgStruct *p) | 
 | 302 | { | 
| vapier | da6657a | 2006-07-04 22:25:19 +0000 | [diff] [blame] | 303 |  socklen_t clen; | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 304 |  int one = 1; | 
 | 305 |  struct protoent *proto; | 
 | 306 |  | 
 | 307 |  clen = sizeof(p->prot.sin2); | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 308 |  if (p->tr) { | 
 | 309 |    if (connect(p->commfd, (struct sockaddr *) &(p->prot.sin1), | 
 | 310 | 	      sizeof(p->prot.sin1)) < 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 311 |      printf("Client: Cannot Connect! errno=%d\n",errno); | 
 | 312 |      exit(-10); | 
 | 313 |    } | 
 | 314 |   } | 
 | 315 |   else { | 
 | 316 |     /* SERVER */ | 
 | 317 |     listen(p->servicefd, 5); | 
 | 318 |     p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sin2), | 
 | 319 | 		       &clen); | 
 | 320 |  | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 321 |     if (p->commfd < 0) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 322 |       printf("Server: Accept Failed! errno=%d\n",errno); | 
 | 323 |       exit(-12); | 
 | 324 |     } | 
 | 325 |  | 
 | 326 |     /* | 
 | 327 |       Attempt to set TCP_NODELAY. TCP_NODELAY may or may not be propagated | 
 | 328 |       to accepted sockets. | 
 | 329 |      */ | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 330 |     if (!(proto = getprotobyname("tcp"))) { | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 331 |       printf("unknown protocol!\n"); | 
 | 332 |       exit(555); | 
 | 333 |     } | 
 | 334 |  | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 335 |     if (setsockopt(p->commfd, proto->p_proto, TCP_NODELAY, | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 336 | 		  &one, sizeof(one)) < 0) | 
 | 337 |     { | 
 | 338 |       printf("setsockopt: TCP_NODELAY failed! errno=%d\n", errno); | 
 | 339 |       exit(556); | 
 | 340 |     } | 
 | 341 |  | 
 | 342 |     /* If requested, set the send and receive buffer sizes */ | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 343 |     if (p->prot.sndbufsz > 0) | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 344 |     { | 
 | 345 |       printf("Send and Receive Buffers on accepted socket set to %d bytes\n", | 
 | 346 | 	     p->prot.sndbufsz); | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 347 |       if (setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 348 |                                        sizeof(p->prot.sndbufsz)) < 0) | 
 | 349 |       { | 
 | 350 | 	printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno); | 
 | 351 | 	exit(556); | 
 | 352 |       } | 
| Garrett Cooper | 43088e1 | 2010-12-13 23:30:59 -0800 | [diff] [blame] | 353 |       if (setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 354 |                                        sizeof(p->prot.rcvbufsz)) < 0) | 
 | 355 |       { | 
 | 356 | 	printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno); | 
 | 357 | 	exit(556); | 
 | 358 |       } | 
 | 359 |     } | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 360 |   } | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 361 |   return(0); | 
 | 362 | } | 
 | 363 |  | 
| vapier | 57c212c | 2006-07-04 22:29:12 +0000 | [diff] [blame] | 364 | int CleanUp(ArgStruct *p) | 
| robbiew | 723b3af | 2003-03-28 18:14:44 +0000 | [diff] [blame] | 365 | { | 
 | 366 |  char *quit="QUIT"; | 
 | 367 |  if (p->tr) | 
 | 368 |  { | 
 | 369 |      write(p->commfd,quit, 5); | 
 | 370 |      read(p->commfd, quit, 5); | 
 | 371 |      close(p->commfd); | 
 | 372 |  } | 
 | 373 |  else | 
 | 374 |  { | 
 | 375 |      read(p->commfd,quit, 5); | 
 | 376 |      write(p->commfd,quit,5); | 
 | 377 |      close(p->commfd); | 
 | 378 |      close(p->servicefd); | 
 | 379 |  } | 
 | 380 |  return(0); | 
| Chris Dearman | ec6edca | 2012-10-17 19:54:01 -0700 | [diff] [blame^] | 381 | } |