2 * Copyright (c) 1990,1994 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
13 #include <sys/syslog.h>
14 #include <sys/param.h>
16 #include <sys/types.h>
17 #include <netatalk/at.h>
18 #include <atalk/atp.h>
22 #include <kerberos/krb.h>
35 int cq_default( struct papfile *, struct papfile * );
36 int cq_k4login( struct papfile *, struct papfile * );
37 int cq_uameth( struct papfile *, struct papfile * );
39 int gq_balance( struct papfile * );
40 int gq_pagecost( struct papfile * );
41 int gq_true( struct papfile * );
42 int gq_rbispoolerid( struct papfile * );
43 int gq_rbiuamlist( struct papfile * );
45 int cq_query( struct papfile *, struct papfile * );
46 void cq_font_answer( char *, char *, struct papfile * );
47 int cq_font( struct papfile *, struct papfile * );
48 int cq_feature( struct papfile *, struct papfile * );
49 int cq_printer( struct papfile *, struct papfile * );
50 int cq_rmjob( struct papfile *, struct papfile * );
51 int cq_listq( struct papfile *, struct papfile * );
52 int cq_rbilogin( struct papfile *, struct papfile * );
56 int cq_default( in, out )
57 struct papfile *in, *out;
59 char *start, *stop, *p;
60 int linelength, crlflength;
61 struct papd_comment *comment = compeek();
64 switch ( markline( in, &start, &linelength, &crlflength )) {
72 stop = start+linelength;
74 if ( comgetflags() == 0 ) { /* started */
75 if ( comment->c_end ) {
79 CONSUME( in, linelength + crlflength );
84 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
85 for ( p = start; p < stop; p++ ) {
95 append( out, p, stop - p + crlflength );
97 CONSUME( in, linelength + crlflength );
102 CONSUME( in, linelength + crlflength );
107 char *LoginOK = "LoginOK\n";
108 char *LoginFailed = "LoginFailed\n";
110 #define h2b(x) (isdigit((x))?(x)-'0':(isupper((x))?(x)-'A':(x)-'a')+10)
112 int cq_k4login( in, out )
113 struct papfile *in, *out;
116 int linelength, crlflength;
118 struct papd_comment *comment = compeek();
123 switch ( markline( in, &start, &linelength, &crlflength )) {
131 p = start + strlen( comment->c_begin );
132 while ( *p == ' ' ) {
136 bzero( &tkt, sizeof( tkt ));
137 stop = start+linelength;
138 for ( i = 0, t = tkt.dat; p < stop; p += 2, t++, i++ ) {
139 *t = ( h2b( (unsigned char)*p ) << 4 ) +
140 h2b( (unsigned char)*( p + 1 ));
144 if (( rc = krb_rd_req( &tkt, "LaserWriter", printer->p_name,
145 0, &ad, "" )) != RD_AP_OK ) {
146 syslog( LOG_ERR, "cq_k4login: %s", krb_err_txt[ rc ] );
147 append( out, LoginFailed, strlen( LoginFailed ));
149 CONSUME( in, linelength + crlflength );
152 syslog( LOG_INFO, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
154 lp_person( ad.pname );
155 lp_host( ad.prealm );
157 append( out, LoginOK, strlen( LoginOK ));
159 CONSUME( in, linelength + crlflength);
163 char *uameth = "UMICHKerberosIV\n*\n";
165 int cq_uameth( in, out )
166 struct papfile *in, *out;
169 int linelength, crlflength;
170 struct papd_comment *c, *comment = compeek();
173 switch ( markline( in, &start, &linelength, &crlflength )) {
181 if ( comgetflags() == 0 ) { /* start */
182 if (( printer->p_flags & P_KRB ) == 0 ) { /* no kerberos */
183 if ( comswitch( queries, cq_default ) < 0 ) {
184 syslog( LOG_ERR, "cq_uameth: can't find default!" );
191 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) { /* end */
192 append( out, uameth, strlen( uameth ));
198 CONSUME( in, linelength + crlflength );
206 if ( printer->p_flags & P_SPOOLED ) {
207 append( out, "true\n", 5 );
214 int gq_pagecost( out )
219 /* check for spooler? XXX */
220 if ( printer->p_pagecost_msg != NULL ) {
221 append( out, printer->p_pagecost_msg,
222 strlen( printer->p_pagecost_msg ));
223 } else if ( printer->p_flags & P_ACCOUNT ) {
227 sprintf( cost, "%d", printer->p_pagecost );
228 append( out, cost, strlen( cost ));
232 append( out, "\n", 1 );
237 int gq_balance( out )
242 if ( lp_pagecost() != 0 ) {
245 sprintf( balance, "$%1.2f\n", printer->p_balance );
246 append( out, balance, strlen( balance ));
253 * Handler for RBISpoolerID
256 static const char *spoolerid = "(PAPD Spooler) 2.1 (2.1.4 pre-release)\n";
258 int gq_rbispoolerid( out )
261 append( out, spoolerid, strlen( spoolerid ));
268 * Handler for RBIUAMListQuery
271 static const char *nouams = "*\n";
273 int gq_rbiuamlist( out )
276 char uamnames[128] = "\0";
278 if (printer->p_flags & P_AUTH_PSSP) {
279 if (getuamnames(UAM_SERVER_PRINTAUTH, uamnames) < 0) {
280 append(out, nouams, strlen(nouams));
283 append(out, uamnames, strlen(uamnames));
287 append(out, nouams, strlen(nouams));
297 { "UMICHCostPerPage", gq_pagecost },
299 { "UMICHUserBalance", gq_balance },
301 { "RBISpoolerID", gq_rbispoolerid },
302 { "RBIUAMListQuery", gq_rbiuamlist },
303 { "UMICHListQueue", gq_true },
304 { "UMICHDeleteJob", gq_true },
308 int cq_query( in, out )
309 struct papfile *in, *out;
311 char *start, *stop, *p, *q;
312 int linelength, crlflength;
313 struct papd_comment *comment = compeek();
318 switch ( markline( in, &start, &linelength, &crlflength )) {
326 stop = start+linelength;
328 if ( comgetflags() == 0 ) { /* started */
331 for ( p = start; p < stop; p++ ) {
337 for ( p++; p < stop; p++ ) {
338 if ( *p != ' ' && *p != '\t' ) {
343 for ( q = p; q < stop; q++ ) {
344 if ( *q == ' ' || *q == '\t' || *q == '\r' || *q == '\n' ) {
349 for ( gq = genqueries; gq->gq_name; gq++ ) {
350 if (( strlen( gq->gq_name ) == q - p ) &&
351 ( strncmp( gq->gq_name, p, q - p ) == 0 )) {
355 if ( gq->gq_name == NULL || gq->gq_handler == NULL ||
356 (gq->gq_handler)( out ) < 0 ) {
357 if ( comswitch( queries, cq_default ) < 0 ) {
358 syslog( LOG_ERR, "cq_feature: can't find default!" );
364 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
366 CONSUME( in, linelength + crlflength );
371 CONSUME( in, linelength + crlflength );
375 void cq_font_answer( start, stop, out )
379 char *p, *q, buf[ 256 ];
380 struct ppd_font *pfo;
384 while (( *p == ' ' || *p == '\t' ) && p < stop ) {
389 while ( *p != ' ' && *p != '\t' &&
390 *p != '\n' && *p != '\r' && p < stop ) {
397 append( out, "/", 1 );
398 append( out, buf, strlen( buf ));
399 append( out, ":", 1 );
401 if (( pfo = ppd_font( buf )) == NULL ) {
402 append( out, "No\n", 3 );
404 append( out, "Yes\n", 4 );
412 int cq_font( in, out )
413 struct papfile *in, *out;
415 char *start, *stop, *p;
416 int linelength, crlflength;
417 struct papd_comment *comment = compeek();
420 switch ( markline( in, &start, &linelength, &crlflength )) {
428 stop = start + linelength;
430 if ( comgetflags() == 0 ) {
433 for ( p = start; p < stop; p++ ) {
440 cq_font_answer( p, stop, out );
442 if ( comgetflags() == 1 &&
443 comcmp( start, stop, comcont, 0 ) == 0 ) {
446 for ( p = start; p < stop; p++ ) {
453 cq_font_answer( p, stop, out );
456 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
457 append( out, "*\n", 2 );
459 CONSUME( in, linelength + crlflength );
465 CONSUME( in, linelength + crlflength );
469 int cq_feature( in, out )
470 struct papfile *in, *out;
472 char *start, *stop, *p;
473 int linelength, crlflength;
474 struct papd_comment *comment = compeek();
475 struct ppd_feature *pfe;
478 switch ( markline( in, &start, &linelength, &crlflength )) {
486 stop = start + linelength;
488 if ( comgetflags() == 0 ) {
491 /* parse for feature */
492 for ( p = start; p < stop; p++ ) {
498 while ( *p == ' ' ) {
502 if (( pfe = ppd_feature( p, stop - p )) == NULL ) {
503 if ( comswitch( queries, cq_default ) < 0 ) {
504 syslog( LOG_ERR, "cq_feature: can't find default!" );
510 append( out, pfe->pd_value, strlen( pfe->pd_value ));
511 append( out, "\r", 1 );
513 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
515 CONSUME( in, linelength + crlflength );
520 CONSUME( in, linelength + crlflength );
524 static const char *psver = "*PSVersion\n";
525 static const char *prod = "*Product\n";
527 int cq_printer( in, out )
528 struct papfile *in, *out;
531 int linelength, crlflength;
532 struct papd_comment *comment = compeek();
533 struct ppd_feature *pdpsver, *pdprod;
536 switch ( markline( in, &start, &linelength, &crlflength )) {
544 if ( comgetflags() == 0 ) {
547 if (( pdpsver = ppd_feature( psver, strlen( psver ))) == NULL ) {
548 if ( comswitch( queries, cq_default ) < 0 ) {
549 syslog( LOG_ERR, "cq_printer: can't find default!" );
555 for ( p = pdpsver->pd_value; *p != '\0'; p++ ) {
561 syslog( LOG_ERR, "cq_printer: can't parse PSVersion!" );
562 if ( comswitch( queries, cq_default ) < 0 ) {
563 syslog( LOG_ERR, "cq_printer: can't find default!" );
569 if (( pdprod = ppd_feature( prod, strlen( prod ))) == NULL ) {
570 if ( comswitch( queries, cq_default ) < 0 ) {
571 syslog( LOG_ERR, "cq_printer: can't find default!" );
578 append( out, p + 1, strlen( p + 1 ));
579 append( out, "\r", 1 );
582 append( out, pdpsver->pd_value, p - pdpsver->pd_value );
583 append( out, "\r", 1 );
586 append( out, pdprod->pd_value, strlen( pdprod->pd_value ));
587 append( out, "\r", 1 );
589 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
591 CONSUME( in, linelength + crlflength );
596 CONSUME( in, linelength + crlflength );
600 static const char *rmjobfailed = "Failed\n";
601 static const char *rmjobok = "Ok\n";
603 int cq_rmjob( in, out )
604 struct papfile *in, *out;
606 char *start, *stop, *p;
607 int linelength, crlflength;
610 switch ( markline( in, &start, &linelength, &crlflength )) {
618 stop = start + linelength;
620 for ( p = start; p < stop; p++ ) {
621 if ( *p == ' ' || *p == '\t' ) {
625 for ( ; p < stop; p++ ) {
626 if ( *p != ' ' && *p != '\t' ) {
632 if ( p < stop && ( job = atoi( p )) > 0 ) {
634 append( out, rmjobok, strlen( rmjobok ));
636 append( out, rmjobfailed, strlen( rmjobfailed ));
640 CONSUME( in, linelength + crlflength );
644 int cq_listq( in, out )
645 struct papfile *in, *out;
648 int linelength, crlflength;
650 switch ( markline( in, &start, &linelength, &crlflength )) {
658 if ( lp_queue( out )) {
659 syslog( LOG_ERR, "cq_listq: lp_queue failed" );
663 CONSUME( in, linelength + crlflength );
669 * Handler for RBILogin
672 static struct uam_obj *papd_uam = NULL;
673 static const char *rbiloginok = "0\r";
674 static const char *rbiloginbad = "-1\r";
675 static const char *rbiloginerrstr = "%%[Error: SecurityError; \
676 SecurityViolation: Unknown user, incorrect password or log on is \
677 disabled ]%%\r%%Flushing: rest of job (to end-of-file) will be \
680 int cq_rbilogin( in, out )
681 struct papfile *in, *out;
683 char *start, *stop, *p, *begin;
684 int linelength, crlflength;
685 char username[9] = "\0";
686 struct papd_comment *comment = compeek();
687 char uamtype[20] = "\0";
690 switch ( markline( in, &start, &linelength, &crlflength )) {
698 stop = start + linelength;
700 if ( comgetflags() == 0 ) { /* first line */
701 begin = start + strlen(comment->c_begin);
708 strncat(uamtype, begin, p - begin);
710 if ((papd_uam = auth_uamfind(UAM_SERVER_PRINTAUTH,
711 uamtype, strlen(uamtype))) == NULL) {
712 syslog(LOG_INFO, "Could not find uam: %s", uamtype);
713 append(out, rbiloginbad, strlen(rbiloginbad));
714 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
716 if ( (papd_uam->u.uam_printer(p,stop,username,out)) == 0 ) {
717 lp_person( username );
719 append(out, rbiloginbad, strlen( rbiloginbad));
720 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
725 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
731 CONSUME( in, linelength + crlflength );
737 * All queries start with %%?Begin and end with %%?End. Note that the
738 * "Begin"/"End" general queries have to be last.
740 struct papd_comment queries[] = {
742 { "%%Login: UMICHKerberosIV", 0, cq_k4login, 0 },
743 { "%%?BeginUAMethodsQuery", "%%?EndUAMethodsQuery:", cq_uameth, C_FULL },
745 { "%UMICHListQueue", 0, cq_listq, C_FULL },
746 { "%UMICHDeleteJob", 0, cq_rmjob, 0 },
747 { "%%?BeginQuery: RBILogin ", "%%?EndQuery", cq_rbilogin, 0 },
748 { "%%?BeginQuery", "%%?EndQuery", cq_query, 0 },
749 { "%%?BeginFeatureQuery", "%%?EndFeatureQuery", cq_feature, 0 },
750 { "%%?BeginFontQuery", "%%?EndFontQuery", cq_font, 0 },
751 { "%%?BeginPrinterQuery", "%%?EndPrinterQuery", cq_printer, C_FULL },
752 { "%%?Begin", "%%?End", cq_default, 0 },