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