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