diff options
Diffstat (limited to 'source3/printing')
-rw-r--r-- | source3/printing/pcap.c | 11 | ||||
-rw-r--r-- | source3/printing/print_svid.c | 2 | ||||
-rw-r--r-- | source3/printing/printfsp.c | 6 | ||||
-rw-r--r-- | source3/printing/printing.c | 399 |
4 files changed, 185 insertions, 233 deletions
diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 4bca63fffb..86489e9587 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -241,15 +241,12 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername) Scan printcap file pszPrintcapname for a printer called pszPrintername. Return True if found, else False. Returns False on error, too, after logging the error at level 0. For generality, the printcap name may be passed - if -passed as NULL, the configuration will be queried for the name. pszPrintername -must be in DOS codepage. -The xxx_printername_ok functions need fixing to understand they are being -given a DOS codepage. FIXME !! JRA. +passed as NULL, the configuration will be queried for the name. ***************************************************************************/ -BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) +BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname) { char *line=NULL; - char *psz; + const char *psz; char *p,*q; XFILE *pfile; @@ -305,8 +302,6 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname) if (strequal(p,pszPrintername)) { - /* normalise the case */ - pstrcpy(pszPrintername,p); SAFE_FREE(line); x_fclose(pfile); return(True); diff --git a/source3/printing/print_svid.c b/source3/printing/print_svid.c index 44127c3700..837a2fba48 100644 --- a/source3/printing/print_svid.c +++ b/source3/printing/print_svid.c @@ -126,7 +126,7 @@ void sysv_printer_fn(void (*fn)(char *, char *)) * provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming * systems. */ -int sysv_printername_ok(char *name) +int sysv_printername_ok(const char *name) { printer_t *tmp; diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index 9f33d57ad5..ff50ac47c4 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -54,7 +54,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) /* setup a full fsp */ fsp->print_jobid = jobid; - fsp->fd = print_job_fd(jobid); + fsp->fd = print_job_fd(SNUM(conn),jobid); GetTimeOfDay(&fsp->open_time); fsp->vuid = current_user.vuid; fsp->size = 0; @@ -70,7 +70,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) fsp->is_directory = False; fsp->directory_delete_on_close = False; fsp->conn = conn; - string_set(&fsp->fsp_name,print_job_fname(jobid)); + string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid)); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf); @@ -96,7 +96,7 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close) sys_ftruncate(fsp->fd, 0); } - print_job_end(fsp->print_jobid, normal_close); + print_job_end(SNUM(fsp->conn),fsp->print_jobid, normal_close); if (fsp->fsp_name) { string_free(&fsp->fsp_name); 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); } } |