2 * Copyright (c) 1990,1994 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
7 #include <sys/syslog.h>
10 #include <sys/types.h>
11 #include <netatalk/at.h>
12 #include <atalk/atp.h>
16 #include <kerberos/krb.h>
29 struct papfile *in, *out;
31 char *start, *stop, *p;
32 int linelength, crlflength;
33 struct comment *comment = compeek();
36 switch ( markline( in, &start, &linelength, &crlflength )) {
44 stop = start+linelength;
46 if ( comgetflags() == 0 ) { /* started */
47 if ( comment->c_end ) {
51 CONSUME( in, linelength + crlflength );
56 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
57 for ( p = start; p < stop; p++ ) {
67 append( out, p, stop - p + crlflength );
69 CONSUME( in, linelength + crlflength );
74 CONSUME( in, linelength + crlflength );
79 char *LoginOK = "LoginOK\n";
80 char *LoginFailed = "LoginFailed\n";
82 #define h2b(x) (isdigit((x))?(x)-'0':(isupper((x))?(x)-'A':(x)-'a')+10)
85 struct papfile *in, *out;
88 int linelength, crlflength;
90 struct comment *comment = compeek();
95 switch ( markline( in, &start, &linelength, &crlflength )) {
103 p = start + strlen( comment->c_begin );
104 while ( *p == ' ' ) {
108 bzero( &tkt, sizeof( tkt ));
109 stop = start+linelength;
110 for ( i = 0, t = tkt.dat; p < stop; p += 2, t++, i++ ) {
111 *t = ( h2b( (unsigned char)*p ) << 4 ) +
112 h2b( (unsigned char)*( p + 1 ));
116 if (( rc = krb_rd_req( &tkt, "LaserWriter", printer->p_name,
117 0, &ad, "" )) != RD_AP_OK ) {
118 syslog( LOG_ERR, "cq_k4login: %s", krb_err_txt[ rc ] );
119 append( out, LoginFailed, strlen( LoginFailed ));
121 CONSUME( in, linelength + crlflength );
124 syslog( LOG_INFO, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
126 lp_person( ad.pname );
127 lp_host( ad.prealm );
129 append( out, LoginOK, strlen( LoginOK ));
131 CONSUME( in, linelength + crlflength);
135 char *uameth = "UMICHKerberosIV\n*\n";
138 struct papfile *in, *out;
141 int linelength, crlflength;
142 struct comment *c, *comment = compeek();
145 switch ( markline( in, &start, &linelength, &crlflength )) {
153 if ( comgetflags() == 0 ) { /* start */
154 if (( printer->p_flags & P_KRB ) == 0 ) { /* no kerberos */
155 if ( comswitch( queries, cq_default ) < 0 ) {
156 syslog( LOG_ERR, "cq_uameth: can't find default!" );
163 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) { /* end */
164 append( out, uameth, strlen( uameth ));
170 CONSUME( in, linelength + crlflength );
178 if ( printer->p_flags & P_SPOOLED ) {
179 append( out, "true\n", 5 );
191 /* check for spooler? XXX */
192 if ( printer->p_pagecost_msg != NULL ) {
193 append( out, printer->p_pagecost_msg,
194 strlen( printer->p_pagecost_msg ));
195 } else if ( printer->p_flags & P_ACCOUNT ) {
199 sprintf( cost, "%d", printer->p_pagecost );
200 append( out, cost, strlen( cost ));
204 append( out, "\n", 1 );
214 if ( lp_pagecost() != 0 ) {
217 sprintf( balance, "$%1.2f\n", printer->p_balance );
218 append( out, balance, strlen( balance ));
225 * Handler for RBISpoolerID
228 static const char *spoolerid = "(PAPD Spooler) 2.1 (2.1.4 pre-release)\n";
230 gq_rbispoolerid( out )
233 append( out, spoolerid, strlen( spoolerid ));
240 * Handler for RBIUAMListQuery
243 static const char *nouams = "*\n";
248 char uamnames[128] = "\0";
250 if (printer->p_flags & P_AUTH) {
251 if (getuamnames(UAM_SERVER_PRINTAUTH, uamnames) < 0) {
252 append(out, nouams, strlen(nouams));
255 append(out, uamnames, strlen(uamnames));
259 append(out, nouams, strlen(nouams));
269 { "UMICHCostPerPage", gq_pagecost },
271 { "UMICHUserBalance", gq_balance },
273 { "RBISpoolerID", gq_rbispoolerid },
274 { "RBIUAMListQuery", gq_rbiuamlist },
275 { "UMICHListQueue", gq_true },
276 { "UMICHDeleteJob", gq_true },
281 struct papfile *in, *out;
283 char *start, *stop, *p, *q;
284 int linelength, crlflength;
285 struct comment *comment = compeek();
290 switch ( markline( in, &start, &linelength, &crlflength )) {
298 stop = start+linelength;
300 if ( comgetflags() == 0 ) { /* started */
303 for ( p = start; p < stop; p++ ) {
309 for ( p++; p < stop; p++ ) {
310 if ( *p != ' ' && *p != '\t' ) {
315 for ( q = p; q < stop; q++ ) {
316 if ( *q == ' ' || *q == '\t' || *q == '\r' || *q == '\n' ) {
321 for ( gq = genqueries; gq->gq_name; gq++ ) {
322 if (( strlen( gq->gq_name ) == q - p ) &&
323 ( strncmp( gq->gq_name, p, q - p ) == 0 )) {
327 if ( gq->gq_name == NULL || gq->gq_handler == NULL ||
328 (gq->gq_handler)( out ) < 0 ) {
329 if ( comswitch( queries, cq_default ) < 0 ) {
330 syslog( LOG_ERR, "cq_feature: can't find default!" );
336 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
338 CONSUME( in, linelength + crlflength );
343 CONSUME( in, linelength + crlflength );
347 cq_font_answer( start, stop, out )
351 char *p, *q, buf[ 256 ];
352 struct ppd_font *pfo;
356 while (( *p == ' ' || *p == '\t' ) && p < stop ) {
361 while ( *p != ' ' && *p != '\t' &&
362 *p != '\n' && *p != '\r' && p < stop ) {
369 append( out, "/", 1 );
370 append( out, buf, strlen( buf ));
371 append( out, ":", 1 );
373 if (( pfo = ppd_font( buf )) == NULL ) {
374 append( out, "No\n", 3 );
376 append( out, "Yes\n", 4 );
385 struct papfile *in, *out;
387 char *start, *stop, *p;
388 int linelength, crlflength;
389 struct comment *comment = compeek();
392 switch ( markline( in, &start, &linelength, &crlflength )) {
400 stop = start + linelength;
402 if ( comgetflags() == 0 ) {
405 for ( p = start; p < stop; p++ ) {
412 cq_font_answer( p, stop, out );
414 if ( comgetflags() == 1 &&
415 comcmp( start, stop, comcont, 0 ) == 0 ) {
418 for ( p = start; p < stop; p++ ) {
425 cq_font_answer( p, stop, out );
428 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
429 append( out, "*\n", 2 );
431 CONSUME( in, linelength + crlflength );
437 CONSUME( in, linelength + crlflength );
441 cq_feature( in, out )
442 struct papfile *in, *out;
444 char *start, *stop, *p;
445 int linelength, crlflength;
446 struct comment *comment = compeek();
447 struct ppd_feature *pfe;
450 switch ( markline( in, &start, &linelength, &crlflength )) {
458 stop = start + linelength;
460 if ( comgetflags() == 0 ) {
463 /* parse for feature */
464 for ( p = start; p < stop; p++ ) {
470 while ( *p == ' ' ) {
474 if (( pfe = ppd_feature( p, stop - p )) == NULL ) {
475 if ( comswitch( queries, cq_default ) < 0 ) {
476 syslog( LOG_ERR, "cq_feature: can't find default!" );
482 append( out, pfe->pd_value, strlen( pfe->pd_value ));
483 append( out, "\r", 1 );
485 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
487 CONSUME( in, linelength + crlflength );
492 CONSUME( in, linelength + crlflength );
496 static const char *psver = "*PSVersion\n";
497 static const char *prod = "*Product\n";
499 cq_printer( in, out )
500 struct papfile *in, *out;
503 int linelength, crlflength;
504 struct comment *comment = compeek();
505 struct ppd_feature *pdpsver, *pdprod;
508 switch ( markline( in, &start, &linelength, &crlflength )) {
516 if ( comgetflags() == 0 ) {
519 if (( pdpsver = ppd_feature( psver, strlen( psver ))) == NULL ) {
520 if ( comswitch( queries, cq_default ) < 0 ) {
521 syslog( LOG_ERR, "cq_printer: can't find default!" );
527 for ( p = pdpsver->pd_value; *p != '\0'; p++ ) {
533 syslog( LOG_ERR, "cq_printer: can't parse PSVersion!" );
534 if ( comswitch( queries, cq_default ) < 0 ) {
535 syslog( LOG_ERR, "cq_printer: can't find default!" );
541 if (( pdprod = ppd_feature( prod, strlen( prod ))) == NULL ) {
542 if ( comswitch( queries, cq_default ) < 0 ) {
543 syslog( LOG_ERR, "cq_printer: can't find default!" );
550 append( out, p + 1, strlen( p + 1 ));
551 append( out, "\r", 1 );
554 append( out, pdpsver->pd_value, p - pdpsver->pd_value );
555 append( out, "\r", 1 );
558 append( out, pdprod->pd_value, strlen( pdprod->pd_value ));
559 append( out, "\r", 1 );
561 if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
563 CONSUME( in, linelength + crlflength );
568 CONSUME( in, linelength + crlflength );
572 static const char *rmjobfailed = "Failed\n";
573 static const char *rmjobok = "Ok\n";
576 struct papfile *in, *out;
578 char *start, *stop, *p;
579 int linelength, crlflength;
582 switch ( markline( in, &start, &linelength, &crlflength )) {
590 stop = start + linelength;
592 for ( p = start; p < stop; p++ ) {
593 if ( *p == ' ' || *p == '\t' ) {
597 for ( ; p < stop; p++ ) {
598 if ( *p != ' ' && *p != '\t' ) {
604 if ( p < stop && ( job = atoi( p )) > 0 ) {
606 append( out, rmjobok, strlen( rmjobok ));
608 append( out, rmjobfailed, strlen( rmjobfailed ));
612 CONSUME( in, linelength + crlflength );
617 struct papfile *in, *out;
620 int linelength, crlflength;
622 switch ( markline( in, &start, &linelength, &crlflength )) {
630 if ( lp_queue( out )) {
631 syslog( LOG_ERR, "cq_listq: lp_queue failed" );
635 CONSUME( in, linelength + crlflength );
641 * Handler for RBILogin
644 static struct uam_obj *papd_uam = NULL;
645 static const char *rbiloginok = "0\r";
646 static const char *rbiloginbad = "-1\r";
647 static const char *rbiloginerrstr = "%%[Error: SecurityError; \
648 SecurityViolation: Unknown user, incorrect password or log on is \
649 disabled ]%%\r%%Flushing: rest of job (to end-of-file) will be \
652 cq_rbilogin( in, out )
653 struct papfile *in, *out;
655 char *start, *stop, *p, *begin;
656 int linelength, crlflength;
657 char username[9] = "\0";
658 struct comment *comment = compeek();
659 char uamtype[20] = "\0";
662 switch ( markline( in, &start, &linelength, &crlflength )) {
670 stop = start + linelength;
672 if ( comgetflags() == 0 ) { /* first line */
673 begin = start + strlen(comment->c_begin);
680 strncat(uamtype, begin, p - begin);
682 if ((papd_uam = auth_uamfind(UAM_SERVER_PRINTAUTH,
683 uamtype, strlen(uamtype))) == NULL) {
684 syslog(LOG_INFO, "Could not find uam: %s", uamtype);
685 append(out, rbiloginbad, strlen(rbiloginbad));
686 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
688 if ( (papd_uam->u.uam_printer(p,stop,username,out)) == 0 ) {
689 lp_person( username );
691 append(out, rbiloginbad, strlen( rbiloginbad));
692 append(out, rbiloginerrstr, strlen(rbiloginerrstr));
697 if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
703 CONSUME( in, linelength + crlflength );
709 * All queries start with %%?Begin and end with %%?End. Note that the
710 * "Begin"/"End" general queries have to be last.
712 struct comment queries[] = {
714 { "%%Login: UMICHKerberosIV", 0, cq_k4login, 0 },
715 { "%%?BeginUAMethodsQuery", "%%?EndUAMethodsQuery:", cq_uameth, C_FULL },
717 { "%UMICHListQueue", 0, cq_listq, C_FULL },
718 { "%UMICHDeleteJob", 0, cq_rmjob, 0 },
719 { "%%?BeginQuery: RBILogin ", "%%?EndQuery", cq_rbilogin, 0 },
720 { "%%?BeginQuery", "%%?EndQuery", cq_query, 0 },
721 { "%%?BeginFeatureQuery", "%%?EndFeatureQuery", cq_feature, 0 },
722 { "%%?BeginFontQuery", "%%?EndFontQuery", cq_font, 0 },
723 { "%%?BeginPrinterQuery", "%%?EndPrinterQuery", cq_printer, C_FULL },
724 { "%%?Begin", "%%?End", cq_default, 0 },