Pretty print and little cleanups.
[kopensolaris-gnu/glibc.git] / nis / nis_call.c
1 /* Copyright (C) 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <string.h>
21 #include <rpc/rpc.h>
22 #include <rpc/auth.h>
23 #include <rpcsvc/nis.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include "nis_intern.h"
28
29 static struct timeval TIMEOUT = {25, 0};
30 static int const MAXTRIES = 3;
31
32 static unsigned long
33 inetstr2int (const char *str)
34 {
35   char buffer[strlen(str)+3];
36   int i, j;
37
38   strcpy (buffer, str);
39
40   j = 0;
41   for (i = 0; i < strlen (buffer); ++i)
42     if (buffer[i] == '.')
43       {
44         ++j;
45         if (j == 4)
46           {
47             buffer[i] = '\0';
48             break;
49           }
50       }
51
52   return inet_addr(buffer);
53 }
54
55 static CLIENT *
56 __nis_dobind (const nis_server *server, u_long flags)
57 {
58   struct sockaddr_in clnt_saddr;
59   int clnt_sock, i;
60   CLIENT *client = NULL;
61   void *out;
62
63   for (i = 0; i < server->ep.ep_len; i++)
64     {
65       memset (&clnt_saddr, '\0', sizeof clnt_saddr);
66       clnt_saddr.sin_family = AF_INET;
67       if (strcmp (server->ep.ep_val[i].family,"loopback") == 0)
68         {
69           if (server->ep.ep_val[i].uaddr[i] == '-')
70             clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
71           else
72             if (strcmp (server->ep.ep_val[i].proto,"udp") == 0)
73               {
74                 if ((flags & USE_DGRAM) == USE_DGRAM)
75                   clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
76                 else
77                   continue;
78               }
79           else
80             if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
81               {
82                 if ((flags & USE_DGRAM) == USE_DGRAM)
83                   continue;
84                 else
85                   clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
86               }
87         }
88       else
89         if (strcmp (server->ep.ep_val[i].family,"inet") == 0)
90           {
91             if (server->ep.ep_val[i].uaddr[i] == '-')
92               clnt_saddr.sin_addr.s_addr =
93                 inetstr2int(server->ep.ep_val[i].uaddr);
94             else
95               if (strcmp (server->ep.ep_val[i].proto,"udp") == 0)
96                 {
97                   if ((flags & USE_DGRAM) == USE_DGRAM)
98                     clnt_saddr.sin_addr.s_addr =
99                       inetstr2int(server->ep.ep_val[i].uaddr);
100                   else
101                     continue;
102                 }
103               else
104                 if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
105                   {
106                     if ((flags & USE_DGRAM) == USE_DGRAM)
107                       continue;
108                     else
109                       clnt_saddr.sin_addr.s_addr =
110                         inetstr2int(server->ep.ep_val[i].uaddr);
111                   }
112           }
113         else
114           continue;
115
116       clnt_sock = RPC_ANYSOCK;
117       if ((flags & USE_DGRAM) == USE_DGRAM)
118         client = clntudp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
119                                  TIMEOUT, &clnt_sock);
120       else
121         client = clnttcp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
122                                  &clnt_sock, 0, 0);
123
124       if (client == NULL)
125         continue;
126 #if 1
127       if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
128                      (xdrproc_t) xdr_void, out, TIMEOUT) != RPC_SUCCESS)
129         {
130           clnt_destroy (client);
131           continue;
132         }
133 #endif
134       if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
135           {
136 #if !defined(NO_DES_RPC)
137             if (server->key_type == NIS_PK_DH)
138               {
139                 char netname[MAXNETNAMELEN+1];
140                 char *p;
141
142                 strcpy(netname,"unix.");
143                 strncat(netname,server->name,MAXNETNAMELEN-5);
144                 netname[MAXNETNAMELEN-5] = '\0';
145                 p = strchr(netname,'.');
146                 *p = '@';
147                 client->cl_auth =
148                   authdes_pk_create(netname, &server->pkey, 300, NULL, NULL);
149                 if (!client->cl_auth)
150                   client->cl_auth = authunix_create_default();
151               }
152             else
153 #endif
154               client->cl_auth = authunix_create_default();
155           }
156       return client;
157     }
158
159   return NULL;
160 }
161
162 nis_error
163 __do_niscall (const nis_server *serv, int serv_len, u_long prog,
164               xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
165               u_long flags)
166 {
167   CLIENT *clnt;
168   directory_obj *dir = NULL;
169   nis_server *server;
170   int try, result, server_len;
171
172   if (serv == NULL || serv_len == 0)
173     {
174       dir = readColdStartFile ();
175       if (dir == NULL)
176         return NIS_UNAVAIL;
177       server = dir->do_servers.do_servers_val;
178       server_len = dir->do_servers.do_servers_len;
179     }
180   else
181     {
182       server = serv;
183       server_len = serv_len;
184     }
185
186   try = 0;
187   result = NIS_NAMEUNREACHABLE;
188
189   while (try < MAXTRIES && result != RPC_SUCCESS)
190     {
191       unsigned int i;
192
193       ++try;
194       for (i = 0; i < server_len; i++)
195         {
196           if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
197             continue;
198
199           result = clnt_call (clnt, prog, xargs, req, xres, resp, TIMEOUT);
200
201           if (result != RPC_SUCCESS)
202             {
203               clnt_perror (clnt, "do_niscall: clnt_call");
204               clnt_destroy (clnt);
205               result = NIS_RPCERROR;
206             }
207           else
208             clnt_destroy (clnt);
209         }
210     }
211
212   if (dir != NULL)
213     nis_free_directory (dir);
214   return result;
215 }