diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/printing/printing.c | 67 |
4 files changed, 56 insertions, 17 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 6911c43be7..b68209434f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1544,6 +1544,7 @@ int _lp_force_dir_security_mode(int ); int lp_max_connections(int ); int lp_defaultcase(int ); int lp_minprintspace(int ); +int lp_maxprintjobs(int ); int lp_printing(int ); int lp_oplock_contention_limit(int ); int lp_write_cache_size(int ); diff --git a/source3/include/smb.h b/source3/include/smb.h index 16fb954ad8..b1efb4260a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -660,6 +660,7 @@ enum {LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR}; typedef struct { fstring message; + int qcount; int status; } print_status_struct; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 09ecdf83fa..bad2ad2fdb 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -316,6 +316,7 @@ typedef struct char *szVfsObjectFile; char *szVfsOptions; int iMinPrintSpace; + int iMaxPrintJobs; int iWriteCacheSize; int iCreate_mask; int iCreate_force_mode; @@ -429,6 +430,7 @@ static service sDefault = { NULL, /* vfs object */ NULL, /* vfs options */ 0, /* iMinPrintSpace */ + 1000, /* iMaxPrintJobs */ 0, /* iWriteCacheSize */ 0744, /* iCreate_mask */ 0000, /* iCreate_force_mode */ @@ -793,6 +795,7 @@ static struct parm_struct parm_table[] = { {"Printing Options", P_SEP, P_SEPARATOR}, + {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT}, {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT}, {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT}, {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0}, @@ -1578,6 +1581,7 @@ FN_LOCAL_INTEGER(_lp_force_dir_security_mode, iDir_Security_force_mode) FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections) FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase) FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace) +FN_LOCAL_INTEGER(lp_maxprintjobs, iMaxPrintJobs) FN_LOCAL_INTEGER(lp_printing, iPrinting) FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit) FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index d71ea25d0d..d856023567 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -60,7 +60,7 @@ static pid_t local_pid; #define UNIX_JOB_START PRINT_MAX_JOBID #define PRINT_SPOOL_PREFIX "smbprn." -#define PRINT_DATABASE_VERSION 1 +#define PRINT_DATABASE_VERSION 2 /**************************************************************************** initialise the printing backend. Called once at startup. @@ -381,6 +381,7 @@ static void print_queue_update(int snum) safe_free(tstruct.queue); /* store the queue status structure */ + status.qcount = qcount; slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); data.dptr = (void *)&status; data.dsize = sizeof(status); @@ -628,6 +629,49 @@ int print_job_write(int jobid, const char *buf, int size) return write(fd, buf, size); } +/**************************************************************************** + Check if the print queue has been updated recently enough. +****************************************************************************/ + +static BOOL print_cache_expired(int snum) +{ + fstring key; + time_t t2, t = time(NULL); + slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); + t2 = tdb_fetch_int(tdb, key); + if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { + return True; + } + return False; +} + +/**************************************************************************** + Determine the number of jobs in a queue. +****************************************************************************/ + +static int print_queue_length(int snum) +{ + fstring keystr; + TDB_DATA data, key; + print_status_struct status; + + /* make sure the database is up to date */ + if (print_cache_expired(snum)) print_queue_update(snum); + + /* also fetch the queue status */ + ZERO_STRUCTP(&status); + slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum)); + key.dptr = keystr; + key.dsize = strlen(keystr); + data = tdb_fetch(tdb, key); + if (data.dptr) { + if (data.dsize == sizeof(status)) { + memcpy(&status, data.dptr, sizeof(status)); + } + free(data.dptr); + } + return status.qcount; +} /*************************************************************************** start spooling a job - return the jobid @@ -670,6 +714,11 @@ int print_job_start(struct current_user *user, int snum, char *jobname) return -1; } + if (print_queue_length(snum) > lp_maxprintjobs(snum)) { + errno = ENOSPC; + return -1; + } + /* create the database entry */ ZERO_STRUCT(pjob); pjob.pid = local_pid; @@ -822,22 +871,6 @@ BOOL print_job_end(int jobid) return True; } -/**************************************************************************** - Check if the print queue has been updated recently enough. -****************************************************************************/ - -static BOOL print_cache_expired(int snum) -{ - fstring key; - time_t t2, t = time(NULL); - slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum)); - t2 = tdb_fetch_int(tdb, key); - if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) { - return True; - } - return False; -} - /* utility fn to enumerate the print queue */ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { |