~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to libatalk/nbp/nbp_lkup.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

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