Use GPL instead of LGPL.
[shishi.git] / lib / netio.c
blob4624a41252ccbce06cff4e9ecd630adb765d3ba1
1 /* netio.c network I/O functions
2 * Copyright (C) 2002 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 int
25 shishi_sendrecv_udp (Shishi * handle,
26 struct sockaddr *addr,
27 char *indata,
28 int inlen, char *outdata, int *outlen, int timeout)
30 struct sockaddr lsa;
31 struct hostent *he;
32 struct sockaddr_in *lsa_inp = (struct sockaddr_in *) &lsa;
33 struct protoent *proto;
34 int sockfd;
35 int bytes_sent;
36 struct sockaddr_storage from_sa;
37 int length = sizeof (struct sockaddr_storage);
38 fd_set readfds;
39 struct timeval tout;
40 int rc;
42 memset (&lsa, 0, sizeof (lsa));
43 lsa_inp->sin_family = AF_INET;
44 lsa_inp->sin_addr.s_addr = htonl (INADDR_ANY);
46 sockfd = socket (AF_INET, SOCK_DGRAM, 0);
47 if (sockfd < 0)
49 shishi_error_set(handle, strerror(errno));
50 return SHISHI_SOCKET_ERROR;
53 if (bind (sockfd, (struct sockaddr *) &lsa, sizeof (lsa)) != 0)
55 shishi_error_set(handle, strerror(errno));
56 close (sockfd);
57 return SHISHI_BIND_ERROR;
60 bytes_sent = sendto (sockfd, (void *) indata, inlen,
61 0, addr, sizeof (*addr));
62 if (bytes_sent != inlen)
64 shishi_error_set(handle, strerror(errno));
65 return SHISHI_SENDTO_ERROR;
68 FD_ZERO (&readfds);
69 FD_SET (sockfd, &readfds);
70 tout.tv_sec = timeout;
71 tout.tv_usec = 0;
72 if ((rc = select (sockfd + 1, &readfds, NULL, NULL, &tout)) != 1)
74 if (rc == -1)
75 shishi_error_set(handle, strerror(errno));
76 else
77 shishi_error_clear(handle);
78 return SHISHI_KDC_TIMEOUT;
81 *outlen = recvfrom (sockfd, outdata, *outlen, 0,
82 (struct sockaddr *) &from_sa, &length);
84 if (*outlen == -1)
86 shishi_error_set(handle, strerror(errno));
87 return SHISHI_RECVFROM_ERROR;
90 if (close (sockfd) != 0)
92 shishi_error_set(handle, strerror(errno));
93 return SHISHI_CLOSE_ERROR;
96 return SHISHI_OK;
99 int
100 shishi_kdc_sendrecv (Shishi * handle,
101 char *realm,
102 char *indata, int inlen, char *outdata, int *outlen)
104 int i, j, k;
105 int rc;
107 for (i = 0; i < handle->nrealminfos; i++)
108 if (realm && strcmp (handle->realminfos[i].name, realm) == 0)
110 for (j = 0; j < handle->kdcretries; j++)
111 for (k = 0; k < handle->realminfos[i].nkdcaddresses; k++)
113 struct Shishi_kdcinfo *ki =
114 &handle->realminfos[i].kdcaddresses[k];
116 if (VERBOSE(handle))
118 printf ("Sending to %s (%s)...\n", ki->name,
119 inet_ntoa (((struct sockaddr_in *)
120 &ki->sockaddress)->sin_addr));
123 rc = shishi_sendrecv_udp (handle, &ki->sockaddress,
124 indata, inlen, outdata, outlen,
125 handle->kdctimeout);
126 if (rc != SHISHI_KDC_TIMEOUT)
127 return rc;
130 shishi_error_clear(handle);
131 return SHISHI_KDC_TIMEOUT;
134 shishi_error_printf (handle, "No KDC defined for realm %s\n", realm);
135 return SHISHI_KDC_NOT_KNOWN_FOR_REALM;