]> arthur.barton.de Git - netatalk.git/blob - libatalk/pap/pap_open.c
autoconf POSIX.1 sys/wait.h check
[netatalk.git] / libatalk / pap / pap_open.c
1 /*
2  * $Id: pap_open.c,v 1.3 2001-06-29 14:14:47 rufustfirefly Exp $
3  *
4  * moved over from bin/pap/pap.c
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif /* HAVE_CONFIG_H */
10
11 static struct {
12   PAP pap;
13   int tickle;
14   pid_t pid;
15 } client;
16
17 static void tickle_handler()
18 {
19   if (client.tickle++ < 4)
20     pap_tickle(client.pap, client.pap->pap_connid, &client.pap->pap_sat);
21   else {
22     kill(client.pid, SIGTERM);
23     syslog(LOG_ERR, "pap_alarm: connection timed out.");
24     exit(1);
25   }
26 }
27
28
29 PAP pap_open(PAP pap, struct nbpnve *nn, u_int8_t quantum, int flags)
30 {
31     struct atp_block atpb;
32     struct timeval stv, tv;
33     u_int16_t waiting;
34     pid_t pid;
35
36     if (!pap->inited) {
37       pap->pap_connid = getpid() & 0xff;
38       pap->cmdbuf[ 0 ] = pap->pap_connid;
39       pap->cmdbuf[ 1 ] = PAP_OPEN;
40       pap->cmdbuf[ 2 ] = pap->cmdbuf[ 3 ] = 0;
41       pap->cmdbuf[ 4 ] = atp_sockaddr( pap->pap_atp )->sat_port;
42       pap->cmdbuf[ 5 ] = quantum;       /* flow quantum */
43       
44       if ( gettimeofday( &stv, NULL ) < 0 ) {
45         perror( "gettimeofday" );
46         return NULL;
47       }
48       
49       for (;;) {
50         if ( flags & PAPFLAG_CUTS ) {
51           waiting = 0xffff;
52         } else {
53           if ( gettimeofday( &tv, NULL ) < 0 ) {
54             perror( "gettimeofday" );
55             return NULL;
56           }
57           waiting = htons( tv.tv_sec - stv.tv_sec );
58         }
59         
60         memcpy(pap->cmdbuf + 6, &waiting, sizeof( waiting ));
61         atpb.atp_saddr = &nn->nn_sat;
62         atpb.atp_sreqdata = pap->cmdbuf;
63         atpb.atp_sreqdlen = 8;          /* bytes in OpenConn request */
64         atpb.atp_sreqto = 2;            /* retry timer */
65         atpb.atp_sreqtries = 5;         /* retry count */
66         if ( atp_sreq( atp, &atpb, 1, ATP_XO ) < 0 ) {
67           perror( "atp_sreq" );
68           return NULL;
69         }
70         
71         iov.iov_base = pap->data;
72         iov.iov_len = sizeof( rbuf );
73         atpb.atp_rresiov = &iov;
74         atpb.atp_rresiovcnt = 1;
75         if ( atp_rresp( atp, &atpb ) < 0 ) {
76           perror( "atp_rresp" );
77           if ( connattempts-- <= 0 ) {
78             fprintf( stderr, "Can't connect!\n" );
79             return NULL;
80           }
81           continue;
82         }
83         
84         /* sanity */
85         if ( iov.iov_len < 8 || pap->data[ 0 ] != pap->pap_connid ||
86              pap->data[ 1 ] != PAP_OPENREPLY ) {
87           fprintf( stderr, "Bad response!\n" );
88           continue;     /* This is weird, since TIDs must match... */
89         }
90         
91         if ( isatty( 1 )) {
92           printf( "%.*s\n", iov.iov_len - 9, iov.iov_base + 9 );
93         }
94         updatestatus( iov.iov_base + 9, iov.iov_len - 9 );
95         
96         bcopy( &rbuf[ 6 ], &result, sizeof( result ));
97         if ( result != 0 ) {
98           sleep( 2 );
99         } else {
100           memcpy(&pap->pap_sat, &nn.nn_sat, sizeof( struct sockaddr_at ));
101           pap->pap_sat.sat_port = rbuf[ 4 ];
102           pap->pap_quantum = rbuf[ 5 ];
103           break;
104         }
105       }
106       
107       if ( isatty( 1 )) {
108         printf( "Connected to %.*s:%.*s@%.*s.\n",
109                 nn.nn_objlen, nn.nn_obj,
110                 nn.nn_typelen, nn.nn_type,
111                 nn.nn_zonelen, nn.nn_zone );
112       }
113
114     /* open a second atp connection */
115     if (( atp = atp_open( 0 )) == NULL ) {
116         perror( "atp_open" );
117         return NULL;
118     }
119
120     client.pap = pap;
121     client.pid = pid;
122     pap->inited = 1;
123     }
124
125     /* wait around for tickles */
126     
127 }