2 * $Id: queries.c,v 1.18 2005-04-28 20:49:49 bfernhomberg Exp $
4 * Copyright (c) 1990,1994 Regents of The University of Michigan.
5 * All Rights Reserved. See COPYRIGHT.
10 #endif /* HAVE_CONFIG_H */
15 #include <atalk/logger.h>
16 #include <sys/param.h>
18 #include <sys/types.h>
19 #include <netatalk/at.h>
20 #include <atalk/atp.h>
24 #include <kerberos/krb.h>
37 int cq_default( struct papfile *, struct papfile * );
38 int cq_k4login( struct papfile *, struct papfile * );
39 int cq_uameth( struct papfile *, struct papfile * );
41 int gq_balance( struct papfile * );
42 int gq_pagecost( struct papfile * );
43 int gq_true( struct papfile * );
44 int gq_rbispoolerid( struct papfile * );
45 int gq_rbiuamlist( struct papfile * );
47 int cq_query( struct papfile *, struct papfile * );
48 void cq_font_answer( char *, char *, struct papfile * );
49 int cq_font( struct papfile *, struct papfile * );
50 int cq_feature( struct papfile *, struct papfile * );
51 int cq_printer( struct papfile *, struct papfile * );
52 int cq_rmjob( struct papfile *, struct papfile * );
54 int cq_listq( struct papfile *, struct papfile * );
55 int cq_rbilogin( struct papfile *, struct papfile * );
56 #endif /* HAVE_CUPS */
60 int cq_default( in, out )
61 struct papfile *in, *out;
63 char *start, *stop, *p;
64 int linelength, crlflength;
65 struct papd_comment *comment = compeek();
68 switch ( markline( in, &start, &linelength, &crlflength )) {
76 stop = start+linelength;
78 if ( comgetflags() == 0 ) { /* started */
79 if ( comment->c_end ) {
83 CONSUME( in, linelength + crlflength );
88 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
89 for ( p = start; p < stop; p++ ) {
99 append( out, p, stop - p + crlflength );
101 CONSUME( in, linelength + crlflength );
106 CONSUME( in, linelength + crlflength );
111 char *LoginOK = "LoginOK\n";
112 char *LoginFailed = "LoginFailed\n";
114 #define h2b(x) (isdigit((x))?(x)-'0':(isupper((x))?(x)-'A':(x)-'a')+10)
116 int cq_k4login( in, out )
117 struct papfile *in, *out;
120 int linelength, crlflength;
122 struct papd_comment *comment = compeek();
127 switch ( markline( in, &start, &linelength, &crlflength )) {
135 p = start + strlen( comment->c_begin );
136 while ( *p == ' ' ) {
140 bzero( &tkt, sizeof( tkt ));
141 stop = start+linelength;
142 for ( i = 0, t = tkt.dat; p < stop; p += 2, t++, i++ ) {
143 *t = ( h2b( (unsigned char)*p ) << 4 ) +
144 h2b( (unsigned char)*( p + 1 ));
148 if (( rc = krb_rd_req( &tkt, "LaserWriter", printer->p_name,
149 0, &ad, "" )) != RD_AP_OK ) {
150 LOG(log_error, logtype_papd, "cq_k4login: %s", krb_err_txt[ rc ] );
151 append( out, LoginFailed, strlen( LoginFailed ));
153 CONSUME( in, linelength + crlflength );
156 LOG(log_info, logtype_papd, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
158 lp_person( ad.pname );
159 lp_host( ad.prealm );
161 append( out, LoginOK, strlen( LoginOK ));
163 CONSUME( in, linelength + crlflength);
167 char *uameth = "UMICHKerberosIV\n*\n";
169 int cq_uameth( in, out )
170 struct papfile *in, *out;
173 int linelength, crlflength;
174 struct papd_comment *c, *comment = compeek();
177 switch ( markline( in, &start, &linelength, &crlflength )) {
185 if ( comgetflags() == 0 ) { /* start */
186 if (( printer->p_flags & P_KRB ) == 0 ) { /* no kerberos */
187 if ( comswitch( queries, cq_default ) < 0 ) {
188 LOG(log_error, logtype_papd, "cq_uameth: can't find default!" );
195 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) { /* end */
196 append( out, uameth, strlen( uameth ));
202 CONSUME( in, linelength + crlflength );
210 if ( printer->p_flags & P_SPOOLED ) {
211 append( out, "true\n", 5 );
218 int gq_pagecost( out )
223 /* check for spooler? XXX */
224 if ( printer->p_pagecost_msg != NULL ) {
225 append( out, printer->p_pagecost_msg,
226 strlen( printer->p_pagecost_msg ));
227 } else if ( printer->p_flags & P_ACCOUNT ) {
230 #endif /* ABS_PRINT */
231 sprintf( cost, "%d", printer->p_pagecost );
232 append( out, cost, strlen( cost ));
236 append( out, "\n", 1 );
241 int gq_balance( out )
246 if ( lp_pagecost() != 0 ) {
249 sprintf( balance, "$%1.2f\n", printer->p_balance );
250 append( out, balance, strlen( balance ));
253 #endif /* ABS_PRINT */
257 * Handler for RBISpoolerID
260 static const char *spoolerid = "(PAPD Spooler) 1.0 (" VERSION ")\n";
262 int gq_rbispoolerid( out )
265 append( out, spoolerid, strlen( spoolerid ));
272 * Handler for RBIUAMListQuery
275 static const char *nouams = "*\n";
277 int gq_rbiuamlist( out )
280 char uamnames[128] = "\0";
282 if (printer->p_flags & P_AUTH_PSSP) {
283 if (getuamnames(UAM_SERVER_PRINTAUTH, uamnames) < 0) {
284 append(out, nouams, strlen(nouams));
287 append(out, uamnames, strlen(uamnames));
291 append(out, nouams, strlen(nouams));
301 { "UMICHCostPerPage", gq_pagecost },
303 { "UMICHUserBalance", gq_balance },
305 { "RBISpoolerID", gq_rbispoolerid },
306 { "RBIUAMListQuery", gq_rbiuamlist },
307 { "ADOIsBinaryOK?", gq_true },
308 { "UMICHListQueue", gq_true },
309 { "UMICHDeleteJob", gq_true },
313 int cq_query( in, out )
314 struct papfile *in, *out;
316 char *start, *stop, *p, *q;
317 int linelength, crlflength;
318 struct papd_comment *comment = compeek();
323 switch ( markline( in, &start, &linelength, &crlflength )) {
331 stop = start+linelength;
333 if ( comgetflags() == 0 ) { /* started */
336 for ( p = start; p < stop; p++ ) {
342 for ( p++; p < stop; p++ ) {
343 if ( *p != ' ' && *p != '\t' ) {
348 for ( q = p; q < stop; q++ ) {
349 if ( *q == ' ' || *q == '\t' || *q == '\r' || *q == '\n' ) {
354 for ( gq = genqueries; gq->gq_name; gq++ ) {
355 if (( strlen( gq->gq_name ) == q - p ) &&
356 ( strncmp( gq->gq_name, p, q - p ) == 0 )) {
360 if ( gq->gq_name == NULL || gq->gq_handler == NULL ||
361 (gq->gq_handler)( out ) < 0 ) {
362 if ( comswitch( queries, cq_default ) < 0 ) {
363 LOG(log_error, logtype_papd, "cq_feature: can't find default!" );
369 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
371 CONSUME( in, linelength + crlflength );
376 CONSUME( in, linelength + crlflength );
380 void cq_font_answer( start, stop, out )
384 char *p, *q, buf[ 256 ];
385 struct ppd_font *pfo;
389 while (( *p == ' ' || *p == '\t' ) && p < stop ) {
394 while ( *p != ' ' && *p != '\t' &&
395 *p != '\n' && *p != '\r' && p < stop ) {
402 append( out, "/", 1 );
403 append( out, buf, strlen( buf ));
404 append( out, ":", 1 );
406 if (( pfo = ppd_font( buf )) == NULL ) {
407 append( out, "No\n", 3 );
409 append( out, "Yes\n", 4 );
417 int cq_font( in, out )
418 struct papfile *in, *out;
420 char *start, *stop, *p;
421 int linelength, crlflength;
422 struct papd_comment *comment = compeek();
425 switch ( markline( in, &start, &linelength, &crlflength )) {
433 stop = start + linelength;
435 if ( comgetflags() == 0 ) {
438 for ( p = start; p < stop; p++ ) {
445 cq_font_answer( p, stop, out );
447 if ( comgetflags() == 1 &&
448 comcmp( start, stop, comcont, 0 ) == 0 ) {
451 for ( p = start; p < stop; p++ ) {
458 cq_font_answer( p, stop, out );
461 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
462 append( out, "*\n", 2 );
464 CONSUME( in, linelength + crlflength );
470 CONSUME( in, linelength + crlflength );
474 int cq_feature( in, out )
475 struct papfile *in, *out;
477 char *start, *stop, *p;
478 int linelength, crlflength;
479 struct papd_comment *comment = compeek();
480 struct ppd_feature *pfe;
483 switch ( markline( in, &start, &linelength, &crlflength )) {
491 stop = start + linelength;
493 if ( comgetflags() == 0 ) {
496 /* parse for feature */
497 for ( p = start; p < stop; p++ ) {
503 while ( *p == ' ' ) {
507 if (( pfe = ppd_feature( p, stop - p )) == NULL ) {
508 if ( comswitch( queries, cq_default ) < 0 ) {
509 LOG(log_error, logtype_papd, "cq_feature: can't find default!" );
515 append( out, pfe->pd_value, strlen( pfe->pd_value ));
516 append( out, "\r", 1 );
518 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
520 CONSUME( in, linelength + crlflength );
525 CONSUME( in, linelength + crlflength );
529 static const char *psver = "*PSVersion\n";
530 static const char *prod = "*Product\n";
532 int cq_printer( in, out )
533 struct papfile *in, *out;
536 int linelength, crlflength;
537 struct papd_comment *comment = compeek();
538 struct ppd_feature *pdpsver, *pdprod;
541 switch ( markline( in, &start, &linelength, &crlflength )) {
549 if ( comgetflags() == 0 ) {
552 if (( pdpsver = ppd_feature( psver, strlen( psver ))) == NULL ) {
553 if ( comswitch( queries, cq_default ) < 0 ) {
554 LOG(log_error, logtype_papd, "cq_printer: can't find default!" );
560 for ( p = pdpsver->pd_value; *p != '\0'; p++ ) {
566 LOG(log_error, logtype_papd, "cq_printer: can't parse PSVersion!" );
567 if ( comswitch( queries, cq_default ) < 0 ) {
568 LOG(log_error, logtype_papd, "cq_printer: can't find default!" );
574 if (( pdprod = ppd_feature( prod, strlen( prod ))) == NULL ) {
575 if ( comswitch( queries, cq_default ) < 0 ) {
576 LOG(log_error, logtype_papd, "cq_printer: can't find default!" );
583 append( out, p + 1, strlen( p + 1 ));
584 append( out, "\r", 1 );
587 append( out, pdpsver->pd_value, p - pdpsver->pd_value );
588 append( out, "\r", 1 );
591 append( out, pdprod->pd_value, strlen( pdprod->pd_value ));
592 append( out, "\r", 1 );
594 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
596 CONSUME( in, linelength + crlflength );
601 CONSUME( in, linelength + crlflength );
607 static const char *rmjobfailed = "Failed\n";
608 static const char *rmjobok = "Ok\n";
610 int cq_rmjob( in, out )
611 struct papfile *in, *out;
613 char *start, *stop, *p;
614 int linelength, crlflength;
617 switch ( markline( in, &start, &linelength, &crlflength )) {
625 stop = start + linelength;
627 for ( p = start; p < stop; p++ ) {
628 if ( *p == ' ' || *p == '\t' ) {
632 for ( ; p < stop; p++ ) {
633 if ( *p != ' ' && *p != '\t' ) {
639 if ( p < stop && ( job = atoi( p )) > 0 ) {
641 append( out, rmjobok, strlen( rmjobok ));
643 append( out, rmjobfailed, strlen( rmjobfailed ));
647 CONSUME( in, linelength + crlflength );
651 int cq_listq( in, out )
652 struct papfile *in, *out;
655 int linelength, crlflength;
657 switch ( markline( in, &start, &linelength, &crlflength )) {
665 if ( lp_queue( out )) {
666 LOG(log_error, logtype_papd, "cq_listq: lp_queue failed" );
670 CONSUME( in, linelength + crlflength );
673 #endif /* HAVE_CUPS */
677 * Handler for RBILogin
680 static struct uam_obj *papd_uam = NULL;
681 static const char *rbiloginok = "0\r";
682 static const char *rbiloginbad = "-1\r";
683 static const char *rbiloginerrstr = "%%[Error: SecurityError; \
684 SecurityViolation: Unknown user, incorrect password or log on is \
685 disabled ]%%\r%%[Flushing: rest of job (to end-of-file) will be \
688 int cq_rbilogin( in, out )
689 struct papfile *in, *out;
691 char *start, *stop, *p, *begin;
692 int linelength, crlflength;
693 char username[UAM_USERNAMELEN + 1] = "\0";
694 struct papd_comment *comment = compeek();
695 char uamtype[20] = "\0";
698 switch ( markline( in, &start, &linelength, &crlflength )) {
706 stop = start + linelength;
708 if ( comgetflags() == 0 ) { /* first line */
709 begin = start + strlen(comment->c_begin);
716 strncat(uamtype, begin, p - begin);
718 if ((papd_uam = auth_uamfind(UAM_SERVER_PRINTAUTH,
719 uamtype, strlen(uamtype))) == NULL) {
720 LOG(log_info, logtype_papd, "Could not find uam: %s", uamtype);
721 append(out, rbiloginbad, strlen(rbiloginbad));
722 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
724 if ( (papd_uam->u.uam_printer(p,stop,username,out)) == 0 ) {
725 lp_person( username );
726 append(out, rbiloginok, strlen( rbiloginok ));
727 LOG(log_info, logtype_papd, "RBILogin: Logged in '%s'", username);
729 append(out, rbiloginbad, strlen( rbiloginbad));
730 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
735 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
741 CONSUME( in, linelength + crlflength );
747 * All queries start with %%?Begin and end with %%?End. Note that the
748 * "Begin"/"End" general queries have to be last.
750 struct papd_comment queries[] = {
752 { "%%Login: UMICHKerberosIV", NULL, cq_k4login, 0 },
753 { "%%?BeginUAMethodsQuery", "%%?EndUAMethodsQuery:", cq_uameth,C_FULL },
756 { "%UMICHListQueue", NULL, cq_listq, C_FULL },
757 { "%UMICHDeleteJob", NULL, cq_rmjob, 0 },
758 #endif /* HAVE_CUPS */
759 { "%%?BeginQuery: RBILogin ", "%%?EndQuery", cq_rbilogin, 0 },
760 { "%%?BeginQuery", "%%?EndQuery", cq_query, 0 },
761 { "%%?BeginFeatureQuery", "%%?EndFeatureQuery", cq_feature, 0 },
762 { "%%?BeginFontQuery", "%%?EndFontQuery", cq_font, 0 },
763 { "%%?BeginPrinterQuery", "%%?EndPrinterQuery", cq_printer,C_FULL },
764 { "%%?Begin", "%%?End", cq_default, 0 },
765 { NULL, NULL, NULL, 0 },