r1383: sync from 3.0 tree
[Samba.git] / source / printing / printing.c
blob8beea9d0cec91334b33509b311530f5c236891d4
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);
603 remove_from_jobs_changed( snum, jobid );
606 /****************************************************************************
607 Parse a file name from the system spooler to generate a jobid.
608 ****************************************************************************/
610 static uint32 print_parse_jobid(char *fname)
612 int jobid;
614 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
615 return (uint32)-1;
616 fname += strlen(PRINT_SPOOL_PREFIX);
618 jobid = atoi(fname);
619 if (jobid <= 0)
620 return (uint32)-1;
622 return (uint32)jobid;
625 /****************************************************************************
626 List a unix job in the print database.
627 ****************************************************************************/
629 static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
631 struct printjob pj, *old_pj;
633 if (jobid == (uint32)-1)
634 jobid = q->job + UNIX_JOB_START;
636 /* Preserve the timestamp on an existing unix print job */
638 old_pj = print_job_find(snum, jobid);
640 ZERO_STRUCT(pj);
642 pj.pid = (pid_t)-1;
643 pj.sysjob = q->job;
644 pj.fd = -1;
645 pj.starttime = old_pj ? old_pj->starttime : q->time;
646 pj.status = q->status;
647 pj.size = q->size;
648 pj.spooled = True;
649 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
650 if (jobid < UNIX_JOB_START) {
651 pj.smbjob = True;
652 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
653 } else {
654 pj.smbjob = False;
655 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
657 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
658 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
660 pjob_store(snum, jobid, &pj);
664 struct traverse_struct {
665 print_queue_struct *queue;
666 int qcount, snum, maxcount, total_jobs;
667 time_t lpq_time;
670 /****************************************************************************
671 Utility fn to delete any jobs that are no longer active.
672 ****************************************************************************/
674 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
676 struct traverse_struct *ts = (struct traverse_struct *)state;
677 struct printjob pjob;
678 uint32 jobid;
679 int i = 0;
681 if ( key.dsize != sizeof(jobid) )
682 return 0;
684 jobid = IVAL(key.dptr, 0);
685 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
686 return 0;
687 free_nt_devicemode( &pjob.nt_devmode );
690 if (ts->snum != lp_servicenumber(pjob.queuename)) {
691 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
692 return 0;
695 if (!pjob.smbjob) {
696 /* remove a unix job if it isn't in the system queue any more */
698 for (i=0;i<ts->qcount;i++) {
699 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
700 if (jobid == u_jobid)
701 break;
703 if (i == ts->qcount) {
704 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
705 (unsigned int)jobid ));
706 pjob_delete(ts->snum, jobid);
707 return 0;
710 /* need to continue the the bottom of the function to
711 save the correct attributes */
714 /* maybe it hasn't been spooled yet */
715 if (!pjob.spooled) {
716 /* if a job is not spooled and the process doesn't
717 exist then kill it. This cleans up after smbd
718 deaths */
719 if (!process_exists(pjob.pid)) {
720 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
721 (unsigned int)jobid, (unsigned int)pjob.pid ));
722 pjob_delete(ts->snum, jobid);
723 } else
724 ts->total_jobs++;
725 return 0;
728 /* this check only makes sense for jobs submitted from Windows clients */
730 if ( pjob.smbjob ) {
731 for (i=0;i<ts->qcount;i++) {
732 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
733 if (jobid == curr_jobid)
734 break;
738 /* The job isn't in the system queue - we have to assume it has
739 completed, so delete the database entry. */
741 if (i == ts->qcount) {
743 /* A race can occur between the time a job is spooled and
744 when it appears in the lpq output. This happens when
745 the job is added to printing.tdb when another smbd
746 running print_queue_update() has completed a lpq and
747 is currently traversing the printing tdb and deleting jobs.
748 Don't delete the job if it was submitted after the lpq_time. */
750 if (pjob.starttime < ts->lpq_time) {
751 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
752 (unsigned int)jobid,
753 (unsigned int)pjob.starttime,
754 (unsigned int)ts->lpq_time ));
755 pjob_delete(ts->snum, jobid);
756 } else
757 ts->total_jobs++;
758 return 0;
761 /* Save the pjob attributes we will store. */
762 /* FIXME!!! This is the only place where queue->job
763 represents the SMB jobid --jerry */
764 ts->queue[i].job = jobid;
765 ts->queue[i].size = pjob.size;
766 ts->queue[i].page_count = pjob.page_count;
767 ts->queue[i].status = pjob.status;
768 ts->queue[i].priority = 1;
769 ts->queue[i].time = pjob.starttime;
770 fstrcpy(ts->queue[i].fs_user, pjob.user);
771 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
773 ts->total_jobs++;
775 return 0;
778 /****************************************************************************
779 Check if the print queue has been updated recently enough.
780 ****************************************************************************/
782 static void print_cache_flush(int snum)
784 fstring key;
785 const char *printername = lp_const_servicename(snum);
786 struct tdb_print_db *pdb = get_print_db_byname(printername);
788 if (!pdb)
789 return;
790 slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
791 tdb_store_int32(pdb->tdb, key, -1);
792 release_print_db(pdb);
795 /****************************************************************************
796 Check if someone already thinks they are doing the update.
797 ****************************************************************************/
799 static pid_t get_updating_pid(fstring printer_name)
801 fstring keystr;
802 TDB_DATA data, key;
803 pid_t updating_pid;
804 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
806 if (!pdb)
807 return (pid_t)-1;
808 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
809 key.dptr = keystr;
810 key.dsize = strlen(keystr);
812 data = tdb_fetch(pdb->tdb, key);
813 release_print_db(pdb);
814 if (!data.dptr || data.dsize != sizeof(pid_t)) {
815 SAFE_FREE(data.dptr);
816 return (pid_t)-1;
819 updating_pid = IVAL(data.dptr, 0);
820 SAFE_FREE(data.dptr);
822 if (process_exists(updating_pid))
823 return updating_pid;
825 return (pid_t)-1;
828 /****************************************************************************
829 Set the fact that we're doing the update, or have finished doing the update
830 in the tdb.
831 ****************************************************************************/
833 static void set_updating_pid(const fstring printer_name, BOOL delete)
835 fstring keystr;
836 TDB_DATA key;
837 TDB_DATA data;
838 pid_t updating_pid = sys_getpid();
839 uint8 buffer[4];
841 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
843 if (!pdb)
844 return;
846 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
847 key.dptr = keystr;
848 key.dsize = strlen(keystr);
850 if (delete) {
851 tdb_delete(pdb->tdb, key);
852 release_print_db(pdb);
853 return;
856 SIVAL( buffer, 0, updating_pid);
857 data.dptr = (void *)buffer;
858 data.dsize = 4; /* we always assume this is a 4 byte value */
860 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
861 release_print_db(pdb);
864 /****************************************************************************
865 Sort print jobs by submittal time.
866 ****************************************************************************/
868 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
870 /* Silly cases */
872 if (!j1 && !j2)
873 return 0;
874 if (!j1)
875 return -1;
876 if (!j2)
877 return 1;
879 /* Sort on job start time */
881 if (j1->time == j2->time)
882 return 0;
883 return (j1->time > j2->time) ? 1 : -1;
886 /****************************************************************************
887 Store the sorted queue representation for later portmon retrieval.
888 ****************************************************************************/
890 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
892 TDB_DATA data, key;
893 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
894 print_queue_struct *queue = pts->queue;
895 size_t len;
896 size_t i;
897 uint qcount;
899 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
900 pts->qcount = max_reported_jobs;
901 qcount = pts->qcount;
903 /* Work out the size. */
904 data.dsize = 0;
905 data.dsize += tdb_pack(NULL, 0, "d", qcount);
907 for (i = 0; i < pts->qcount; i++) {
908 data.dsize += tdb_pack(NULL, 0, "ddddddff",
909 (uint32)queue[i].job,
910 (uint32)queue[i].size,
911 (uint32)queue[i].page_count,
912 (uint32)queue[i].status,
913 (uint32)queue[i].priority,
914 (uint32)queue[i].time,
915 queue[i].fs_user,
916 queue[i].fs_file);
919 if ((data.dptr = malloc(data.dsize)) == NULL)
920 return;
922 len = 0;
923 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
924 for (i = 0; i < pts->qcount; i++) {
925 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
926 (uint32)queue[i].job,
927 (uint32)queue[i].size,
928 (uint32)queue[i].page_count,
929 (uint32)queue[i].status,
930 (uint32)queue[i].priority,
931 (uint32)queue[i].time,
932 queue[i].fs_user,
933 queue[i].fs_file);
936 key.dptr = "INFO/linear_queue_array";
937 key.dsize = strlen(key.dptr);
938 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
939 SAFE_FREE(data.dptr);
940 return;
943 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
945 TDB_DATA data, key;
947 key.dptr = "INFO/jobs_changed";
948 key.dsize = strlen(key.dptr);
949 ZERO_STRUCT(data);
951 data = tdb_fetch(pdb->tdb, key);
952 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
953 SAFE_FREE(data.dptr);
954 ZERO_STRUCT(data);
957 return data;
960 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
962 unsigned int i;
963 unsigned int job_count = data.dsize / 4;
965 for (i = 0; i < job_count; i++) {
966 uint32 ch_jobid;
968 ch_jobid = IVAL(data.dptr, i*4);
969 if (ch_jobid == jobid)
970 remove_from_jobs_changed(snum, jobid);
974 /****************************************************************************
975 Update the internal database from the system print queue for a queue.
976 ****************************************************************************/
978 static void print_queue_update_internal(int snum)
980 int i, qcount;
981 print_queue_struct *queue = NULL;
982 print_status_struct status;
983 print_status_struct old_status;
984 struct printjob *pjob;
985 struct traverse_struct tstruct;
986 fstring keystr, printer_name, cachestr;
987 TDB_DATA data, key;
988 TDB_DATA jcdata;
989 struct tdb_print_db *pdb;
990 struct printif *current_printif = get_printer_fns( snum );
992 fstrcpy(printer_name, lp_const_servicename(snum));
993 pdb = get_print_db_byname(printer_name);
994 if (!pdb)
995 return;
998 * Check to see if someone else is doing this update.
999 * This is essentially a mutex on the update.
1002 if (get_updating_pid(printer_name) != -1) {
1003 release_print_db(pdb);
1004 return;
1007 /* Lock the queue for the database update */
1009 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
1010 /* Only wait 10 seconds for this. */
1011 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1012 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
1013 release_print_db(pdb);
1014 return;
1018 * Ensure that no one else got in here.
1019 * If the updating pid is still -1 then we are
1020 * the winner.
1023 if (get_updating_pid(printer_name) != -1) {
1025 * Someone else is doing the update, exit.
1027 tdb_unlock_bystring(pdb->tdb, keystr);
1028 release_print_db(pdb);
1029 return;
1033 * We're going to do the update ourselves.
1036 /* Tell others we're doing the update. */
1037 set_updating_pid(printer_name, False);
1040 * Allow others to enter and notice we're doing
1041 * the update.
1044 tdb_unlock_bystring(pdb->tdb, keystr);
1047 * Update the cache time FIRST ! Stops others even
1048 * attempting to get the lock and doing this
1049 * if the lpq takes a long time.
1052 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
1053 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1055 /* get the current queue using the appropriate interface */
1056 ZERO_STRUCT(status);
1058 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
1060 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1061 "s" : "", printer_name));
1063 /* Sort the queue by submission time otherwise they are displayed
1064 in hash order. */
1066 qsort(queue, qcount, sizeof(print_queue_struct),
1067 QSORT_CAST(printjob_comp));
1070 any job in the internal database that is marked as spooled
1071 and doesn't exist in the system queue is considered finished
1072 and removed from the database
1074 any job in the system database but not in the internal database
1075 is added as a unix job
1077 fill in any system job numbers as we go
1080 jcdata = get_jobs_changed_data(pdb);
1082 for (i=0; i<qcount; i++) {
1083 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1085 if (jobid == (uint32)-1) {
1086 /* assume its a unix print job */
1087 print_unix_job(snum, &queue[i], jobid);
1088 continue;
1091 /* we have an active SMB print job - update its status */
1092 pjob = print_job_find(snum, jobid);
1093 if (!pjob) {
1094 /* err, somethings wrong. Probably smbd was restarted
1095 with jobs in the queue. All we can do is treat them
1096 like unix jobs. Pity. */
1097 print_unix_job(snum, &queue[i], jobid);
1098 continue;
1101 pjob->sysjob = queue[i].job;
1102 pjob->status = queue[i].status;
1103 pjob_store(snum, jobid, pjob);
1104 check_job_changed(snum, jcdata, jobid);
1107 SAFE_FREE(jcdata.dptr);
1109 /* now delete any queued entries that don't appear in the
1110 system queue */
1111 tstruct.queue = queue;
1112 tstruct.qcount = qcount;
1113 tstruct.snum = snum;
1114 tstruct.total_jobs = 0;
1115 tstruct.lpq_time = time(NULL);
1117 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1119 /* Store the linearised queue, max jobs only. */
1120 store_queue_struct(pdb, &tstruct);
1122 SAFE_FREE(tstruct.queue);
1124 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1125 printer_name, tstruct.total_jobs ));
1127 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1129 get_queue_status(snum, &old_status);
1130 if (old_status.qcount != qcount)
1131 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1132 old_status.qcount, qcount, printer_name ));
1134 /* store the new queue status structure */
1135 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1136 key.dptr = keystr;
1137 key.dsize = strlen(keystr);
1139 status.qcount = qcount;
1140 data.dptr = (void *)&status;
1141 data.dsize = sizeof(status);
1142 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1145 * Update the cache time again. We want to do this call
1146 * as little as possible...
1149 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1150 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1152 /* Delete our pid from the db. */
1153 set_updating_pid(printer_name, True);
1154 release_print_db(pdb);
1157 /****************************************************************************
1158 this is the receive function of the background lpq updater
1159 ****************************************************************************/
1160 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
1162 int snum;
1163 snum=*((int *)buf);
1164 print_queue_update_internal(snum);
1167 static pid_t background_lpq_updater_pid = -1;
1169 /****************************************************************************
1170 main thread of the background lpq updater
1171 ****************************************************************************/
1172 void start_background_queue(void)
1174 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1175 background_lpq_updater_pid = sys_fork();
1177 if (background_lpq_updater_pid == -1) {
1178 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1179 exit(1);
1182 if(background_lpq_updater_pid == 0) {
1183 /* Child. */
1184 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1186 claim_connection( NULL, "smbd lpq backend", 0, False,
1187 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINTING );
1189 if (!locking_init(0)) {
1190 exit(1);
1193 if (!print_backend_init()) {
1194 exit(1);
1197 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1199 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1200 while (1) {
1201 pause();
1203 /* check for some essential signals first */
1205 if (got_sig_term) {
1206 exit_server("Caught TERM signal");
1209 if (reload_after_sighup) {
1210 change_to_root_user();
1211 DEBUG(1,("Reloading services after SIGHUP\n"));
1212 reload_services(False);
1213 reload_after_sighup = 0;
1216 /* now check for messages */
1218 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1219 message_dispatch();
1224 /****************************************************************************
1225 update the internal database from the system print queue for a queue
1226 ****************************************************************************/
1227 static void print_queue_update(int snum)
1230 * Make sure that the backgroup queueu process exists.
1231 * Otherwise just do the update ourselves
1234 if ( background_lpq_updater_pid != -1 ) {
1235 become_root();
1236 message_send_pid(background_lpq_updater_pid,
1237 MSG_PRINTER_UPDATE, &snum, sizeof(snum),
1238 False);
1239 unbecome_root();
1240 } else
1241 print_queue_update_internal( snum );
1244 /****************************************************************************
1245 Create/Update an entry in the print tdb that will allow us to send notify
1246 updates only to interested smbd's.
1247 ****************************************************************************/
1249 BOOL print_notify_register_pid(int snum)
1251 TDB_DATA data;
1252 struct tdb_print_db *pdb = NULL;
1253 TDB_CONTEXT *tdb = NULL;
1254 const char *printername;
1255 uint32 mypid = (uint32)sys_getpid();
1256 BOOL ret = False;
1257 size_t i;
1259 /* if (snum == -1), then the change notify request was
1260 on a print server handle and we need to register on
1261 all print queus */
1263 if (snum == -1)
1265 int num_services = lp_numservices();
1266 int idx;
1268 for ( idx=0; idx<num_services; idx++ ) {
1269 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1270 print_notify_register_pid(idx);
1273 return True;
1275 else /* register for a specific printer */
1277 printername = lp_const_servicename(snum);
1278 pdb = get_print_db_byname(printername);
1279 if (!pdb)
1280 return False;
1281 tdb = pdb->tdb;
1284 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1285 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1286 printername));
1287 if (pdb)
1288 release_print_db(pdb);
1289 return False;
1292 data = get_printer_notify_pid_list( tdb, printername, True );
1294 /* Add ourselves and increase the refcount. */
1296 for (i = 0; i < data.dsize; i += 8) {
1297 if (IVAL(data.dptr,i) == mypid) {
1298 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1299 SIVAL(data.dptr, i+4, new_refcount);
1300 break;
1304 if (i == data.dsize) {
1305 /* We weren't in the list. Realloc. */
1306 data.dptr = Realloc(data.dptr, data.dsize + 8);
1307 if (!data.dptr) {
1308 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1309 printername));
1310 goto done;
1312 data.dsize += 8;
1313 SIVAL(data.dptr,data.dsize - 8,mypid);
1314 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1317 /* Store back the record. */
1318 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1319 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1320 list for printer %s\n", printername));
1321 goto done;
1324 ret = True;
1326 done:
1328 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1329 if (pdb)
1330 release_print_db(pdb);
1331 SAFE_FREE(data.dptr);
1332 return ret;
1335 /****************************************************************************
1336 Update an entry in the print tdb that will allow us to send notify
1337 updates only to interested smbd's.
1338 ****************************************************************************/
1340 BOOL print_notify_deregister_pid(int snum)
1342 TDB_DATA data;
1343 struct tdb_print_db *pdb = NULL;
1344 TDB_CONTEXT *tdb = NULL;
1345 const char *printername;
1346 uint32 mypid = (uint32)sys_getpid();
1347 size_t i;
1348 BOOL ret = False;
1350 /* if ( snum == -1 ), we are deregister a print server handle
1351 which means to deregister on all print queues */
1353 if (snum == -1)
1355 int num_services = lp_numservices();
1356 int idx;
1358 for ( idx=0; idx<num_services; idx++ ) {
1359 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1360 print_notify_deregister_pid(idx);
1363 return True;
1365 else /* deregister a specific printer */
1367 printername = lp_const_servicename(snum);
1368 pdb = get_print_db_byname(printername);
1369 if (!pdb)
1370 return False;
1371 tdb = pdb->tdb;
1374 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1375 DEBUG(0,("print_notify_register_pid: Failed to lock \
1376 printer %s database\n", printername));
1377 if (pdb)
1378 release_print_db(pdb);
1379 return False;
1382 data = get_printer_notify_pid_list( tdb, printername, True );
1384 /* Reduce refcount. Remove ourselves if zero. */
1386 for (i = 0; i < data.dsize; ) {
1387 if (IVAL(data.dptr,i) == mypid) {
1388 uint32 refcount = IVAL(data.dptr, i+4);
1390 refcount--;
1392 if (refcount == 0) {
1393 if (data.dsize - i > 8)
1394 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1395 data.dsize -= 8;
1396 continue;
1398 SIVAL(data.dptr, i+4, refcount);
1401 i += 8;
1404 if (data.dsize == 0)
1405 SAFE_FREE(data.dptr);
1407 /* Store back the record. */
1408 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1409 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1410 list for printer %s\n", printername));
1411 goto done;
1414 ret = True;
1416 done:
1418 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1419 if (pdb)
1420 release_print_db(pdb);
1421 SAFE_FREE(data.dptr);
1422 return ret;
1425 /****************************************************************************
1426 Check if a jobid is valid. It is valid if it exists in the database.
1427 ****************************************************************************/
1429 BOOL print_job_exists(int snum, uint32 jobid)
1431 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1432 BOOL ret;
1434 if (!pdb)
1435 return False;
1436 ret = tdb_exists(pdb->tdb, print_key(jobid));
1437 release_print_db(pdb);
1438 return ret;
1441 /****************************************************************************
1442 Give the fd used for a jobid.
1443 ****************************************************************************/
1445 int print_job_fd(int snum, uint32 jobid)
1447 struct printjob *pjob = print_job_find(snum, jobid);
1448 if (!pjob)
1449 return -1;
1450 /* don't allow another process to get this info - it is meaningless */
1451 if (pjob->pid != local_pid)
1452 return -1;
1453 return pjob->fd;
1456 /****************************************************************************
1457 Give the filename used for a jobid.
1458 Only valid for the process doing the spooling and when the job
1459 has not been spooled.
1460 ****************************************************************************/
1462 char *print_job_fname(int snum, uint32 jobid)
1464 struct printjob *pjob = print_job_find(snum, jobid);
1465 if (!pjob || pjob->spooled || pjob->pid != local_pid)
1466 return NULL;
1467 return pjob->filename;
1471 /****************************************************************************
1472 Give the filename used for a jobid.
1473 Only valid for the process doing the spooling and when the job
1474 has not been spooled.
1475 ****************************************************************************/
1477 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1479 struct printjob *pjob = print_job_find(snum, jobid);
1481 if ( !pjob )
1482 return NULL;
1484 return pjob->nt_devmode;
1487 /****************************************************************************
1488 Set the place in the queue for a job.
1489 ****************************************************************************/
1491 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1493 DEBUG(2,("print_job_set_place not implemented yet\n"));
1494 return False;
1497 /****************************************************************************
1498 Set the name of a job. Only possible for owner.
1499 ****************************************************************************/
1501 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1503 struct printjob *pjob = print_job_find(snum, jobid);
1504 if (!pjob || pjob->pid != local_pid)
1505 return False;
1507 fstrcpy(pjob->jobname, name);
1508 return pjob_store(snum, jobid, pjob);
1511 /***************************************************************************
1512 Remove a jobid from the 'jobs changed' list.
1513 ***************************************************************************/
1515 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1517 const char *printername = lp_const_servicename(snum);
1518 struct tdb_print_db *pdb = get_print_db_byname(printername);
1519 TDB_DATA data, key;
1520 size_t job_count, i;
1521 BOOL ret = False;
1522 BOOL gotlock = False;
1524 key.dptr = "INFO/jobs_changed";
1525 key.dsize = strlen(key.dptr);
1526 ZERO_STRUCT(data);
1528 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1529 goto out;
1531 gotlock = True;
1533 data = tdb_fetch(pdb->tdb, key);
1535 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1536 goto out;
1538 job_count = data.dsize / 4;
1539 for (i = 0; i < job_count; i++) {
1540 uint32 ch_jobid;
1542 ch_jobid = IVAL(data.dptr, i*4);
1543 if (ch_jobid == jobid) {
1544 if (i < job_count -1 )
1545 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1546 data.dsize -= 4;
1547 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1548 goto out;
1549 break;
1553 ret = True;
1554 out:
1556 if (gotlock)
1557 tdb_chainunlock(pdb->tdb, key);
1558 SAFE_FREE(data.dptr);
1559 release_print_db(pdb);
1560 if (ret)
1561 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1562 else
1563 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1564 return ret;
1567 /****************************************************************************
1568 Delete a print job - don't update queue.
1569 ****************************************************************************/
1571 static BOOL print_job_delete1(int snum, uint32 jobid)
1573 struct printjob *pjob = print_job_find(snum, jobid);
1574 int result = 0;
1575 struct printif *current_printif = get_printer_fns( snum );
1577 if (!pjob)
1578 return False;
1581 * If already deleting just return.
1584 if (pjob->status == LPQ_DELETING)
1585 return True;
1587 /* Hrm - we need to be able to cope with deleting a job before it
1588 has reached the spooler. */
1590 if (pjob->sysjob == -1) {
1591 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1594 /* Set the tdb entry to be deleting. */
1596 pjob->status = LPQ_DELETING;
1597 pjob_store(snum, jobid, pjob);
1599 if (pjob->spooled && pjob->sysjob != -1)
1600 result = (*(current_printif->job_delete))(snum, pjob);
1601 else
1602 remove_from_jobs_changed(snum, jobid);
1604 /* Delete the tdb entry if the delete succeeded or the job hasn't
1605 been spooled. */
1607 if (result == 0) {
1608 const char *printername = lp_const_servicename(snum);
1609 struct tdb_print_db *pdb = get_print_db_byname(printername);
1610 int njobs = 1;
1612 if (!pdb)
1613 return False;
1614 pjob_delete(snum, jobid);
1615 /* Ensure we keep a rough count of the number of total jobs... */
1616 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1617 release_print_db(pdb);
1620 return (result == 0);
1623 /****************************************************************************
1624 Return true if the current user owns the print job.
1625 ****************************************************************************/
1627 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1629 struct printjob *pjob = print_job_find(snum, jobid);
1630 user_struct *vuser;
1632 if (!pjob || !user)
1633 return False;
1635 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1636 return strequal(pjob->user, vuser->user.smb_name);
1637 } else {
1638 return strequal(pjob->user, uidtoname(user->uid));
1642 /****************************************************************************
1643 Delete a print job.
1644 ****************************************************************************/
1646 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1648 BOOL owner, deleted;
1649 char *fname;
1651 *errcode = WERR_OK;
1653 owner = is_owner(user, snum, jobid);
1655 /* Check access against security descriptor or whether the user
1656 owns their job. */
1658 if (!owner &&
1659 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1660 DEBUG(3, ("delete denied by security descriptor\n"));
1661 *errcode = WERR_ACCESS_DENIED;
1663 /* BEGIN_ADMIN_LOG */
1664 sys_adminlog( LOG_ERR,
1665 "Permission denied-- user not allowed to delete, \
1666 pause, or resume print job. User name: %s. Printer name: %s.",
1667 uidtoname(user->uid), PRINTERNAME(snum) );
1668 /* END_ADMIN_LOG */
1670 return False;
1674 * get the spooled filename of the print job
1675 * if this works, then the file has not been spooled
1676 * to the underlying print system. Just delete the
1677 * spool file & return.
1680 if ( (fname = print_job_fname( snum, jobid )) != NULL )
1682 /* remove the spool file */
1683 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1684 if ( unlink( fname ) == -1 ) {
1685 *errcode = map_werror_from_unix(errno);
1686 return False;
1689 return True;
1692 if (!print_job_delete1(snum, jobid)) {
1693 *errcode = WERR_ACCESS_DENIED;
1694 return False;
1697 /* force update the database and say the delete failed if the
1698 job still exists */
1700 print_queue_update(snum);
1702 deleted = !print_job_exists(snum, jobid);
1703 if ( !deleted )
1704 *errcode = WERR_ACCESS_DENIED;
1706 return deleted;
1709 /****************************************************************************
1710 Pause a job.
1711 ****************************************************************************/
1713 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1715 struct printjob *pjob = print_job_find(snum, jobid);
1716 int ret = -1;
1717 struct printif *current_printif = get_printer_fns( snum );
1719 if (!pjob || !user)
1720 return False;
1722 if (!pjob->spooled || pjob->sysjob == -1)
1723 return False;
1725 if (!is_owner(user, snum, jobid) &&
1726 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1727 DEBUG(3, ("pause denied by security descriptor\n"));
1729 /* BEGIN_ADMIN_LOG */
1730 sys_adminlog( LOG_ERR,
1731 "Permission denied-- user not allowed to delete, \
1732 pause, or resume print job. User name: %s. Printer name: %s.",
1733 uidtoname(user->uid), PRINTERNAME(snum) );
1734 /* END_ADMIN_LOG */
1736 *errcode = WERR_ACCESS_DENIED;
1737 return False;
1740 /* need to pause the spooled entry */
1741 ret = (*(current_printif->job_pause))(snum, pjob);
1743 if (ret != 0) {
1744 *errcode = WERR_INVALID_PARAM;
1745 return False;
1748 /* force update the database */
1749 print_cache_flush(snum);
1751 /* Send a printer notify message */
1753 notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1755 /* how do we tell if this succeeded? */
1757 return True;
1760 /****************************************************************************
1761 Resume a job.
1762 ****************************************************************************/
1764 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1766 struct printjob *pjob = print_job_find(snum, jobid);
1767 int ret;
1768 struct printif *current_printif = get_printer_fns( snum );
1770 if (!pjob || !user)
1771 return False;
1773 if (!pjob->spooled || pjob->sysjob == -1)
1774 return False;
1776 if (!is_owner(user, snum, jobid) &&
1777 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1778 DEBUG(3, ("resume denied by security descriptor\n"));
1779 *errcode = WERR_ACCESS_DENIED;
1781 /* BEGIN_ADMIN_LOG */
1782 sys_adminlog( LOG_ERR,
1783 "Permission denied-- user not allowed to delete, \
1784 pause, or resume print job. User name: %s. Printer name: %s.",
1785 uidtoname(user->uid), PRINTERNAME(snum) );
1786 /* END_ADMIN_LOG */
1787 return False;
1790 ret = (*(current_printif->job_resume))(snum, pjob);
1792 if (ret != 0) {
1793 *errcode = WERR_INVALID_PARAM;
1794 return False;
1797 /* force update the database */
1798 print_cache_flush(snum);
1800 /* Send a printer notify message */
1802 notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1804 return True;
1807 /****************************************************************************
1808 Write to a print file.
1809 ****************************************************************************/
1811 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1813 int return_code;
1814 struct printjob *pjob = print_job_find(snum, jobid);
1816 if (!pjob)
1817 return -1;
1818 /* don't allow another process to get this info - it is meaningless */
1819 if (pjob->pid != local_pid)
1820 return -1;
1822 return_code = write(pjob->fd, buf, size);
1823 if (return_code>0) {
1824 pjob->size += size;
1825 pjob_store(snum, jobid, pjob);
1827 return return_code;
1830 /****************************************************************************
1831 Check if the print queue has been updated recently enough.
1832 ****************************************************************************/
1834 static BOOL print_cache_expired(int snum)
1836 fstring key;
1837 time_t last_qscan_time, time_now = time(NULL);
1838 const char *printername = lp_const_servicename(snum);
1839 struct tdb_print_db *pdb = get_print_db_byname(printername);
1841 if (!pdb)
1842 return False;
1844 slprintf(key, sizeof(key), "CACHE/%s", printername);
1845 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1848 * Invalidate the queue for 3 reasons.
1849 * (1). last queue scan time == -1.
1850 * (2). Current time - last queue scan time > allowed cache time.
1851 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1852 * This last test picks up machines for which the clock has been moved
1853 * forward, an lpq scan done and then the clock moved back. Otherwise
1854 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1857 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1858 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1859 DEBUG(3, ("print cache expired for queue %s \
1860 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1861 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1862 release_print_db(pdb);
1863 return True;
1865 release_print_db(pdb);
1866 return False;
1869 /****************************************************************************
1870 Get the queue status - do not update if db is out of date.
1871 ****************************************************************************/
1873 static int get_queue_status(int snum, print_status_struct *status)
1875 fstring keystr;
1876 TDB_DATA data, key;
1877 const char *printername = lp_const_servicename(snum);
1878 struct tdb_print_db *pdb = get_print_db_byname(printername);
1879 int len;
1881 if (!pdb)
1882 return 0;
1884 if (status) {
1885 ZERO_STRUCTP(status);
1886 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1887 key.dptr = keystr;
1888 key.dsize = strlen(keystr);
1889 data = tdb_fetch(pdb->tdb, key);
1890 if (data.dptr) {
1891 if (data.dsize == sizeof(print_status_struct))
1892 /* this memcpy is ok since the status struct was
1893 not packed before storing it in the tdb */
1894 memcpy(status, data.dptr, sizeof(print_status_struct));
1895 SAFE_FREE(data.dptr);
1898 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1899 release_print_db(pdb);
1900 return (len == -1 ? 0 : len);
1903 /****************************************************************************
1904 Determine the number of jobs in a queue.
1905 ****************************************************************************/
1907 int print_queue_length(int snum, print_status_struct *pstatus)
1909 print_status_struct status;
1910 int len;
1912 /* make sure the database is up to date */
1913 if (print_cache_expired(snum))
1914 print_queue_update(snum);
1916 /* also fetch the queue status */
1917 memset(&status, 0, sizeof(status));
1918 len = get_queue_status(snum, &status);
1920 if (pstatus)
1921 *pstatus = status;
1923 return len;
1926 /***************************************************************************
1927 Allocate a jobid. Hold the lock for as short a time as possible.
1928 ***************************************************************************/
1930 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1932 int i;
1933 uint32 jobid;
1935 *pjobid = (uint32)-1;
1937 for (i = 0; i < 3; i++) {
1938 /* Lock the database - only wait 20 seconds. */
1939 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1940 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1941 return False;
1944 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1945 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1946 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1947 printername ));
1948 return False;
1950 jobid = 0;
1953 jobid = NEXT_JOBID(jobid);
1955 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1956 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1957 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1958 return False;
1961 /* We've finished with the INFO/nextjob lock. */
1962 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1964 if (!print_job_exists(snum, jobid))
1965 break;
1968 if (i > 2) {
1969 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1970 printername ));
1971 /* Probably full... */
1972 errno = ENOSPC;
1973 return False;
1976 /* Store a dummy placeholder. */
1978 TDB_DATA dum;
1979 dum.dptr = NULL;
1980 dum.dsize = 0;
1981 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1982 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1983 jobid ));
1984 return False;
1988 *pjobid = jobid;
1989 return True;
1992 /***************************************************************************
1993 Append a jobid to the 'jobs changed' list.
1994 ***************************************************************************/
1996 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1998 TDB_DATA data, key;
1999 uint32 store_jobid;
2001 key.dptr = "INFO/jobs_changed";
2002 key.dsize = strlen(key.dptr);
2003 SIVAL(&store_jobid, 0, jobid);
2004 data.dptr = (char *)&store_jobid;
2005 data.dsize = 4;
2007 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2009 return (tdb_append(pdb->tdb, key, data) == 0);
2012 /***************************************************************************
2013 Start spooling a job - return the jobid.
2014 ***************************************************************************/
2016 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2018 uint32 jobid;
2019 char *path;
2020 struct printjob pjob;
2021 user_struct *vuser;
2022 const char *printername = lp_const_servicename(snum);
2023 struct tdb_print_db *pdb = get_print_db_byname(printername);
2024 int njobs;
2026 errno = 0;
2028 if (!pdb)
2029 return (uint32)-1;
2031 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2032 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2033 release_print_db(pdb);
2034 return (uint32)-1;
2037 if (!print_time_access_check(snum)) {
2038 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2039 release_print_db(pdb);
2040 return (uint32)-1;
2043 path = lp_pathname(snum);
2045 /* see if we have sufficient disk space */
2046 if (lp_minprintspace(snum)) {
2047 SMB_BIG_UINT dspace, dsize;
2048 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2049 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2050 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2051 release_print_db(pdb);
2052 errno = ENOSPC;
2053 return (uint32)-1;
2057 /* for autoloaded printers, check that the printcap entry still exists */
2058 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
2059 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2060 release_print_db(pdb);
2061 errno = ENOENT;
2062 return (uint32)-1;
2065 /* Insure the maximum queue size is not violated */
2066 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2067 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2068 printername, njobs, lp_maxprintjobs(snum) ));
2069 release_print_db(pdb);
2070 errno = ENOSPC;
2071 return (uint32)-1;
2074 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2075 printername, njobs, lp_maxprintjobs(snum) ));
2077 if (!allocate_print_jobid(pdb, snum, printername, &jobid))
2078 goto fail;
2080 /* create the database entry */
2082 ZERO_STRUCT(pjob);
2084 pjob.pid = local_pid;
2085 pjob.sysjob = -1;
2086 pjob.fd = -1;
2087 pjob.starttime = time(NULL);
2088 pjob.status = LPQ_SPOOLING;
2089 pjob.size = 0;
2090 pjob.spooled = False;
2091 pjob.smbjob = True;
2092 pjob.nt_devmode = nt_devmode;
2094 fstrcpy(pjob.jobname, jobname);
2096 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2097 fstrcpy(pjob.user, vuser->user.smb_name);
2098 } else {
2099 fstrcpy(pjob.user, uidtoname(user->uid));
2102 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2104 /* we have a job entry - now create the spool file */
2105 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2106 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2107 pjob.fd = smb_mkstemp(pjob.filename);
2109 if (pjob.fd == -1) {
2110 if (errno == EACCES) {
2111 /* Common setup error, force a report. */
2112 DEBUG(0, ("print_job_start: insufficient permissions \
2113 to open spool file %s.\n", pjob.filename));
2114 } else {
2115 /* Normal case, report at level 3 and above. */
2116 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2117 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2119 goto fail;
2122 pjob_store(snum, jobid, &pjob);
2124 /* Update the 'jobs changed' entry used by print_queue_status. */
2125 add_to_jobs_changed(pdb, jobid);
2127 /* Ensure we keep a rough count of the number of total jobs... */
2128 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2130 release_print_db(pdb);
2132 return jobid;
2134 fail:
2135 if (jobid != -1)
2136 pjob_delete(snum, jobid);
2138 release_print_db(pdb);
2140 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2141 return (uint32)-1;
2144 /****************************************************************************
2145 Update the number of pages spooled to jobid
2146 ****************************************************************************/
2148 void print_job_endpage(int snum, uint32 jobid)
2150 struct printjob *pjob = print_job_find(snum, jobid);
2151 if (!pjob)
2152 return;
2153 /* don't allow another process to get this info - it is meaningless */
2154 if (pjob->pid != local_pid)
2155 return;
2157 pjob->page_count++;
2158 pjob_store(snum, jobid, pjob);
2161 /****************************************************************************
2162 Print a file - called on closing the file. This spools the job.
2163 If normal close is false then we're tearing down the jobs - treat as an
2164 error.
2165 ****************************************************************************/
2167 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2169 struct printjob *pjob = print_job_find(snum, jobid);
2170 int ret;
2171 SMB_STRUCT_STAT sbuf;
2172 struct printif *current_printif = get_printer_fns( snum );
2174 if (!pjob)
2175 return False;
2177 if (pjob->spooled || pjob->pid != local_pid)
2178 return False;
2180 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2181 pjob->size = sbuf.st_size;
2182 close(pjob->fd);
2183 pjob->fd = -1;
2184 } else {
2187 * Not a normal close or we couldn't stat the job file,
2188 * so something has gone wrong. Cleanup.
2190 close(pjob->fd);
2191 pjob->fd = -1;
2192 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2193 goto fail;
2196 /* Technically, this is not quite right. If the printer has a separator
2197 * page turned on, the NT spooler prints the separator page even if the
2198 * print job is 0 bytes. 010215 JRR */
2199 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2200 /* don't bother spooling empty files or something being deleted. */
2201 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2202 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2203 unlink(pjob->filename);
2204 pjob_delete(snum, jobid);
2205 return True;
2208 pjob->smbjob = jobid;
2210 ret = (*(current_printif->job_submit))(snum, pjob);
2212 if (ret)
2213 goto fail;
2215 /* The print job has been sucessfully handed over to the back-end */
2217 pjob->spooled = True;
2218 pjob->status = LPQ_QUEUED;
2219 pjob_store(snum, jobid, pjob);
2221 /* make sure the database is up to date */
2222 if (print_cache_expired(snum))
2223 print_queue_update(snum);
2225 return True;
2227 fail:
2229 /* The print job was not succesfully started. Cleanup */
2230 /* Still need to add proper error return propagation! 010122:JRR */
2231 unlink(pjob->filename);
2232 pjob_delete(snum, jobid);
2233 remove_from_jobs_changed(snum, jobid);
2234 return False;
2237 /****************************************************************************
2238 Get a snapshot of jobs in the system without traversing.
2239 ****************************************************************************/
2241 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2243 TDB_DATA data, key, cgdata;
2244 print_queue_struct *queue = NULL;
2245 uint32 qcount = 0;
2246 uint32 extra_count = 0;
2247 int total_count = 0;
2248 size_t len = 0;
2249 uint32 i;
2250 int max_reported_jobs = lp_max_reported_jobs(snum);
2251 BOOL ret = False;
2253 /* make sure the database is up to date */
2254 if (print_cache_expired(snum))
2255 print_queue_update(snum);
2257 *pcount = 0;
2258 *ppqueue = NULL;
2260 ZERO_STRUCT(data);
2261 ZERO_STRUCT(cgdata);
2262 key.dptr = "INFO/linear_queue_array";
2263 key.dsize = strlen(key.dptr);
2265 /* Get the stored queue data. */
2266 data = tdb_fetch(pdb->tdb, key);
2268 if (data.dptr && data.dsize >= sizeof(qcount))
2269 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2271 /* Get the changed jobs list. */
2272 key.dptr = "INFO/jobs_changed";
2273 key.dsize = strlen(key.dptr);
2275 cgdata = tdb_fetch(pdb->tdb, key);
2276 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2277 extra_count = cgdata.dsize/4;
2279 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2281 /* Allocate the queue size. */
2282 if (qcount == 0 && extra_count == 0)
2283 goto out;
2285 if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2286 goto out;
2288 /* Retrieve the linearised queue data. */
2290 for( i = 0; i < qcount; i++) {
2291 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2292 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2293 &qjob,
2294 &qsize,
2295 &qpage_count,
2296 &qstatus,
2297 &qpriority,
2298 &qtime,
2299 queue[i].fs_user,
2300 queue[i].fs_file);
2301 queue[i].job = qjob;
2302 queue[i].size = qsize;
2303 queue[i].page_count = qpage_count;
2304 queue[i].status = qstatus;
2305 queue[i].priority = qpriority;
2306 queue[i].time = qtime;
2309 total_count = qcount;
2311 /* Add in the changed jobids. */
2312 for( i = 0; i < extra_count; i++) {
2313 uint32 jobid;
2314 struct printjob *pjob;
2316 jobid = IVAL(cgdata.dptr, i*4);
2317 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2318 pjob = print_job_find(snum, jobid);
2319 if (!pjob) {
2320 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2321 remove_from_jobs_changed(snum, jobid);
2322 continue;
2325 queue[total_count].job = jobid;
2326 queue[total_count].size = pjob->size;
2327 queue[total_count].page_count = pjob->page_count;
2328 queue[total_count].status = pjob->status;
2329 queue[total_count].priority = 1;
2330 queue[total_count].time = pjob->starttime;
2331 fstrcpy(queue[total_count].fs_user, pjob->user);
2332 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2333 total_count++;
2336 /* Sort the queue by submission time otherwise they are displayed
2337 in hash order. */
2339 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2341 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2343 if (max_reported_jobs && total_count > max_reported_jobs)
2344 total_count = max_reported_jobs;
2346 *ppqueue = queue;
2347 *pcount = total_count;
2349 ret = True;
2351 out:
2353 SAFE_FREE(data.dptr);
2354 SAFE_FREE(cgdata.dptr);
2355 return ret;
2358 /****************************************************************************
2359 Get a printer queue listing.
2360 set queue = NULL and status = NULL if you just want to update the cache
2361 ****************************************************************************/
2363 int print_queue_status(int snum,
2364 print_queue_struct **ppqueue,
2365 print_status_struct *status)
2367 fstring keystr;
2368 TDB_DATA data, key;
2369 const char *printername;
2370 struct tdb_print_db *pdb;
2371 int count = 0;
2373 /* make sure the database is up to date */
2375 if (print_cache_expired(snum))
2376 print_queue_update(snum);
2378 /* return if we are done */
2379 if ( !ppqueue || !status )
2380 return 0;
2382 *ppqueue = NULL;
2383 printername = lp_const_servicename(snum);
2384 pdb = get_print_db_byname(printername);
2386 if (!pdb)
2387 return 0;
2390 * Fetch the queue status. We must do this first, as there may
2391 * be no jobs in the queue.
2394 ZERO_STRUCTP(status);
2395 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2396 key.dptr = keystr;
2397 key.dsize = strlen(keystr);
2398 data = tdb_fetch(pdb->tdb, key);
2399 if (data.dptr) {
2400 if (data.dsize == sizeof(*status)) {
2401 /* this memcpy is ok since the status struct was
2402 not packed before storing it in the tdb */
2403 memcpy(status, data.dptr, sizeof(*status));
2405 SAFE_FREE(data.dptr);
2409 * Now, fetch the print queue information. We first count the number
2410 * of entries, and then only retrieve the queue if necessary.
2413 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2414 release_print_db(pdb);
2415 return 0;
2418 release_print_db(pdb);
2419 return count;
2422 /****************************************************************************
2423 Pause a queue.
2424 ****************************************************************************/
2426 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2428 int ret;
2429 struct printif *current_printif = get_printer_fns( snum );
2431 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2432 *errcode = WERR_ACCESS_DENIED;
2433 return False;
2436 ret = (*(current_printif->queue_pause))(snum);
2438 if (ret != 0) {
2439 *errcode = WERR_INVALID_PARAM;
2440 return False;
2443 /* force update the database */
2444 print_cache_flush(snum);
2446 /* Send a printer notify message */
2448 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2450 return True;
2453 /****************************************************************************
2454 Resume a queue.
2455 ****************************************************************************/
2457 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2459 int ret;
2460 struct printif *current_printif = get_printer_fns( snum );
2462 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2463 *errcode = WERR_ACCESS_DENIED;
2464 return False;
2467 ret = (*(current_printif->queue_resume))(snum);
2469 if (ret != 0) {
2470 *errcode = WERR_INVALID_PARAM;
2471 return False;
2474 /* make sure the database is up to date */
2475 if (print_cache_expired(snum))
2476 print_queue_update(snum);
2478 /* Send a printer notify message */
2480 notify_printer_status(snum, PRINTER_STATUS_OK);
2482 return True;
2485 /****************************************************************************
2486 Purge a queue - implemented by deleting all jobs that we can delete.
2487 ****************************************************************************/
2489 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2491 print_queue_struct *queue;
2492 print_status_struct status;
2493 int njobs, i;
2494 BOOL can_job_admin;
2496 /* Force and update so the count is accurate (i.e. not a cached count) */
2497 print_queue_update(snum);
2499 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2500 njobs = print_queue_status(snum, &queue, &status);
2502 for (i=0;i<njobs;i++) {
2503 BOOL owner = is_owner(user, snum, queue[i].job);
2505 if (owner || can_job_admin) {
2506 print_job_delete1(snum, queue[i].job);
2510 SAFE_FREE(queue);
2512 return True;