]> arthur.barton.de Git - netatalk.git/blobdiff - etc/papd/queries.c
changed all LOG messages using logtype_default to use logtype_papd
[netatalk.git] / etc / papd / queries.c
index 28df08003b65f6c3b4d02cc10bffcbb8a88b8e14..a1ef26066a6f81a84435fbdedbb04f88eb1fb443 100644 (file)
@@ -1,10 +1,18 @@
 /*
+ * $Id: queries.c,v 1.15 2002-09-29 23:29:14 sibaz Exp $
+ *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include <string.h>
-#include <sys/syslog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <atalk/logger.h>
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #ifdef KRB
 #ifdef SOLARIS
 #include <kerberos/krb.h>
-#else
+#else /* SOLARIS */
 #include <krb.h>
-#endif
-#endif KRB
+#endif /* SOLARIS */
+#endif /* KRB */
 
 #include "file.h"
 #include "comment.h"
 #include "printer.h"
 #include "ppd.h"
+#include "lp.h"
+#include "uam_auth.h"
+
+int cq_default( struct papfile *, struct papfile * );
+int cq_k4login( struct papfile *, struct papfile * );
+int cq_uameth( struct papfile *, struct papfile * );
+
+int gq_balance( struct papfile * );
+int gq_pagecost( struct papfile * );
+int gq_true( struct papfile * );
+int gq_rbispoolerid( struct papfile * );
+int gq_rbiuamlist( struct papfile * );
+
+int cq_query( struct papfile *, struct papfile * );
+void cq_font_answer( char *, char *, struct papfile * );
+int cq_font( struct papfile *, struct papfile * );
+int cq_feature( struct papfile *, struct papfile * );
+int cq_printer( struct papfile *, struct papfile * );
+int cq_rmjob( struct papfile *, struct papfile * );
+int cq_listq( struct papfile *, struct papfile * );
+int cq_rbilogin( struct papfile *, struct papfile * );
 
-cq_default( in, out )
+
+
+int cq_default( in, out )
     struct papfile     *in, *out;
 {
     char               *start, *stop, *p;
-    struct comment     *comment = compeek();
+    int                        linelength, crlflength;
+    struct papd_comment        *comment = compeek();
 
     for (;;) {
-       switch ( markline( &start, &stop, in )) {
+       switch ( markline( in, &start, &linelength, &crlflength )) {
        case 0 :
            return( 0 );
 
@@ -39,17 +71,19 @@ cq_default( in, out )
            return( CH_MORE );
        }
 
+       stop = start+linelength;
+
        if ( comgetflags() == 0 ) {     /* started */
            if ( comment->c_end ) {
                comsetflags( 1 );
            } else {
                compop();
-               consumetomark( start, stop, in );
+               CONSUME( in, linelength + crlflength );
                return( CH_DONE );
            }
        } else {
            /* return default */
-           if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
+           if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
                for ( p = start; p < stop; p++ ) {
                    if ( *p == ':' ) {
                        break;
@@ -60,15 +94,14 @@ cq_default( in, out )
                    p++;
                }
 
-               *stop = '\n';
-               APPEND( out, p, stop - p + 1 );
+               append( out, p, stop - p + crlflength );
                compop();
-               consumetomark( start, stop, in );
+               CONSUME( in, linelength + crlflength );
                return( CH_DONE );
            }
        }
 
-       consumetomark( start, stop, in );
+       CONSUME( in, linelength + crlflength );
     }
 }
 
@@ -78,17 +111,18 @@ char       *LoginFailed = "LoginFailed\n";
 
 #define h2b(x) (isdigit((x))?(x)-'0':(isupper((x))?(x)-'A':(x)-'a')+10)
 
-cq_k4login( in, out )
+int cq_k4login( in, out )
     struct papfile     *in, *out;
 {
-    char               *start, *stop, *p;
+    char               *start, *p;
+    int                        linelength, crlflength;
     unsigned char      *t;
-    struct comment     *comment = compeek();
+    struct papd_comment        *comment = compeek();
     KTEXT_ST           tkt;
     AUTH_DAT           ad;
     int                        rc, i;
 
-    switch ( markline( &start, &stop, in )) {
+    switch ( markline( in, &start, &linelength, &crlflength )) {
     case 0 :
        return( 0 );
 
@@ -102,6 +136,7 @@ cq_k4login( in, out )
     }
 
     bzero( &tkt, sizeof( tkt ));
+    stop = start+linelength;
     for ( i = 0, t = tkt.dat; p < stop; p += 2, t++, i++ ) {
        *t = ( h2b( (unsigned char)*p ) << 4 ) +
                h2b( (unsigned char)*( p + 1 ));
@@ -110,33 +145,34 @@ cq_k4login( in, out )
 
     if (( rc = krb_rd_req( &tkt, "LaserWriter", printer->p_name,
            0, &ad, "" )) != RD_AP_OK ) {
-       syslog( LOG_ERR, "cq_k4login: %s", krb_err_txt[ rc ] );
-       APPEND( out, LoginFailed, strlen( LoginFailed ));
+       LOG(log_error, logtype_papd, "cq_k4login: %s", krb_err_txt[ rc ] );
+       append( out, LoginFailed, strlen( LoginFailed ));
        compop();
-       consumetomark( start, stop, in );
+       CONSUME( in, linelength + crlflength );
        return( CH_DONE );
     }
-    syslog( LOG_INFO, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
+    LOG(log_info, logtype_papd, "cq_k4login: %s.%s@%s", ad.pname, ad.pinst,
            ad.prealm );
     lp_person( ad.pname );
     lp_host( ad.prealm );
 
-    APPEND( out, LoginOK, strlen( LoginOK ));
+    append( out, LoginOK, strlen( LoginOK ));
     compop();
-    consumetomark( start, stop, in );
+    CONSUME( in, linelength + crlflength);
     return( CH_DONE );
 }
 
 char   *uameth = "UMICHKerberosIV\n*\n";
 
-cq_uameth( in, out )
+int cq_uameth( in, out )
     struct papfile     *in, *out;
 {
-    char               *start, *stop;
-    struct comment     *c, *comment = compeek();
+    char               *start;
+    int                        linelength, crlflength;
+    struct papd_comment        *c, *comment = compeek();
 
     for (;;) {
-       switch ( markline( &start, &stop, in )) {
+       switch ( markline( in, &start, &linelength, &crlflength )) {
        case 0 :
            return( 0 );
 
@@ -145,9 +181,9 @@ cq_uameth( in, out )
        }
 
        if ( comgetflags() == 0 ) {     /* start */
-           if (( printer->p_flags & P_AUTH ) == 0 ) {  /* no kerberos */
+           if (( printer->p_flags & P_KRB ) == 0 ) {   /* no kerberos */
                if ( comswitch( queries, cq_default ) < 0 ) {
-                   syslog( LOG_ERR, "cq_uameth: can't find default!" );
+                   LOG(log_error, logtype_papd, "cq_uameth: can't find default!" );
                    exit( 1 );
                }
                return( CH_DONE );
@@ -155,52 +191,52 @@ cq_uameth( in, out )
            comsetflags( 1 );
        } else {
            if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) { /* end */
-               APPEND( out, uameth, strlen( uameth ));
+               append( out, uameth, strlen( uameth ));
                compop();
                return( CH_DONE );
            }
        }
 
-       consumetomark( start, stop, in );
+       CONSUME( in, linelength + crlflength );
     }
 }
-#endif KRB
+#endif /* KRB */
 
-gq_true( out )
+int gq_true( out )
     struct papfile     *out;
 {
     if ( printer->p_flags & P_SPOOLED ) {
-       APPEND( out, "true\n", 5 );
+       append( out, "true\n", 5 );
        return( 0 );
     } else {
        return( -1 );
     }
 }
 
-gq_pagecost( out )
+int gq_pagecost( out )
     struct papfile     *out;
 {
     char               cost[ 60 ];
 
     /* check for spooler? XXX */
     if ( printer->p_pagecost_msg != NULL ) {
-       APPEND( out, printer->p_pagecost_msg,
+       append( out, printer->p_pagecost_msg,
                strlen( printer->p_pagecost_msg ));
     } else if ( printer->p_flags & P_ACCOUNT ) {
 #ifdef ABS_PRINT
        lp_pagecost();
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
        sprintf( cost, "%d", printer->p_pagecost );
-       APPEND( out, cost, strlen( cost ));
+       append( out, cost, strlen( cost ));
     } else {
        return( -1 );
     }
-    APPEND( out, "\n", 1 );
+    append( out, "\n", 1 );
     return( 0 );
 }
 
 #ifdef ABS_PRINT
-gq_balance( out )
+int gq_balance( out )
     struct papfile     *out;
 {
     char               balance[ 60 ];
@@ -209,10 +245,52 @@ gq_balance( out )
        return( -1 );
     }
     sprintf( balance, "$%1.2f\n", printer->p_balance );
-    APPEND( out, balance, strlen( balance ));
+    append( out, balance, strlen( balance ));
     return( 0 );
 }
-#endif ABS_PRINT
+#endif /* ABS_PRINT */
+
+
+/*
+ * Handler for RBISpoolerID
+ */
+
+static const char *spoolerid = "(PAPD Spooler) " VERSION "\n";
+
+int gq_rbispoolerid( out )
+    struct papfile     *out;
+{
+    append( out, spoolerid, strlen( spoolerid ));
+    return(0);
+}
+
+
+
+/*
+ * Handler for RBIUAMListQuery
+ */
+
+static const char *nouams = "*\n";
+
+int gq_rbiuamlist( out )
+    struct papfile      *out;
+{
+    char uamnames[128] = "\0";
+
+    if (printer->p_flags & P_AUTH_PSSP) {
+       if (getuamnames(UAM_SERVER_PRINTAUTH, uamnames) < 0) {
+           append(out, nouams, strlen(nouams));
+           return(0);
+       } else {
+           append(out, uamnames, strlen(uamnames));
+           return(0);
+       }
+    } else {
+       append(out, nouams, strlen(nouams));
+       return(0);
+    }
+}
+
 
 struct genquery {
     char       *gq_name;
@@ -221,22 +299,26 @@ struct genquery {
     { "UMICHCostPerPage", gq_pagecost },
 #ifdef notdef
     { "UMICHUserBalance", gq_balance },
-#endif 
+#endif /* notdef */
+    { "RBISpoolerID",  gq_rbispoolerid },
+    { "RBIUAMListQuery", gq_rbiuamlist },
+    { "ADOIsBinaryOK?", gq_true },
     { "UMICHListQueue", gq_true },
     { "UMICHDeleteJob", gq_true },
     { NULL },
 };
 
-cq_query( in, out )
+int cq_query( in, out )
     struct papfile     *in, *out;
 {
     char               *start, *stop, *p, *q;
-    struct comment     *comment = compeek();
+    int                        linelength, crlflength;
+    struct papd_comment        *comment = compeek();
     struct genquery    *gq;
 
 
     for (;;) {
-       switch ( markline( &start, &stop, in )) {
+       switch ( markline( in, &start, &linelength, &crlflength )) {
        case 0 :
            return( 0 );
 
@@ -244,6 +326,8 @@ cq_query( in, out )
            return( CH_MORE );
        }
 
+       stop = start+linelength;
+
        if ( comgetflags() == 0 ) {     /* started */
            comsetflags( 1 );
 
@@ -274,7 +358,7 @@ cq_query( in, out )
            if ( gq->gq_name == NULL || gq->gq_handler == NULL ||
                    (gq->gq_handler)( out ) < 0 ) {
                if ( comswitch( queries, cq_default ) < 0 ) {
-                   syslog( LOG_ERR, "cq_feature: can't find default!" );
+                   LOG(log_error, logtype_papd, "cq_feature: can't find default!" );
                    exit( 1 );
                }
                return( CH_DONE );
@@ -282,16 +366,16 @@ cq_query( in, out )
        } else {
            if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
                compop();
-               consumetomark( start, stop, in );
+               CONSUME( in, linelength + crlflength );
                return( CH_DONE );
            }
        }
 
-       consumetomark( start, stop, in );
+       CONSUME( in, linelength + crlflength );
     }
 }
 
-cq_font_answer( start, stop, out )
+void cq_font_answer( start, stop, out )
     char               *start, *stop;
     struct papfile     *out;
 {
@@ -313,14 +397,14 @@ cq_font_answer( start, stop, out )
        if ( q != buf ) {
            *q = '\0';
 
-           APPEND( out, "/", 1 );
-           APPEND( out, buf, strlen( buf ));
-           APPEND( out, ":", 1 );
+           append( out, "/", 1 );
+           append( out, buf, strlen( buf ));
+           append( out, ":", 1 );
 
            if (( pfo = ppd_font( buf )) == NULL ) {
-               APPEND( out, "No\n", 3 );
+               append( out, "No\n", 3 );
            } else {
-               APPEND( out, "Yes\n", 4 );
+               append( out, "Yes\n", 4 );
            }
        }
     }
@@ -328,14 +412,15 @@ cq_font_answer( start, stop, out )
     return;
 }
 
-cq_font( in, out )
+int cq_font( in, out )
     struct papfile     *in, *out;
 {
     char               *start, *stop, *p;
-    struct comment     *comment = compeek();
+    int                        linelength, crlflength;
+    struct papd_comment        *comment = compeek();
 
     for (;;) {
-       switch ( markline( &start, &stop, in )) {
+       switch ( markline( in, &start, &linelength, &crlflength )) {
        case 0 :
            return( 0 );
 
@@ -343,6 +428,8 @@ cq_font( in, out )
            return( CH_MORE );
        }
 
+       stop = start + linelength;
+
        if ( comgetflags() == 0 ) {
            comsetflags( 1 );
 
@@ -370,27 +457,28 @@ cq_font( in, out )
            } else {
                comsetflags( 2 );
                if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
-                   APPEND( out, "*\n", 2 );
+                   append( out, "*\n", 2 );
                    compop();
-                   consumetomark( start, stop, in );
+                   CONSUME( in, linelength + crlflength );
                    return( CH_DONE );
                }
            }
        }
 
-       consumetomark( start, stop, in );
+        CONSUME( in, linelength + crlflength );
     }
 }
 
-cq_feature( in, out )
+int cq_feature( in, out )
     struct papfile     *in, *out;
 {
     char               *start, *stop, *p;
-    struct comment     *comment = compeek();
+    int                        linelength, crlflength;
+    struct papd_comment        *comment = compeek();
     struct ppd_feature *pfe;
 
     for (;;) {
-       switch ( markline( &start, &stop, in )) {
+       switch ( markline( in, &start, &linelength, &crlflength )) {
        case 0 :
            return( 0 );
 
@@ -398,6 +486,8 @@ cq_feature( in, out )
            return( CH_MORE );
        }
 
+       stop = start + linelength;
+
        if ( comgetflags() == 0 ) {
            comsetflags( 1 );
 
@@ -414,38 +504,39 @@ cq_feature( in, out )
 
            if (( pfe = ppd_feature( p, stop - p )) == NULL ) {
                if ( comswitch( queries, cq_default ) < 0 ) {
-                   syslog( LOG_ERR, "cq_feature: can't find default!" );
+                   LOG(log_error, logtype_papd, "cq_feature: can't find default!" );
                    exit( 1 );
                }
                return( CH_DONE );
            }
 
-           APPEND( out, pfe->pd_value, strlen( pfe->pd_value ));
-           APPEND( out, "\r", 1 );
+           append( out, pfe->pd_value, strlen( pfe->pd_value ));
+           append( out, "\r", 1 );
        } else {
            if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
                compop();
-               consumetomark( start, stop, in );
+               CONSUME( in, linelength + crlflength );
                return( CH_DONE );
            }
        }
 
-       consumetomark( start, stop, in );
+       CONSUME( in, linelength + crlflength );
     }
 }
 
 static const char      *psver = "*PSVersion\n";
 static const char      *prod = "*Product\n";
 
-cq_printer( in, out )
+int cq_printer( in, out )
     struct papfile     *in, *out;
 {
-    char               *start, *stop, *p;
-    struct comment     *c, *comment = compeek();
+    char               *start, *p;
+    int                        linelength, crlflength;
+    struct papd_comment        *comment = compeek();
     struct ppd_feature *pdpsver, *pdprod;
 
     for (;;) {
-       switch ( markline( &start, &stop, in )) {
+       switch ( markline( in, &start, &linelength, &crlflength )) {
        case 0 :
            return( 0 );
 
@@ -458,7 +549,7 @@ cq_printer( in, out )
 
            if (( pdpsver = ppd_feature( psver, strlen( psver ))) == NULL ) {
                if ( comswitch( queries, cq_default ) < 0 ) {
-                   syslog( LOG_ERR, "cq_printer: can't find default!" );
+                   LOG(log_error, logtype_papd, "cq_printer: can't find default!" );
                    exit( 1 );
                }
                return( CH_DONE );
@@ -470,9 +561,9 @@ cq_printer( in, out )
                }
            }
            if ( *p == '\0' ) {
-               syslog( LOG_ERR, "cq_printer: can't parse PSVersion!" );
+               LOG(log_error, logtype_papd, "cq_printer: can't parse PSVersion!" );
                if ( comswitch( queries, cq_default ) < 0 ) {
-                   syslog( LOG_ERR, "cq_printer: can't find default!" );
+                   LOG(log_error, logtype_papd, "cq_printer: can't find default!" );
                    exit( 1 );
                }
                return( CH_DONE );
@@ -480,45 +571,46 @@ cq_printer( in, out )
 
            if (( pdprod = ppd_feature( prod, strlen( prod ))) == NULL ) {
                if ( comswitch( queries, cq_default ) < 0 ) {
-                   syslog( LOG_ERR, "cq_printer: can't find default!" );
+                   LOG(log_error, logtype_papd, "cq_printer: can't find default!" );
                    exit( 1 );
                }
                return( CH_DONE );
            }
 
            /* revision */
-           APPEND( out, p + 1, strlen( p + 1 ));
-           APPEND( out, "\r", 1 );
+           append( out, p + 1, strlen( p + 1 ));
+           append( out, "\r", 1 );
 
            /* version */
-           APPEND( out, pdpsver->pd_value, p - pdpsver->pd_value );
-           APPEND( out, "\r", 1 );
+           append( out, pdpsver->pd_value, p - pdpsver->pd_value );
+           append( out, "\r", 1 );
 
            /* product */
-           APPEND( out, pdprod->pd_value, strlen( pdprod->pd_value ));
-           APPEND( out, "\r", 1 );
+           append( out, pdprod->pd_value, strlen( pdprod->pd_value ));
+           append( out, "\r", 1 );
        } else {
-           if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
+           if ( comcmp( start, start+linelength, comment->c_end, 0 ) == 0 ) {
                compop();
-               consumetomark( start, stop, in );
+               CONSUME( in, linelength + crlflength );
                return( CH_DONE );
            }
        }
 
-       consumetomark( start, stop, in );
+       CONSUME( in, linelength + crlflength );
     }
 }
 
 static const char      *rmjobfailed = "Failed\n";
 static const char      *rmjobok = "Ok\n";
 
-cq_rmjob( in, out )
+int cq_rmjob( in, out )
     struct papfile     *in, *out;
 {
     char               *start, *stop, *p;
+    int                        linelength, crlflength;
     int                        job;
 
-    switch ( markline( &start, &stop, in )) {
+    switch ( markline( in, &start, &linelength, &crlflength )) {
     case 0 :
        return( 0 );
 
@@ -526,6 +618,8 @@ cq_rmjob( in, out )
        return( CH_MORE );
     }
 
+    stop = start + linelength;
+
     for ( p = start; p < stop; p++ ) {
        if ( *p == ' ' || *p == '\t' ) {
            break;
@@ -540,22 +634,23 @@ cq_rmjob( in, out )
     *stop = '\0';
     if ( p < stop && ( job = atoi( p )) > 0 ) {
        lp_rmjob( job );
-       APPEND( out, rmjobok, strlen( rmjobok ));
+       append( out, rmjobok, strlen( rmjobok ));
     } else {
-       APPEND( out, rmjobfailed, strlen( rmjobfailed ));
+       append( out, rmjobfailed, strlen( rmjobfailed ));
     }
 
     compop();
-    consumetomark( start, stop, in );
+    CONSUME( in, linelength + crlflength );
     return( CH_DONE );
 }
 
-cq_listq( in, out )
+int cq_listq( in, out )
     struct papfile     *in, *out;
 {
-    char               *start, *stop;
+    char               *start;
+    int                        linelength, crlflength;
 
-    switch ( markline( &start, &stop, in )) {
+    switch ( markline( in, &start, &linelength, &crlflength )) {
     case 0 :
        return( 0 );
 
@@ -564,25 +659,95 @@ cq_listq( in, out )
     }
 
     if ( lp_queue( out )) {
-       syslog( LOG_ERR, "cq_listq: lp_queue failed" );
+       LOG(log_error, logtype_papd, "cq_listq: lp_queue failed" );
     }
 
     compop();
-    consumetomark( start, stop, in );
+    CONSUME( in, linelength + crlflength );
     return( CH_DONE );
 }
 
+
+/*
+ * Handler for RBILogin
+ */
+
+static struct uam_obj *papd_uam = NULL;
+static const char *rbiloginok = "0\r";
+static const char *rbiloginbad = "-1\r";
+static const char *rbiloginerrstr = "%%[Error: SecurityError; \
+SecurityViolation: Unknown user, incorrect password or log on is \
+disabled ]%%\r%%[Flushing: rest of job (to end-of-file) will be \
+ignored ]%%\r";
+
+int cq_rbilogin( in, out )
+    struct papfile      *in, *out;
+{
+    char               *start, *stop, *p, *begin;
+    int                        linelength, crlflength;
+    char               username[9] = "\0";
+    struct papd_comment        *comment = compeek();
+    char               uamtype[20] = "\0";
+
+    for (;;) {
+        switch ( markline( in, &start, &linelength, &crlflength )) {
+        case 0 :
+            return( 0 );
+
+        case -1 :
+            return( CH_MORE );
+        }
+
+       stop = start + linelength;
+
+        if ( comgetflags() == 0 ) { /* first line */
+           begin = start + strlen(comment->c_begin);
+           p = begin;
+
+           while (*p != ' ') {
+               p++;
+           }
+
+           strncat(uamtype, begin, p - begin);
+
+           if ((papd_uam = auth_uamfind(UAM_SERVER_PRINTAUTH,
+                               uamtype, strlen(uamtype))) == NULL) {
+               LOG(log_info, logtype_papd, "Could not find uam: %s", uamtype);
+               append(out, rbiloginbad, strlen(rbiloginbad));
+               append(out, rbiloginerrstr, strlen(rbiloginerrstr));
+           } else {
+                if ( (papd_uam->u.uam_printer(p,stop,username,out)) == 0 ) {
+                    lp_person( username );
+                } else {
+                    append(out, rbiloginbad, strlen( rbiloginbad));
+                    append(out, rbiloginerrstr, strlen(rbiloginerrstr));
+                }
+           }
+            comsetflags( 1 );
+        } else {
+            if ( comcmp( start, stop, comment->c_end, 0 ) == 0 ) {
+                compop();
+                return( CH_DONE );
+            }
+        }
+
+        CONSUME( in, linelength + crlflength );
+    }
+}
+
+
 /*
  * All queries start with %%?Begin and end with %%?End.  Note that the
  * "Begin"/"End" general queries have to be last.
  */
-struct comment queries[] = {
+struct papd_comment    queries[] = {
 #ifdef KRB
     { "%%Login: UMICHKerberosIV", 0,                   cq_k4login,     0 },
     { "%%?BeginUAMethodsQuery",        "%%?EndUAMethodsQuery:", cq_uameth, C_FULL },
-#endif KRB
+#endif /* KRB */
     { "%UMICHListQueue", 0,                            cq_listq, C_FULL },
     { "%UMICHDeleteJob", 0,                            cq_rmjob,       0 },
+    { "%%?BeginQuery: RBILogin ", "%%?EndQuery",       cq_rbilogin,    0 },
     { "%%?BeginQuery",         "%%?EndQuery",          cq_query,       0 },
     { "%%?BeginFeatureQuery",  "%%?EndFeatureQuery",   cq_feature,     0 },
     { "%%?BeginFontQuery",     "%%?EndFontQuery",      cq_font,        0 },