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