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