]> arthur.barton.de Git - netatalk.git/blob - libatalk/nbp/nbp_rgstr.c
5fa024925491a138431eb7a579f6535502f4b3af
[netatalk.git] / libatalk / nbp / nbp_rgstr.c
1 /*
2  * $Id: nbp_rgstr.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
3  *
4  * Copyright (c) 1990,1993 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 <sys/types.h>
14 #include <sys/param.h>
15 #include <sys/socket.h>
16 #include <sys/signal.h>
17 #include <sys/time.h>
18 #include <errno.h>
19
20 #include <netatalk/at.h>
21 #include <netatalk/endian.h>
22 #include <atalk/nbp.h>
23 #include <atalk/ddp.h>
24 #include <atalk/netddp.h>
25
26 #ifdef HAVE_NETDB_H
27 #include <netdb.h>
28 #endif /* HAVE_NETDB_H */
29 #include  "nbp_conf.h"
30
31 /* FIXME/SOCKLEN_T: socklen_t is a unix98 feature. */
32 #ifndef SOCKLEN_T
33 #define SOCKLEN_T unsigned int
34 #endif /* ! SOCKLEN_T */
35
36 int nbp_rgstr( sat, obj, type, zone )
37     struct sockaddr_at  *sat;
38     const char          *obj, *type, *zone;
39 {
40     struct sockaddr_at  to;
41     struct nbpnve       nn;
42     struct nbphdr       nh;
43     struct nbptuple     nt;
44     struct timeval      timeout;
45     fd_set              readfd;
46     struct servent      *se;
47     char                *data;
48     int                 s, cc;
49     SOCKLEN_T           namelen;
50
51     if ( nbp_lookup( obj, type, zone, &nn, 1, &sat->sat_addr ) > 0 ) {
52         errno = EADDRINUSE;
53         return( -1 );
54     }
55
56     memset(&to, 0, sizeof(to));
57     if ((s = netddp_open(&to, NULL)) < 0)
58         return -1;
59
60     data = nbp_send;
61     *data++ = DDPTYPE_NBP;
62     nh.nh_op = NBPOP_RGSTR;
63     nh.nh_cnt = 1;
64     nh.nh_id = ++nbp_id;
65     memcpy( data, &nh, SZ_NBPHDR );
66     data += SZ_NBPHDR;
67
68     memset(&nt, 0, sizeof(nt));
69     nt.nt_net = sat->sat_addr.s_net;
70     nt.nt_node = sat->sat_addr.s_node;
71     nt.nt_port = sat->sat_port;
72     memcpy( data, &nt, SZ_NBPTUPLE);
73     data += SZ_NBPTUPLE;
74
75     if ( obj ) {
76         if (( cc = strlen( obj )) > NBPSTRLEN ) return( -1 );
77         *data++ = cc;
78         memcpy( data, obj, cc );
79         data += cc;
80     } else {
81         *data++ = 0;
82     }
83
84     if ( type ) {
85         if (( cc = strlen( type )) > NBPSTRLEN ) return( -1 );
86         *data++ = cc;
87         memcpy( data, type, cc );
88         data += cc;
89     } else {
90         *data++ = 0;
91     }
92
93     if ( zone ) {
94         if (( cc = strlen( zone )) > NBPSTRLEN ) return( -1 );
95         *data++ = cc;
96         memcpy( data, zone, cc );
97         data += cc;
98     } else {
99         *data++ = 1;
100         *data++ = '*'; /* default zone */
101     }
102
103     
104     if ( nbp_port == 0 ) {
105         if (( se = getservbyname( "nbp", "ddp" )) == NULL ) {
106             nbp_port = 2;
107         } else {
108             nbp_port = ntohs( se->s_port );
109         }
110     }
111     to.sat_port = nbp_port;
112
113     if ( netddp_sendto( s, nbp_send, data - nbp_send, 0, 
114                         (struct sockaddr *)&to,
115                         sizeof( struct sockaddr_at )) < 0 ) {
116         goto register_err;
117     }
118
119     FD_ZERO( &readfd );
120     FD_SET( s, &readfd );
121     timeout.tv_sec = 2;
122     timeout.tv_usec = 0;
123     if (( cc = select( s + 1, &readfd, 0, 0, &timeout )) < 0 ) {
124         goto register_err;
125     }
126     if ( cc == 0 ) {
127         errno = ETIMEDOUT;
128         goto register_err;
129     }
130
131     namelen = sizeof( struct sockaddr_at );
132     if (( cc = netddp_recvfrom( s, nbp_recv, sizeof( nbp_recv ), 0,
133                         (struct sockaddr *)&to, &namelen )) < 0 ) {
134         goto register_err;
135     }
136
137     netddp_close( s );
138
139     data = nbp_recv;
140     if ( *data++ != DDPTYPE_NBP ) {
141         return( -1 );
142     }
143     memcpy( &nh, data, SZ_NBPHDR );
144     if ( nh.nh_op != NBPOP_OK ) {
145         return -1;
146     }
147     return( 0 );
148
149 register_err:
150     netddp_close(s);
151     return -1;
152 }