]> arthur.barton.de Git - netatalk.git/blob - libatalk/nbp/nbp_lkup.c
implemented config.h
[netatalk.git] / libatalk / nbp / nbp_lkup.c
1 /*
2  * Copyright (c) 1990,1997 Regents of The University of Michigan.
3  * All Rights Reserved. See COPYRIGHT.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/param.h>
13 #include <sys/socket.h>
14 #include <sys/signal.h>
15 #include <sys/time.h>
16 #include <netatalk/endian.h>
17 #include <netatalk/at.h>
18 #include <netatalk/ddp.h>
19 #include <atalk/compat.h>
20 #include <atalk/nbp.h>
21 #include <atalk/netddp.h>
22 #include <atalk/ddp.h>
23
24 #include <netdb.h>
25 #include <errno.h>
26
27 #include  "nbp_conf.h"
28
29 /* FIXME/SOCKLEN_T: socklen_t is a unix98 feature. */
30 #ifndef SOCKLEN_T
31 #define SOCKLEN_T unsigned int
32 #endif
33
34 int nbp_lookup( obj, type, zone, nn, nncnt, ataddr )
35     const char          *obj, *type, *zone;
36     struct nbpnve       *nn;
37     int                 nncnt;
38     const struct at_addr *ataddr;
39 {
40     struct sockaddr_at  addr, from;
41     struct timeval      tv, tv_begin, tv_end;
42     fd_set              fds;
43     struct nbpnve       nve;
44     struct nbphdr       nh;
45     struct nbptuple     nt;
46     struct servent      *se;
47     char                *data = nbp_send;
48     SOCKLEN_T           namelen;
49     int                 s, cnt, tries, sc, cc, i, c;
50
51     memset(&addr, 0, sizeof(addr));
52     memset(&from, 0, sizeof(from));
53     if (ataddr) 
54       memcpy(&addr.sat_addr, ataddr, sizeof(struct at_addr));
55     if ((s = netddp_open(&addr, &from)) < 0)
56       return -1;
57
58     *data++ = DDPTYPE_NBP;
59 #ifdef MACOSX_SERVER
60     nh.nh_op = from.sat_addr.s_node ? NBPOP_BRRQ : NBPOP_LKUP;
61 #else
62     nh.nh_op = NBPOP_BRRQ;
63 #endif
64
65     nh.nh_cnt = 1;
66     nh.nh_id = ++nbp_id;
67     memcpy( data, &nh, SZ_NBPHDR );
68     data += SZ_NBPHDR;
69
70     memset(&nt, 0, sizeof(nt));
71     nt.nt_net = addr.sat_addr.s_net;
72     nt.nt_node = addr.sat_addr.s_node;
73     nt.nt_port = addr.sat_port;
74
75     memcpy( data, &nt, SZ_NBPTUPLE);
76     data += SZ_NBPTUPLE;
77
78     if ( obj ) {
79         if (( cc = strlen( obj )) > NBPSTRLEN ) goto lookup_err;
80         *data++ = cc;
81         memcpy( data, obj, cc );
82         data += cc;
83     } else {
84         *data++ = 1;
85         *data++ = '='; /* match anything */
86     }
87
88     if ( type ) {
89         if (( cc = strlen( type )) > NBPSTRLEN ) goto lookup_err;
90         *data++ = cc;
91         memcpy( data, type, cc );
92         data += cc;
93     } else {
94         *data++ = 1;
95         *data++ = '='; /* match anything */
96     }
97
98     if ( zone ) {
99         if (( cc = strlen( zone )) > NBPSTRLEN ) goto lookup_err;
100         *data++ = cc;
101         memcpy( data, zone, cc );
102         data += cc;
103     } else {
104         *data++ = 1;
105         *data++ = '*'; /* default zone */
106     }
107
108     if ( nbp_port == 0 ) {
109       if (( se = getservbyname( "nbp", "ddp" )) == NULL ) {
110                     nbp_port = 2;
111       } else {
112                     nbp_port = ntohs( se->s_port );
113       }
114     }
115
116 #ifdef MACOSX_SERVER
117     if (from.sat_addr.s_node) {
118       memcpy(&addr.sat_addr, &from.sat_addr, sizeof(addr.sat_addr));
119     } else {
120       addr.sat_addr.s_net = ATADDR_ANYNET;
121       addr.sat_addr.s_node = ATADDR_BCAST;
122     }
123 #endif
124     addr.sat_port = nbp_port;
125
126     cnt = 0;
127     tries = 3;
128     sc = data - nbp_send;
129     while ( tries > 0 ) {
130         if ( netddp_sendto( s, nbp_send, sc, 0, (struct sockaddr *)&addr,
131                 sizeof( struct sockaddr_at )) < 0 ) {
132             goto lookup_err;
133         }
134
135         tv.tv_sec = 2L;
136         tv.tv_usec = 0;
137
138         for (;;) {
139             FD_ZERO( &fds );
140             FD_SET( s, &fds );
141             if ( gettimeofday( &tv_begin, NULL ) < 0 ) {
142                 goto lookup_err;
143             }
144             if (( c = select( s + 1, &fds, NULL, NULL, &tv )) < 0 ) {
145                 goto lookup_err;
146             }
147             if ( c == 0 || FD_ISSET( s, &fds ) == 0 ) {
148                 break;
149             }
150             if ( gettimeofday( &tv_end, NULL ) < 0 ) {
151                 goto lookup_err;
152             }
153             if ( tv_begin.tv_usec > tv_end.tv_sec ) {
154                 tv_end.tv_usec += 1000000;
155                 tv_end.tv_sec -= 1;
156             }
157             if (( tv.tv_usec -= ( tv_end.tv_usec - tv_begin.tv_usec )) < 0 ) {
158                 tv.tv_usec += 1000000;
159                 tv.tv_sec -= 1;
160             }
161             if (( tv.tv_sec -= ( tv_end.tv_sec - tv_begin.tv_sec )) < 0 ) {
162                 break;
163             }
164
165             namelen = sizeof( struct sockaddr_at );
166             if (( cc = netddp_recvfrom( s, nbp_recv, sizeof( nbp_recv ), 0,
167                     (struct sockaddr *)&from, &namelen )) < 0 ) {
168                 goto lookup_err;
169             }
170
171             data = nbp_recv;
172             if ( *data++ != DDPTYPE_NBP ) {
173                 continue;
174             }
175             cc--;
176
177             memcpy( &nh, data, SZ_NBPHDR );
178             data += SZ_NBPHDR;
179             if ( nh.nh_op != NBPOP_LKUPREPLY ) {
180                 continue;
181             }
182             cc -= SZ_NBPHDR;
183
184             while (( i = nbp_parse( data, &nve, cc )) >= 0 ) {
185                 data += cc - i;
186                 cc = i;
187                 /*
188                  * Check to see if nve is already in nn. If not,
189                  * put it in, and increment cnt.
190                  */
191                 for ( i = 0; i < cnt; i++ ) {
192                     if ( nbp_match( &nve, &nn[ i ],
193                             NBPMATCH_NOZONE|NBPMATCH_NOGLOB )) {
194                         break;
195                     }
196                 }
197                 if ( i == cnt ) {
198                     nn[ cnt++ ] = nve;
199                 }
200                 if ( cnt == nncnt ) {
201                     tries = 0;
202                     break;
203                 }
204             }
205             if ( cnt == nncnt ) {
206                 tries = 0;
207                 break;
208             }
209         }
210         tries--;
211     }
212
213     netddp_close(s);
214     errno = 0;
215     return( cnt );
216
217 lookup_err:
218     netddp_close(s);
219     return -1;
220 }