1/* 2 * $Id: nbp_unrgstr.c,v 1.6 2009-10-14 02:24:05 didg Exp $ 3 * 4 * Copyright (c) 1990,1997 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/endian.h> 22#include <netatalk/at.h> 23#include <atalk/nbp.h> 24#include <atalk/netddp.h> 25#include <atalk/ddp.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_unrgstr(const char *obj,const char *type,const char *zone, const struct at_addr *addr) 38{ 39 struct sockaddr_at to; 40 struct nbphdr nh; 41 struct timeval timeout; 42 fd_set readfd; 43 struct servent *se; 44 char *data; 45 int s, cc; 46 SOCKLEN_T namelen; 47 48 49 memset(&to, 0, sizeof(to)); 50 if ((s = netddp_open(&to, NULL)) < 0) 51 return -1; 52 53 data = nbp_send; 54 *data++ = DDPTYPE_NBP; 55 nh.nh_op = NBPOP_UNRGSTR; 56 nh.nh_cnt = 1; 57 nh.nh_id = ++nbp_id; 58 memcpy( data, &nh, SZ_NBPHDR ); 59 data += SZ_NBPHDR; 60 61 memset(data, 0, SZ_NBPTUPLE); 62 data += SZ_NBPTUPLE; 63 64 if ( obj ) { 65 if (( cc = strlen( obj )) > NBPSTRLEN ) return( -1 ); 66 *data++ = cc; 67 memcpy( data, obj, cc ); 68 data += cc; 69 } else { 70 *data++ = 0; 71 } 72 73 if ( type ) { 74 if (( cc = strlen( type )) > NBPSTRLEN ) return( -1 ); 75 *data++ = cc; 76 memcpy( data, type, cc ); 77 data += cc; 78 } else { 79 *data++ = 0; 80 } 81 82 if ( zone ) { 83 if (( cc = strlen( zone )) > NBPSTRLEN ) return( -1 ); 84 *data++ = cc; 85 memcpy( data, zone, cc ); 86 data += cc; 87 } else { 88 *data++ = 0; 89 } 90 91 memset( &to, 0, sizeof( struct sockaddr_at )); 92 to.sat_family = AF_APPLETALK; 93 if (addr) 94 memcpy(&to.sat_addr, addr, sizeof(struct at_addr)); 95#ifdef BSD4_4 96 to.sat_len = sizeof( struct sockaddr_at ); 97#endif /* BSD4_4 */ 98 99 if ( nbp_port == 0 ) { 100 if (( se = getservbyname( "nbp", "ddp" )) == NULL ) { 101 nbp_port = 2; 102 } else { 103 nbp_port = ntohs( se->s_port ); 104 } 105 } 106 to.sat_port = nbp_port; 107 108 if ( netddp_sendto( s, nbp_send, data - nbp_send, 0, 109 (struct sockaddr *)&to, 110 sizeof( struct sockaddr_at )) < 0 ) { 111 goto unregister_err; 112 } 113 114 FD_ZERO( &readfd ); 115 FD_SET( s, &readfd ); 116 timeout.tv_sec = 2; 117 timeout.tv_usec = 0; 118 if (( cc = select( s + 1, &readfd, NULL, NULL, &timeout )) < 0 ) { 119 goto unregister_err; 120 } 121 if ( cc == 0 ) { 122 errno = ETIMEDOUT; 123 goto unregister_err; 124 } 125 126 namelen = sizeof( struct sockaddr_at ); 127 if (( cc = netddp_recvfrom( s, nbp_recv, sizeof( nbp_recv ), 0, 128 (struct sockaddr *)&to, &namelen )) < 0 ) { 129 goto unregister_err; 130 } 131 netddp_close( s ); 132 133 data = nbp_recv; 134 if ( *data++ != DDPTYPE_NBP ) { 135 return( -1 ); 136 } 137 memcpy( &nh, data, SZ_NBPHDR ); 138 if ( nh.nh_op != NBPOP_OK ) { 139 return( -1 ); 140 } 141 return( 0 ); 142 143unregister_err: 144 netddp_close(s); 145 return -1; 146} 147