2 * $Id: queries.c,v 1.13 2002-02-15 16:15:21 morgana 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 * );
53 int cq_listq( struct papfile *, struct papfile * );
54 int cq_rbilogin( struct papfile *, struct papfile * );
58 int cq_default( in, out )
59 struct papfile *in, *out;
61 char *start, *stop, *p;
62 int linelength, crlflength;
63 struct papd_comment *comment = compeek();
66 switch ( markline( in, &start, &linelength, &crlflength )) {
74 stop = start+linelength;
76 if ( comgetflags() == 0 ) { /* started */
77 if ( comment->c_end ) {
81 CONSUME( in, linelength + crlflength );
86 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
87 for ( p = start; p < stop; p++ ) {
97 append( out, p, stop - p + crlflength );
99 CONSUME( in, linelength + crlflength );
104 CONSUME( in, linelength + crlflength );
109 char *LoginOK = "LoginOK\n";
110 char *LoginFailed = "LoginFailed\n";
112 #define h2b(x) (isdigit((x))?(x)-'0':(isupper((x))?(x)-'A':(x)-'a')+10)
114 int cq_k4login( in, out )
115 struct papfile *in, *out;
118 int linelength, crlflength;
120 struct papd_comment *comment = compeek();
125 switch ( markline( in, &start, &linelength, &crlflength )) {
133 p = start + strlen( comment->c_begin );
134 while ( *p == ' ' ) {
138 bzero( &tkt, sizeof( tkt ));
139 stop = start+linelength;
140 for ( i = 0, t = tkt.dat; p < stop; p += 2, t++, i++ ) {
141 *t = ( h2b( (unsigned char)*p ) << 4 ) +
142 h2b( (unsigned char)*( p + 1 ));
146 if (( rc = krb_rd_req( &tkt, "LaserWriter", printer->p_name,
147 0, &ad, "" )) != RD_AP_OK ) {
148 LOG(log_error, logtype_default, "cq_k4login: %s", krb_err_txt[ rc ] );
149 append( out, LoginFailed, strlen( LoginFailed ));
151 CONSUME( in, linelength + crlflength );
154 LOG(log_info, logtype_default, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
156 lp_person( ad.pname );
157 lp_host( ad.prealm );
159 append( out, LoginOK, strlen( LoginOK ));
161 CONSUME( in, linelength + crlflength);
165 char *uameth = "UMICHKerberosIV\n*\n";
167 int cq_uameth( in, out )
168 struct papfile *in, *out;
171 int linelength, crlflength;
172 struct papd_comment *c, *comment = compeek();
175 switch ( markline( in, &start, &linelength, &crlflength )) {
183 if ( comgetflags() == 0 ) { /* start */
184 if (( printer->p_flags & P_KRB ) == 0 ) { /* no kerberos */
185 if ( comswitch( queries, cq_default ) < 0 ) {
186 LOG(log_error, logtype_default, "cq_uameth: can't find default!" );
193 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) { /* end */
194 append( out, uameth, strlen( uameth ));
200 CONSUME( in, linelength + crlflength );
208 if ( printer->p_flags & P_SPOOLED ) {
209 append( out, "true\n", 5 );
216 int gq_pagecost( out )
221 /* check for spooler? XXX */
222 if ( printer->p_pagecost_msg != NULL ) {
223 append( out, printer->p_pagecost_msg,
224 strlen( printer->p_pagecost_msg ));
225 } else if ( printer->p_flags & P_ACCOUNT ) {
228 #endif /* ABS_PRINT */
229 sprintf( cost, "%d", printer->p_pagecost );
230 append( out, cost, strlen( cost ));
234 append( out, "\n", 1 );
239 int gq_balance( out )
244 if ( lp_pagecost() != 0 ) {
247 sprintf( balance, "$%1.2f\n", printer->p_balance );
248 append( out, balance, strlen( balance ));
251 #endif /* ABS_PRINT */
255 * Handler for RBISpoolerID
258 static const char *spoolerid = "(PAPD Spooler) VERSION\n";
260 int gq_rbispoolerid( out )
263 append( out, spoolerid, strlen( spoolerid ));
270 * Handler for RBIUAMListQuery
273 static const char *nouams = "*\n";
275 int gq_rbiuamlist( out )
278 char uamnames[128] = "\0";
280 if (printer->p_flags & P_AUTH_PSSP) {
281 if (getuamnames(UAM_SERVER_PRINTAUTH, uamnames) < 0) {
282 append(out, nouams, strlen(nouams));
285 append(out, uamnames, strlen(uamnames));
289 append(out, nouams, strlen(nouams));
299 { "UMICHCostPerPage", gq_pagecost },
301 { "UMICHUserBalance", gq_balance },
303 { "RBISpoolerID", gq_rbispoolerid },
304 { "RBIUAMListQuery", gq_rbiuamlist },
305 { "ADOIsBinaryOK?", gq_true },
306 { "UMICHListQueue", gq_true },
307 { "UMICHDeleteJob", gq_true },
311 int cq_query( in, out )
312 struct papfile *in, *out;
314 char *start, *stop, *p, *q;
315 int linelength, crlflength;
316 struct papd_comment *comment = compeek();
321 switch ( markline( in, &start, &linelength, &crlflength )) {
329 stop = start+linelength;
331 if ( comgetflags() == 0 ) { /* started */
334 for ( p = start; p < stop; p++ ) {
340 for ( p++; p < stop; p++ ) {
341 if ( *p != ' ' && *p != '\t' ) {
346 for ( q = p; q < stop; q++ ) {
347 if ( *q == ' ' || *q == '\t' || *q == '\r' || *q == '\n' ) {
352 for ( gq = genqueries; gq->gq_name; gq++ ) {
353 if (( strlen( gq->gq_name ) == q - p ) &&
354 ( strncmp( gq->gq_name, p, q - p ) == 0 )) {
358 if ( gq->gq_name == NULL || gq->gq_handler == NULL ||
359 (gq->gq_handler)( out ) < 0 ) {
360 if ( comswitch( queries, cq_default ) < 0 ) {
361 LOG(log_error, logtype_default, "cq_feature: can't find default!" );
367 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
369 CONSUME( in, linelength + crlflength );
374 CONSUME( in, linelength + crlflength );
378 void cq_font_answer( start, stop, out )
382 char *p, *q, buf[ 256 ];
383 struct ppd_font *pfo;
387 while (( *p == ' ' || *p == '\t' ) && p < stop ) {
392 while ( *p != ' ' && *p != '\t' &&
393 *p != '\n' && *p != '\r' && p < stop ) {
400 append( out, "/", 1 );
401 append( out, buf, strlen( buf ));
402 append( out, ":", 1 );
404 if (( pfo = ppd_font( buf )) == NULL ) {
405 append( out, "No\n", 3 );
407 append( out, "Yes\n", 4 );
415 int cq_font( in, out )
416 struct papfile *in, *out;
418 char *start, *stop, *p;
419 int linelength, crlflength;
420 struct papd_comment *comment = compeek();
423 switch ( markline( in, &start, &linelength, &crlflength )) {
431 stop = start + linelength;
433 if ( comgetflags() == 0 ) {
436 for ( p = start; p < stop; p++ ) {
443 cq_font_answer( p, stop, out );
445 if ( comgetflags() == 1 &&
446 comcmp( start, stop, comcont, 0 ) == 0 ) {
449 for ( p = start; p < stop; p++ ) {
456 cq_font_answer( p, stop, out );
459 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
460 append( out, "*\n", 2 );
462 CONSUME( in, linelength + crlflength );
468 CONSUME( in, linelength + crlflength );
472 int cq_feature( in, out )
473 struct papfile *in, *out;
475 char *start, *stop, *p;
476 int linelength, crlflength;
477 struct papd_comment *comment = compeek();
478 struct ppd_feature *pfe;
481 switch ( markline( in, &start, &linelength, &crlflength )) {
489 stop = start + linelength;
491 if ( comgetflags() == 0 ) {
494 /* parse for feature */
495 for ( p = start; p < stop; p++ ) {
501 while ( *p == ' ' ) {
505 if (( pfe = ppd_feature( p, stop - p )) == NULL ) {
506 if ( comswitch( queries, cq_default ) < 0 ) {
507 LOG(log_error, logtype_default, "cq_feature: can't find default!" );
513 append( out, pfe->pd_value, strlen( pfe->pd_value ));
514 append( out, "\r", 1 );
516 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
518 CONSUME( in, linelength + crlflength );
523 CONSUME( in, linelength + crlflength );
527 static const char *psver = "*PSVersion\n";
528 static const char *prod = "*Product\n";
530 int cq_printer( in, out )
531 struct papfile *in, *out;
534 int linelength, crlflength;
535 struct papd_comment *comment = compeek();
536 struct ppd_feature *pdpsver, *pdprod;
539 switch ( markline( in, &start, &linelength, &crlflength )) {
547 if ( comgetflags() == 0 ) {
550 if (( pdpsver = ppd_feature( psver, strlen( psver ))) == NULL ) {
551 if ( comswitch( queries, cq_default ) < 0 ) {
552 LOG(log_error, logtype_default, "cq_printer: can't find default!" );
558 for ( p = pdpsver->pd_value; *p != '\0'; p++ ) {
564 LOG(log_error, logtype_default, "cq_printer: can't parse PSVersion!" );
565 if ( comswitch( queries, cq_default ) < 0 ) {
566 LOG(log_error, logtype_default, "cq_printer: can't find default!" );
572 if (( pdprod = ppd_feature( prod, strlen( prod ))) == NULL ) {
573 if ( comswitch( queries, cq_default ) < 0 ) {
574 LOG(log_error, logtype_default, "cq_printer: can't find default!" );
581 append( out, p + 1, strlen( p + 1 ));
582 append( out, "\r", 1 );
585 append( out, pdpsver->pd_value, p - pdpsver->pd_value );
586 append( out, "\r", 1 );
589 append( out, pdprod->pd_value, strlen( pdprod->pd_value ));
590 append( out, "\r", 1 );
592 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
594 CONSUME( in, linelength + crlflength );
599 CONSUME( in, linelength + crlflength );
603 static const char *rmjobfailed = "Failed\n";
604 static const char *rmjobok = "Ok\n";
606 int cq_rmjob( in, out )
607 struct papfile *in, *out;
609 char *start, *stop, *p;
610 int linelength, crlflength;
613 switch ( markline( in, &start, &linelength, &crlflength )) {
621 stop = start + linelength;
623 for ( p = start; p < stop; p++ ) {
624 if ( *p == ' ' || *p == '\t' ) {
628 for ( ; p < stop; p++ ) {
629 if ( *p != ' ' && *p != '\t' ) {
635 if ( p < stop && ( job = atoi( p )) > 0 ) {
637 append( out, rmjobok, strlen( rmjobok ));
639 append( out, rmjobfailed, strlen( rmjobfailed ));
643 CONSUME( in, linelength + crlflength );
647 int cq_listq( in, out )
648 struct papfile *in, *out;
651 int linelength, crlflength;
653 switch ( markline( in, &start, &linelength, &crlflength )) {
661 if ( lp_queue( out )) {
662 LOG(log_error, logtype_default, "cq_listq: lp_queue failed" );
666 CONSUME( in, linelength + crlflength );
672 * Handler for RBILogin
675 static struct uam_obj *papd_uam = NULL;
676 static const char *rbiloginok = "0\r";
677 static const char *rbiloginbad = "-1\r";
678 static const char *rbiloginerrstr = "%%[Error: SecurityError; \
679 SecurityViolation: Unknown user, incorrect password or log on is \
680 disabled ]%%\r%%[Flushing: rest of job (to end-of-file) will be \
683 int cq_rbilogin( in, out )
684 struct papfile *in, *out;
686 char *start, *stop, *p, *begin;
687 int linelength, crlflength;
688 char username[9] = "\0";
689 struct papd_comment *comment = compeek();
690 char uamtype[20] = "\0";
693 switch ( markline( in, &start, &linelength, &crlflength )) {
701 stop = start + linelength;
703 if ( comgetflags() == 0 ) { /* first line */
704 begin = start + strlen(comment->c_begin);
711 strncat(uamtype, begin, p - begin);
713 if ((papd_uam = auth_uamfind(UAM_SERVER_PRINTAUTH,
714 uamtype, strlen(uamtype))) == NULL) {
715 LOG(log_info, logtype_default, "Could not find uam: %s", uamtype);
716 append(out, rbiloginbad, strlen(rbiloginbad));
717 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
719 if ( (papd_uam->u.uam_printer(p,stop,username,out)) == 0 ) {
720 lp_person( username );
722 append(out, rbiloginbad, strlen( rbiloginbad));
723 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
728 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
734 CONSUME( in, linelength + crlflength );
740 * All queries start with %%?Begin and end with %%?End. Note that the
741 * "Begin"/"End" general queries have to be last.
743 struct papd_comment queries[] = {
745 { "%%Login: UMICHKerberosIV", 0, cq_k4login, 0 },
746 { "%%?BeginUAMethodsQuery", "%%?EndUAMethodsQuery:", cq_uameth, C_FULL },
748 { "%UMICHListQueue", 0, cq_listq, C_FULL },
749 { "%UMICHDeleteJob", 0, cq_rmjob, 0 },
750 { "%%?BeginQuery: RBILogin ", "%%?EndQuery", cq_rbilogin, 0 },
751 { "%%?BeginQuery", "%%?EndQuery", cq_query, 0 },
752 { "%%?BeginFeatureQuery", "%%?EndFeatureQuery", cq_feature, 0 },
753 { "%%?BeginFontQuery", "%%?EndFontQuery", cq_font, 0 },
754 { "%%?BeginPrinterQuery", "%%?EndPrinterQuery", cq_printer, C_FULL },
755 { "%%?Begin", "%%?End", cq_default, 0 },