summaryrefslogtreecommitdiff
path: root/source3/printing/printing.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/printing/printing.c')
-rw-r--r--source3/printing/printing.c399
1 files changed, 178 insertions, 221 deletions
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 7bfce43af6..cb689c05d6 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -39,98 +39,97 @@ static struct printif *current_printif = &generic_printif;
jobids are assigned when a job starts spooling.
*/
-static pid_t local_pid;
-
-/* Mapping between printer names and queue id's in job id's. */
-struct printer_queueid_map {
- struct printer_queueid_map *next, *prev;
- char *printername;
- uint32 queueid;
-};
-
-static struct printer_queueid_map *printer_queueid_map_head;
-static uint32 last_queueid;
-
-#define QUEUEID_BITS 12
-#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1)
-#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 )
+/***************************************************************************
+ Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
+ bit RPC jobids.... JRA.
+***************************************************************************/
-/****************************************************************************
- Create an association between a printer name and a queueid. Used to encode
- the printer queueid in jobid's.
- This could be converted to use an internal tdb if searching the list is
- too slow. JRA.
-****************************************************************************/
+static TDB_CONTEXT *rap_tdb;
+static uint16 next_rap_jobid;
-BOOL create_printer_queueid(const char *printername)
+uint16 pjobid_to_rap(int snum, uint32 jobid)
{
- struct printer_queueid_map *p;
+ uint16 rap_jobid;
+ TDB_DATA data, key;
+ char jinfo[8];
- for (p = printer_queueid_map_head; p; p = p->next) {
- if (strequal(p->printername, printername))
- return True;
+ if (!rap_tdb) {
+ /* Create the in-memory tdb. */
+ rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
+ if (!rap_tdb)
+ return 0;
}
- p = (struct printer_queueid_map *)malloc(sizeof(*p));
- if (!p) {
- DEBUG(0,("create_printer_queueid: malloc fail !\n"));
- return False;
- }
- ZERO_STRUCTP(p);
- p->printername = strdup(printername);
- if (!p->printername) {
- DEBUG(0,("create_printer_queueid: malloc fail !\n"));
- SAFE_FREE(p);
- return False;
- }
- p->queueid = (++last_queueid);
- if (p->queueid > QUEUEID_MASK) {
- DEBUG(0,("create_printer_queueid: malloc fail !\n"));
- SAFE_FREE(p->printername);
- SAFE_FREE(p);
- return False;
+ SIVAL(&jinfo,0,(int32)snum);
+ SIVAL(&jinfo,4,jobid);
+
+ key.dptr = (char *)&jinfo;
+ key.dsize = sizeof(jinfo);
+ data = tdb_fetch(rap_tdb, key);
+ if (data.dptr && data.dsize == sizeof(uint16)) {
+ memcpy(&rap_jobid, data.dptr, sizeof(uint16));
+ SAFE_FREE(data.dptr);
+ return rap_jobid;
}
- DLIST_ADD(printer_queueid_map_head, p);
- return True;
+ /* Not found - create and store mapping. */
+ rap_jobid = ++next_rap_jobid;
+ if (rap_jobid == 0)
+ rap_jobid = ++next_rap_jobid;
+ data.dptr = (char *)&rap_jobid;
+ data.dsize = sizeof(rap_jobid);
+ tdb_store(rap_tdb, key, data, TDB_REPLACE);
+ tdb_store(rap_tdb, data, key, TDB_REPLACE);
+ return rap_jobid;
}
-void set_register_printer_fn(void)
+BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
{
- extern BOOL (*register_printer_fn)(const char *);
- register_printer_fn = create_printer_queueid;
-}
-
-/****************************************************************************
- Lookups.
-****************************************************************************/
+ TDB_DATA data, key;
+ char jinfo[8];
-static uint32 get_printer_queueid_byname(const char *printername)
-{
- struct printer_queueid_map *p;
+ if (!rap_tdb)
+ return False;
- for (p = printer_queueid_map_head; p; p = p->next) {
- if (strequal(p->printername, printername))
- return p->queueid;
+ key.dptr = (char *)&rap_jobid;
+ key.dsize = sizeof(rap_jobid);
+ data = tdb_fetch(rap_tdb, key);
+ if (data.dptr && data.dsize == sizeof(jinfo)) {
+ *psnum = IVAL(&jinfo,0);
+ *pjobid = IVAL(&jinfo,4);
+ SAFE_FREE(data.dptr);
+ return True;
}
- return 0;
+ return False;
}
-/****************************************************************************
- Lookups.
-****************************************************************************/
-
-static const char *get_printer_name_byjobid(uint32 jobid)
+static void rap_jobid_delete(int snum, uint32 jobid)
{
- struct printer_queueid_map *p;
- uint32 queueid = (((jobid)>>20) & QUEUEID_MASK);
+ TDB_DATA key, data;
+ uint16 rap_jobid;
+ char jinfo[8];
- for (p = printer_queueid_map_head; p; p = p->next) {
- if (p->queueid == queueid)
- return p->printername;
- }
- return NULL;
+ if (!rap_tdb)
+ return;
+
+ SIVAL(&jinfo,0,(int32)snum);
+ SIVAL(&jinfo,4,jobid);
+
+ key.dptr = (char *)&jinfo;
+ key.dsize = sizeof(jinfo);
+ data = tdb_fetch(rap_tdb, key);
+ if (!data.dptr || (data.dsize != sizeof(uint16)))
+ return;
+
+ memcpy(&rap_jobid, data.dptr, sizeof(uint16));
+ SAFE_FREE(data.dptr);
+ data.dptr = (char *)&rap_jobid;
+ data.dsize = sizeof(rap_jobid);
+ tdb_delete(rap_tdb, key);
+ tdb_delete(rap_tdb, data);
}
+static pid_t local_pid;
+
static int get_queue_status(int, print_status_struct *);
#define MAX_PRINT_DBS_OPEN 1
@@ -186,9 +185,14 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
DLIST_ADD(print_db_head, p);
}
- pstrcpy(printdb_path, lock_path(printername));
+ pstrcpy(printdb_path, lock_path("printing/"));
+ pstrcat(printdb_path, printername);
pstrcat(printdb_path, ".tdb");
+
+ become_root();
p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ unbecome_root();
+
if (!p->tdb) {
DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
printdb_path ));
@@ -200,14 +204,6 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
return p;
}
-static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
-{
- const char *printername = get_printer_name_byjobid(jobid);
- if (!printername)
- return NULL;
- return get_print_db_byname(printername);
-}
-
/****************************************************************************
Initialise the printing backend. Called once at startup.
Does not survive a fork
@@ -215,20 +211,28 @@ static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
BOOL print_backend_init(void)
{
- struct printer_queueid_map *p;
char *sversion = "INFO/version";
+ pstring printing_path;
+ int services = lp_numservices();
+ int snum;
if (local_pid == sys_getpid())
return True;
unlink(lock_path("printing.tdb"));
+ pstrcpy(printing_path,lock_path("printing"));
+ mkdir(printing_path,0755);
+
local_pid = sys_getpid();
/* handle a Samba upgrade */
- for (p = printer_queueid_map_head; p; p = p->next) {
- struct tdb_print_db *pdb = get_print_db_byname(p->printername);
+ for (snum = 0; snum < services; snum++) {
+ struct tdb_print_db *pdb;
+ if (!lp_print_ok(snum))
+ continue;
+ pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
continue;
tdb_lock_bystring(pdb->tdb, sversion);
@@ -286,11 +290,11 @@ static TDB_DATA print_key(uint32 jobid)
Useful function to find a print job in the database.
****************************************************************************/
-static struct printjob *print_job_find(uint32 jobid)
+static struct printjob *print_job_find(int snum, uint32 jobid)
{
static struct printjob pjob;
TDB_DATA ret;
- struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+ struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
return NULL;
@@ -334,11 +338,16 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
uint32 sysjob_to_jobid(int unix_jobid)
{
- struct printer_queueid_map *p;
+ int services = lp_numservices();
+ int snum;
+
sysjob_to_jobid_value = (uint32)-1;
- for (p = printer_queueid_map_head; p; p = p->next) {
- struct tdb_print_db *pdb = get_print_db_byname(p->printername);
+ for (snum = 0; snum < services; snum++) {
+ struct tdb_print_db *pdb;
+ if (!lp_print_ok(snum))
+ continue;
+ pdb = get_print_db_byname(lp_const_servicename(snum));
if (pdb)
tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
if (sysjob_to_jobid_value != (uint32)-1)
@@ -385,14 +394,10 @@ static uint32 map_to_spoolss_status(uint32 lpq_status)
return 0;
}
-static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
+static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
struct printjob *new_data)
{
BOOL new_job = False;
- int snum = print_job_snum(jobid);
-
- if (snum == -1)
- return;
if (!old_data)
new_job = True;
@@ -427,11 +432,11 @@ static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
Store a job structure back to the database.
****************************************************************************/
-static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
+static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
{
TDB_DATA old_data, new_data;
BOOL ret;
- struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+ struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
return False;
@@ -450,7 +455,7 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) {
pjob_store_notify(
- jobid, (struct printjob *)old_data.dptr,
+ snum, jobid, (struct printjob *)old_data.dptr,
(struct printjob *)new_data.dptr);
free(old_data.dptr);
}
@@ -462,12 +467,11 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
Remove a job structure from the database.
****************************************************************************/
-static void pjob_delete(uint32 jobid)
+static void pjob_delete(int snum, uint32 jobid)
{
- int snum;
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
uint32 job_status = 0;
- struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+ struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
return;
@@ -486,7 +490,6 @@ static void pjob_delete(uint32 jobid)
JOB_STATUS_DELETED for the port monitor to delete the job
properly. */
- snum = print_job_snum(jobid);
job_status |= JOB_STATUS_DELETING;
notify_job_status(snum, jobid, job_status);
@@ -496,6 +499,7 @@ static void pjob_delete(uint32 jobid)
/* Remove from printing.tdb */
tdb_delete(pdb->tdb, print_key(jobid));
+ rap_jobid_delete(snum, jobid);
}
/****************************************************************************
@@ -523,13 +527,12 @@ static uint32 print_parse_jobid(char *fname)
static void print_unix_job(int snum, print_queue_struct *q)
{
- uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum));
- uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid);
+ uint32 jobid = q->job + UNIX_JOB_START;
struct printjob pj, *old_pj;
/* Preserve the timestamp on an existing unix print job */
- old_pj = print_job_find(jobid);
+ old_pj = print_job_find(snum, jobid);
ZERO_STRUCT(pj);
@@ -546,7 +549,7 @@ static void print_unix_job(int snum, print_queue_struct *q)
fstrcpy(pj.user, q->fs_user);
fstrcpy(pj.queuename, lp_const_servicename(snum));
- pjob_store(jobid, &pj);
+ pjob_store(snum, jobid, &pj);
}
@@ -561,7 +564,6 @@ struct traverse_struct {
static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
{
- uint32 queueid;
struct traverse_struct *ts = (struct traverse_struct *)state;
struct printjob pjob;
uint32 jobid;
@@ -577,18 +579,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
return 0;
}
- queueid = get_printer_queueid_byname(pjob.queuename);
-
if (!pjob.smbjob) {
/* remove a unix job if it isn't in the system queue any more */
for (i=0;i<ts->qcount;i++) {
- uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid));
+ uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
if (jobid == u_jobid)
break;
}
if (i == ts->qcount)
- pjob_delete(jobid);
+ pjob_delete(ts->snum, jobid);
else
ts->total_jobs++;
return 0;
@@ -600,14 +600,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
exist then kill it. This cleans up after smbd
deaths */
if (!process_exists(pjob.pid))
- pjob_delete(jobid);
+ pjob_delete(ts->snum, jobid);
else
ts->total_jobs++;
return 0;
}
for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid);
+ uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
if (jobid == curr_jobid)
break;
}
@@ -627,7 +627,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
submitted less than lp_lpqcachetime() seconds ago. */
if ((cur_t - pjob.starttime) > lp_lpqcachetime())
- pjob_delete(jobid);
+ pjob_delete(ts->snum, jobid);
else
ts->total_jobs++;
}
@@ -688,7 +688,7 @@ static pid_t get_updating_pid(fstring printer_name)
in the tdb.
****************************************************************************/
-static void set_updating_pid(fstring printer_name, BOOL delete)
+static void set_updating_pid(const fstring printer_name, BOOL delete)
{
fstring keystr;
TDB_DATA key;
@@ -813,7 +813,7 @@ static void print_queue_update(int snum)
}
/* we have an active SMB print job - update its status */
- pjob = print_job_find(jobid);
+ pjob = print_job_find(snum, jobid);
if (!pjob) {
/* err, somethings wrong. Probably smbd was restarted
with jobs in the queue. All we can do is treat them
@@ -825,7 +825,7 @@ static void print_queue_update(int snum)
pjob->sysjob = queue[i].job;
pjob->status = queue[i].status;
- pjob_store(jobid, pjob);
+ pjob_store(snum, jobid, pjob);
}
/* now delete any queued entries that don't appear in the
@@ -871,36 +871,21 @@ static void print_queue_update(int snum)
Check if a jobid is valid. It is valid if it exists in the database.
****************************************************************************/
-BOOL print_job_exists(uint32 jobid)
+BOOL print_job_exists(int snum, uint32 jobid)
{
- struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+ struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
return False;
return tdb_exists(pdb->tdb, print_key(jobid));
}
/****************************************************************************
- Work out which service a jobid is for.
- Note that we have to look up by queue name to ensure that it works for
- other than the process that started the job.
-****************************************************************************/
-
-int print_job_snum(uint32 jobid)
-{
- struct printjob *pjob = print_job_find(jobid);
- if (!pjob)
- return -1;
-
- return find_service(pjob->queuename);
-}
-
-/****************************************************************************
Give the fd used for a jobid.
****************************************************************************/
-int print_job_fd(uint32 jobid)
+int print_job_fd(int snum, uint32 jobid)
{
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
if (!pjob)
return -1;
/* don't allow another process to get this info - it is meaningless */
@@ -915,9 +900,9 @@ int print_job_fd(uint32 jobid)
has not been spooled.
****************************************************************************/
-char *print_job_fname(uint32 jobid)
+char *print_job_fname(int snum, uint32 jobid)
{
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
if (!pjob || pjob->spooled || pjob->pid != local_pid)
return NULL;
return pjob->filename;
@@ -927,7 +912,7 @@ char *print_job_fname(uint32 jobid)
Set the place in the queue for a job.
****************************************************************************/
-BOOL print_job_set_place(uint32 jobid, int place)
+BOOL print_job_set_place(int snum, uint32 jobid, int place)
{
DEBUG(2,("print_job_set_place not implemented yet\n"));
return False;
@@ -937,24 +922,24 @@ BOOL print_job_set_place(uint32 jobid, int place)
Set the name of a job. Only possible for owner.
****************************************************************************/
-BOOL print_job_set_name(uint32 jobid, char *name)
+BOOL print_job_set_name(int snum, uint32 jobid, char *name)
{
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
if (!pjob || pjob->pid != local_pid)
return False;
fstrcpy(pjob->jobname, name);
- return pjob_store(jobid, pjob);
+ return pjob_store(snum, jobid, pjob);
}
/****************************************************************************
Delete a print job - don't update queue.
****************************************************************************/
-static BOOL print_job_delete1(uint32 jobid)
+static BOOL print_job_delete1(int snum, uint32 jobid)
{
- struct printjob *pjob = print_job_find(jobid);
- int snum, result = 0;
+ struct printjob *pjob = print_job_find(snum, jobid);
+ int result = 0;
if (!pjob)
return False;
@@ -966,12 +951,6 @@ static BOOL print_job_delete1(uint32 jobid)
if (pjob->status == LPQ_DELETING)
return True;
- snum = print_job_snum(jobid);
- if (snum == -1) {
- DEBUG(5,("print_job_delete1: unknown service number for jobid %u\n", (unsigned int)jobid));
- return False;
- }
-
/* Hrm - we need to be able to cope with deleting a job before it
has reached the spooler. */
@@ -982,7 +961,7 @@ static BOOL print_job_delete1(uint32 jobid)
/* Set the tdb entry to be deleting. */
pjob->status = LPQ_DELETING;
- pjob_store(jobid, pjob);
+ pjob_store(snum, jobid, pjob);
if (pjob->spooled && pjob->sysjob != -1)
result = (*(current_printif->job_delete))(snum, pjob);
@@ -991,7 +970,7 @@ static BOOL print_job_delete1(uint32 jobid)
been spooled. */
if (result == 0)
- pjob_delete(jobid);
+ pjob_delete(snum, jobid);
return (result == 0);
}
@@ -1000,9 +979,9 @@ static BOOL print_job_delete1(uint32 jobid)
Return true if the current user owns the print job.
****************************************************************************/
-static BOOL is_owner(struct current_user *user, uint32 jobid)
+static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
{
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
user_struct *vuser;
if (!pjob || !user)
@@ -1019,17 +998,11 @@ static BOOL is_owner(struct current_user *user, uint32 jobid)
Delete a print job.
****************************************************************************/
-BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
+BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
{
- int snum = print_job_snum(jobid);
BOOL owner;
- if (snum == -1) {
- DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid));
- return False;
- }
-
- owner = is_owner(user, jobid);
+ owner = is_owner(user, snum, jobid);
/* Check access against security descriptor or whether the user
owns their job. */
@@ -1041,7 +1014,7 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
return False;
}
- if (!print_job_delete1(jobid))
+ if (!print_job_delete1(snum, jobid))
return False;
/* force update the database and say the delete failed if the
@@ -1049,17 +1022,17 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
print_queue_update(snum);
- return !print_job_exists(jobid);
+ return !print_job_exists(snum, jobid);
}
/****************************************************************************
Pause a job.
****************************************************************************/
-BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
+BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
{
- struct printjob *pjob = print_job_find(jobid);
- int snum, ret = -1;
+ struct printjob *pjob = print_job_find(snum, jobid);
+ int ret = -1;
if (!pjob || !user)
return False;
@@ -1067,13 +1040,7 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
if (!pjob->spooled || pjob->sysjob == -1)
return False;
- snum = print_job_snum(jobid);
- if (snum == -1) {
- DEBUG(5,("print_job_pause: unknown service number for jobid %u\n", (unsigned int)jobid));
- return False;
- }
-
- if (!is_owner(user, jobid) &&
+ if (!is_owner(user, snum, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
@@ -1104,10 +1071,10 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
Resume a job.
****************************************************************************/
-BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
+BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
{
- struct printjob *pjob = print_job_find(jobid);
- int snum, ret;
+ struct printjob *pjob = print_job_find(snum, jobid);
+ int ret;
if (!pjob || !user)
return False;
@@ -1115,13 +1082,7 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
if (!pjob->spooled || pjob->sysjob == -1)
return False;
- snum = print_job_snum(jobid);
- if (snum == -1) {
- DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid));
- return False;
- }
-
- if (!is_owner(user, jobid) &&
+ if (!is_owner(user, snum, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("resume denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
@@ -1149,10 +1110,10 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
Write to a print file.
****************************************************************************/
-int print_job_write(uint32 jobid, const char *buf, int size)
+int print_job_write(int snum, uint32 jobid, const char *buf, int size)
{
int return_code;
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
if (!pjob)
return -1;
@@ -1163,7 +1124,7 @@ int print_job_write(uint32 jobid, const char *buf, int size)
return_code = write(pjob->fd, buf, size);
if (return_code>0) {
pjob->size += size;
- pjob_store(jobid, pjob);
+ pjob_store(snum, jobid, pjob);
}
return return_code;
}
@@ -1260,18 +1221,24 @@ int print_queue_length(int snum, print_status_struct *pstatus)
static int get_total_jobs(void)
{
- int total_jobs;
- struct printer_queueid_map *p;
+ int total_jobs = 0;
+ int snum;
+ int services = lp_numservices();
- for (p = printer_queueid_map_head; p; p = p->next) {
+ for (snum = 0; snum < services; snum++) {
+ struct tdb_print_db *pdb;
int jobs;
- struct tdb_print_db *pdb = get_print_db_byname(p->printername);
+
+ if (!lp_print_ok(snum))
+ continue;
+
+ pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
continue;
/* make sure the database is up to date */
- if (print_cache_expired(lp_servicenumber(p->printername)))
- print_queue_update(lp_servicenumber(p->printername));
+ if (print_cache_expired(snum))
+ print_queue_update(snum);
jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
if (jobs > 0)
@@ -1294,7 +1261,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
int njobs = 0;
const char *printername = lp_const_servicename(snum);
struct tdb_print_db *pdb = get_print_db_byname(printername);
- uint32 queueid = queueid = get_printer_queueid_byname(printername);
errno = 0;
@@ -1376,10 +1342,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
next_jobid = 1;
for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
- if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid)))
+ if (!print_job_exists(snum, jobid))
break;
}
- if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) {
+ if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) {
DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n",
jobid, next_jobid ));
jobid = -1;
@@ -1392,9 +1358,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
goto fail;
}
- /* Ensure the queuid is added to the jobid. */
- jobid |= QUEUEID_TO_JOBID(queueid);
-
/* we have a job entry - now create the spool file */
slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
@@ -1413,7 +1376,7 @@ to open spool file %s.\n", pjob.filename));
goto fail;
}
- pjob_store(jobid, &pjob);
+ pjob_store(snum, jobid, &pjob);
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
@@ -1425,14 +1388,14 @@ to open spool file %s.\n", pjob.filename));
* tim@fsg.com 09/06/94
*/
if (lp_postscript(snum)) {
- print_job_write(jobid, "%!\n",3);
+ print_job_write(snum, jobid, "%!\n",3);
}
return jobid;
fail:
if (jobid != -1)
- pjob_delete(jobid);
+ pjob_delete(snum, jobid);
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
@@ -1444,9 +1407,9 @@ to open spool file %s.\n", pjob.filename));
Update the number of pages spooled to jobid
****************************************************************************/
-void print_job_endpage(uint32 jobid)
+void print_job_endpage(int snum, uint32 jobid)
{
- struct printjob *pjob = print_job_find(jobid);
+ struct printjob *pjob = print_job_find(snum, jobid);
if (!pjob)
return;
/* don't allow another process to get this info - it is meaningless */
@@ -1454,7 +1417,7 @@ void print_job_endpage(uint32 jobid)
return;
pjob->page_count++;
- pjob_store(jobid, pjob);
+ pjob_store(snum, jobid, pjob);
}
/****************************************************************************
@@ -1463,10 +1426,10 @@ void print_job_endpage(uint32 jobid)
error.
****************************************************************************/
-BOOL print_job_end(uint32 jobid, BOOL normal_close)
+BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
{
- struct printjob *pjob = print_job_find(jobid);
- int snum, ret;
+ struct printjob *pjob = print_job_find(snum, jobid);
+ int ret;
SMB_STRUCT_STAT sbuf;
if (!pjob)
@@ -1475,12 +1438,6 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
if (pjob->spooled || pjob->pid != local_pid)
return False;
- snum = print_job_snum(jobid);
- if (snum == -1) {
- DEBUG(5,("print_job_end: unknown service number for jobid %u\n", (unsigned int)jobid));
- return False;
- }
-
if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
pjob->size = sbuf.st_size;
close(pjob->fd);
@@ -1505,7 +1462,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
pjob->filename, pjob->size ? "deleted" : "zero length" ));
unlink(pjob->filename);
- pjob_delete(jobid);
+ pjob_delete(snum, jobid);
return True;
}
@@ -1518,7 +1475,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
pjob->spooled = True;
pjob->status = LPQ_QUEUED;
- pjob_store(jobid, pjob);
+ pjob_store(snum, jobid, pjob);
/* make sure the database is up to date */
if (print_cache_expired(snum))
@@ -1531,7 +1488,7 @@ fail:
/* The print job was not succesfully started. Cleanup */
/* Still need to add proper error return propagation! 010122:JRR */
unlink(pjob->filename);
- pjob_delete(jobid);
+ pjob_delete(snum, jobid);
return False;
}
@@ -1793,10 +1750,10 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
njobs = print_queue_status(snum, &queue, &status);
for (i=0;i<njobs;i++) {
- BOOL owner = is_owner(user, queue[i].job);
+ BOOL owner = is_owner(user, snum, queue[i].job);
if (owner || can_job_admin) {
- print_job_delete1(queue[i].job);
+ print_job_delete1(snum, queue[i].job);
}
}