2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 extern SIG_ATOMIC_T got_sig_term;
26 extern SIG_ATOMIC_T reload_after_sighup;
27 extern struct current_user current_user;
28 extern userdom_struct current_user_info;
30 /* Current printer interface */
31 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
34 the printing backend revolves around a tdb database that stores the
35 SMB view of the print queue
37 The key for this database is a jobid - a internally generated number that
38 uniquely identifies a print job
40 reading the print queue involves two steps:
41 - possibly running lpq and updating the internal database from that
42 - reading entries from the database
44 jobids are assigned when a job starts spooling.
47 static TDB_CONTEXT *rap_tdb;
48 static uint16 next_rap_jobid;
49 struct rap_jobid_key {
54 /***************************************************************************
55 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
56 bit RPC jobids.... JRA.
57 ***************************************************************************/
59 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
63 struct rap_jobid_key jinfo;
66 DEBUG(10,("pjobid_to_rap: called.\n"));
69 /* Create the in-memory tdb. */
70 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
76 fstrcpy( jinfo.sharename, sharename );
78 key.dptr = (uint8 *)&jinfo;
79 key.dsize = sizeof(jinfo);
81 data = tdb_fetch(rap_tdb, key);
82 if (data.dptr && data.dsize == sizeof(uint16)) {
83 rap_jobid = SVAL(data.dptr, 0);
85 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
86 (unsigned int)jobid, (unsigned int)rap_jobid));
90 /* Not found - create and store mapping. */
91 rap_jobid = ++next_rap_jobid;
93 rap_jobid = ++next_rap_jobid;
94 SSVAL(buf,0,rap_jobid);
96 data.dsize = sizeof(rap_jobid);
97 tdb_store(rap_tdb, key, data, TDB_REPLACE);
98 tdb_store(rap_tdb, data, key, TDB_REPLACE);
100 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
101 (unsigned int)jobid, (unsigned int)rap_jobid));
105 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
110 DEBUG(10,("rap_to_pjobid called.\n"));
115 SSVAL(buf,0,rap_jobid);
117 key.dsize = sizeof(rap_jobid);
118 data = tdb_fetch(rap_tdb, key);
119 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
121 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
122 fstrcpy( sharename, jinfo->sharename );
123 *pjobid = jinfo->jobid;
124 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
125 (unsigned int)*pjobid, (unsigned int)rap_jobid));
126 SAFE_FREE(data.dptr);
130 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
131 (unsigned int)rap_jobid));
132 SAFE_FREE(data.dptr);
136 static void rap_jobid_delete(const char* sharename, uint32 jobid)
140 struct rap_jobid_key jinfo;
143 DEBUG(10,("rap_jobid_delete: called.\n"));
148 ZERO_STRUCT( jinfo );
149 fstrcpy( jinfo.sharename, sharename );
151 key.dptr = (uint8 *)&jinfo;
152 key.dsize = sizeof(jinfo);
154 data = tdb_fetch(rap_tdb, key);
155 if (!data.dptr || (data.dsize != sizeof(uint16))) {
156 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
157 (unsigned int)jobid ));
158 SAFE_FREE(data.dptr);
162 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
163 (unsigned int)jobid ));
165 rap_jobid = SVAL(data.dptr, 0);
166 SAFE_FREE(data.dptr);
167 SSVAL(buf,0,rap_jobid);
169 data.dsize = sizeof(rap_jobid);
170 tdb_delete(rap_tdb, key);
171 tdb_delete(rap_tdb, data);
174 static int get_queue_status(const char* sharename, print_status_struct *);
176 /****************************************************************************
177 Initialise the printing backend. Called once at startup before the fork().
178 ****************************************************************************/
180 bool print_backend_init(struct messaging_context *msg_ctx)
182 const char *sversion = "INFO/version";
183 int services = lp_numservices();
186 unlink(lock_path("printing.tdb"));
187 mkdir(lock_path("printing"),0755);
189 /* handle a Samba upgrade */
191 for (snum = 0; snum < services; snum++) {
192 struct tdb_print_db *pdb;
193 if (!lp_print_ok(snum))
196 pdb = get_print_db_byname(lp_const_servicename(snum));
199 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
200 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
201 release_print_db(pdb);
204 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
205 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
206 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
208 tdb_unlock_bystring(pdb->tdb, sversion);
209 release_print_db(pdb);
212 close_all_print_db(); /* Don't leave any open. */
214 /* do NT print initialization... */
215 return nt_printing_init(msg_ctx);
218 /****************************************************************************
219 Shut down printing backend. Called once at shutdown to close the tdb.
220 ****************************************************************************/
222 void printing_end(void)
224 close_all_print_db(); /* Don't leave any open. */
227 /****************************************************************************
228 Retrieve the set of printing functions for a given service. This allows
229 us to set the printer function table based on the value of the 'printing'
232 Use the generic interface as the default and only use cups interface only
233 when asked for (and only when supported)
234 ****************************************************************************/
236 static struct printif *get_printer_fns_from_type( enum printing_types type )
238 struct printif *printer_fns = &generic_printif;
241 if ( type == PRINT_CUPS ) {
242 printer_fns = &cups_printif;
244 #endif /* HAVE_CUPS */
247 if ( type == PRINT_IPRINT ) {
248 printer_fns = &iprint_printif;
250 #endif /* HAVE_IPRINT */
252 printer_fns->type = type;
257 static struct printif *get_printer_fns( int snum )
259 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
263 /****************************************************************************
264 Useful function to generate a tdb key.
265 ****************************************************************************/
267 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
271 SIVAL(tmp, 0, jobid);
272 ret.dptr = (uint8 *)tmp;
273 ret.dsize = sizeof(*tmp);
277 /***********************************************************************
278 unpack a pjob from a tdb buffer
279 ***********************************************************************/
281 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
285 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
286 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
291 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
309 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
315 pjob->sysjob = pjsysjob;
317 pjob->starttime = pjstarttime;
318 pjob->status = pjstatus;
320 pjob->page_count = pjpage_count;
321 pjob->spooled = pjspooled;
322 pjob->smbjob = pjsmbjob;
328 /****************************************************************************
329 Useful function to find a print job in the database.
330 ****************************************************************************/
332 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
334 static struct printjob pjob;
337 struct tdb_print_db *pdb = get_print_db_byname(sharename);
339 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
340 (unsigned int)jobid, sharename ));
346 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
347 release_print_db(pdb);
350 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
354 if ( pjob.nt_devmode ) {
355 free_nt_devicemode( &pjob.nt_devmode );
360 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
361 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
368 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
369 (int)pjob.sysjob, (unsigned int)jobid ));
374 /* Convert a unix jobid to a smb jobid */
376 static uint32 sysjob_to_jobid_value;
378 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
379 TDB_DATA data, void *state)
381 struct printjob *pjob;
382 int *sysjob = (int *)state;
384 if (!data.dptr || data.dsize == 0)
387 pjob = (struct printjob *)data.dptr;
388 if (key.dsize != sizeof(uint32))
391 if (*sysjob == pjob->sysjob) {
392 uint32 jobid = IVAL(key.dptr,0);
394 sysjob_to_jobid_value = jobid;
401 /****************************************************************************
402 This is a *horribly expensive call as we have to iterate through all the
403 current printer tdb's. Don't do this often ! JRA.
404 ****************************************************************************/
406 uint32 sysjob_to_jobid(int unix_jobid)
408 int services = lp_numservices();
411 sysjob_to_jobid_value = (uint32)-1;
413 for (snum = 0; snum < services; snum++) {
414 struct tdb_print_db *pdb;
415 if (!lp_print_ok(snum))
417 pdb = get_print_db_byname(lp_const_servicename(snum));
421 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
422 release_print_db(pdb);
423 if (sysjob_to_jobid_value != (uint32)-1)
424 return sysjob_to_jobid_value;
429 /****************************************************************************
430 Send notifications based on what has changed after a pjob_store.
431 ****************************************************************************/
433 static const struct {
435 uint32 spoolss_status;
436 } lpq_to_spoolss_status_map[] = {
437 { LPQ_QUEUED, JOB_STATUS_QUEUED },
438 { LPQ_PAUSED, JOB_STATUS_PAUSED },
439 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
440 { LPQ_PRINTING, JOB_STATUS_PRINTING },
441 { LPQ_DELETING, JOB_STATUS_DELETING },
442 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
443 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
444 { LPQ_PRINTED, JOB_STATUS_PRINTED },
445 { LPQ_DELETED, JOB_STATUS_DELETED },
446 { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
447 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
451 /* Convert a lpq status value stored in printing.tdb into the
452 appropriate win32 API constant. */
454 static uint32 map_to_spoolss_status(uint32 lpq_status)
458 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
459 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
460 return lpq_to_spoolss_status_map[i].spoolss_status;
467 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
468 struct printjob *new_data)
470 bool new_job = False;
475 /* Job attributes that can't be changed. We only send
476 notification for these on a new job. */
478 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
479 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
480 time first or else we'll end up with potential alignment
481 errors. I don't think the systemtime should be spooled as
482 a string, but this gets us around that error.
483 --jerry (i'll feel dirty for this) */
486 notify_job_submitted(sharename, jobid, new_data->starttime);
487 notify_job_username(sharename, jobid, new_data->user);
490 if (new_job || !strequal(old_data->jobname, new_data->jobname))
491 notify_job_name(sharename, jobid, new_data->jobname);
493 /* Job attributes of a new job or attributes that can be
496 if (new_job || !strequal(old_data->jobname, new_data->jobname))
497 notify_job_name(sharename, jobid, new_data->jobname);
499 if (new_job || old_data->status != new_data->status)
500 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
502 if (new_job || old_data->size != new_data->size)
503 notify_job_total_bytes(sharename, jobid, new_data->size);
505 if (new_job || old_data->page_count != new_data->page_count)
506 notify_job_total_pages(sharename, jobid, new_data->page_count);
509 /****************************************************************************
510 Store a job structure back to the database.
511 ****************************************************************************/
513 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
516 TDB_DATA old_data, new_data;
518 struct tdb_print_db *pdb = get_print_db_byname(sharename);
520 int len, newlen, buflen;
528 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
530 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
537 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
539 (uint32)pjob->sysjob,
541 (uint32)pjob->starttime,
542 (uint32)pjob->status,
544 (uint32)pjob->page_count,
545 (uint32)pjob->spooled,
546 (uint32)pjob->smbjob,
552 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
555 buf = (uint8 *)SMB_REALLOC(buf, len);
557 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
562 } while ( buflen != len );
568 new_data.dsize = len;
569 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
572 release_print_db(pdb);
574 /* Send notify updates for what has changed */
577 struct printjob old_pjob;
579 if ( old_data.dsize )
581 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
583 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
584 free_nt_devicemode( &old_pjob.nt_devmode );
589 pjob_store_notify( sharename, jobid, NULL, pjob );
594 SAFE_FREE( old_data.dptr );
600 /****************************************************************************
601 Remove a job structure from the database.
602 ****************************************************************************/
604 void pjob_delete(const char* sharename, uint32 jobid)
607 struct printjob *pjob;
608 uint32 job_status = 0;
609 struct tdb_print_db *pdb;
611 pdb = get_print_db_byname( sharename );
616 pjob = print_job_find( sharename, jobid );
619 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
620 (unsigned int)jobid));
621 release_print_db(pdb);
625 /* We must cycle through JOB_STATUS_DELETING and
626 JOB_STATUS_DELETED for the port monitor to delete the job
629 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
630 notify_job_status(sharename, jobid, job_status);
632 /* Remove from printing.tdb */
634 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
635 remove_from_jobs_changed(sharename, jobid);
636 release_print_db( pdb );
637 rap_jobid_delete(sharename, jobid);
640 /****************************************************************************
641 Parse a file name from the system spooler to generate a jobid.
642 ****************************************************************************/
644 static uint32 print_parse_jobid(char *fname)
648 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
650 fname += strlen(PRINT_SPOOL_PREFIX);
656 return (uint32)jobid;
659 /****************************************************************************
660 List a unix job in the print database.
661 ****************************************************************************/
663 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
665 struct printjob pj, *old_pj;
667 if (jobid == (uint32)-1)
668 jobid = q->job + UNIX_JOB_START;
670 /* Preserve the timestamp on an existing unix print job */
672 old_pj = print_job_find(sharename, jobid);
679 pj.starttime = old_pj ? old_pj->starttime : q->time;
680 pj.status = q->status;
683 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
684 if (jobid < UNIX_JOB_START) {
686 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
689 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
691 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
692 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
694 pjob_store(sharename, jobid, &pj);
698 struct traverse_struct {
699 print_queue_struct *queue;
700 int qcount, snum, maxcount, total_jobs;
701 const char *sharename;
703 const char *lprm_command;
704 struct printif *print_if;
707 /****************************************************************************
708 Utility fn to delete any jobs that are no longer active.
709 ****************************************************************************/
711 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
713 struct traverse_struct *ts = (struct traverse_struct *)state;
714 struct printjob pjob;
718 if ( key.dsize != sizeof(jobid) )
721 jobid = IVAL(key.dptr, 0);
722 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
724 free_nt_devicemode( &pjob.nt_devmode );
728 /* remove a unix job if it isn't in the system queue any more */
730 for (i=0;i<ts->qcount;i++) {
731 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
732 if (jobid == u_jobid)
735 if (i == ts->qcount) {
736 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
737 (unsigned int)jobid ));
738 pjob_delete(ts->sharename, jobid);
742 /* need to continue the the bottom of the function to
743 save the correct attributes */
746 /* maybe it hasn't been spooled yet */
748 /* if a job is not spooled and the process doesn't
749 exist then kill it. This cleans up after smbd
751 if (!process_exists_by_pid(pjob.pid)) {
752 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
753 (unsigned int)jobid, (unsigned int)pjob.pid ));
754 pjob_delete(ts->sharename, jobid);
760 /* this check only makes sense for jobs submitted from Windows clients */
763 for (i=0;i<ts->qcount;i++) {
766 if ( pjob.status == LPQ_DELETED )
769 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
771 if (jobid == curr_jobid) {
773 /* try to clean up any jobs that need to be deleted */
775 if ( pjob.status == LPQ_DELETING ) {
778 result = (*(ts->print_if->job_delete))(
779 ts->sharename, ts->lprm_command, &pjob );
782 /* if we can't delete, then reset the job status */
783 pjob.status = LPQ_QUEUED;
784 pjob_store(ts->sharename, jobid, &pjob);
787 /* if we deleted the job, the remove the tdb record */
788 pjob_delete(ts->sharename, jobid);
789 pjob.status = LPQ_DELETED;
799 /* The job isn't in the system queue - we have to assume it has
800 completed, so delete the database entry. */
802 if (i == ts->qcount) {
804 /* A race can occur between the time a job is spooled and
805 when it appears in the lpq output. This happens when
806 the job is added to printing.tdb when another smbd
807 running print_queue_update() has completed a lpq and
808 is currently traversing the printing tdb and deleting jobs.
809 Don't delete the job if it was submitted after the lpq_time. */
811 if (pjob.starttime < ts->lpq_time) {
812 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
814 (unsigned int)pjob.starttime,
815 (unsigned int)ts->lpq_time ));
816 pjob_delete(ts->sharename, jobid);
822 /* Save the pjob attributes we will store.
823 FIXME!!! This is the only place where queue->job
824 represents the SMB jobid --jerry */
826 ts->queue[i].job = jobid;
827 ts->queue[i].size = pjob.size;
828 ts->queue[i].page_count = pjob.page_count;
829 ts->queue[i].status = pjob.status;
830 ts->queue[i].priority = 1;
831 ts->queue[i].time = pjob.starttime;
832 fstrcpy(ts->queue[i].fs_user, pjob.user);
833 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
840 /****************************************************************************
841 Check if the print queue has been updated recently enough.
842 ****************************************************************************/
844 static void print_cache_flush(const char *sharename)
847 struct tdb_print_db *pdb = get_print_db_byname(sharename);
851 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
852 tdb_store_int32(pdb->tdb, key, -1);
853 release_print_db(pdb);
856 /****************************************************************************
857 Check if someone already thinks they are doing the update.
858 ****************************************************************************/
860 static pid_t get_updating_pid(const char *sharename)
865 struct tdb_print_db *pdb = get_print_db_byname(sharename);
869 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
870 key = string_tdb_data(keystr);
872 data = tdb_fetch(pdb->tdb, key);
873 release_print_db(pdb);
874 if (!data.dptr || data.dsize != sizeof(pid_t)) {
875 SAFE_FREE(data.dptr);
879 updating_pid = IVAL(data.dptr, 0);
880 SAFE_FREE(data.dptr);
882 if (process_exists_by_pid(updating_pid))
888 /****************************************************************************
889 Set the fact that we're doing the update, or have finished doing the update
891 ****************************************************************************/
893 static void set_updating_pid(const fstring sharename, bool updating)
898 pid_t updating_pid = sys_getpid();
901 struct tdb_print_db *pdb = get_print_db_byname(sharename);
906 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
907 key = string_tdb_data(keystr);
909 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
910 updating ? "" : "not ",
914 tdb_delete(pdb->tdb, key);
915 release_print_db(pdb);
919 SIVAL( buffer, 0, updating_pid);
921 data.dsize = 4; /* we always assume this is a 4 byte value */
923 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
924 release_print_db(pdb);
927 /****************************************************************************
928 Sort print jobs by submittal time.
929 ****************************************************************************/
931 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
942 /* Sort on job start time */
944 if (j1->time == j2->time)
946 return (j1->time > j2->time) ? 1 : -1;
949 /****************************************************************************
950 Store the sorted queue representation for later portmon retrieval.
952 ****************************************************************************/
954 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
957 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
958 print_queue_struct *queue = pts->queue;
963 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
964 pts->qcount = max_reported_jobs;
967 /* Work out the size. */
969 data.dsize += tdb_pack(NULL, 0, "d", qcount);
971 for (i = 0; i < pts->qcount; i++) {
972 if ( queue[i].status == LPQ_DELETED )
976 data.dsize += tdb_pack(NULL, 0, "ddddddff",
977 (uint32)queue[i].job,
978 (uint32)queue[i].size,
979 (uint32)queue[i].page_count,
980 (uint32)queue[i].status,
981 (uint32)queue[i].priority,
982 (uint32)queue[i].time,
987 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
991 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
992 for (i = 0; i < pts->qcount; i++) {
993 if ( queue[i].status == LPQ_DELETED )
996 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
997 (uint32)queue[i].job,
998 (uint32)queue[i].size,
999 (uint32)queue[i].page_count,
1000 (uint32)queue[i].status,
1001 (uint32)queue[i].priority,
1002 (uint32)queue[i].time,
1007 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1009 SAFE_FREE(data.dptr);
1013 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1019 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1020 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1021 SAFE_FREE(data.dptr);
1028 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1031 unsigned int job_count = data.dsize / 4;
1033 for (i = 0; i < job_count; i++) {
1036 ch_jobid = IVAL(data.dptr, i*4);
1037 if (ch_jobid == jobid)
1038 remove_from_jobs_changed(sharename, jobid);
1042 /****************************************************************************
1043 Check if the print queue has been updated recently enough.
1044 ****************************************************************************/
1046 static bool print_cache_expired(const char *sharename, bool check_pending)
1049 time_t last_qscan_time, time_now = time(NULL);
1050 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1051 bool result = False;
1056 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1057 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1060 * Invalidate the queue for 3 reasons.
1061 * (1). last queue scan time == -1.
1062 * (2). Current time - last queue scan time > allowed cache time.
1063 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1064 * This last test picks up machines for which the clock has been moved
1065 * forward, an lpq scan done and then the clock moved back. Otherwise
1066 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1069 if (last_qscan_time == ((time_t)-1)
1070 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1071 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1074 time_t msg_pending_time;
1076 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1077 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1078 sharename, (int)last_qscan_time, (int)time_now,
1079 (int)lp_lpqcachetime() ));
1081 /* check if another smbd has already sent a message to update the
1082 queue. Give the pending message one minute to clear and
1083 then send another message anyways. Make sure to check for
1084 clocks that have been run forward and then back again. */
1086 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1089 && tdb_fetch_uint32( pdb->tdb, key, &u )
1090 && (msg_pending_time=u) > 0
1091 && msg_pending_time <= time_now
1092 && (time_now - msg_pending_time) < 60 )
1094 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1103 release_print_db(pdb);
1107 /****************************************************************************
1108 main work for updating the lpq cahe for a printer queue
1109 ****************************************************************************/
1111 static void print_queue_update_internal( const char *sharename,
1112 struct printif *current_printif,
1113 char *lpq_command, char *lprm_command )
1116 print_queue_struct *queue = NULL;
1117 print_status_struct status;
1118 print_status_struct old_status;
1119 struct printjob *pjob;
1120 struct traverse_struct tstruct;
1123 fstring keystr, cachestr;
1124 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1130 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1131 sharename, current_printif->type, lpq_command));
1134 * Update the cache time FIRST ! Stops others even
1135 * attempting to get the lock and doing this
1136 * if the lpq takes a long time.
1139 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1140 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1142 /* get the current queue using the appropriate interface */
1143 ZERO_STRUCT(status);
1145 qcount = (*(current_printif->queue_get))(sharename,
1146 current_printif->type,
1147 lpq_command, &queue, &status);
1149 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1150 qcount, (qcount != 1) ? "s" : "", sharename));
1152 /* Sort the queue by submission time otherwise they are displayed
1155 qsort(queue, qcount, sizeof(print_queue_struct),
1156 QSORT_CAST(printjob_comp));
1159 any job in the internal database that is marked as spooled
1160 and doesn't exist in the system queue is considered finished
1161 and removed from the database
1163 any job in the system database but not in the internal database
1164 is added as a unix job
1166 fill in any system job numbers as we go
1169 jcdata = get_jobs_changed_data(pdb);
1171 for (i=0; i<qcount; i++) {
1172 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1174 if (jobid == (uint32)-1) {
1175 /* assume its a unix print job */
1176 print_unix_job(sharename, &queue[i], jobid);
1180 /* we have an active SMB print job - update its status */
1181 pjob = print_job_find(sharename, jobid);
1183 /* err, somethings wrong. Probably smbd was restarted
1184 with jobs in the queue. All we can do is treat them
1185 like unix jobs. Pity. */
1186 print_unix_job(sharename, &queue[i], jobid);
1190 pjob->sysjob = queue[i].job;
1192 /* don't reset the status on jobs to be deleted */
1194 if ( pjob->status != LPQ_DELETING )
1195 pjob->status = queue[i].status;
1197 pjob_store(sharename, jobid, pjob);
1199 check_job_changed(sharename, jcdata, jobid);
1202 SAFE_FREE(jcdata.dptr);
1204 /* now delete any queued entries that don't appear in the
1206 tstruct.queue = queue;
1207 tstruct.qcount = qcount;
1209 tstruct.total_jobs = 0;
1210 tstruct.lpq_time = time(NULL);
1211 tstruct.sharename = sharename;
1212 tstruct.lprm_command = lprm_command;
1213 tstruct.print_if = current_printif;
1215 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1217 /* Store the linearised queue, max jobs only. */
1218 store_queue_struct(pdb, &tstruct);
1220 SAFE_FREE(tstruct.queue);
1222 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1223 sharename, tstruct.total_jobs ));
1225 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1227 get_queue_status(sharename, &old_status);
1228 if (old_status.qcount != qcount)
1229 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1230 old_status.qcount, qcount, sharename));
1232 /* store the new queue status structure */
1233 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1234 key = string_tdb_data(keystr);
1236 status.qcount = qcount;
1237 data.dptr = (uint8 *)&status;
1238 data.dsize = sizeof(status);
1239 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1242 * Update the cache time again. We want to do this call
1243 * as little as possible...
1246 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1247 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1249 /* clear the msg pending record for this queue */
1251 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1253 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1254 /* log a message but continue on */
1256 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1260 release_print_db( pdb );
1265 /****************************************************************************
1266 Update the internal database from the system print queue for a queue.
1267 obtain a lock on the print queue before proceeding (needed when mutiple
1268 smbd processes maytry to update the lpq cache concurrently).
1269 ****************************************************************************/
1271 static void print_queue_update_with_lock( const char *sharename,
1272 struct printif *current_printif,
1273 char *lpq_command, char *lprm_command )
1276 struct tdb_print_db *pdb;
1278 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1279 pdb = get_print_db_byname(sharename);
1283 if ( !print_cache_expired(sharename, False) ) {
1284 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1285 release_print_db(pdb);
1290 * Check to see if someone else is doing this update.
1291 * This is essentially a mutex on the update.
1294 if (get_updating_pid(sharename) != -1) {
1295 release_print_db(pdb);
1299 /* Lock the queue for the database update */
1301 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1302 /* Only wait 10 seconds for this. */
1303 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1304 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1305 release_print_db(pdb);
1310 * Ensure that no one else got in here.
1311 * If the updating pid is still -1 then we are
1315 if (get_updating_pid(sharename) != -1) {
1317 * Someone else is doing the update, exit.
1319 tdb_unlock_bystring(pdb->tdb, keystr);
1320 release_print_db(pdb);
1325 * We're going to do the update ourselves.
1328 /* Tell others we're doing the update. */
1329 set_updating_pid(sharename, True);
1332 * Allow others to enter and notice we're doing
1336 tdb_unlock_bystring(pdb->tdb, keystr);
1338 /* do the main work now */
1340 print_queue_update_internal( sharename, current_printif,
1341 lpq_command, lprm_command );
1343 /* Delete our pid from the db. */
1344 set_updating_pid(sharename, False);
1345 release_print_db(pdb);
1348 /****************************************************************************
1349 this is the receive function of the background lpq updater
1350 ****************************************************************************/
1351 static void print_queue_receive(struct messaging_context *msg,
1354 struct server_id server_id,
1358 char *lpqcommand = NULL, *lprmcommand = NULL;
1362 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1369 SAFE_FREE(lpqcommand);
1370 SAFE_FREE(lprmcommand);
1371 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1375 print_queue_update_with_lock(sharename,
1376 get_printer_fns_from_type((enum printing_types)printing_type),
1377 lpqcommand, lprmcommand );
1379 SAFE_FREE(lpqcommand);
1380 SAFE_FREE(lprmcommand);
1384 static pid_t background_lpq_updater_pid = -1;
1386 /****************************************************************************
1387 main thread of the background lpq updater
1388 ****************************************************************************/
1389 void start_background_queue(void)
1391 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1392 background_lpq_updater_pid = sys_fork();
1394 if (background_lpq_updater_pid == -1) {
1395 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1399 if(background_lpq_updater_pid == 0) {
1401 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1403 claim_connection( NULL, "smbd lpq backend",
1404 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1406 if (!locking_init(0)) {
1410 messaging_register(smbd_messaging_context(), NULL,
1411 MSG_PRINTER_UPDATE, print_queue_receive);
1413 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1417 /* check for some essential signals first */
1420 exit_server_cleanly(NULL);
1423 if (reload_after_sighup) {
1424 change_to_root_user();
1425 DEBUG(1,("Reloading services after SIGHUP\n"));
1426 reload_services(False);
1427 reload_after_sighup = 0;
1430 /* now check for messages */
1432 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1433 message_dispatch(smbd_messaging_context());
1435 /* process any pending print change notify messages */
1437 print_notify_send_messages(smbd_messaging_context(),
1443 /****************************************************************************
1444 update the internal database from the system print queue for a queue
1445 ****************************************************************************/
1447 static void print_queue_update(int snum, bool force)
1451 char *lpqcommand = NULL;
1452 char *lprmcommand = NULL;
1453 uint8 *buffer = NULL;
1456 struct tdb_print_db *pdb;
1458 struct printif *current_printif;
1459 TALLOC_CTX *ctx = talloc_tos();
1461 fstrcpy( sharename, lp_const_servicename(snum));
1463 /* don't strip out characters like '$' from the printername */
1465 lpqcommand = talloc_string_sub2(ctx,
1466 lp_lpqcommand(snum),
1469 false, false, false);
1473 lpqcommand = talloc_sub_advanced(ctx,
1474 lp_servicename(snum),
1475 current_user_info.unix_name,
1477 current_user.ut.gid,
1478 get_current_username(),
1479 current_user_info.domain,
1485 lprmcommand = talloc_string_sub2(ctx,
1486 lp_lprmcommand(snum),
1489 false, false, false);
1493 lprmcommand = talloc_sub_advanced(ctx,
1494 lp_servicename(snum),
1495 current_user_info.unix_name,
1497 current_user.ut.gid,
1498 get_current_username(),
1499 current_user_info.domain,
1506 * Make sure that the background queue process exists.
1507 * Otherwise just do the update ourselves
1510 if ( force || background_lpq_updater_pid == -1 ) {
1511 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1512 current_printif = get_printer_fns( snum );
1513 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1518 type = lp_printing(snum);
1520 /* get the length */
1522 len = tdb_pack( NULL, 0, "fdPP",
1528 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1530 /* now pack the buffer */
1531 newlen = tdb_pack( buffer, len, "fdPP",
1537 SMB_ASSERT( newlen == len );
1539 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1540 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1541 sharename, type, lpqcommand, lprmcommand ));
1543 /* here we set a msg pending record for other smbd processes
1544 to throttle the number of duplicate print_queue_update msgs
1547 pdb = get_print_db_byname(sharename);
1553 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1555 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1556 /* log a message but continue on */
1558 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1562 release_print_db( pdb );
1564 /* finally send the message */
1566 messaging_send_buf(smbd_messaging_context(),
1567 pid_to_procid(background_lpq_updater_pid),
1568 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1570 SAFE_FREE( buffer );
1575 /****************************************************************************
1576 Create/Update an entry in the print tdb that will allow us to send notify
1577 updates only to interested smbd's.
1578 ****************************************************************************/
1580 bool print_notify_register_pid(int snum)
1583 struct tdb_print_db *pdb = NULL;
1584 TDB_CONTEXT *tdb = NULL;
1585 const char *printername;
1586 uint32 mypid = (uint32)sys_getpid();
1590 /* if (snum == -1), then the change notify request was
1591 on a print server handle and we need to register on
1596 int num_services = lp_numservices();
1599 for ( idx=0; idx<num_services; idx++ ) {
1600 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1601 print_notify_register_pid(idx);
1606 else /* register for a specific printer */
1608 printername = lp_const_servicename(snum);
1609 pdb = get_print_db_byname(printername);
1615 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1616 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1619 release_print_db(pdb);
1623 data = get_printer_notify_pid_list( tdb, printername, True );
1625 /* Add ourselves and increase the refcount. */
1627 for (i = 0; i < data.dsize; i += 8) {
1628 if (IVAL(data.dptr,i) == mypid) {
1629 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1630 SIVAL(data.dptr, i+4, new_refcount);
1635 if (i == data.dsize) {
1636 /* We weren't in the list. Realloc. */
1637 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1639 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1644 SIVAL(data.dptr,data.dsize - 8,mypid);
1645 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1648 /* Store back the record. */
1649 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1650 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1651 list for printer %s\n", printername));
1659 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1661 release_print_db(pdb);
1662 SAFE_FREE(data.dptr);
1666 /****************************************************************************
1667 Update an entry in the print tdb that will allow us to send notify
1668 updates only to interested smbd's.
1669 ****************************************************************************/
1671 bool print_notify_deregister_pid(int snum)
1674 struct tdb_print_db *pdb = NULL;
1675 TDB_CONTEXT *tdb = NULL;
1676 const char *printername;
1677 uint32 mypid = (uint32)sys_getpid();
1681 /* if ( snum == -1 ), we are deregister a print server handle
1682 which means to deregister on all print queues */
1686 int num_services = lp_numservices();
1689 for ( idx=0; idx<num_services; idx++ ) {
1690 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1691 print_notify_deregister_pid(idx);
1696 else /* deregister a specific printer */
1698 printername = lp_const_servicename(snum);
1699 pdb = get_print_db_byname(printername);
1705 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1706 DEBUG(0,("print_notify_register_pid: Failed to lock \
1707 printer %s database\n", printername));
1709 release_print_db(pdb);
1713 data = get_printer_notify_pid_list( tdb, printername, True );
1715 /* Reduce refcount. Remove ourselves if zero. */
1717 for (i = 0; i < data.dsize; ) {
1718 if (IVAL(data.dptr,i) == mypid) {
1719 uint32 refcount = IVAL(data.dptr, i+4);
1723 if (refcount == 0) {
1724 if (data.dsize - i > 8)
1725 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1729 SIVAL(data.dptr, i+4, refcount);
1735 if (data.dsize == 0)
1736 SAFE_FREE(data.dptr);
1738 /* Store back the record. */
1739 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1740 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1741 list for printer %s\n", printername));
1749 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1751 release_print_db(pdb);
1752 SAFE_FREE(data.dptr);
1756 /****************************************************************************
1757 Check if a jobid is valid. It is valid if it exists in the database.
1758 ****************************************************************************/
1760 bool print_job_exists(const char* sharename, uint32 jobid)
1762 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1768 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1769 release_print_db(pdb);
1773 /****************************************************************************
1774 Give the fd used for a jobid.
1775 ****************************************************************************/
1777 int print_job_fd(const char* sharename, uint32 jobid)
1779 struct printjob *pjob = print_job_find(sharename, jobid);
1782 /* don't allow another process to get this info - it is meaningless */
1783 if (pjob->pid != sys_getpid())
1788 /****************************************************************************
1789 Give the filename used for a jobid.
1790 Only valid for the process doing the spooling and when the job
1791 has not been spooled.
1792 ****************************************************************************/
1794 char *print_job_fname(const char* sharename, uint32 jobid)
1796 struct printjob *pjob = print_job_find(sharename, jobid);
1797 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1799 return pjob->filename;
1803 /****************************************************************************
1804 Give the filename used for a jobid.
1805 Only valid for the process doing the spooling and when the job
1806 has not been spooled.
1807 ****************************************************************************/
1809 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1811 struct printjob *pjob = print_job_find(sharename, jobid);
1816 return pjob->nt_devmode;
1819 /****************************************************************************
1820 Set the place in the queue for a job.
1821 ****************************************************************************/
1823 bool print_job_set_place(const char *sharename, uint32 jobid, int place)
1825 DEBUG(2,("print_job_set_place not implemented yet\n"));
1829 /****************************************************************************
1830 Set the name of a job. Only possible for owner.
1831 ****************************************************************************/
1833 bool print_job_set_name(const char *sharename, uint32 jobid, char *name)
1835 struct printjob *pjob;
1837 pjob = print_job_find(sharename, jobid);
1838 if (!pjob || pjob->pid != sys_getpid())
1841 fstrcpy(pjob->jobname, name);
1842 return pjob_store(sharename, jobid, pjob);
1845 /***************************************************************************
1846 Remove a jobid from the 'jobs changed' list.
1847 ***************************************************************************/
1849 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
1851 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1853 size_t job_count, i;
1855 bool gotlock = False;
1863 key = string_tdb_data("INFO/jobs_changed");
1865 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1870 data = tdb_fetch(pdb->tdb, key);
1872 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1875 job_count = data.dsize / 4;
1876 for (i = 0; i < job_count; i++) {
1879 ch_jobid = IVAL(data.dptr, i*4);
1880 if (ch_jobid == jobid) {
1881 if (i < job_count -1 )
1882 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1884 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1894 tdb_chainunlock(pdb->tdb, key);
1895 SAFE_FREE(data.dptr);
1896 release_print_db(pdb);
1898 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1900 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1904 /****************************************************************************
1905 Delete a print job - don't update queue.
1906 ****************************************************************************/
1908 static bool print_job_delete1(int snum, uint32 jobid)
1910 const char* sharename = lp_const_servicename(snum);
1911 struct printjob *pjob = print_job_find(sharename, jobid);
1913 struct printif *current_printif = get_printer_fns( snum );
1919 * If already deleting just return.
1922 if (pjob->status == LPQ_DELETING)
1925 /* Hrm - we need to be able to cope with deleting a job before it
1926 has reached the spooler. Just mark it as LPQ_DELETING and
1927 let the print_queue_update() code rmeove the record */
1930 if (pjob->sysjob == -1) {
1931 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1934 /* Set the tdb entry to be deleting. */
1936 pjob->status = LPQ_DELETING;
1937 pjob_store(sharename, jobid, pjob);
1939 if (pjob->spooled && pjob->sysjob != -1)
1941 result = (*(current_printif->job_delete))(
1943 lp_lprmcommand(snum),
1946 /* Delete the tdb entry if the delete succeeded or the job hasn't
1950 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1955 pjob_delete(sharename, jobid);
1956 /* Ensure we keep a rough count of the number of total jobs... */
1957 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1958 release_print_db(pdb);
1962 remove_from_jobs_changed( sharename, jobid );
1964 return (result == 0);
1967 /****************************************************************************
1968 Return true if the current user owns the print job.
1969 ****************************************************************************/
1971 static bool is_owner(struct current_user *user, const char *servicename,
1974 struct printjob *pjob = print_job_find(servicename, jobid);
1980 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1981 return strequal(pjob->user, vuser->user.smb_name);
1983 return strequal(pjob->user, uidtoname(user->ut.uid));
1987 /****************************************************************************
1989 ****************************************************************************/
1991 bool print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1993 const char* sharename = lp_const_servicename( snum );
1994 struct printjob *pjob;
2000 owner = is_owner(user, lp_const_servicename(snum), jobid);
2002 /* Check access against security descriptor or whether the user
2006 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2007 DEBUG(3, ("delete denied by security descriptor\n"));
2008 *errcode = WERR_ACCESS_DENIED;
2010 /* BEGIN_ADMIN_LOG */
2011 sys_adminlog( LOG_ERR,
2012 "Permission denied-- user not allowed to delete, \
2013 pause, or resume print job. User name: %s. Printer name: %s.",
2014 uidtoname(user->ut.uid), PRINTERNAME(snum) );
2021 * get the spooled filename of the print job
2022 * if this works, then the file has not been spooled
2023 * to the underlying print system. Just delete the
2024 * spool file & return.
2027 if ( (fname = print_job_fname( sharename, jobid )) != NULL )
2029 /* remove the spool file */
2030 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
2031 if ( unlink( fname ) == -1 ) {
2032 *errcode = map_werror_from_unix(errno);
2037 if (!print_job_delete1(snum, jobid)) {
2038 *errcode = WERR_ACCESS_DENIED;
2042 /* force update the database and say the delete failed if the
2045 print_queue_update(snum, True);
2047 pjob = print_job_find(sharename, jobid);
2048 if ( pjob && (pjob->status != LPQ_DELETING) )
2049 *errcode = WERR_ACCESS_DENIED;
2051 return (pjob == NULL );
2054 /****************************************************************************
2056 ****************************************************************************/
2058 bool print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2060 const char* sharename = lp_const_servicename(snum);
2061 struct printjob *pjob;
2063 struct printif *current_printif = get_printer_fns( snum );
2065 pjob = print_job_find(sharename, jobid);
2067 if (!pjob || !user) {
2068 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2069 (unsigned int)jobid ));
2073 if (!pjob->spooled || pjob->sysjob == -1) {
2074 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2075 (int)pjob->sysjob, (unsigned int)jobid ));
2079 if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2080 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2081 DEBUG(3, ("pause denied by security descriptor\n"));
2083 /* BEGIN_ADMIN_LOG */
2084 sys_adminlog( LOG_ERR,
2085 "Permission denied-- user not allowed to delete, \
2086 pause, or resume print job. User name: %s. Printer name: %s.",
2087 uidtoname(user->ut.uid), PRINTERNAME(snum) );
2090 *errcode = WERR_ACCESS_DENIED;
2094 /* need to pause the spooled entry */
2095 ret = (*(current_printif->job_pause))(snum, pjob);
2098 *errcode = WERR_INVALID_PARAM;
2102 /* force update the database */
2103 print_cache_flush(lp_const_servicename(snum));
2105 /* Send a printer notify message */
2107 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
2109 /* how do we tell if this succeeded? */
2114 /****************************************************************************
2116 ****************************************************************************/
2118 bool print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2120 const char *sharename = lp_const_servicename(snum);
2121 struct printjob *pjob;
2123 struct printif *current_printif = get_printer_fns( snum );
2125 pjob = print_job_find(sharename, jobid);
2127 if (!pjob || !user) {
2128 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2129 (unsigned int)jobid ));
2133 if (!pjob->spooled || pjob->sysjob == -1) {
2134 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2135 (int)pjob->sysjob, (unsigned int)jobid ));
2139 if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2140 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2141 DEBUG(3, ("resume denied by security descriptor\n"));
2142 *errcode = WERR_ACCESS_DENIED;
2144 /* BEGIN_ADMIN_LOG */
2145 sys_adminlog( LOG_ERR,
2146 "Permission denied-- user not allowed to delete, \
2147 pause, or resume print job. User name: %s. Printer name: %s.",
2148 uidtoname(user->ut.uid), PRINTERNAME(snum) );
2153 ret = (*(current_printif->job_resume))(snum, pjob);
2156 *errcode = WERR_INVALID_PARAM;
2160 /* force update the database */
2161 print_cache_flush(lp_const_servicename(snum));
2163 /* Send a printer notify message */
2165 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2170 /****************************************************************************
2171 Write to a print file.
2172 ****************************************************************************/
2174 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2176 const char* sharename = lp_const_servicename(snum);
2178 struct printjob *pjob;
2180 pjob = print_job_find(sharename, jobid);
2184 /* don't allow another process to get this info - it is meaningless */
2185 if (pjob->pid != sys_getpid())
2188 return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2190 if (return_code>0) {
2192 pjob_store(sharename, jobid, pjob);
2197 /****************************************************************************
2198 Get the queue status - do not update if db is out of date.
2199 ****************************************************************************/
2201 static int get_queue_status(const char* sharename, print_status_struct *status)
2205 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2209 ZERO_STRUCTP(status);
2216 fstr_sprintf(keystr, "STATUS/%s", sharename);
2217 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2219 if (data.dsize == sizeof(print_status_struct))
2220 /* this memcpy is ok since the status struct was
2221 not packed before storing it in the tdb */
2222 memcpy(status, data.dptr, sizeof(print_status_struct));
2223 SAFE_FREE(data.dptr);
2226 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2227 release_print_db(pdb);
2228 return (len == -1 ? 0 : len);
2231 /****************************************************************************
2232 Determine the number of jobs in a queue.
2233 ****************************************************************************/
2235 int print_queue_length(int snum, print_status_struct *pstatus)
2237 const char* sharename = lp_const_servicename( snum );
2238 print_status_struct status;
2241 ZERO_STRUCT( status );
2243 /* make sure the database is up to date */
2244 if (print_cache_expired(lp_const_servicename(snum), True))
2245 print_queue_update(snum, False);
2247 /* also fetch the queue status */
2248 memset(&status, 0, sizeof(status));
2249 len = get_queue_status(sharename, &status);
2257 /***************************************************************************
2258 Allocate a jobid. Hold the lock for as short a time as possible.
2259 ***************************************************************************/
2261 static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2266 *pjobid = (uint32)-1;
2268 for (i = 0; i < 3; i++) {
2269 /* Lock the database - only wait 20 seconds. */
2270 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
2271 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2275 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2276 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2277 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2284 jobid = NEXT_JOBID(jobid);
2286 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2287 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2288 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2292 /* We've finished with the INFO/nextjob lock. */
2293 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2295 if (!print_job_exists(sharename, jobid))
2300 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2302 /* Probably full... */
2307 /* Store a dummy placeholder. */
2313 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2314 TDB_INSERT) == -1) {
2315 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2325 /***************************************************************************
2326 Append a jobid to the 'jobs changed' list.
2327 ***************************************************************************/
2329 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2334 SIVAL(&store_jobid, 0, jobid);
2335 data.dptr = (uint8 *)&store_jobid;
2338 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2340 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2344 /***************************************************************************
2345 Start spooling a job - return the jobid.
2346 ***************************************************************************/
2348 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2352 struct printjob pjob;
2354 const char *sharename = lp_const_servicename(snum);
2355 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2363 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2364 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2365 release_print_db(pdb);
2369 if (!print_time_access_check(lp_servicename(snum))) {
2370 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2371 release_print_db(pdb);
2375 path = lp_pathname(snum);
2377 /* see if we have sufficient disk space */
2378 if (lp_minprintspace(snum)) {
2379 SMB_BIG_UINT dspace, dsize;
2380 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2381 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2382 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2383 release_print_db(pdb);
2389 /* for autoloaded printers, check that the printcap entry still exists */
2390 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2391 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2392 release_print_db(pdb);
2397 /* Insure the maximum queue size is not violated */
2398 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2399 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2400 sharename, njobs, lp_maxprintjobs(snum) ));
2401 release_print_db(pdb);
2406 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2407 sharename, njobs, lp_maxprintjobs(snum) ));
2409 if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2412 /* create the database entry */
2416 pjob.pid = sys_getpid();
2419 pjob.starttime = time(NULL);
2420 pjob.status = LPQ_SPOOLING;
2422 pjob.spooled = False;
2424 pjob.nt_devmode = nt_devmode;
2426 fstrcpy(pjob.jobname, jobname);
2428 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2429 fstrcpy(pjob.user, lp_printjob_username(snum));
2430 standard_sub_basic(vuser->user.smb_name, vuser->user.domain,
2431 pjob.user, sizeof(pjob.user)-1);
2432 /* ensure NULL termination */
2433 pjob.user[sizeof(pjob.user)-1] = '\0';
2435 fstrcpy(pjob.user, uidtoname(user->ut.uid));
2438 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2440 /* we have a job entry - now create the spool file */
2441 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2442 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2443 pjob.fd = smb_mkstemp(pjob.filename);
2445 if (pjob.fd == -1) {
2446 if (errno == EACCES) {
2447 /* Common setup error, force a report. */
2448 DEBUG(0, ("print_job_start: insufficient permissions \
2449 to open spool file %s.\n", pjob.filename));
2451 /* Normal case, report at level 3 and above. */
2452 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2453 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2458 pjob_store(sharename, jobid, &pjob);
2460 /* Update the 'jobs changed' entry used by print_queue_status. */
2461 add_to_jobs_changed(pdb, jobid);
2463 /* Ensure we keep a rough count of the number of total jobs... */
2464 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2466 release_print_db(pdb);
2472 pjob_delete(sharename, jobid);
2474 release_print_db(pdb);
2476 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2480 /****************************************************************************
2481 Update the number of pages spooled to jobid
2482 ****************************************************************************/
2484 void print_job_endpage(int snum, uint32 jobid)
2486 const char* sharename = lp_const_servicename(snum);
2487 struct printjob *pjob;
2489 pjob = print_job_find(sharename, jobid);
2492 /* don't allow another process to get this info - it is meaningless */
2493 if (pjob->pid != sys_getpid())
2497 pjob_store(sharename, jobid, pjob);
2500 /****************************************************************************
2501 Print a file - called on closing the file. This spools the job.
2502 If normal close is false then we're tearing down the jobs - treat as an
2504 ****************************************************************************/
2506 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
2508 const char* sharename = lp_const_servicename(snum);
2509 struct printjob *pjob;
2511 SMB_STRUCT_STAT sbuf;
2512 struct printif *current_printif = get_printer_fns( snum );
2514 pjob = print_job_find(sharename, jobid);
2519 if (pjob->spooled || pjob->pid != sys_getpid())
2522 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
2523 (sys_fstat(pjob->fd, &sbuf) == 0)) {
2524 pjob->size = sbuf.st_size;
2530 * Not a normal close or we couldn't stat the job file,
2531 * so something has gone wrong. Cleanup.
2535 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2539 /* Technically, this is not quite right. If the printer has a separator
2540 * page turned on, the NT spooler prints the separator page even if the
2541 * print job is 0 bytes. 010215 JRR */
2542 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2543 /* don't bother spooling empty files or something being deleted. */
2544 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2545 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2546 unlink(pjob->filename);
2547 pjob_delete(sharename, jobid);
2551 pjob->smbjob = jobid;
2553 ret = (*(current_printif->job_submit))(snum, pjob);
2558 /* The print job has been sucessfully handed over to the back-end */
2560 pjob->spooled = True;
2561 pjob->status = LPQ_QUEUED;
2562 pjob_store(sharename, jobid, pjob);
2564 /* make sure the database is up to date */
2565 if (print_cache_expired(lp_const_servicename(snum), True))
2566 print_queue_update(snum, False);
2572 /* The print job was not succesfully started. Cleanup */
2573 /* Still need to add proper error return propagation! 010122:JRR */
2574 unlink(pjob->filename);
2575 pjob_delete(sharename, jobid);
2579 /****************************************************************************
2580 Get a snapshot of jobs in the system without traversing.
2581 ****************************************************************************/
2583 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2585 TDB_DATA data, cgdata;
2586 print_queue_struct *queue = NULL;
2588 uint32 extra_count = 0;
2589 int total_count = 0;
2592 int max_reported_jobs = lp_max_reported_jobs(snum);
2594 const char* sharename = lp_servicename(snum);
2596 /* make sure the database is up to date */
2597 if (print_cache_expired(lp_const_servicename(snum), True))
2598 print_queue_update(snum, False);
2604 ZERO_STRUCT(cgdata);
2606 /* Get the stored queue data. */
2607 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2609 if (data.dptr && data.dsize >= sizeof(qcount))
2610 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2612 /* Get the changed jobs list. */
2613 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2614 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2615 extra_count = cgdata.dsize/4;
2617 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2619 /* Allocate the queue size. */
2620 if (qcount == 0 && extra_count == 0)
2623 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2626 /* Retrieve the linearised queue data. */
2628 for( i = 0; i < qcount; i++) {
2629 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2630 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2639 queue[i].job = qjob;
2640 queue[i].size = qsize;
2641 queue[i].page_count = qpage_count;
2642 queue[i].status = qstatus;
2643 queue[i].priority = qpriority;
2644 queue[i].time = qtime;
2647 total_count = qcount;
2649 /* Add in the changed jobids. */
2650 for( i = 0; i < extra_count; i++) {
2652 struct printjob *pjob;
2654 jobid = IVAL(cgdata.dptr, i*4);
2655 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2656 pjob = print_job_find(lp_const_servicename(snum), jobid);
2658 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2659 remove_from_jobs_changed(sharename, jobid);
2663 queue[total_count].job = jobid;
2664 queue[total_count].size = pjob->size;
2665 queue[total_count].page_count = pjob->page_count;
2666 queue[total_count].status = pjob->status;
2667 queue[total_count].priority = 1;
2668 queue[total_count].time = pjob->starttime;
2669 fstrcpy(queue[total_count].fs_user, pjob->user);
2670 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2674 /* Sort the queue by submission time otherwise they are displayed
2677 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2679 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2681 if (max_reported_jobs && total_count > max_reported_jobs)
2682 total_count = max_reported_jobs;
2685 *pcount = total_count;
2691 SAFE_FREE(data.dptr);
2692 SAFE_FREE(cgdata.dptr);
2696 /****************************************************************************
2697 Get a printer queue listing.
2698 set queue = NULL and status = NULL if you just want to update the cache
2699 ****************************************************************************/
2701 int print_queue_status(int snum,
2702 print_queue_struct **ppqueue,
2703 print_status_struct *status)
2707 const char *sharename;
2708 struct tdb_print_db *pdb;
2711 /* make sure the database is up to date */
2713 if (print_cache_expired(lp_const_servicename(snum), True))
2714 print_queue_update(snum, False);
2716 /* return if we are done */
2717 if ( !ppqueue || !status )
2721 sharename = lp_const_servicename(snum);
2722 pdb = get_print_db_byname(sharename);
2728 * Fetch the queue status. We must do this first, as there may
2729 * be no jobs in the queue.
2732 ZERO_STRUCTP(status);
2733 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2734 key = string_tdb_data(keystr);
2736 data = tdb_fetch(pdb->tdb, key);
2738 if (data.dsize == sizeof(*status)) {
2739 /* this memcpy is ok since the status struct was
2740 not packed before storing it in the tdb */
2741 memcpy(status, data.dptr, sizeof(*status));
2743 SAFE_FREE(data.dptr);
2747 * Now, fetch the print queue information. We first count the number
2748 * of entries, and then only retrieve the queue if necessary.
2751 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2752 release_print_db(pdb);
2756 release_print_db(pdb);
2760 /****************************************************************************
2762 ****************************************************************************/
2764 bool print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2767 struct printif *current_printif = get_printer_fns( snum );
2769 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2770 *errcode = WERR_ACCESS_DENIED;
2777 ret = (*(current_printif->queue_pause))(snum);
2782 *errcode = WERR_INVALID_PARAM;
2786 /* force update the database */
2787 print_cache_flush(lp_const_servicename(snum));
2789 /* Send a printer notify message */
2791 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2796 /****************************************************************************
2798 ****************************************************************************/
2800 bool print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2803 struct printif *current_printif = get_printer_fns( snum );
2805 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2806 *errcode = WERR_ACCESS_DENIED;
2812 ret = (*(current_printif->queue_resume))(snum);
2817 *errcode = WERR_INVALID_PARAM;
2821 /* make sure the database is up to date */
2822 if (print_cache_expired(lp_const_servicename(snum), True))
2823 print_queue_update(snum, True);
2825 /* Send a printer notify message */
2827 notify_printer_status(snum, PRINTER_STATUS_OK);
2832 /****************************************************************************
2833 Purge a queue - implemented by deleting all jobs that we can delete.
2834 ****************************************************************************/
2836 bool print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2838 print_queue_struct *queue;
2839 print_status_struct status;
2843 /* Force and update so the count is accurate (i.e. not a cached count) */
2844 print_queue_update(snum, True);
2846 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2847 njobs = print_queue_status(snum, &queue, &status);
2849 if ( can_job_admin )
2852 for (i=0;i<njobs;i++) {
2853 bool owner = is_owner(user, lp_const_servicename(snum), queue[i].job);
2855 if (owner || can_job_admin) {
2856 print_job_delete1(snum, queue[i].job);
2860 if ( can_job_admin )
2863 /* update the cache */
2864 print_queue_update( snum, True );