r1899: this is 3.0.6 -- will release tomorrow
[Samba.git] / source / printing / printing.c
blob31cb0faa9b0379ac007d57d592c0e30d163106fd
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
24 #include "printing.h"
26 extern SIG_ATOMIC_T got_sig_term;
27 extern SIG_ATOMIC_T reload_after_sighup;
29 /* Current printer interface */
30 static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
32 /*
33 the printing backend revolves around a tdb database that stores the
34 SMB view of the print queue
36 The key for this database is a jobid - a internally generated number that
37 uniquely identifies a print job
39 reading the print queue involves two steps:
40 - possibly running lpq and updating the internal database from that
41 - reading entries from the database
43 jobids are assigned when a job starts spooling.
46 /***************************************************************************
47 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
48 bit RPC jobids.... JRA.
49 ***************************************************************************/
51 static TDB_CONTEXT *rap_tdb;
52 static uint16 next_rap_jobid;
54 uint16 pjobid_to_rap(int snum, uint32 jobid)
56 uint16 rap_jobid;
57 TDB_DATA data, key;
58 char jinfo[8];
60 DEBUG(10,("pjobid_to_rap: called.\n"));
62 if (!rap_tdb) {
63 /* Create the in-memory tdb. */
64 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
65 if (!rap_tdb)
66 return 0;
69 SIVAL(&jinfo,0,(int32)snum);
70 SIVAL(&jinfo,4,jobid);
72 key.dptr = (char *)&jinfo;
73 key.dsize = sizeof(jinfo);
74 data = tdb_fetch(rap_tdb, key);
75 if (data.dptr && data.dsize == sizeof(uint16)) {
76 rap_jobid = SVAL(data.dptr, 0);
77 SAFE_FREE(data.dptr);
78 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
79 (unsigned int)jobid,
80 (unsigned int)rap_jobid));
81 return rap_jobid;
83 SAFE_FREE(data.dptr);
84 /* Not found - create and store mapping. */
85 rap_jobid = ++next_rap_jobid;
86 if (rap_jobid == 0)
87 rap_jobid = ++next_rap_jobid;
88 data.dptr = (char *)&rap_jobid;
89 data.dsize = sizeof(rap_jobid);
90 tdb_store(rap_tdb, key, data, TDB_REPLACE);
91 tdb_store(rap_tdb, data, key, TDB_REPLACE);
93 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
94 (unsigned int)jobid,
95 (unsigned int)rap_jobid));
96 return rap_jobid;
99 BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
101 TDB_DATA data, key;
103 DEBUG(10,("rap_to_pjobid called.\n"));
105 if (!rap_tdb)
106 return False;
108 key.dptr = (char *)&rap_jobid;
109 key.dsize = sizeof(rap_jobid);
110 data = tdb_fetch(rap_tdb, key);
111 if (data.dptr && data.dsize == 8) {
112 *psnum = IVAL(data.dptr,0);
113 *pjobid = IVAL(data.dptr,4);
114 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
115 (unsigned int)*pjobid,
116 (unsigned int)rap_jobid));
117 SAFE_FREE(data.dptr);
118 return True;
121 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
122 (unsigned int)rap_jobid));
123 SAFE_FREE(data.dptr);
124 return False;
127 static void rap_jobid_delete(int snum, uint32 jobid)
129 TDB_DATA key, data;
130 uint16 rap_jobid;
131 char jinfo[8];
133 DEBUG(10,("rap_jobid_delete: called.\n"));
135 if (!rap_tdb)
136 return;
138 SIVAL(&jinfo,0,(int32)snum);
139 SIVAL(&jinfo,4,jobid);
141 key.dptr = (char *)&jinfo;
142 key.dsize = sizeof(jinfo);
143 data = tdb_fetch(rap_tdb, key);
144 if (!data.dptr || (data.dsize != sizeof(uint16))) {
145 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
146 (unsigned int)jobid ));
147 SAFE_FREE(data.dptr);
148 return;
151 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
152 (unsigned int)jobid ));
154 rap_jobid = SVAL(data.dptr, 0);
155 SAFE_FREE(data.dptr);
156 data.dptr = (char *)&rap_jobid;
157 data.dsize = sizeof(rap_jobid);
158 tdb_delete(rap_tdb, key);
159 tdb_delete(rap_tdb, data);
162 static pid_t local_pid;
164 static int get_queue_status(int, print_status_struct *);
166 /****************************************************************************
167 Initialise the printing backend. Called once at startup before the fork().
168 ****************************************************************************/
170 BOOL print_backend_init(void)
172 const char *sversion = "INFO/version";
173 pstring printing_path;
174 int services = lp_numservices();
175 int snum;
177 if (local_pid == sys_getpid())
178 return True;
180 unlink(lock_path("printing.tdb"));
181 pstrcpy(printing_path,lock_path("printing"));
182 mkdir(printing_path,0755);
184 local_pid = sys_getpid();
186 /* handle a Samba upgrade */
188 for (snum = 0; snum < services; snum++) {
189 struct tdb_print_db *pdb;
190 if (!lp_print_ok(snum))
191 continue;
193 pdb = get_print_db_byname(lp_const_servicename(snum));
194 if (!pdb)
195 continue;
196 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
197 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
198 release_print_db(pdb);
199 return False;
201 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
202 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
203 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
205 tdb_unlock_bystring(pdb->tdb, sversion);
206 release_print_db(pdb);
209 close_all_print_db(); /* Don't leave any open. */
211 /* do NT print initialization... */
212 return nt_printing_init();
215 /****************************************************************************
216 Shut down printing backend. Called once at shutdown to close the tdb.
217 ****************************************************************************/
219 void printing_end(void)
221 close_all_print_db(); /* Don't leave any open. */
224 /****************************************************************************
225 Retrieve the set of printing functions for a given service. This allows
226 us to set the printer function table based on the value of the 'printing'
227 service parameter.
229 Use the generic interface as the default and only use cups interface only
230 when asked for (and only when supported)
231 ****************************************************************************/
233 static struct printif *get_printer_fns( int snum )
235 struct printif *printer_fns = &generic_printif;
237 #ifdef HAVE_CUPS
238 if ( lp_printing(snum) == PRINT_CUPS ) {
239 printer_fns = &cups_printif;
241 #endif /* HAVE_CUPS */
243 return printer_fns;
246 /****************************************************************************
247 Useful function to generate a tdb key.
248 ****************************************************************************/
250 static TDB_DATA print_key(uint32 jobid)
252 static uint32 j;
253 TDB_DATA ret;
255 SIVAL(&j, 0, jobid);
256 ret.dptr = (void *)&j;
257 ret.dsize = sizeof(j);
258 return ret;
261 /***********************************************************************
262 unpack a pjob from a tdb buffer
263 ***********************************************************************/
265 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
267 int len = 0;
268 int used;
269 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
270 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
272 if ( !buf || !pjob )
273 return -1;
275 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
276 &pjpid,
277 &pjsysjob,
278 &pjfd,
279 &pjstarttime,
280 &pjstatus,
281 &pjsize,
282 &pjpage_count,
283 &pjspooled,
284 &pjsmbjob,
285 pjob->filename,
286 pjob->jobname,
287 pjob->user,
288 pjob->queuename);
290 if ( len == -1 )
291 return -1;
293 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
294 return -1;
296 len += used;
298 pjob->pid = pjpid;
299 pjob->sysjob = pjsysjob;
300 pjob->fd = pjfd;
301 pjob->starttime = pjstarttime;
302 pjob->status = pjstatus;
303 pjob->size = pjsize;
304 pjob->page_count = pjpage_count;
305 pjob->spooled = pjspooled;
306 pjob->smbjob = pjsmbjob;
308 return len;
312 /****************************************************************************
313 Useful function to find a print job in the database.
314 ****************************************************************************/
316 static struct printjob *print_job_find(int snum, uint32 jobid)
318 static struct printjob pjob;
319 TDB_DATA ret;
320 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
323 if (!pdb)
324 return NULL;
326 ret = tdb_fetch(pdb->tdb, print_key(jobid));
327 release_print_db(pdb);
329 if (!ret.dptr)
330 return NULL;
332 if ( pjob.nt_devmode )
333 free_nt_devicemode( &pjob.nt_devmode );
335 ZERO_STRUCT( pjob );
337 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
338 SAFE_FREE(ret.dptr);
339 return NULL;
342 SAFE_FREE(ret.dptr);
343 return &pjob;
346 /* Convert a unix jobid to a smb jobid */
348 static uint32 sysjob_to_jobid_value;
350 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
351 TDB_DATA data, void *state)
353 struct printjob *pjob;
354 int *sysjob = (int *)state;
356 if (!data.dptr || data.dsize == 0)
357 return 0;
359 pjob = (struct printjob *)data.dptr;
360 if (key.dsize != sizeof(uint32))
361 return 0;
363 if (*sysjob == pjob->sysjob) {
364 uint32 jobid = IVAL(key.dptr,0);
366 sysjob_to_jobid_value = jobid;
367 return 1;
370 return 0;
373 /****************************************************************************
374 This is a *horribly expensive call as we have to iterate through all the
375 current printer tdb's. Don't do this often ! JRA.
376 ****************************************************************************/
378 uint32 sysjob_to_jobid(int unix_jobid)
380 int services = lp_numservices();
381 int snum;
383 sysjob_to_jobid_value = (uint32)-1;
385 for (snum = 0; snum < services; snum++) {
386 struct tdb_print_db *pdb;
387 if (!lp_print_ok(snum))
388 continue;
389 pdb = get_print_db_byname(lp_const_servicename(snum));
390 if (pdb)
391 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
392 release_print_db(pdb);
393 if (sysjob_to_jobid_value != (uint32)-1)
394 return sysjob_to_jobid_value;
396 return (uint32)-1;
399 /****************************************************************************
400 Send notifications based on what has changed after a pjob_store.
401 ****************************************************************************/
403 static struct {
404 uint32 lpq_status;
405 uint32 spoolss_status;
406 } lpq_to_spoolss_status_map[] = {
407 { LPQ_QUEUED, JOB_STATUS_QUEUED },
408 { LPQ_PAUSED, JOB_STATUS_PAUSED },
409 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
410 { LPQ_PRINTING, JOB_STATUS_PRINTING },
411 { LPQ_DELETING, JOB_STATUS_DELETING },
412 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
413 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
414 { LPQ_PRINTED, JOB_STATUS_PRINTED },
415 { LPQ_DELETED, JOB_STATUS_DELETED },
416 { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
417 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
418 { -1, 0 }
421 /* Convert a lpq status value stored in printing.tdb into the
422 appropriate win32 API constant. */
424 static uint32 map_to_spoolss_status(uint32 lpq_status)
426 int i = 0;
428 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
429 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
430 return lpq_to_spoolss_status_map[i].spoolss_status;
431 i++;
434 return 0;
437 static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
438 struct printjob *new_data)
440 BOOL new_job = False;
442 if (!old_data)
443 new_job = True;
445 /* Notify the job name first */
447 if (new_job || !strequal(old_data->jobname, new_data->jobname))
448 notify_job_name(snum, jobid, new_data->jobname);
450 /* Job attributes that can't be changed. We only send
451 notification for these on a new job. */
453 if (new_job) {
454 notify_job_submitted(snum, jobid, new_data->starttime);
455 notify_job_username(snum, jobid, new_data->user);
458 /* Job attributes of a new job or attributes that can be
459 modified. */
461 if (new_job || old_data->status != new_data->status)
462 notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
464 if (new_job || old_data->size != new_data->size)
465 notify_job_total_bytes(snum, jobid, new_data->size);
467 if (new_job || old_data->page_count != new_data->page_count)
468 notify_job_total_pages(snum, jobid, new_data->page_count);
471 /****************************************************************************
472 Store a job structure back to the database.
473 ****************************************************************************/
475 static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
477 TDB_DATA old_data, new_data;
478 BOOL ret = False;
479 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
480 char *buf = NULL;
481 int len, newlen, buflen;
484 if (!pdb)
485 return False;
487 /* Get old data */
489 old_data = tdb_fetch(pdb->tdb, print_key(jobid));
491 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
493 newlen = 0;
495 do {
496 len = 0;
497 buflen = newlen;
498 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
499 (uint32)pjob->pid,
500 (uint32)pjob->sysjob,
501 (uint32)pjob->fd,
502 (uint32)pjob->starttime,
503 (uint32)pjob->status,
504 (uint32)pjob->size,
505 (uint32)pjob->page_count,
506 (uint32)pjob->spooled,
507 (uint32)pjob->smbjob,
508 pjob->filename,
509 pjob->jobname,
510 pjob->user,
511 pjob->queuename);
513 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
515 if (buflen != len) {
516 char *tb;
518 tb = (char *)Realloc(buf, len);
519 if (!tb) {
520 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
521 goto done;
523 else
524 buf = tb;
525 newlen = len;
527 } while ( buflen != len );
530 /* Store new data */
532 new_data.dptr = buf;
533 new_data.dsize = len;
534 ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
536 release_print_db(pdb);
538 /* Send notify updates for what has changed */
540 if ( ret ) {
541 struct printjob old_pjob;
543 if ( old_data.dsize )
545 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
547 pjob_store_notify( snum, jobid, &old_pjob , pjob );
548 free_nt_devicemode( &old_pjob.nt_devmode );
551 else {
552 /* new job */
553 pjob_store_notify( snum, jobid, NULL, pjob );
557 done:
558 SAFE_FREE( old_data.dptr );
559 SAFE_FREE( buf );
561 return ret;
564 /****************************************************************************
565 Remove a job structure from the database.
566 ****************************************************************************/
568 void pjob_delete(int snum, uint32 jobid)
570 struct printjob *pjob = print_job_find(snum, jobid);
571 uint32 job_status = 0;
572 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
574 if (!pdb)
575 return;
577 if (!pjob) {
578 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
579 (unsigned int)jobid));
580 release_print_db(pdb);
581 return;
584 /* Send a notification that a job has been deleted */
586 job_status = map_to_spoolss_status(pjob->status);
588 /* We must cycle through JOB_STATUS_DELETING and
589 JOB_STATUS_DELETED for the port monitor to delete the job
590 properly. */
592 job_status |= JOB_STATUS_DELETING;
593 notify_job_status(snum, jobid, job_status);
595 job_status |= JOB_STATUS_DELETED;
596 notify_job_status(snum, jobid, job_status);
598 /* Remove from printing.tdb */
600 tdb_delete(pdb->tdb, print_key(jobid));
601 release_print_db(pdb);
602 rap_jobid_delete(snum, jobid);
605 /****************************************************************************
606 Parse a file name from the system spooler to generate a jobid.
607 ****************************************************************************/
609 static uint32 print_parse_jobid(char *fname)
611 int jobid;
613 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
614 return (uint32)-1;
615 fname += strlen(PRINT_SPOOL_PREFIX);
617 jobid = atoi(fname);
618 if (jobid <= 0)
619 return (uint32)-1;
621 return (uint32)jobid;
624 /****************************************************************************
625 List a unix job in the print database.
626 ****************************************************************************/
628 static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
630 struct printjob pj, *old_pj;
632 if (jobid == (uint32)-1)
633 jobid = q->job + UNIX_JOB_START;
635 /* Preserve the timestamp on an existing unix print job */
637 old_pj = print_job_find(snum, jobid);
639 ZERO_STRUCT(pj);
641 pj.pid = (pid_t)-1;
642 pj.sysjob = q->job;
643 pj.fd = -1;
644 pj.starttime = old_pj ? old_pj->starttime : q->time;
645 pj.status = q->status;
646 pj.size = q->size;
647 pj.spooled = True;
648 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
649 if (jobid < UNIX_JOB_START) {
650 pj.smbjob = True;
651 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
652 } else {
653 pj.smbjob = False;
654 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
656 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
657 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
659 pjob_store(snum, jobid, &pj);
663 struct traverse_struct {
664 print_queue_struct *queue;
665 int qcount, snum, maxcount, total_jobs;
666 time_t lpq_time;
669 /****************************************************************************
670 Utility fn to delete any jobs that are no longer active.
671 ****************************************************************************/
673 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
675 struct traverse_struct *ts = (struct traverse_struct *)state;
676 struct printjob pjob;
677 uint32 jobid;
678 int i = 0;
680 if ( key.dsize != sizeof(jobid) )
681 return 0;
683 jobid = IVAL(key.dptr, 0);
684 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
685 return 0;
686 free_nt_devicemode( &pjob.nt_devmode );
689 if (ts->snum != lp_servicenumber(pjob.queuename)) {
690 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
691 return 0;
694 if (!pjob.smbjob) {
695 /* remove a unix job if it isn't in the system queue any more */
697 for (i=0;i<ts->qcount;i++) {
698 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
699 if (jobid == u_jobid)
700 break;
702 if (i == ts->qcount) {
703 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
704 (unsigned int)jobid ));
705 pjob_delete(ts->snum, jobid);
706 return 0;
709 /* need to continue the the bottom of the function to
710 save the correct attributes */
713 /* maybe it hasn't been spooled yet */
714 if (!pjob.spooled) {
715 /* if a job is not spooled and the process doesn't
716 exist then kill it. This cleans up after smbd
717 deaths */
718 if (!process_exists(pjob.pid)) {
719 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
720 (unsigned int)jobid, (unsigned int)pjob.pid ));
721 pjob_delete(ts->snum, jobid);
722 } else
723 ts->total_jobs++;
724 return 0;
727 /* this check only makes sense for jobs submitted from Windows clients */
729 if ( pjob.smbjob ) {
730 for (i=0;i<ts->qcount;i++) {
731 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
732 if (jobid == curr_jobid)
733 break;
737 /* The job isn't in the system queue - we have to assume it has
738 completed, so delete the database entry. */
740 if (i == ts->qcount) {
742 /* A race can occur between the time a job is spooled and
743 when it appears in the lpq output. This happens when
744 the job is added to printing.tdb when another smbd
745 running print_queue_update() has completed a lpq and
746 is currently traversing the printing tdb and deleting jobs.
747 Don't delete the job if it was submitted after the lpq_time. */
749 if (pjob.starttime < ts->lpq_time) {
750 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
751 (unsigned int)jobid,
752 (unsigned int)pjob.starttime,
753 (unsigned int)ts->lpq_time ));
754 pjob_delete(ts->snum, jobid);
755 } else
756 ts->total_jobs++;
757 return 0;
760 /* Save the pjob attributes we will store. */
761 /* FIXME!!! This is the only place where queue->job
762 represents the SMB jobid --jerry */
763 ts->queue[i].job = jobid;
764 ts->queue[i].size = pjob.size;
765 ts->queue[i].page_count = pjob.page_count;
766 ts->queue[i].status = pjob.status;
767 ts->queue[i].priority = 1;
768 ts->queue[i].time = pjob.starttime;
769 fstrcpy(ts->queue[i].fs_user, pjob.user);
770 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
772 ts->total_jobs++;
774 return 0;
777 /****************************************************************************
778 Check if the print queue has been updated recently enough.
779 ****************************************************************************/
781 static void print_cache_flush(int snum)
783 fstring key;
784 const char *printername = lp_const_servicename(snum);
785 struct tdb_print_db *pdb = get_print_db_byname(printername);
787 if (!pdb)
788 return;
789 slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
790 tdb_store_int32(pdb->tdb, key, -1);
791 release_print_db(pdb);
794 /****************************************************************************
795 Check if someone already thinks they are doing the update.
796 ****************************************************************************/
798 static pid_t get_updating_pid(fstring printer_name)
800 fstring keystr;
801 TDB_DATA data, key;
802 pid_t updating_pid;
803 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
805 if (!pdb)
806 return (pid_t)-1;
807 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
808 key.dptr = keystr;
809 key.dsize = strlen(keystr);
811 data = tdb_fetch(pdb->tdb, key);
812 release_print_db(pdb);
813 if (!data.dptr || data.dsize != sizeof(pid_t)) {
814 SAFE_FREE(data.dptr);
815 return (pid_t)-1;
818 updating_pid = IVAL(data.dptr, 0);
819 SAFE_FREE(data.dptr);
821 if (process_exists(updating_pid))
822 return updating_pid;
824 return (pid_t)-1;
827 /****************************************************************************
828 Set the fact that we're doing the update, or have finished doing the update
829 in the tdb.
830 ****************************************************************************/
832 static void set_updating_pid(const fstring printer_name, BOOL delete)
834 fstring keystr;
835 TDB_DATA key;
836 TDB_DATA data;
837 pid_t updating_pid = sys_getpid();
838 uint8 buffer[4];
840 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
842 if (!pdb)
843 return;
845 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
846 key.dptr = keystr;
847 key.dsize = strlen(keystr);
849 if (delete) {
850 tdb_delete(pdb->tdb, key);
851 release_print_db(pdb);
852 return;
855 SIVAL( buffer, 0, updating_pid);
856 data.dptr = (void *)buffer;
857 data.dsize = 4; /* we always assume this is a 4 byte value */
859 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
860 release_print_db(pdb);
863 /****************************************************************************
864 Sort print jobs by submittal time.
865 ****************************************************************************/
867 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
869 /* Silly cases */
871 if (!j1 && !j2)
872 return 0;
873 if (!j1)
874 return -1;
875 if (!j2)
876 return 1;
878 /* Sort on job start time */
880 if (j1->time == j2->time)
881 return 0;
882 return (j1->time > j2->time) ? 1 : -1;
885 /****************************************************************************
886 Store the sorted queue representation for later portmon retrieval.
887 ****************************************************************************/
889 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
891 TDB_DATA data, key;
892 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
893 print_queue_struct *queue = pts->queue;
894 size_t len;
895 size_t i;
896 uint qcount;
898 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
899 pts->qcount = max_reported_jobs;
900 qcount = pts->qcount;
902 /* Work out the size. */
903 data.dsize = 0;
904 data.dsize += tdb_pack(NULL, 0, "d", qcount);
906 for (i = 0; i < pts->qcount; i++) {
907 data.dsize += tdb_pack(NULL, 0, "ddddddff",
908 (uint32)queue[i].job,
909 (uint32)queue[i].size,
910 (uint32)queue[i].page_count,
911 (uint32)queue[i].status,
912 (uint32)queue[i].priority,
913 (uint32)queue[i].time,
914 queue[i].fs_user,
915 queue[i].fs_file);
918 if ((data.dptr = malloc(data.dsize)) == NULL)
919 return;
921 len = 0;
922 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
923 for (i = 0; i < pts->qcount; i++) {
924 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
925 (uint32)queue[i].job,
926 (uint32)queue[i].size,
927 (uint32)queue[i].page_count,
928 (uint32)queue[i].status,
929 (uint32)queue[i].priority,
930 (uint32)queue[i].time,
931 queue[i].fs_user,
932 queue[i].fs_file);
935 key.dptr = "INFO/linear_queue_array";
936 key.dsize = strlen(key.dptr);
937 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
938 SAFE_FREE(data.dptr);
939 return;
942 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
944 TDB_DATA data, key;
946 key.dptr = "INFO/jobs_changed";
947 key.dsize = strlen(key.dptr);
948 ZERO_STRUCT(data);
950 data = tdb_fetch(pdb->tdb, key);
951 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
952 SAFE_FREE(data.dptr);
953 ZERO_STRUCT(data);
956 return data;
959 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
961 unsigned int i;
962 unsigned int job_count = data.dsize / 4;
964 for (i = 0; i < job_count; i++) {
965 uint32 ch_jobid;
967 ch_jobid = IVAL(data.dptr, i*4);
968 if (ch_jobid == jobid)
969 remove_from_jobs_changed(snum, jobid);
973 /****************************************************************************
974 Update the internal database from the system print queue for a queue.
975 ****************************************************************************/
977 static void print_queue_update_internal(int snum)
979 int i, qcount;
980 print_queue_struct *queue = NULL;
981 print_status_struct status;
982 print_status_struct old_status;
983 struct printjob *pjob;
984 struct traverse_struct tstruct;
985 fstring keystr, printer_name, cachestr;
986 TDB_DATA data, key;
987 TDB_DATA jcdata;
988 struct tdb_print_db *pdb;
989 struct printif *current_printif = get_printer_fns( snum );
991 fstrcpy(printer_name, lp_const_servicename(snum));
992 pdb = get_print_db_byname(printer_name);
993 if (!pdb)
994 return;
997 * Check to see if someone else is doing this update.
998 * This is essentially a mutex on the update.
1001 if (get_updating_pid(printer_name) != -1) {
1002 release_print_db(pdb);
1003 return;
1006 /* Lock the queue for the database update */
1008 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
1009 /* Only wait 10 seconds for this. */
1010 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1011 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
1012 release_print_db(pdb);
1013 return;
1017 * Ensure that no one else got in here.
1018 * If the updating pid is still -1 then we are
1019 * the winner.
1022 if (get_updating_pid(printer_name) != -1) {
1024 * Someone else is doing the update, exit.
1026 tdb_unlock_bystring(pdb->tdb, keystr);
1027 release_print_db(pdb);
1028 return;
1032 * We're going to do the update ourselves.
1035 /* Tell others we're doing the update. */
1036 set_updating_pid(printer_name, False);
1039 * Allow others to enter and notice we're doing
1040 * the update.
1043 tdb_unlock_bystring(pdb->tdb, keystr);
1046 * Update the cache time FIRST ! Stops others even
1047 * attempting to get the lock and doing this
1048 * if the lpq takes a long time.
1051 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
1052 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1054 /* get the current queue using the appropriate interface */
1055 ZERO_STRUCT(status);
1057 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
1059 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1060 "s" : "", printer_name));
1062 /* Sort the queue by submission time otherwise they are displayed
1063 in hash order. */
1065 qsort(queue, qcount, sizeof(print_queue_struct),
1066 QSORT_CAST(printjob_comp));
1069 any job in the internal database that is marked as spooled
1070 and doesn't exist in the system queue is considered finished
1071 and removed from the database
1073 any job in the system database but not in the internal database
1074 is added as a unix job
1076 fill in any system job numbers as we go
1079 jcdata = get_jobs_changed_data(pdb);
1081 for (i=0; i<qcount; i++) {
1082 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1084 if (jobid == (uint32)-1) {
1085 /* assume its a unix print job */
1086 print_unix_job(snum, &queue[i], jobid);
1087 continue;
1090 /* we have an active SMB print job - update its status */
1091 pjob = print_job_find(snum, jobid);
1092 if (!pjob) {
1093 /* err, somethings wrong. Probably smbd was restarted
1094 with jobs in the queue. All we can do is treat them
1095 like unix jobs. Pity. */
1096 print_unix_job(snum, &queue[i], jobid);
1097 continue;
1100 pjob->sysjob = queue[i].job;
1101 pjob->status = queue[i].status;
1102 pjob_store(snum, jobid, pjob);
1103 check_job_changed(snum, jcdata, jobid);
1106 SAFE_FREE(jcdata.dptr);
1108 /* now delete any queued entries that don't appear in the
1109 system queue */
1110 tstruct.queue = queue;
1111 tstruct.qcount = qcount;
1112 tstruct.snum = snum;
1113 tstruct.total_jobs = 0;
1114 tstruct.lpq_time = time(NULL);
1116 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1118 /* Store the linearised queue, max jobs only. */
1119 store_queue_struct(pdb, &tstruct);
1121 SAFE_FREE(tstruct.queue);
1123 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1124 printer_name, tstruct.total_jobs ));
1126 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1128 get_queue_status(snum, &old_status);
1129 if (old_status.qcount != qcount)
1130 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1131 old_status.qcount, qcount, printer_name ));
1133 /* store the new queue status structure */
1134 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1135 key.dptr = keystr;
1136 key.dsize = strlen(keystr);
1138 status.qcount = qcount;
1139 data.dptr = (void *)&status;
1140 data.dsize = sizeof(status);
1141 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1144 * Update the cache time again. We want to do this call
1145 * as little as possible...
1148 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1149 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1151 /* Delete our pid from the db. */
1152 set_updating_pid(printer_name, True);
1153 release_print_db(pdb);
1156 /****************************************************************************
1157 this is the receive function of the background lpq updater
1158 ****************************************************************************/
1159 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
1161 int snum;
1162 snum=*((int *)buf);
1163 print_queue_update_internal(snum);
1166 static pid_t background_lpq_updater_pid = -1;
1168 /****************************************************************************
1169 main thread of the background lpq updater
1170 ****************************************************************************/
1171 void start_background_queue(void)
1173 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1174 background_lpq_updater_pid = sys_fork();
1176 if (background_lpq_updater_pid == -1) {
1177 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1178 exit(1);
1181 if(background_lpq_updater_pid == 0) {
1182 /* Child. */
1183 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1185 claim_connection( NULL, "smbd lpq backend", 0, False,
1186 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1188 if (!locking_init(0)) {
1189 exit(1);
1192 if (!print_backend_init()) {
1193 exit(1);
1196 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1198 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1199 while (1) {
1200 pause();
1202 /* check for some essential signals first */
1204 if (got_sig_term) {
1205 exit_server("Caught TERM signal");
1208 if (reload_after_sighup) {
1209 change_to_root_user();
1210 DEBUG(1,("Reloading services after SIGHUP\n"));
1211 reload_services(False);
1212 reload_after_sighup = 0;
1215 /* now check for messages */
1217 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1218 message_dispatch();
1223 /****************************************************************************
1224 update the internal database from the system print queue for a queue
1225 ****************************************************************************/
1226 static void print_queue_update(int snum)
1229 * Make sure that the backgroup queueu process exists.
1230 * Otherwise just do the update ourselves
1233 if ( background_lpq_updater_pid != -1 ) {
1234 become_root();
1235 message_send_pid(background_lpq_updater_pid,
1236 MSG_PRINTER_UPDATE, &snum, sizeof(snum),
1237 False);
1238 unbecome_root();
1239 } else
1240 print_queue_update_internal( snum );
1243 /****************************************************************************
1244 Create/Update an entry in the print tdb that will allow us to send notify
1245 updates only to interested smbd's.
1246 ****************************************************************************/
1248 BOOL print_notify_register_pid(int snum)
1250 TDB_DATA data;
1251 struct tdb_print_db *pdb = NULL;
1252 TDB_CONTEXT *tdb = NULL;
1253 const char *printername;
1254 uint32 mypid = (uint32)sys_getpid();
1255 BOOL ret = False;
1256 size_t i;
1258 /* if (snum == -1), then the change notify request was
1259 on a print server handle and we need to register on
1260 all print queus */
1262 if (snum == -1)
1264 int num_services = lp_numservices();
1265 int idx;
1267 for ( idx=0; idx<num_services; idx++ ) {
1268 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1269 print_notify_register_pid(idx);
1272 return True;
1274 else /* register for a specific printer */
1276 printername = lp_const_servicename(snum);
1277 pdb = get_print_db_byname(printername);
1278 if (!pdb)
1279 return False;
1280 tdb = pdb->tdb;
1283 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1284 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1285 printername));
1286 if (pdb)
1287 release_print_db(pdb);
1288 return False;
1291 data = get_printer_notify_pid_list( tdb, printername, True );
1293 /* Add ourselves and increase the refcount. */
1295 for (i = 0; i < data.dsize; i += 8) {
1296 if (IVAL(data.dptr,i) == mypid) {
1297 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1298 SIVAL(data.dptr, i+4, new_refcount);
1299 break;
1303 if (i == data.dsize) {
1304 /* We weren't in the list. Realloc. */
1305 data.dptr = Realloc(data.dptr, data.dsize + 8);
1306 if (!data.dptr) {
1307 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1308 printername));
1309 goto done;
1311 data.dsize += 8;
1312 SIVAL(data.dptr,data.dsize - 8,mypid);
1313 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1316 /* Store back the record. */
1317 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1318 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1319 list for printer %s\n", printername));
1320 goto done;
1323 ret = True;
1325 done:
1327 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1328 if (pdb)
1329 release_print_db(pdb);
1330 SAFE_FREE(data.dptr);
1331 return ret;
1334 /****************************************************************************
1335 Update an entry in the print tdb that will allow us to send notify
1336 updates only to interested smbd's.
1337 ****************************************************************************/
1339 BOOL print_notify_deregister_pid(int snum)
1341 TDB_DATA data;
1342 struct tdb_print_db *pdb = NULL;
1343 TDB_CONTEXT *tdb = NULL;
1344 const char *printername;
1345 uint32 mypid = (uint32)sys_getpid();
1346 size_t i;
1347 BOOL ret = False;
1349 /* if ( snum == -1 ), we are deregister a print server handle
1350 which means to deregister on all print queues */
1352 if (snum == -1)
1354 int num_services = lp_numservices();
1355 int idx;
1357 for ( idx=0; idx<num_services; idx++ ) {
1358 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1359 print_notify_deregister_pid(idx);
1362 return True;
1364 else /* deregister a specific printer */
1366 printername = lp_const_servicename(snum);
1367 pdb = get_print_db_byname(printername);
1368 if (!pdb)
1369 return False;
1370 tdb = pdb->tdb;
1373 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1374 DEBUG(0,("print_notify_register_pid: Failed to lock \
1375 printer %s database\n", printername));
1376 if (pdb)
1377 release_print_db(pdb);
1378 return False;
1381 data = get_printer_notify_pid_list( tdb, printername, True );
1383 /* Reduce refcount. Remove ourselves if zero. */
1385 for (i = 0; i < data.dsize; ) {
1386 if (IVAL(data.dptr,i) == mypid) {
1387 uint32 refcount = IVAL(data.dptr, i+4);
1389 refcount--;
1391 if (refcount == 0) {
1392 if (data.dsize - i > 8)
1393 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1394 data.dsize -= 8;
1395 continue;
1397 SIVAL(data.dptr, i+4, refcount);
1400 i += 8;
1403 if (data.dsize == 0)
1404 SAFE_FREE(data.dptr);
1406 /* Store back the record. */
1407 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1408 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1409 list for printer %s\n", printername));
1410 goto done;
1413 ret = True;
1415 done:
1417 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1418 if (pdb)
1419 release_print_db(pdb);
1420 SAFE_FREE(data.dptr);
1421 return ret;
1424 /****************************************************************************
1425 Check if a jobid is valid. It is valid if it exists in the database.
1426 ****************************************************************************/
1428 BOOL print_job_exists(int snum, uint32 jobid)
1430 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1431 BOOL ret;
1433 if (!pdb)
1434 return False;
1435 ret = tdb_exists(pdb->tdb, print_key(jobid));
1436 release_print_db(pdb);
1437 return ret;
1440 /****************************************************************************
1441 Give the fd used for a jobid.
1442 ****************************************************************************/
1444 int print_job_fd(int snum, uint32 jobid)
1446 struct printjob *pjob = print_job_find(snum, jobid);
1447 if (!pjob)
1448 return -1;
1449 /* don't allow another process to get this info - it is meaningless */
1450 if (pjob->pid != local_pid)
1451 return -1;
1452 return pjob->fd;
1455 /****************************************************************************
1456 Give the filename used for a jobid.
1457 Only valid for the process doing the spooling and when the job
1458 has not been spooled.
1459 ****************************************************************************/
1461 char *print_job_fname(int snum, uint32 jobid)
1463 struct printjob *pjob = print_job_find(snum, jobid);
1464 if (!pjob || pjob->spooled || pjob->pid != local_pid)
1465 return NULL;
1466 return pjob->filename;
1470 /****************************************************************************
1471 Give the filename used for a jobid.
1472 Only valid for the process doing the spooling and when the job
1473 has not been spooled.
1474 ****************************************************************************/
1476 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1478 struct printjob *pjob = print_job_find(snum, jobid);
1480 if ( !pjob )
1481 return NULL;
1483 return pjob->nt_devmode;
1486 /****************************************************************************
1487 Set the place in the queue for a job.
1488 ****************************************************************************/
1490 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1492 DEBUG(2,("print_job_set_place not implemented yet\n"));
1493 return False;
1496 /****************************************************************************
1497 Set the name of a job. Only possible for owner.
1498 ****************************************************************************/
1500 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1502 struct printjob *pjob = print_job_find(snum, jobid);
1503 if (!pjob || pjob->pid != local_pid)
1504 return False;
1506 fstrcpy(pjob->jobname, name);
1507 return pjob_store(snum, jobid, pjob);
1510 /***************************************************************************
1511 Remove a jobid from the 'jobs changed' list.
1512 ***************************************************************************/
1514 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1516 const char *printername = lp_const_servicename(snum);
1517 struct tdb_print_db *pdb = get_print_db_byname(printername);
1518 TDB_DATA data, key;
1519 size_t job_count, i;
1520 BOOL ret = False;
1521 BOOL gotlock = False;
1523 key.dptr = "INFO/jobs_changed";
1524 key.dsize = strlen(key.dptr);
1525 ZERO_STRUCT(data);
1527 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1528 goto out;
1530 gotlock = True;
1532 data = tdb_fetch(pdb->tdb, key);
1534 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1535 goto out;
1537 job_count = data.dsize / 4;
1538 for (i = 0; i < job_count; i++) {
1539 uint32 ch_jobid;
1541 ch_jobid = IVAL(data.dptr, i*4);
1542 if (ch_jobid == jobid) {
1543 if (i < job_count -1 )
1544 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1545 data.dsize -= 4;
1546 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1547 goto out;
1548 break;
1552 ret = True;
1553 out:
1555 if (gotlock)
1556 tdb_chainunlock(pdb->tdb, key);
1557 SAFE_FREE(data.dptr);
1558 release_print_db(pdb);
1559 if (ret)
1560 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1561 else
1562 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1563 return ret;
1566 /****************************************************************************
1567 Delete a print job - don't update queue.
1568 ****************************************************************************/
1570 static BOOL print_job_delete1(int snum, uint32 jobid)
1572 struct printjob *pjob = print_job_find(snum, jobid);
1573 int result = 0;
1574 struct printif *current_printif = get_printer_fns( snum );
1576 if (!pjob)
1577 return False;
1580 * If already deleting just return.
1583 if (pjob->status == LPQ_DELETING)
1584 return True;
1586 /* Hrm - we need to be able to cope with deleting a job before it
1587 has reached the spooler. */
1589 if (pjob->sysjob == -1) {
1590 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1593 /* Set the tdb entry to be deleting. */
1595 pjob->status = LPQ_DELETING;
1596 pjob_store(snum, jobid, pjob);
1598 if (pjob->spooled && pjob->sysjob != -1)
1599 result = (*(current_printif->job_delete))(snum, pjob);
1600 else
1601 remove_from_jobs_changed(snum, jobid);
1603 /* Delete the tdb entry if the delete succeeded or the job hasn't
1604 been spooled. */
1606 if (result == 0) {
1607 const char *printername = lp_const_servicename(snum);
1608 struct tdb_print_db *pdb = get_print_db_byname(printername);
1609 int njobs = 1;
1611 if (!pdb)
1612 return False;
1613 pjob_delete(snum, jobid);
1614 /* Ensure we keep a rough count of the number of total jobs... */
1615 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1616 release_print_db(pdb);
1619 return (result == 0);
1622 /****************************************************************************
1623 Return true if the current user owns the print job.
1624 ****************************************************************************/
1626 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1628 struct printjob *pjob = print_job_find(snum, jobid);
1629 user_struct *vuser;
1631 if (!pjob || !user)
1632 return False;
1634 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1635 return strequal(pjob->user, vuser->user.smb_name);
1636 } else {
1637 return strequal(pjob->user, uidtoname(user->uid));
1641 /****************************************************************************
1642 Delete a print job.
1643 ****************************************************************************/
1645 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1647 BOOL owner, deleted;
1648 char *fname;
1650 *errcode = WERR_OK;
1652 owner = is_owner(user, snum, jobid);
1654 /* Check access against security descriptor or whether the user
1655 owns their job. */
1657 if (!owner &&
1658 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1659 DEBUG(3, ("delete denied by security descriptor\n"));
1660 *errcode = WERR_ACCESS_DENIED;
1662 /* BEGIN_ADMIN_LOG */
1663 sys_adminlog( LOG_ERR,
1664 "Permission denied-- user not allowed to delete, \
1665 pause, or resume print job. User name: %s. Printer name: %s.",
1666 uidtoname(user->uid), PRINTERNAME(snum) );
1667 /* END_ADMIN_LOG */
1669 return False;
1673 * get the spooled filename of the print job
1674 * if this works, then the file has not been spooled
1675 * to the underlying print system. Just delete the
1676 * spool file & return.
1679 if ( (fname = print_job_fname( snum, jobid )) != NULL )
1681 /* remove the spool file */
1682 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1683 if ( unlink( fname ) == -1 ) {
1684 *errcode = map_werror_from_unix(errno);
1685 return False;
1689 if (!print_job_delete1(snum, jobid)) {
1690 *errcode = WERR_ACCESS_DENIED;
1691 return False;
1694 /* force update the database and say the delete failed if the
1695 job still exists */
1697 print_queue_update(snum);
1699 deleted = !print_job_exists(snum, jobid);
1700 if ( !deleted )
1701 *errcode = WERR_ACCESS_DENIED;
1703 return deleted;
1706 /****************************************************************************
1707 Pause a job.
1708 ****************************************************************************/
1710 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1712 struct printjob *pjob = print_job_find(snum, jobid);
1713 int ret = -1;
1714 struct printif *current_printif = get_printer_fns( snum );
1716 if (!pjob || !user)
1717 return False;
1719 if (!pjob->spooled || pjob->sysjob == -1)
1720 return False;
1722 if (!is_owner(user, snum, jobid) &&
1723 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1724 DEBUG(3, ("pause denied by security descriptor\n"));
1726 /* BEGIN_ADMIN_LOG */
1727 sys_adminlog( LOG_ERR,
1728 "Permission denied-- user not allowed to delete, \
1729 pause, or resume print job. User name: %s. Printer name: %s.",
1730 uidtoname(user->uid), PRINTERNAME(snum) );
1731 /* END_ADMIN_LOG */
1733 *errcode = WERR_ACCESS_DENIED;
1734 return False;
1737 /* need to pause the spooled entry */
1738 ret = (*(current_printif->job_pause))(snum, pjob);
1740 if (ret != 0) {
1741 *errcode = WERR_INVALID_PARAM;
1742 return False;
1745 /* force update the database */
1746 print_cache_flush(snum);
1748 /* Send a printer notify message */
1750 notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1752 /* how do we tell if this succeeded? */
1754 return True;
1757 /****************************************************************************
1758 Resume a job.
1759 ****************************************************************************/
1761 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1763 struct printjob *pjob = print_job_find(snum, jobid);
1764 int ret;
1765 struct printif *current_printif = get_printer_fns( snum );
1767 if (!pjob || !user)
1768 return False;
1770 if (!pjob->spooled || pjob->sysjob == -1)
1771 return False;
1773 if (!is_owner(user, snum, jobid) &&
1774 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1775 DEBUG(3, ("resume denied by security descriptor\n"));
1776 *errcode = WERR_ACCESS_DENIED;
1778 /* BEGIN_ADMIN_LOG */
1779 sys_adminlog( LOG_ERR,
1780 "Permission denied-- user not allowed to delete, \
1781 pause, or resume print job. User name: %s. Printer name: %s.",
1782 uidtoname(user->uid), PRINTERNAME(snum) );
1783 /* END_ADMIN_LOG */
1784 return False;
1787 ret = (*(current_printif->job_resume))(snum, pjob);
1789 if (ret != 0) {
1790 *errcode = WERR_INVALID_PARAM;
1791 return False;
1794 /* force update the database */
1795 print_cache_flush(snum);
1797 /* Send a printer notify message */
1799 notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1801 return True;
1804 /****************************************************************************
1805 Write to a print file.
1806 ****************************************************************************/
1808 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1810 int return_code;
1811 struct printjob *pjob = print_job_find(snum, jobid);
1813 if (!pjob)
1814 return -1;
1815 /* don't allow another process to get this info - it is meaningless */
1816 if (pjob->pid != local_pid)
1817 return -1;
1819 return_code = write(pjob->fd, buf, size);
1820 if (return_code>0) {
1821 pjob->size += size;
1822 pjob_store(snum, jobid, pjob);
1824 return return_code;
1827 /****************************************************************************
1828 Check if the print queue has been updated recently enough.
1829 ****************************************************************************/
1831 static BOOL print_cache_expired(int snum)
1833 fstring key;
1834 time_t last_qscan_time, time_now = time(NULL);
1835 const char *printername = lp_const_servicename(snum);
1836 struct tdb_print_db *pdb = get_print_db_byname(printername);
1838 if (!pdb)
1839 return False;
1841 slprintf(key, sizeof(key), "CACHE/%s", printername);
1842 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1845 * Invalidate the queue for 3 reasons.
1846 * (1). last queue scan time == -1.
1847 * (2). Current time - last queue scan time > allowed cache time.
1848 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1849 * This last test picks up machines for which the clock has been moved
1850 * forward, an lpq scan done and then the clock moved back. Otherwise
1851 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1854 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1855 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1856 DEBUG(3, ("print cache expired for queue %s \
1857 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1858 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1859 release_print_db(pdb);
1860 return True;
1862 release_print_db(pdb);
1863 return False;
1866 /****************************************************************************
1867 Get the queue status - do not update if db is out of date.
1868 ****************************************************************************/
1870 static int get_queue_status(int snum, print_status_struct *status)
1872 fstring keystr;
1873 TDB_DATA data, key;
1874 const char *printername = lp_const_servicename(snum);
1875 struct tdb_print_db *pdb = get_print_db_byname(printername);
1876 int len;
1878 if (!pdb)
1879 return 0;
1881 if (status) {
1882 ZERO_STRUCTP(status);
1883 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1884 key.dptr = keystr;
1885 key.dsize = strlen(keystr);
1886 data = tdb_fetch(pdb->tdb, key);
1887 if (data.dptr) {
1888 if (data.dsize == sizeof(print_status_struct))
1889 /* this memcpy is ok since the status struct was
1890 not packed before storing it in the tdb */
1891 memcpy(status, data.dptr, sizeof(print_status_struct));
1892 SAFE_FREE(data.dptr);
1895 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1896 release_print_db(pdb);
1897 return (len == -1 ? 0 : len);
1900 /****************************************************************************
1901 Determine the number of jobs in a queue.
1902 ****************************************************************************/
1904 int print_queue_length(int snum, print_status_struct *pstatus)
1906 print_status_struct status;
1907 int len;
1909 /* make sure the database is up to date */
1910 if (print_cache_expired(snum))
1911 print_queue_update(snum);
1913 /* also fetch the queue status */
1914 memset(&status, 0, sizeof(status));
1915 len = get_queue_status(snum, &status);
1917 if (pstatus)
1918 *pstatus = status;
1920 return len;
1923 /***************************************************************************
1924 Allocate a jobid. Hold the lock for as short a time as possible.
1925 ***************************************************************************/
1927 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1929 int i;
1930 uint32 jobid;
1932 *pjobid = (uint32)-1;
1934 for (i = 0; i < 3; i++) {
1935 /* Lock the database - only wait 20 seconds. */
1936 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1937 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1938 return False;
1941 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1942 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1943 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1944 printername ));
1945 return False;
1947 jobid = 0;
1950 jobid = NEXT_JOBID(jobid);
1952 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1953 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1954 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1955 return False;
1958 /* We've finished with the INFO/nextjob lock. */
1959 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1961 if (!print_job_exists(snum, jobid))
1962 break;
1965 if (i > 2) {
1966 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1967 printername ));
1968 /* Probably full... */
1969 errno = ENOSPC;
1970 return False;
1973 /* Store a dummy placeholder. */
1975 TDB_DATA dum;
1976 dum.dptr = NULL;
1977 dum.dsize = 0;
1978 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1979 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1980 jobid ));
1981 return False;
1985 *pjobid = jobid;
1986 return True;
1989 /***************************************************************************
1990 Append a jobid to the 'jobs changed' list.
1991 ***************************************************************************/
1993 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1995 TDB_DATA data, key;
1996 uint32 store_jobid;
1998 key.dptr = "INFO/jobs_changed";
1999 key.dsize = strlen(key.dptr);
2000 SIVAL(&store_jobid, 0, jobid);
2001 data.dptr = (char *)&store_jobid;
2002 data.dsize = 4;
2004 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2006 return (tdb_append(pdb->tdb, key, data) == 0);
2009 /***************************************************************************
2010 Start spooling a job - return the jobid.
2011 ***************************************************************************/
2013 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2015 uint32 jobid;
2016 char *path;
2017 struct printjob pjob;
2018 user_struct *vuser;
2019 const char *printername = lp_const_servicename(snum);
2020 struct tdb_print_db *pdb = get_print_db_byname(printername);
2021 int njobs;
2023 errno = 0;
2025 if (!pdb)
2026 return (uint32)-1;
2028 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2029 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2030 release_print_db(pdb);
2031 return (uint32)-1;
2034 if (!print_time_access_check(snum)) {
2035 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2036 release_print_db(pdb);
2037 return (uint32)-1;
2040 path = lp_pathname(snum);
2042 /* see if we have sufficient disk space */
2043 if (lp_minprintspace(snum)) {
2044 SMB_BIG_UINT dspace, dsize;
2045 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2046 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2047 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2048 release_print_db(pdb);
2049 errno = ENOSPC;
2050 return (uint32)-1;
2054 /* for autoloaded printers, check that the printcap entry still exists */
2055 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
2056 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2057 release_print_db(pdb);
2058 errno = ENOENT;
2059 return (uint32)-1;
2062 /* Insure the maximum queue size is not violated */
2063 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2064 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2065 printername, njobs, lp_maxprintjobs(snum) ));
2066 release_print_db(pdb);
2067 errno = ENOSPC;
2068 return (uint32)-1;
2071 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2072 printername, njobs, lp_maxprintjobs(snum) ));
2074 if (!allocate_print_jobid(pdb, snum, printername, &jobid))
2075 goto fail;
2077 /* create the database entry */
2079 ZERO_STRUCT(pjob);
2081 pjob.pid = local_pid;
2082 pjob.sysjob = -1;
2083 pjob.fd = -1;
2084 pjob.starttime = time(NULL);
2085 pjob.status = LPQ_SPOOLING;
2086 pjob.size = 0;
2087 pjob.spooled = False;
2088 pjob.smbjob = True;
2089 pjob.nt_devmode = nt_devmode;
2091 fstrcpy(pjob.jobname, jobname);
2093 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2094 fstrcpy(pjob.user, vuser->user.smb_name);
2095 } else {
2096 fstrcpy(pjob.user, uidtoname(user->uid));
2099 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2101 /* we have a job entry - now create the spool file */
2102 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2103 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2104 pjob.fd = smb_mkstemp(pjob.filename);
2106 if (pjob.fd == -1) {
2107 if (errno == EACCES) {
2108 /* Common setup error, force a report. */
2109 DEBUG(0, ("print_job_start: insufficient permissions \
2110 to open spool file %s.\n", pjob.filename));
2111 } else {
2112 /* Normal case, report at level 3 and above. */
2113 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2114 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2116 goto fail;
2119 pjob_store(snum, jobid, &pjob);
2121 /* Update the 'jobs changed' entry used by print_queue_status. */
2122 add_to_jobs_changed(pdb, jobid);
2124 /* Ensure we keep a rough count of the number of total jobs... */
2125 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2127 release_print_db(pdb);
2129 return jobid;
2131 fail:
2132 if (jobid != -1)
2133 pjob_delete(snum, jobid);
2135 release_print_db(pdb);
2137 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2138 return (uint32)-1;
2141 /****************************************************************************
2142 Update the number of pages spooled to jobid
2143 ****************************************************************************/
2145 void print_job_endpage(int snum, uint32 jobid)
2147 struct printjob *pjob = print_job_find(snum, jobid);
2148 if (!pjob)
2149 return;
2150 /* don't allow another process to get this info - it is meaningless */
2151 if (pjob->pid != local_pid)
2152 return;
2154 pjob->page_count++;
2155 pjob_store(snum, jobid, pjob);
2158 /****************************************************************************
2159 Print a file - called on closing the file. This spools the job.
2160 If normal close is false then we're tearing down the jobs - treat as an
2161 error.
2162 ****************************************************************************/
2164 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2166 struct printjob *pjob = print_job_find(snum, jobid);
2167 int ret;
2168 SMB_STRUCT_STAT sbuf;
2169 struct printif *current_printif = get_printer_fns( snum );
2171 if (!pjob)
2172 return False;
2174 if (pjob->spooled || pjob->pid != local_pid)
2175 return False;
2177 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2178 pjob->size = sbuf.st_size;
2179 close(pjob->fd);
2180 pjob->fd = -1;
2181 } else {
2184 * Not a normal close or we couldn't stat the job file,
2185 * so something has gone wrong. Cleanup.
2187 close(pjob->fd);
2188 pjob->fd = -1;
2189 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2190 goto fail;
2193 /* Technically, this is not quite right. If the printer has a separator
2194 * page turned on, the NT spooler prints the separator page even if the
2195 * print job is 0 bytes. 010215 JRR */
2196 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2197 /* don't bother spooling empty files or something being deleted. */
2198 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2199 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2200 unlink(pjob->filename);
2201 pjob_delete(snum, jobid);
2202 return True;
2205 pjob->smbjob = jobid;
2207 ret = (*(current_printif->job_submit))(snum, pjob);
2209 if (ret)
2210 goto fail;
2212 /* The print job has been sucessfully handed over to the back-end */
2214 pjob->spooled = True;
2215 pjob->status = LPQ_QUEUED;
2216 pjob_store(snum, jobid, pjob);
2218 /* make sure the database is up to date */
2219 if (print_cache_expired(snum))
2220 print_queue_update(snum);
2222 return True;
2224 fail:
2226 /* The print job was not succesfully started. Cleanup */
2227 /* Still need to add proper error return propagation! 010122:JRR */
2228 unlink(pjob->filename);
2229 pjob_delete(snum, jobid);
2230 remove_from_jobs_changed(snum, jobid);
2231 return False;
2234 /****************************************************************************
2235 Get a snapshot of jobs in the system without traversing.
2236 ****************************************************************************/
2238 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2240 TDB_DATA data, key, cgdata;
2241 print_queue_struct *queue = NULL;
2242 uint32 qcount = 0;
2243 uint32 extra_count = 0;
2244 int total_count = 0;
2245 size_t len = 0;
2246 uint32 i;
2247 int max_reported_jobs = lp_max_reported_jobs(snum);
2248 BOOL ret = False;
2250 /* make sure the database is up to date */
2251 if (print_cache_expired(snum))
2252 print_queue_update(snum);
2254 *pcount = 0;
2255 *ppqueue = NULL;
2257 ZERO_STRUCT(data);
2258 ZERO_STRUCT(cgdata);
2259 key.dptr = "INFO/linear_queue_array";
2260 key.dsize = strlen(key.dptr);
2262 /* Get the stored queue data. */
2263 data = tdb_fetch(pdb->tdb, key);
2265 if (data.dptr && data.dsize >= sizeof(qcount))
2266 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2268 /* Get the changed jobs list. */
2269 key.dptr = "INFO/jobs_changed";
2270 key.dsize = strlen(key.dptr);
2272 cgdata = tdb_fetch(pdb->tdb, key);
2273 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2274 extra_count = cgdata.dsize/4;
2276 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2278 /* Allocate the queue size. */
2279 if (qcount == 0 && extra_count == 0)
2280 goto out;
2282 if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2283 goto out;
2285 /* Retrieve the linearised queue data. */
2287 for( i = 0; i < qcount; i++) {
2288 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2289 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2290 &qjob,
2291 &qsize,
2292 &qpage_count,
2293 &qstatus,
2294 &qpriority,
2295 &qtime,
2296 queue[i].fs_user,
2297 queue[i].fs_file);
2298 queue[i].job = qjob;
2299 queue[i].size = qsize;
2300 queue[i].page_count = qpage_count;
2301 queue[i].status = qstatus;
2302 queue[i].priority = qpriority;
2303 queue[i].time = qtime;
2306 total_count = qcount;
2308 /* Add in the changed jobids. */
2309 for( i = 0; i < extra_count; i++) {
2310 uint32 jobid;
2311 struct printjob *pjob;
2313 jobid = IVAL(cgdata.dptr, i*4);
2314 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2315 pjob = print_job_find(snum, jobid);
2316 if (!pjob) {
2317 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2318 remove_from_jobs_changed(snum, jobid);
2319 continue;
2322 queue[total_count].job = jobid;
2323 queue[total_count].size = pjob->size;
2324 queue[total_count].page_count = pjob->page_count;
2325 queue[total_count].status = pjob->status;
2326 queue[total_count].priority = 1;
2327 queue[total_count].time = pjob->starttime;
2328 fstrcpy(queue[total_count].fs_user, pjob->user);
2329 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2330 total_count++;
2333 /* Sort the queue by submission time otherwise they are displayed
2334 in hash order. */
2336 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2338 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2340 if (max_reported_jobs && total_count > max_reported_jobs)
2341 total_count = max_reported_jobs;
2343 *ppqueue = queue;
2344 *pcount = total_count;
2346 ret = True;
2348 out:
2350 SAFE_FREE(data.dptr);
2351 SAFE_FREE(cgdata.dptr);
2352 return ret;
2355 /****************************************************************************
2356 Get a printer queue listing.
2357 set queue = NULL and status = NULL if you just want to update the cache
2358 ****************************************************************************/
2360 int print_queue_status(int snum,
2361 print_queue_struct **ppqueue,
2362 print_status_struct *status)
2364 fstring keystr;
2365 TDB_DATA data, key;
2366 const char *printername;
2367 struct tdb_print_db *pdb;
2368 int count = 0;
2370 /* make sure the database is up to date */
2372 if (print_cache_expired(snum))
2373 print_queue_update(snum);
2375 /* return if we are done */
2376 if ( !ppqueue || !status )
2377 return 0;
2379 *ppqueue = NULL;
2380 printername = lp_const_servicename(snum);
2381 pdb = get_print_db_byname(printername);
2383 if (!pdb)
2384 return 0;
2387 * Fetch the queue status. We must do this first, as there may
2388 * be no jobs in the queue.
2391 ZERO_STRUCTP(status);
2392 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2393 key.dptr = keystr;
2394 key.dsize = strlen(keystr);
2395 data = tdb_fetch(pdb->tdb, key);
2396 if (data.dptr) {
2397 if (data.dsize == sizeof(*status)) {
2398 /* this memcpy is ok since the status struct was
2399 not packed before storing it in the tdb */
2400 memcpy(status, data.dptr, sizeof(*status));
2402 SAFE_FREE(data.dptr);
2406 * Now, fetch the print queue information. We first count the number
2407 * of entries, and then only retrieve the queue if necessary.
2410 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2411 release_print_db(pdb);
2412 return 0;
2415 release_print_db(pdb);
2416 return count;
2419 /****************************************************************************
2420 Pause a queue.
2421 ****************************************************************************/
2423 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2425 int ret;
2426 struct printif *current_printif = get_printer_fns( snum );
2428 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2429 *errcode = WERR_ACCESS_DENIED;
2430 return False;
2433 ret = (*(current_printif->queue_pause))(snum);
2435 if (ret != 0) {
2436 *errcode = WERR_INVALID_PARAM;
2437 return False;
2440 /* force update the database */
2441 print_cache_flush(snum);
2443 /* Send a printer notify message */
2445 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2447 return True;
2450 /****************************************************************************
2451 Resume a queue.
2452 ****************************************************************************/
2454 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2456 int ret;
2457 struct printif *current_printif = get_printer_fns( snum );
2459 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2460 *errcode = WERR_ACCESS_DENIED;
2461 return False;
2464 ret = (*(current_printif->queue_resume))(snum);
2466 if (ret != 0) {
2467 *errcode = WERR_INVALID_PARAM;
2468 return False;
2471 /* make sure the database is up to date */
2472 if (print_cache_expired(snum))
2473 print_queue_update(snum);
2475 /* Send a printer notify message */
2477 notify_printer_status(snum, PRINTER_STATUS_OK);
2479 return True;
2482 /****************************************************************************
2483 Purge a queue - implemented by deleting all jobs that we can delete.
2484 ****************************************************************************/
2486 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2488 print_queue_struct *queue;
2489 print_status_struct status;
2490 int njobs, i;
2491 BOOL can_job_admin;
2493 /* Force and update so the count is accurate (i.e. not a cached count) */
2494 print_queue_update(snum);
2496 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2497 njobs = print_queue_status(snum, &queue, &status);
2499 for (i=0;i<njobs;i++) {
2500 BOOL owner = is_owner(user, snum, queue[i].job);
2502 if (owner || can_job_admin) {
2503 print_job_delete1(snum, queue[i].job);
2507 SAFE_FREE(queue);
2509 return True;