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