]> arthur.barton.de Git - netatalk.git/blob - bin/pap/papstatus.c
Previous fix 9e4e07c1811edbaf3376ad6e238a1353b405002b resulted in the inability to...
[netatalk.git] / bin / pap / papstatus.c
1 /*
2  * $Id: papstatus.c,v 1.7 2009-10-14 01:38:28 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 <sys/types.h>
31 #include <sys/time.h>
32 #include <sys/uio.h>
33 #include <sys/file.h>
34 #include <netatalk/endian.h>
35 #include <netatalk/at.h>
36 #include <errno.h>
37 #include <atalk/atp.h>
38 #include <atalk/pap.h>
39 #include <atalk/nbp.h>
40 #include <atalk/util.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #define _PATH_PAPRC     ".paprc"
46
47 /* Forward Declaration */
48 static void getstatus(ATP atp, struct sockaddr_at *sat);
49
50 static void usage(char *path)
51 {
52     char        *p;
53
54     if (( p = strrchr( path, '/' )) == NULL ) {
55         p = path;
56     } else {
57         p++;
58     }
59     fprintf( stderr,
60         "Usage:\t%s [ -A address ] [ -p printername ]\n", p );
61     exit( 1 );
62 }
63
64 static char *
65 paprc(void)
66 {
67     static char s[ 32 + 1 + 32 + 1 + 32 ];
68     char        *name = NULL;
69     FILE        *f;
70
71     if (( f = fopen( _PATH_PAPRC, "r" )) == NULL ) {
72         return( NULL );
73     }
74     while ( fgets( s, sizeof( s ), f ) != NULL ) {
75         s[ strlen( s ) - 1 ] = '\0';    /* remove trailing newline */
76         if ( *s == '#' ) {
77             continue;
78         }
79         name = s;
80         break;
81     }
82     fclose( f );
83     return( name );
84 }
85
86 static char                     *printer = NULL;
87
88 static char                     cbuf[ 8 ];
89 static struct nbpnve            nn;
90
91 int main( int ac, char **av)
92 {
93     ATP                 atp;
94     int                 wait, c, err = 0;
95     char                *obj = NULL, *type = "LaserWriter", *zone = "*";
96     struct at_addr      addr;
97
98     extern char         *optarg;
99     extern int          optind;
100
101     memset(&addr, 0, sizeof(addr));
102     while (( c = getopt( ac, av, "p:s:A:" )) != EOF ) {
103         switch ( c ) {
104         case 'A':
105             if (!atalk_aton(optarg, &addr)) {
106               fprintf(stderr, "Bad address.\n");
107               exit(1);
108             }
109             break;
110         case 'p' :
111             printer = optarg;
112             break;
113
114         default :
115             fprintf( stderr, "Unknown option: '%c'\n", c );
116             err++;
117         }
118     }
119     if ( err ) {
120         usage( *av );
121     }
122     if ( printer == NULL && (( printer = paprc()) == NULL )) {
123         usage( *av );
124     }
125
126     /*
127      * Open connection.
128      */
129     if ( nbp_name( printer, &obj, &type, &zone ) < 0 ) {
130         fprintf( stderr, "%s: Bad name\n", printer );
131         exit( 1 );
132     }
133     if ( obj == NULL ) {
134         fprintf( stderr, "%s: Bad name\n", printer );
135         exit( 1 );
136     }
137     if ( nbp_lookup( obj, type, zone, &nn, 1, &addr ) <= 0 ) {
138         if ( errno != 0 ) {
139             perror( "nbp_lookup" );
140         } else {
141             fprintf( stderr, "%s:%s@%s: NBP Lookup failed\n", obj, type, zone );
142         }
143         exit( 1 );
144     }
145
146     if (( atp = atp_open( ATADDR_ANYPORT, &addr )) == NULL ) {
147         perror( "atp_open" );
148         exit( 1 );
149     }
150
151     if ( optind == ac ) {
152         getstatus( atp, &nn.nn_sat );
153         exit( 0 );
154     }
155     if ( optind - ac > 1 ) {
156         usage( *av );
157     }
158     wait = atoi( av[ optind ] );
159     for (;;) {
160         getstatus( atp, &nn.nn_sat );
161         sleep( wait );
162     }
163
164     return 0;
165 }
166
167 static void getstatus(ATP atp, struct sockaddr_at *sat)
168 {
169     struct iovec        iov;
170     struct atp_block    atpb;
171     char                rbuf[ ATP_MAXDATA ];
172
173     cbuf[ 0 ] = 0;
174     cbuf[ 1 ] = PAP_SENDSTATUS;
175     cbuf[ 2 ] = cbuf[ 3 ] = 0;
176
177     atpb.atp_saddr = sat;
178     atpb.atp_sreqdata = cbuf;
179     atpb.atp_sreqdlen = 4;              /* bytes in SendStatus request */
180     atpb.atp_sreqto = 2;                /* retry timer */
181     atpb.atp_sreqtries = 5;             /* retry count */
182     if ( atp_sreq( atp, &atpb, 1, ATP_XO ) < 0 ) {
183         perror( "atp_sreq" );
184         exit( 1 );
185     }
186
187     iov.iov_base = rbuf;
188     iov.iov_len = sizeof( rbuf );
189     atpb.atp_rresiov = &iov;
190     atpb.atp_rresiovcnt = 1;
191     if ( atp_rresp( atp, &atpb ) < 0 ) {
192         perror( "atp_rresp" );
193         exit( 1 );
194     }
195
196     /* sanity */
197     if ( iov.iov_len < 8 ||
198             rbuf[ 1 ] != PAP_STATUS ) {
199         fprintf( stderr, "Bad response!\n" );
200         return; /* This is weird, since TIDs must match... */
201     }
202
203     printf( "%.*s\n", (int)iov.iov_len - 9, (char *) iov.iov_base + 9 );
204 }