]> arthur.barton.de Git - netatalk.git/blob - bin/getzones/getzones.c
Remove bdb env on exit
[netatalk.git] / bin / getzones / getzones.c
1 /*
2  * $Id: getzones.c,v 1.9 2009-10-14 01:38:28 didg Exp $
3  */
4
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif /* HAVE_CONFIG_H */
8
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <sys/param.h>
12 #include <sys/uio.h>
13 #include <sys/time.h>
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif /* HAVE_UNISTD_H */
17 #ifdef HAVE_NETDB_H
18 #include <netdb.h>
19 #endif /* HAVE_NETDB_H */
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <netatalk/endian.h>
24 #include <netatalk/at.h>
25 #include <atalk/atp.h>
26 #include <atalk/util.h>
27 #include <atalk/unicode.h>
28 #include <atalk/zip.h>
29
30 static void print_zones(short n, char *buf);
31
32 static void usage( char *s)
33 {
34     fprintf( stderr, "usage:\t%s [-m | -l] [address]\n", s );
35     exit( 1 );
36 }
37
38 int main( int argc, char *argv[])
39 {
40     struct atp_handle   *ah;
41     struct atp_block    atpb;
42     struct sockaddr_at  saddr;
43     struct servent      *se;
44     char                reqdata[4], buf[ ATP_MAXDATA ];
45     struct iovec        iov;
46     short               temp, index = 0;
47     int                 c, myzoneflg = 0, localzonesflg = 0, errflg = 0;
48     extern int          optind;
49
50     reqdata[ 0 ] = ZIPOP_GETZONELIST;
51
52     while (( c = getopt( argc, argv, "ml" )) != EOF ) {
53         switch (c) {
54         case 'm':
55             if ( localzonesflg ) {
56                 ++errflg;
57             }
58             ++myzoneflg;
59             reqdata[ 0 ] = ZIPOP_GETMYZONE;
60             break;
61         case 'l':
62             if ( myzoneflg ) {
63                 ++errflg;
64             }
65             ++localzonesflg;
66             reqdata[ 0 ] = ZIPOP_GETLOCALZONES;
67             break;
68         default:
69             ++errflg;
70         }
71     }
72
73     if ( errflg || argc - optind > 1 ) {
74         usage( argv[ 0 ] );
75     }
76
77     memset( &saddr, 0, sizeof( struct sockaddr_at ));
78 #ifdef BSD4_4
79     saddr.sat_len = sizeof( struct sockaddr_at );
80 #endif /* BSD4_4 */
81     saddr.sat_family = AF_APPLETALK;
82     if (( se = getservbyname( "zip", "ddp" )) == NULL )
83         saddr.sat_port = 6;
84     else 
85         saddr.sat_port = ntohs( se->s_port );
86
87     if ( argc == optind ) {
88         saddr.sat_addr.s_net = ATADDR_ANYNET;
89         saddr.sat_addr.s_node = ATADDR_ANYNODE;
90     } else {
91         if ( !atalk_aton( argv[ optind ], &saddr.sat_addr )) {
92             fprintf( stderr, "Bad address.\n" );
93             exit( 1 );
94         }
95     }
96
97     if (( ah = atp_open( ATADDR_ANYPORT, &saddr.sat_addr )) == NULL ) {
98         perror( "atp_open" );
99         exit( 1 );
100     }
101
102     index = ( myzoneflg ? 0 : 1 );
103     reqdata[1] = 0;
104
105     do {
106         atpb.atp_saddr = &saddr;
107         temp = htons( index );
108         memcpy( reqdata + 2, &temp, 2 );
109         atpb.atp_sreqdata = reqdata;
110         atpb.atp_sreqdlen = 4;
111         atpb.atp_sreqto = 2;
112         atpb.atp_sreqtries = 5;
113
114         /* send getzone request zones (or get my zone)
115         */
116         if ( atp_sreq( ah, &atpb, 1, 0 ) < 0 ) {
117             perror( "atp_sreq" );
118             exit( 1 );
119         }
120
121         iov.iov_base = buf;
122         iov.iov_len = ATP_MAXDATA;
123         atpb.atp_rresiov = &iov;
124         atpb.atp_rresiovcnt = 1;
125
126         if ( atp_rresp( ah, &atpb ) < 0 ) {
127             perror( "atp_rresp" );
128             exit( 1 );
129         }
130
131         memcpy( &temp, (char *) iov.iov_base + 2, 2 );
132         temp = ntohs( temp );
133         print_zones( temp, (char *) iov.iov_base+4 );
134         index += temp;
135     } while ( !myzoneflg && !((char *)iov.iov_base)[ 0 ] );
136
137     if ( atp_close( ah ) != 0 ) {
138         perror( "atp_close" );
139         exit( 1 );
140     }
141
142     exit( 0 );
143 }
144
145
146 /*
147  * n:   number of zones in this packet
148  * buf: zone length/name pairs
149  */
150 static void print_zones( short n, char *buf )
151 {
152     size_t zone_len;
153     char *zone;
154
155     for ( ; n--; buf += (*buf) + 1 ) {
156
157         if ((size_t)(-1) == (zone_len = convert_string_allocate( CH_MAC,
158                        CH_UNIX, buf+1, *buf, &zone)) ) {
159             zone_len = *buf;
160             if (( zone = strdup(buf+1)) == NULL ) {
161                 perror( "strdup" );
162                 exit( 1 );
163             }
164         }
165
166         printf( "%.*s\n", (int)zone_len, zone );
167
168         free(zone);
169     }
170 }