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