2 * Copyright (c) 1990,1994 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
11 #include <sys/syslog.h>
12 #include <sys/param.h>
14 #include <sys/types.h>
15 #include <netatalk/at.h>
16 #include <atalk/atp.h>
20 #include <kerberos/krb.h>
33 struct papfile *in, *out;
35 char *start, *stop, *p;
36 int linelength, crlflength;
37 struct comment *comment = compeek();
40 switch ( markline( in, &start, &linelength, &crlflength )) {
48 stop = start+linelength;
50 if ( comgetflags() == 0 ) { /* started */
51 if ( comment->c_end ) {
55 CONSUME( in, linelength + crlflength );
60 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
61 for ( p = start; p < stop; p++ ) {
71 append( out, p, stop - p + crlflength );
73 CONSUME( in, linelength + crlflength );
78 CONSUME( in, linelength + crlflength );
83 char *LoginOK = "LoginOK\n";
84 char *LoginFailed = "LoginFailed\n";
86 #define h2b(x) (isdigit((x))?(x)-'0':(isupper((x))?(x)-'A':(x)-'a')+10)
89 struct papfile *in, *out;
92 int linelength, crlflength;
94 struct comment *comment = compeek();
99 switch ( markline( in, &start, &linelength, &crlflength )) {
107 p = start + strlen( comment->c_begin );
108 while ( *p == ' ' ) {
112 bzero( &tkt, sizeof( tkt ));
113 stop = start+linelength;
114 for ( i = 0, t = tkt.dat; p < stop; p += 2, t++, i++ ) {
115 *t = ( h2b( (unsigned char)*p ) << 4 ) +
116 h2b( (unsigned char)*( p + 1 ));
120 if (( rc = krb_rd_req( &tkt, "LaserWriter", printer->p_name,
121 0, &ad, "" )) != RD_AP_OK ) {
122 syslog( LOG_ERR, "cq_k4login: %s", krb_err_txt[ rc ] );
123 append( out, LoginFailed, strlen( LoginFailed ));
125 CONSUME( in, linelength + crlflength );
128 syslog( LOG_INFO, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
130 lp_person( ad.pname );
131 lp_host( ad.prealm );
133 append( out, LoginOK, strlen( LoginOK ));
135 CONSUME( in, linelength + crlflength);
139 char *uameth = "UMICHKerberosIV\n*\n";
142 struct papfile *in, *out;
145 int linelength, crlflength;
146 struct comment *c, *comment = compeek();
149 switch ( markline( in, &start, &linelength, &crlflength )) {
157 if ( comgetflags() == 0 ) { /* start */
158 if (( printer->p_flags & P_KRB ) == 0 ) { /* no kerberos */
159 if ( comswitch( queries, cq_default ) < 0 ) {
160 syslog( LOG_ERR, "cq_uameth: can't find default!" );
167 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) { /* end */
168 append( out, uameth, strlen( uameth ));
174 CONSUME( in, linelength + crlflength );
182 if ( printer->p_flags & P_SPOOLED ) {
183 append( out, "true\n", 5 );
195 /* check for spooler? XXX */
196 if ( printer->p_pagecost_msg != NULL ) {
197 append( out, printer->p_pagecost_msg,
198 strlen( printer->p_pagecost_msg ));
199 } else if ( printer->p_flags & P_ACCOUNT ) {
203 sprintf( cost, "%d", printer->p_pagecost );
204 append( out, cost, strlen( cost ));
208 append( out, "\n", 1 );
218 if ( lp_pagecost() != 0 ) {
221 sprintf( balance, "$%1.2f\n", printer->p_balance );
222 append( out, balance, strlen( balance ));
229 * Handler for RBISpoolerID
232 static const char *spoolerid = "(PAPD Spooler) 2.1 (2.1.4 pre-release)\n";
234 gq_rbispoolerid( out )
237 append( out, spoolerid, strlen( spoolerid ));
244 * Handler for RBIUAMListQuery
247 static const char *nouams = "*\n";
252 char uamnames[128] = "\0";
254 if (printer->p_flags & P_AUTH_PSSP) {
255 if (getuamnames(UAM_SERVER_PRINTAUTH, uamnames) < 0) {
256 append(out, nouams, strlen(nouams));
259 append(out, uamnames, strlen(uamnames));
263 append(out, nouams, strlen(nouams));
273 { "UMICHCostPerPage", gq_pagecost },
275 { "UMICHUserBalance", gq_balance },
277 { "RBISpoolerID", gq_rbispoolerid },
278 { "RBIUAMListQuery", gq_rbiuamlist },
279 { "UMICHListQueue", gq_true },
280 { "UMICHDeleteJob", gq_true },
285 struct papfile *in, *out;
287 char *start, *stop, *p, *q;
288 int linelength, crlflength;
289 struct comment *comment = compeek();
294 switch ( markline( in, &start, &linelength, &crlflength )) {
302 stop = start+linelength;
304 if ( comgetflags() == 0 ) { /* started */
307 for ( p = start; p < stop; p++ ) {
313 for ( p++; p < stop; p++ ) {
314 if ( *p != ' ' && *p != '\t' ) {
319 for ( q = p; q < stop; q++ ) {
320 if ( *q == ' ' || *q == '\t' || *q == '\r' || *q == '\n' ) {
325 for ( gq = genqueries; gq->gq_name; gq++ ) {
326 if (( strlen( gq->gq_name ) == q - p ) &&
327 ( strncmp( gq->gq_name, p, q - p ) == 0 )) {
331 if ( gq->gq_name == NULL || gq->gq_handler == NULL ||
332 (gq->gq_handler)( out ) < 0 ) {
333 if ( comswitch( queries, cq_default ) < 0 ) {
334 syslog( LOG_ERR, "cq_feature: can't find default!" );
340 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
342 CONSUME( in, linelength + crlflength );
347 CONSUME( in, linelength + crlflength );
351 cq_font_answer( start, stop, out )
355 char *p, *q, buf[ 256 ];
356 struct ppd_font *pfo;
360 while (( *p == ' ' || *p == '\t' ) && p < stop ) {
365 while ( *p != ' ' && *p != '\t' &&
366 *p != '\n' && *p != '\r' && p < stop ) {
373 append( out, "/", 1 );
374 append( out, buf, strlen( buf ));
375 append( out, ":", 1 );
377 if (( pfo = ppd_font( buf )) == NULL ) {
378 append( out, "No\n", 3 );
380 append( out, "Yes\n", 4 );
389 struct papfile *in, *out;
391 char *start, *stop, *p;
392 int linelength, crlflength;
393 struct comment *comment = compeek();
396 switch ( markline( in, &start, &linelength, &crlflength )) {
404 stop = start + linelength;
406 if ( comgetflags() == 0 ) {
409 for ( p = start; p < stop; p++ ) {
416 cq_font_answer( p, stop, out );
418 if ( comgetflags() == 1 &&
419 comcmp( start, stop, comcont, 0 ) == 0 ) {
422 for ( p = start; p < stop; p++ ) {
429 cq_font_answer( p, stop, out );
432 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
433 append( out, "*\n", 2 );
435 CONSUME( in, linelength + crlflength );
441 CONSUME( in, linelength + crlflength );
445 cq_feature( in, out )
446 struct papfile *in, *out;
448 char *start, *stop, *p;
449 int linelength, crlflength;
450 struct comment *comment = compeek();
451 struct ppd_feature *pfe;
454 switch ( markline( in, &start, &linelength, &crlflength )) {
462 stop = start + linelength;
464 if ( comgetflags() == 0 ) {
467 /* parse for feature */
468 for ( p = start; p < stop; p++ ) {
474 while ( *p == ' ' ) {
478 if (( pfe = ppd_feature( p, stop - p )) == NULL ) {
479 if ( comswitch( queries, cq_default ) < 0 ) {
480 syslog( LOG_ERR, "cq_feature: can't find default!" );
486 append( out, pfe->pd_value, strlen( pfe->pd_value ));
487 append( out, "\r", 1 );
489 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
491 CONSUME( in, linelength + crlflength );
496 CONSUME( in, linelength + crlflength );
500 static const char *psver = "*PSVersion\n";
501 static const char *prod = "*Product\n";
503 cq_printer( in, out )
504 struct papfile *in, *out;
507 int linelength, crlflength;
508 struct comment *comment = compeek();
509 struct ppd_feature *pdpsver, *pdprod;
512 switch ( markline( in, &start, &linelength, &crlflength )) {
520 if ( comgetflags() == 0 ) {
523 if (( pdpsver = ppd_feature( psver, strlen( psver ))) == NULL ) {
524 if ( comswitch( queries, cq_default ) < 0 ) {
525 syslog( LOG_ERR, "cq_printer: can't find default!" );
531 for ( p = pdpsver->pd_value; *p != '\0'; p++ ) {
537 syslog( LOG_ERR, "cq_printer: can't parse PSVersion!" );
538 if ( comswitch( queries, cq_default ) < 0 ) {
539 syslog( LOG_ERR, "cq_printer: can't find default!" );
545 if (( pdprod = ppd_feature( prod, strlen( prod ))) == NULL ) {
546 if ( comswitch( queries, cq_default ) < 0 ) {
547 syslog( LOG_ERR, "cq_printer: can't find default!" );
554 append( out, p + 1, strlen( p + 1 ));
555 append( out, "\r", 1 );
558 append( out, pdpsver->pd_value, p - pdpsver->pd_value );
559 append( out, "\r", 1 );
562 append( out, pdprod->pd_value, strlen( pdprod->pd_value ));
563 append( out, "\r", 1 );
565 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
567 CONSUME( in, linelength + crlflength );
572 CONSUME( in, linelength + crlflength );
576 static const char *rmjobfailed = "Failed\n";
577 static const char *rmjobok = "Ok\n";
580 struct papfile *in, *out;
582 char *start, *stop, *p;
583 int linelength, crlflength;
586 switch ( markline( in, &start, &linelength, &crlflength )) {
594 stop = start + linelength;
596 for ( p = start; p < stop; p++ ) {
597 if ( *p == ' ' || *p == '\t' ) {
601 for ( ; p < stop; p++ ) {
602 if ( *p != ' ' && *p != '\t' ) {
608 if ( p < stop && ( job = atoi( p )) > 0 ) {
610 append( out, rmjobok, strlen( rmjobok ));
612 append( out, rmjobfailed, strlen( rmjobfailed ));
616 CONSUME( in, linelength + crlflength );
621 struct papfile *in, *out;
624 int linelength, crlflength;
626 switch ( markline( in, &start, &linelength, &crlflength )) {
634 if ( lp_queue( out )) {
635 syslog( LOG_ERR, "cq_listq: lp_queue failed" );
639 CONSUME( in, linelength + crlflength );
645 * Handler for RBILogin
648 static struct uam_obj *papd_uam = NULL;
649 static const char *rbiloginok = "0\r";
650 static const char *rbiloginbad = "-1\r";
651 static const char *rbiloginerrstr = "%%[Error: SecurityError; \
652 SecurityViolation: Unknown user, incorrect password or log on is \
653 disabled ]%%\r%%Flushing: rest of job (to end-of-file) will be \
656 cq_rbilogin( in, out )
657 struct papfile *in, *out;
659 char *start, *stop, *p, *begin;
660 int linelength, crlflength;
661 char username[9] = "\0";
662 struct comment *comment = compeek();
663 char uamtype[20] = "\0";
666 switch ( markline( in, &start, &linelength, &crlflength )) {
674 stop = start + linelength;
676 if ( comgetflags() == 0 ) { /* first line */
677 begin = start + strlen(comment->c_begin);
684 strncat(uamtype, begin, p - begin);
686 if ((papd_uam = auth_uamfind(UAM_SERVER_PRINTAUTH,
687 uamtype, strlen(uamtype))) == NULL) {
688 syslog(LOG_INFO, "Could not find uam: %s", uamtype);
689 append(out, rbiloginbad, strlen(rbiloginbad));
690 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
692 if ( (papd_uam->u.uam_printer(p,stop,username,out)) == 0 ) {
693 lp_person( username );
695 append(out, rbiloginbad, strlen( rbiloginbad));
696 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
701 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
707 CONSUME( in, linelength + crlflength );
713 * All queries start with %%?Begin and end with %%?End. Note that the
714 * "Begin"/"End" general queries have to be last.
716 struct comment queries[] = {
718 { "%%Login: UMICHKerberosIV", 0, cq_k4login, 0 },
719 { "%%?BeginUAMethodsQuery", "%%?EndUAMethodsQuery:", cq_uameth, C_FULL },
721 { "%UMICHListQueue", 0, cq_listq, C_FULL },
722 { "%UMICHDeleteJob", 0, cq_rmjob, 0 },
723 { "%%?BeginQuery: RBILogin ", "%%?EndQuery", cq_rbilogin, 0 },
724 { "%%?BeginQuery", "%%?EndQuery", cq_query, 0 },
725 { "%%?BeginFeatureQuery", "%%?EndFeatureQuery", cq_feature, 0 },
726 { "%%?BeginFontQuery", "%%?EndFontQuery", cq_font, 0 },
727 { "%%?BeginPrinterQuery", "%%?EndPrinterQuery", cq_printer, C_FULL },
728 { "%%?Begin", "%%?End", cq_default, 0 },