/* Copyright (c) 2008-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file prqd.h Main header file for the prqd project. */ #ifndef PRQD_H_INCLUDED #define PRQD_H_INCLUDED #include #if DK_HAVE_DB_H /** Flag: Use Berkeley DB. */ #define USE_DB_H 1 #endif #if DK_HAVE_NDBM_H /** Flag: use NDBM. */ #define USE_NDBM_H 1 #if defined(USE_GDBM_H) #undef USE_GDBM_H #endif #else #if DK_HAVE_GDBM_H /** Flag: Use GDBM. */ #define USE_GDBM_H 1 #if defined(USE_NDBM_H) /** Flag: Use NDBM. */ #undef USE_NDBM_H #endif #endif #endif /** Log priority: None. */ #define PRQD_PRIO_NONE 0 /** Log priority: Fatal error. */ #define PRQD_PRIO_FATAL 1 /** Log priority: Error. */ #define PRQD_PRIO_ERROR 2 /** Log priority: Warning. */ #define PRQD_PRIO_WARNING 3 /** Log priority: Informational message. */ #define PRQD_PRIO_INFO 4 /** Log priority: Progress indicator message. */ #define PRQD_PRIO_PROGRESS 5 /** Log priority: Debug message. */ #define PRQD_PRIO_DEBUG 6 /** State: start of configuration file. */ #define PRQD_RDCONF_STATE_START 0 /** State: Reading options. */ #define PRQD_RDCONF_STATE_OPTIONS 1 /** State: Reading printer class information. */ #define PRQD_RDCONF_STATE_CLASS 2 /** State: Reading printer information. */ #define PRQD_RDCONF_STATE_PRINTER 3 #include #if DK_HAVE_STDLIB_H #include #endif #if DK_HAVE_UNISTD_H #include #endif #if DK_HAVE_SIGNAL_H #include #endif #if DK_TIME_WITH_SYS_TIME #include #include #else #if DK_HAVE_TIME_H #include #else #if DK_HAVE_SYS_TIME_H #include #endif #endif #endif #if DK_HAVE_SYSLOG #include #endif #if DK_HAVE_STDARG_H #include #endif #if DK_HAVE_STRING_H #include #endif #if DK_HAVE_STRINGS_H #include #endif #if DK_HAVE_SYS_SOCKET_H #include #else #error "No sys/socket.h available!" #endif #if DK_HAVE_NETINET_IN_H #include #endif #if DK_HAVE_ARPA_INET_H #include #endif #if DK_HAVE_NETDB_H #include #endif #if DK_HAVE_SELECT_H #include #endif #if DK_HAVE_SYS_UN_H #include #endif #if DK_HAVE_ERRNO_H #include #endif #if DK_HAVE_PWD_H #include #endif #if DK_HAVE_GRP_H #include #endif #if DK_HAVE_MATH_H #include #endif #if USE_DB_H #include #endif #if USE_GDBM_H #include #endif #if USE_NDBM_H #include #endif #include #include #include #include #include #include /** Default line buffer size. */ #define PRQD_BUFFER_SIZE 4096 /** Default database entry size. */ #define PRQD_DBENTRY_SIZE 128 /** Limit entry type: General default. */ #define LIMIT_ENTRY_TYPE_DEFAULT 0 /** Limit entry type: Group limit. */ #define LIMIT_ENTRY_TYPE_GROUP 1 /** Limit entry type: User limit. */ #define LIMIT_ENTRY_TYPE_USER 2 /** Limit value type: Access to printer denied. */ #define LIMIT_VALUE_DENIED 0 /** Limit value type: Number of pages restricted. */ #define LIMIT_VALUE_PAGES 1 /** Limit value type: Unrestricted access to printer. */ #define LIMIT_VALUE_UNLIMITED 2 /** Deny action: Remove job. */ #define DENY_ACTION_REMOVE 0 /** Deny action: Hold job. */ #define DENY_ACTION_HOLD 1 /** Deny action: Report failure. */ #define DENY_ACTION_FAIL 2 /** UNIX socket address type. */ typedef struct sockaddr_un SOUN; /** Size of UNIX socket address type. */ #define SZSOUN sizeof(SOUN) /** Limit entry. */ typedef struct { int tp; /**< Limit entry type, LIMIT_ENTRY_TYPE_xxx. */ char *who; /**< User or group name. */ int val; /**< Limit value type, LIMIT_VALUE_xxx. */ unsigned long p; /**< Number of pages. */ } LE; /** Printer class. */ typedef struct { char *n; /**< Class name. */ dk_storage_t *l; /**< Limit entries. */ dk_storage_iterator_t *li; /**< Iterator for limit entries. */ int da; /**< Deny action, DENY_ACTION_xxx */ int wi; /**< Flag: Write info files */ } PC; /** Printer. */ typedef struct _printer_ { char *n; /**< Printer name. */ PC *pc; /**< Printer class. */ struct _printer_ *alt; /**< Alias target. */ char *cj; /**< Current job "user:pages_at_start" */ size_t sz_cj; /**< Size of cj buffer in bytes. */ } PR; /** Complete configuration file. */ typedef struct { dk_storage_t *cl; /**< Printer classes storage. */ dk_storage_iterator_t *cli; /**< Printer classes storage iterator. */ dk_storage_t *pr; /**< Printers storage. */ dk_storage_iterator_t *pri; /**< Printers storage iterator. */ char *dbname; /**< File name of database file. */ char *sockname; /**< File name of socket. */ char *rau; /**< User name to run as. */ char *rag; /**< Group name to run as. */ unsigned long to_seconds; /**< Socket timeout (seconds). */ unsigned long to_microseconds; /**< Socket timeout (microseconds). */ char *userinfdir; /**< User information directory */ int do_balance; /**< Balance limit overflow to account. */ } PRQDC; /** Database type: Unknown. */ #define DATABASE_TYPE_UNKNOWN 0 /** Database type: Berkeley DB. */ #define DATABASE_TYPE_BDB 1 /** Database type: GDBM. */ #define DATABASE_TYPE_GDBM 2 /** Database type: NDBM. */ #define DATABASE_TYPE_NDBM 3 /** Request type: Start of job. */ #define PRQD_RQ_T_JOBSTART 0 /** Request type: Start of file. */ #define PRQD_RQ_T_FILESTART 1 /** Request type: Start. */ #define PRQD_RQ_T_START 2 /** Request type: End. */ #define PRQD_RQ_T_END 3 /** Request type: End of file. */ #define PRQD_RQ_T_FILEEND 4 /** Request type: End of job. */ #define PRQD_RQ_T_JOBEND 5 /** Request type: Info. */ #define PRQD_RQ_T_INFO 6 /** Request type: Control. */ #define PRQD_RQ_T_CONTROL 7 /** Prqd program data. */ typedef struct { int ec; /**< Exit code. */ int deb; /**< Flag: Debugging mode. */ int e1; /**< Flag: Serious error, exit program. */ int e2; /**< Flag: Recovery attempt, reconfiguration. */ int e3; /**< Flag: Error in a session. */ time_t last_log_time; /**< Timestamp of last log message. */ PRQDC *prqdc; /**< Current printer class to deal with. */ int ss; /**< Session socket. */ int sock; /**< Listen socket. */ int backlog; /**< Listen backlog. */ int allow_file_logging; /**< Flag: Allow logging to file (prqd only). */ struct { int tp; /**< Database type. */ union { struct { char *fn; /**< Database file name. */ #if USE_DB_H DB *dbp; /**< Pointer to database structure. */ #endif } bdb; /**< Details for Berkeley DB backend. */ struct { char *fn; /**< Database file name. */ char *myfn; /**< Private copy of database file name. */ } gdbm; /**< Details for GDBM backend. */ struct { char *fn; /**< Database file name. */ #if USE_NDBM_H DBM *db; /**< Pointer to database structure. */ #endif } ndbm; /**< Details for NDBM backend. */ } c; } dbbe; /**< Details about database backend. */ char *b1; /**< Input line buffer. */ size_t sz_b1; /**< Size of b1 in bytes. */ char *b2; /**< Output buffer. */ size_t sz_b2; /**< Size of b2 in bytes. */ char *b3; /**< Buffer for the user's primary group name */ size_t sz_b3; /**< Size of b3 in bytes. */ char *dbkey; /**< Database key buffer. */ size_t sz_dbkey; /**< Size of dbkey in bytes. */ char *dbval; /**< Database value buffer. */ size_t sz_dbval; /**< Size of dbval in bytes. */ unsigned char must_respond; /**< Flag: Must send response. */ char **args; /**< 53 elements. */ int rqt; /**< Request type PRQD_RQ_T_xxx. */ /* Data following here is possibly destroyed by later operations */ char *rqtstr; /**< Pointer to request type. */ char *uname; /**< Pointer to user name. */ char *pname; /**< Pointer to printer name. */ char *rname; /**< Real printer name (aliases resolved) */ char *tname; /**< ? */ char *pages; /**< ? */ char *cname; /**< Pointer to printer class name. */ char *hname; /**< Pointer to host name. */ int limit_type; /**< Limit type. */ unsigned long limit_pages; /**< Limit pages. */ /* Set in control requests. */ char *cr_cname; /**< Pointer to control request subtype. */ char *cr_uname; /**< Pointer to user name. */ char *cr_pages; /**< Pointer to number of pages. */ char *cr_pname; /**< Pointer to printer name. */ long cr_deltap; /**< Number of pages to add. */ dk_storage_t *cr_st; /**< Storage for request args. */ dk_storage_iterator_t *cr_sti; /**< Iterator for storage. */ } PJ; /** Key/value pair. */ typedef struct { char *k; /**< Key. */ char *v; /**< Value. */ } KEYVALUE; #if DK_HAVE_PROTOTYPES /** Database traversal function. @param pj Print job description. @param k Buffer for key. @param v Buffer for value. @return 1 on success, 0 on non-critical error (continue traversal), <0 on critical error (stop traversal). */ typedef int PRQD_TRAVERSE_FCT(PJ *pj, char *k, char *v); #else typedef int PRQD_TRAVERSE_FCT(); #endif #if defined(EXTERN) #undef EXTERN #endif #if PRQDLOG_C #define EXTERN /* nix */ #else #if DK_HAVE_PROTOTYPES #define EXTERN /* nix */ #else #define EXTERN extern #endif #endif #if defined(__cplusplus) extern "C" { #endif EXTERN int prqdlog DK_PR((PJ *pj, int prio, char *f, ...)); #if defined(__cplusplus) } #endif #if defined(EXTERN) #undef EXTERN #endif #if PRQDPJ_C #define EXTERN /* nix */ #else #if DK_HAVE_PROTOTYPES #define EXTERN /* nix */ #else #define EXTERN extern #endif #endif #if defined(__cplusplus) extern "C" { #endif EXTERN void prqd_pj_init DK_PR((PJ *pj)); EXTERN void prqd_pj_set_arg DK_PR((PJ *pj, char c, char *s)); EXTERN char *prqd_pj_get_arg DK_PR((PJ *pj, char c)); EXTERN void prqd_pj_set_all_args DK_PR((PJ *pj, char *il)); EXTERN int prqd_pj_is_acceptable_name DK_PR((char *s)); EXTERN void prqd_pj_get_rq_type DK_PR((PJ *pj, char *s)); EXTERN void prqd_pj_get_names DK_PR((PJ *pj)); EXTERN void prqd_pj_find_limit DK_PR((PJ *pj)); EXTERN void prqd_pj_use_deny_action DK_PR((PJ *pj)); #if defined(__cplusplus) } #endif #if defined(EXTERN) #undef EXTERN #endif #if PRQD_C #define EXTERN /* nix */ #else #if DK_HAVE_PROTOTYPES #define EXTERN /* nix */ #else #define EXTERN extern #endif #endif #if defined(__cplusplus) extern "C" { #endif EXTERN void prqd_write_userinfo_file DK_PR((PJ *pj, char *u, char *c)); #if defined(__cplusplus) } #endif #if defined(EXTERN) #undef EXTERN #endif #if PRQDCONF_C #define EXTERN /* nix */ #else #if DK_HAVE_PROTOTYPES #define EXTERN /* nix */ #else #define EXTERN extern #endif #endif #if defined(__cplusplus) extern "C" { #endif EXTERN char *prqdconf_get_progname DK_PR((void)); EXTERN int prqdconf_get_debug DK_PR((PJ *pj)); EXTERN char *prqdconf_get_logfile DK_PR((void)); EXTERN char *prqdconf_get_cfgfile DK_PR((void)); EXTERN PRQDC *prqdconf_new_prqdc DK_PR((PJ *pj, char *n)); EXTERN void prqdconf_delete_prqdc DK_PR((PRQDC *prqdc)); EXTERN char *prqd_get_kw DK_PR((size_t s)); #if defined(__cplusplus) } #endif #if defined(EXTERN) #undef EXTERN #endif #if PRQDBE_C #define EXTERN /* nix */ #else #if DK_HAVE_PROTOTYPES #define EXTERN /* nix */ #else #define EXTERN extern #endif #endif #if defined(__cplusplus) extern "C" { #endif EXTERN void prqdbe_change_ownership DK_PR((PJ *pj, uid_t u, gid_t g)); EXTERN int prqdbe_open DK_PR((PJ *pj)); EXTERN void prqdbe_close DK_PR((PJ *pj)); EXTERN int prqdbe_store DK_PR((PJ *pj, char *k, char *v)); EXTERN size_t prqdbe_fetch DK_PR((PJ *pj, char *k, char *v, size_t sz)); EXTERN int prqdbe_traverse DK_PR((PJ *pj, PRQD_TRAVERSE_FCT *f)); EXTERN int prqdbe_delete DK_PR((PJ *pj, char *k)); #if defined(__cplusplus) } #endif #if defined(EXTERN) #undef EXTERN #endif #if PRQDCTRL_C #define EXTERN /* nix */ #else #if DK_HAVE_PROTOTYPES #define EXTERN /* nix */ #else #define EXTERN extern #endif #endif #if defined(__cplusplus) extern "C" { #endif EXTERN int prqdctrl_request DK_PR((PJ *pj, char *args)); #if defined(__cplusplus) } #endif /* ##### delete this for real quota enforcement */ /* define ALWAYS_PERMIT 1 */ #endif /* PRQD_H_INCLUDED */