1/* 2 * $Id: atp_rreq.c,v 1.4 2009-10-13 22:55:37 didg Exp $ 3 * 4 * Copyright (c) 1990,1991 Regents of The University of Michigan. 5 * All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and distribute this software and 8 * its documentation for any purpose and without fee is hereby granted, 9 * provided that the above copyright notice appears in all copies and 10 * that both that copyright notice and this permission notice appear 11 * in supporting documentation, and that the name of The University 12 * of Michigan not be used in advertising or publicity pertaining to 13 * distribution of the software without specific, written prior 14 * permission. This software is supplied as is without expressed or 15 * implied warranties of any kind. 16 * 17 * Research Systems Unix Group 18 * The University of Michigan 19 * c/o Mike Clark 20 * 535 W. William Street 21 * Ann Arbor, Michigan 22 * +1-313-763-0525 23 * netatalk@itd.umich.edu 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif /* HAVE_CONFIG_H */ 29 30#include <stdlib.h> 31#include <string.h> 32#include <sys/types.h> 33#include <sys/time.h> 34#include <errno.h> 35 36#include <netinet/in.h> 37#include <netatalk/at.h> 38#include <netatalk/endian.h> 39#include <atalk/atp.h> 40 41#include "atp_internals.h" 42 43 44/* wait for a tranasaction service request 45*/ 46int atp_rreq( 47 ATP ah, /* open atp handle */ 48 struct atp_block *atpb) /* parameter block */ 49{ 50 struct atpbuf *req_buf; /* for receiving request packet */ 51 struct atphdr req_hdr; /* request header overlay */ 52 struct sockaddr_at faddr; /* sender's address */ 53 int recvlen; /* length of received packet */ 54 u_int16_t tid; 55 int rc; 56 u_int8_t func; 57 58#ifdef EBUG 59 atp_print_bufuse( ah, "atp_rreq" ); 60#endif /* EBUG */ 61 62 while (( rc = atp_rsel( ah, atpb->atp_saddr, ATP_TREQ )) == 0 ) { 63 ; 64 } 65 66 if ( rc != ATP_TREQ ) { 67#ifdef EBUG 68 printf( "<%d> atp_rreq: atp_rsel returns err %d\n", getpid(), rc ); 69#endif /* EBUG */ 70 return( rc ); 71 } 72 73 /* allocate a buffer for receiving request 74 */ 75 if (( req_buf = atp_alloc_buf()) == NULL ) { 76 return -1; 77 } 78 79 memcpy( &faddr, atpb->atp_saddr, sizeof( struct sockaddr_at )); 80 func = ATP_TREQ; 81 if (( recvlen = atp_recv_atp( ah, &faddr, &func, ATP_TIDANY, 82 req_buf->atpbuf_info.atpbuf_data, 1 )) < 0 ) { 83 atp_free_buf( req_buf ); 84 return -1; 85 } 86 87 memcpy( &req_hdr, req_buf->atpbuf_info.atpbuf_data + 1, 88 sizeof( struct atphdr )); 89 tid = ntohs( req_hdr.atphd_tid ); 90 91 ah->atph_rtid = tid; 92 if (( ah->atph_rxo = req_hdr.atphd_ctrlinfo & ATP_XO ) != 0 ) { 93 ah->atph_rreltime = ATP_RELTIME * 94 ( 1 << ( req_hdr.atphd_ctrlinfo & ATP_TRELMASK )); 95 } 96 97 memcpy( atpb->atp_saddr, &faddr, sizeof( struct sockaddr_at )); 98 99 if ( recvlen - ATP_HDRSIZE > atpb->atp_rreqdlen ) { 100 atp_free_buf( req_buf ); 101 errno = EMSGSIZE; 102 return -1; 103 } 104 105 atpb->atp_rreqdlen = recvlen - ATP_HDRSIZE; 106 memcpy( atpb->atp_rreqdata, 107 req_buf->atpbuf_info.atpbuf_data + ATP_HDRSIZE, 108 recvlen - ATP_HDRSIZE ); 109 atpb->atp_bitmap = req_hdr.atphd_bitmap; 110 atp_free_buf( req_buf ); 111 return( 0 ); 112} 113