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 */ 48static void getstatus(ATP atp, struct sockaddr_at *sat); 49 50static 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 64static char * 65paprc(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 86static char *printer = NULL; 87 88static char cbuf[ 8 ]; 89static struct nbpnve nn; 90 91int 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 167static 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} 205