Merge up from branch.
[shibboleth/cpp-sp.git] / acx_rpctest.m4
1 AC_DEFUN([ACX_RPCTEST], [
2
3 AC_LANG_SAVE
4 AC_LANG_C
5
6 AC_REQUIRE([AC_CANONICAL_HOST])
7
8 old_LIBS="$LIBS"
9 AC_SEARCH_LIBS(svcfd_create,nsl,,)
10 AC_SEARCH_LIBS(socket,socket,,)
11
12 AC_TRY_RUN([
13 /*
14  * test-svc-fd -- see if we can use svc_fd
15  */
16
17 #include <unistd.h>
18 #include <stdio.h>
19 #include <sys/select.h>
20 #include <errno.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <errno.h>
27
28 #ifdef NEED_RPC_TLI
29 #ifdef HAVE_STROPTS_H
30 #include <stropts.h>
31 #endif
32 #endif
33
34 #include <rpc/rpc.h>
35 typedef int ShibSocket;
36
37 #ifdef USE_AF_INET
38 typedef unsigned short ShibSockName;
39 #define SHIB_SHAR_SOCKET 12345
40 #else
41 typedef char* ShibSockName;
42 #define SHIB_SHAR_SOCKET "/tmp/testing-socket"
43 #endif
44
45 #ifndef UNIX_PATH_MAX
46 #define UNIX_PATH_MAX 100
47 #endif
48
49 #ifdef NEED_SVCFD_CREATE_DEFN
50 extern SVCXPRT* svcfd_create ();
51 #endif
52
53 /* Create a ShibSocket -- return 0 on success; non-zero on error */
54 static int
55 shib_sock_create (ShibSocket *sock)
56 {
57   if (!sock) return EINVAL;
58
59   *sock = socket (
60 #ifdef USE_AF_INET
61                   PF_INET,
62 #else
63                   PF_UNIX,
64 #endif
65                   SOCK_STREAM, 0);
66   if (*sock < 0) {
67     perror ("socket");
68     return EINVAL;
69   }
70     
71   return 0;
72 }
73
74 /* Bind the socket to the name. 
75  *
76  * NOTE: This will close the socket on failure 
77  */
78 static int
79 shib_sock_bind (ShibSocket s, ShibSockName name)
80 {
81 #ifdef USE_AF_INET
82   struct sockaddr_in sunaddr;
83
84   memset (&sunaddr, 0, sizeof (sunaddr));
85   sunaddr.sin_family = AF_INET;
86   sunaddr.sin_addr.s_addr = INADDR_LOOPBACK;
87   sunaddr.sin_port = name;
88
89 #else
90   struct sockaddr_un sunaddr;
91
92   memset (&sunaddr, 0, sizeof (sunaddr));
93   sunaddr.sun_family = AF_UNIX;
94   strncpy (sunaddr.sun_path, name, UNIX_PATH_MAX);
95 #endif
96
97   if (bind (s, (struct sockaddr *)&sunaddr, sizeof (sunaddr)) < 0) {
98     perror ("bind");
99     close (s);
100     return EINVAL;
101   }
102
103   /* Make sure that only the creator can read -- we don't want just
104    * anyone connecting, do we?
105    */
106 #ifndef USE_AF_INET
107   if (chmod (name, 0777) < 0) {
108     perror("chmod");
109     close (s);
110     unlink (name);
111     return EINVAL;
112   }
113 #endif
114
115   listen (s, 3);
116
117   return 0;
118 }
119
120 static int
121 test_svc_create (ShibSocket sock)
122 {
123   int i;
124   SVCXPRT *svc;
125
126 #if NEED_RPC_TLI
127   /*
128    * there's an undocumented restriction that the fd you pass in
129    * needs to support the TLI operations.
130    */
131   if (ioctl (sock, I_PUSH, "timod") < 0) {
132     perror("I_PUSH");
133     close (sock);
134     return -1;
135   }
136 #endif
137
138   /* Wrap an RPC Service around the new connection socket */
139   svc = svcfd_create (sock, 0, 0);
140   if (!svc) {
141     perror("svc_fd_create");
142     fprintf (stderr, "Cannot create RPC Listener\n");
143     return -2;
144   }
145
146   return 0;
147 }
148
149 int
150 main (int argc, char *argv[])
151 {
152   ShibSocket sock;
153   int retval;
154
155   /* Create the SHAR listener socket */
156   if (shib_sock_create (&sock) != 0)
157     exit(-3);
158
159   /* Bind to the proper port */
160   if (shib_sock_bind (sock, SHIB_SHAR_SOCKET) != 0)
161     exit(-4);
162
163   retval = test_svc_create (sock);
164 #ifndef USE_AF_INET  
165   unlink (SHIB_SHAR_SOCKET);
166 #endif
167   exit(retval);
168 }],
169 [$1],
170 [$2]
171 )
172
173 LIBS="$old_LIBS"
174
175 AC_LANG_RESTORE
176
177 ])
178