• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.5/libatalk/atp/
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