r3220: merging current 3.0 code to release branch
[Samba.git] / source / printing / printing.c
blob1e897c962a61ac7ab10334ebff999d77c0fecb8b
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(const char* sharename, 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;
53 struct rap_jobid_key {
54 fstring sharename;
55 uint32 jobid;
58 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
60 uint16 rap_jobid;
61 TDB_DATA data, key;
62 struct rap_jobid_key jinfo;
64 DEBUG(10,("pjobid_to_rap: called.\n"));
66 if (!rap_tdb) {
67 /* Create the in-memory tdb. */
68 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
69 if (!rap_tdb)
70 return 0;
73 ZERO_STRUCT( jinfo );
74 fstrcpy( jinfo.sharename, sharename );
75 jinfo.jobid = jobid;
76 key.dptr = (char*)&jinfo;
77 key.dsize = sizeof(jinfo);
79 data = tdb_fetch(rap_tdb, key);
80 if (data.dptr && data.dsize == sizeof(uint16)) {
81 rap_jobid = SVAL(data.dptr, 0);
82 SAFE_FREE(data.dptr);
83 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
84 (unsigned int)jobid, (unsigned int)rap_jobid));
85 return rap_jobid;
87 SAFE_FREE(data.dptr);
88 /* Not found - create and store mapping. */
89 rap_jobid = ++next_rap_jobid;
90 if (rap_jobid == 0)
91 rap_jobid = ++next_rap_jobid;
92 data.dptr = (char *)&rap_jobid;
93 data.dsize = sizeof(rap_jobid);
94 tdb_store(rap_tdb, key, data, TDB_REPLACE);
95 tdb_store(rap_tdb, data, key, TDB_REPLACE);
97 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
98 (unsigned int)jobid, (unsigned int)rap_jobid));
99 return rap_jobid;
102 BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
104 TDB_DATA data, key;
106 DEBUG(10,("rap_to_pjobid called.\n"));
108 if (!rap_tdb)
109 return False;
111 key.dptr = (char *)&rap_jobid;
112 key.dsize = sizeof(rap_jobid);
113 data = tdb_fetch(rap_tdb, key);
114 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
116 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
117 fstrcpy( sharename, jinfo->sharename );
118 *pjobid = jinfo->jobid;
119 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
120 (unsigned int)*pjobid, (unsigned int)rap_jobid));
121 SAFE_FREE(data.dptr);
122 return True;
125 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
126 (unsigned int)rap_jobid));
127 SAFE_FREE(data.dptr);
128 return False;
131 static void rap_jobid_delete(const char* sharename, uint32 jobid)
133 TDB_DATA key, data;
134 uint16 rap_jobid;
135 struct rap_jobid_key jinfo;
137 DEBUG(10,("rap_jobid_delete: called.\n"));
139 if (!rap_tdb)
140 return;
142 ZERO_STRUCT( jinfo );
143 fstrcpy( jinfo.sharename, sharename );
144 jinfo.jobid = jobid;
145 key.dptr = (char*)&jinfo;
146 key.dsize = sizeof(jinfo);
148 data = tdb_fetch(rap_tdb, key);
149 if (!data.dptr || (data.dsize != sizeof(uint16))) {
150 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
151 (unsigned int)jobid ));
152 SAFE_FREE(data.dptr);
153 return;
156 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
157 (unsigned int)jobid ));
159 rap_jobid = SVAL(data.dptr, 0);
160 SAFE_FREE(data.dptr);
161 data.dptr = (char *)&rap_jobid;
162 data.dsize = sizeof(rap_jobid);
163 tdb_delete(rap_tdb, key);
164 tdb_delete(rap_tdb, data);
167 static int get_queue_status(const char* sharename, print_status_struct *);
169 /****************************************************************************
170 Initialise the printing backend. Called once at startup before the fork().
171 ****************************************************************************/
173 BOOL print_backend_init(void)
175 const char *sversion = "INFO/version";
176 pstring printing_path;
177 int services = lp_numservices();
178 int snum;
180 unlink(lock_path("printing.tdb"));
181 pstrcpy(printing_path,lock_path("printing"));
182 mkdir(printing_path,0755);
184 /* handle a Samba upgrade */
186 for (snum = 0; snum < services; snum++) {
187 struct tdb_print_db *pdb;
188 if (!lp_print_ok(snum))
189 continue;
191 pdb = get_print_db_byname(lp_const_servicename(snum));
192 if (!pdb)
193 continue;
194 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
195 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
196 release_print_db(pdb);
197 return False;
199 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
200 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
201 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
203 tdb_unlock_bystring(pdb->tdb, sversion);
204 release_print_db(pdb);
207 close_all_print_db(); /* Don't leave any open. */
209 /* do NT print initialization... */
210 return nt_printing_init();
213 /****************************************************************************
214 Shut down printing backend. Called once at shutdown to close the tdb.
215 ****************************************************************************/
217 void printing_end(void)
219 close_all_print_db(); /* Don't leave any open. */
222 /****************************************************************************
223 Retrieve the set of printing functions for a given service. This allows
224 us to set the printer function table based on the value of the 'printing'
225 service parameter.
227 Use the generic interface as the default and only use cups interface only
228 when asked for (and only when supported)
229 ****************************************************************************/
231 static struct printif *get_printer_fns_from_type( enum printing_types type )
233 struct printif *printer_fns = &generic_printif;
235 #ifdef HAVE_CUPS
236 if ( type == PRINT_CUPS ) {
237 printer_fns = &cups_printif;
239 #endif /* HAVE_CUPS */
241 printer_fns->type = type;
243 return printer_fns;
246 static struct printif *get_printer_fns( int snum )
248 return get_printer_fns_from_type( lp_printing(snum) );
252 /****************************************************************************
253 Useful function to generate a tdb key.
254 ****************************************************************************/
256 static TDB_DATA print_key(uint32 jobid)
258 static uint32 j;
259 TDB_DATA ret;
261 SIVAL(&j, 0, jobid);
262 ret.dptr = (void *)&j;
263 ret.dsize = sizeof(j);
264 return ret;
267 /***********************************************************************
268 unpack a pjob from a tdb buffer
269 ***********************************************************************/
271 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
273 int len = 0;
274 int used;
275 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
276 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
278 if ( !buf || !pjob )
279 return -1;
281 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
282 &pjpid,
283 &pjsysjob,
284 &pjfd,
285 &pjstarttime,
286 &pjstatus,
287 &pjsize,
288 &pjpage_count,
289 &pjspooled,
290 &pjsmbjob,
291 pjob->filename,
292 pjob->jobname,
293 pjob->user,
294 pjob->queuename);
296 if ( len == -1 )
297 return -1;
299 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
300 return -1;
302 len += used;
304 pjob->pid = pjpid;
305 pjob->sysjob = pjsysjob;
306 pjob->fd = pjfd;
307 pjob->starttime = pjstarttime;
308 pjob->status = pjstatus;
309 pjob->size = pjsize;
310 pjob->page_count = pjpage_count;
311 pjob->spooled = pjspooled;
312 pjob->smbjob = pjsmbjob;
314 return len;
318 /****************************************************************************
319 Useful function to find a print job in the database.
320 ****************************************************************************/
322 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
324 static struct printjob pjob;
325 TDB_DATA ret;
326 struct tdb_print_db *pdb = get_print_db_byname(sharename);
329 if (!pdb)
330 return NULL;
332 ret = tdb_fetch(pdb->tdb, print_key(jobid));
333 release_print_db(pdb);
335 if (!ret.dptr)
336 return NULL;
338 if ( pjob.nt_devmode )
339 free_nt_devicemode( &pjob.nt_devmode );
341 ZERO_STRUCT( pjob );
343 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
344 SAFE_FREE(ret.dptr);
345 return NULL;
348 SAFE_FREE(ret.dptr);
349 return &pjob;
352 /* Convert a unix jobid to a smb jobid */
354 static uint32 sysjob_to_jobid_value;
356 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
357 TDB_DATA data, void *state)
359 struct printjob *pjob;
360 int *sysjob = (int *)state;
362 if (!data.dptr || data.dsize == 0)
363 return 0;
365 pjob = (struct printjob *)data.dptr;
366 if (key.dsize != sizeof(uint32))
367 return 0;
369 if (*sysjob == pjob->sysjob) {
370 uint32 jobid = IVAL(key.dptr,0);
372 sysjob_to_jobid_value = jobid;
373 return 1;
376 return 0;
379 /****************************************************************************
380 This is a *horribly expensive call as we have to iterate through all the
381 current printer tdb's. Don't do this often ! JRA.
382 ****************************************************************************/
384 uint32 sysjob_to_jobid(int unix_jobid)
386 int services = lp_numservices();
387 int snum;
389 sysjob_to_jobid_value = (uint32)-1;
391 for (snum = 0; snum < services; snum++) {
392 struct tdb_print_db *pdb;
393 if (!lp_print_ok(snum))
394 continue;
395 pdb = get_print_db_byname(lp_const_servicename(snum));
396 if (pdb)
397 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
398 release_print_db(pdb);
399 if (sysjob_to_jobid_value != (uint32)-1)
400 return sysjob_to_jobid_value;
402 return (uint32)-1;
405 /****************************************************************************
406 Send notifications based on what has changed after a pjob_store.
407 ****************************************************************************/
409 static struct {
410 uint32 lpq_status;
411 uint32 spoolss_status;
412 } lpq_to_spoolss_status_map[] = {
413 { LPQ_QUEUED, JOB_STATUS_QUEUED },
414 { LPQ_PAUSED, JOB_STATUS_PAUSED },
415 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
416 { LPQ_PRINTING, JOB_STATUS_PRINTING },
417 { LPQ_DELETING, JOB_STATUS_DELETING },
418 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
419 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
420 { LPQ_PRINTED, JOB_STATUS_PRINTED },
421 { LPQ_DELETED, JOB_STATUS_DELETED },
422 { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
423 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
424 { -1, 0 }
427 /* Convert a lpq status value stored in printing.tdb into the
428 appropriate win32 API constant. */
430 static uint32 map_to_spoolss_status(uint32 lpq_status)
432 int i = 0;
434 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
435 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
436 return lpq_to_spoolss_status_map[i].spoolss_status;
437 i++;
440 return 0;
443 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
444 struct printjob *new_data)
446 BOOL new_job = False;
448 if (!old_data)
449 new_job = True;
451 /* Job attributes that can't be changed. We only send
452 notification for these on a new job. */
454 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
455 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
456 time first or else we'll end up with potential alignment
457 errors. I don't think the systemtime should be spooled as
458 a string, but this gets us around that error.
459 --jerry (i'll feel dirty for this) */
461 if (new_job) {
462 notify_job_submitted(sharename, jobid, new_data->starttime);
463 notify_job_username(sharename, jobid, new_data->user);
466 if (new_job || !strequal(old_data->jobname, new_data->jobname))
467 notify_job_name(sharename, jobid, new_data->jobname);
469 /* Job attributes of a new job or attributes that can be
470 modified. */
472 if (new_job || !strequal(old_data->jobname, new_data->jobname))
473 notify_job_name(sharename, jobid, new_data->jobname);
475 if (new_job || old_data->status != new_data->status)
476 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
478 if (new_job || old_data->size != new_data->size)
479 notify_job_total_bytes(sharename, jobid, new_data->size);
481 if (new_job || old_data->page_count != new_data->page_count)
482 notify_job_total_pages(sharename, jobid, new_data->page_count);
485 /****************************************************************************
486 Store a job structure back to the database.
487 ****************************************************************************/
489 static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
491 TDB_DATA old_data, new_data;
492 BOOL ret = False;
493 struct tdb_print_db *pdb = get_print_db_byname(sharename);
494 char *buf = NULL;
495 int len, newlen, buflen;
498 if (!pdb)
499 return False;
501 /* Get old data */
503 old_data = tdb_fetch(pdb->tdb, print_key(jobid));
505 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
507 newlen = 0;
509 do {
510 len = 0;
511 buflen = newlen;
512 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
513 (uint32)pjob->pid,
514 (uint32)pjob->sysjob,
515 (uint32)pjob->fd,
516 (uint32)pjob->starttime,
517 (uint32)pjob->status,
518 (uint32)pjob->size,
519 (uint32)pjob->page_count,
520 (uint32)pjob->spooled,
521 (uint32)pjob->smbjob,
522 pjob->filename,
523 pjob->jobname,
524 pjob->user,
525 pjob->queuename);
527 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
529 if (buflen != len) {
530 char *tb;
532 tb = (char *)Realloc(buf, len);
533 if (!tb) {
534 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
535 goto done;
537 else
538 buf = tb;
539 newlen = len;
541 } while ( buflen != len );
544 /* Store new data */
546 new_data.dptr = buf;
547 new_data.dsize = len;
548 ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
550 release_print_db(pdb);
552 /* Send notify updates for what has changed */
554 if ( ret ) {
555 struct printjob old_pjob;
557 if ( old_data.dsize )
559 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
561 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
562 free_nt_devicemode( &old_pjob.nt_devmode );
565 else {
566 /* new job */
567 pjob_store_notify( sharename, jobid, NULL, pjob );
571 done:
572 SAFE_FREE( old_data.dptr );
573 SAFE_FREE( buf );
575 return ret;
578 /****************************************************************************
579 Remove a job structure from the database.
580 ****************************************************************************/
582 void pjob_delete(const char* sharename, uint32 jobid)
584 struct printjob *pjob;
585 uint32 job_status = 0;
586 struct tdb_print_db *pdb;
588 pdb = get_print_db_byname( sharename );
590 if (!pdb)
591 return;
593 pjob = print_job_find( sharename, jobid );
595 if (!pjob) {
596 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
597 (unsigned int)jobid));
598 release_print_db(pdb);
599 return;
602 /* We must cycle through JOB_STATUS_DELETING and
603 JOB_STATUS_DELETED for the port monitor to delete the job
604 properly. */
606 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
607 notify_job_status(sharename, jobid, job_status);
609 /* Remove from printing.tdb */
611 tdb_delete(pdb->tdb, print_key(jobid));
612 remove_from_jobs_changed(sharename, jobid);
613 release_print_db( pdb );
614 rap_jobid_delete(sharename, jobid);
617 /****************************************************************************
618 Parse a file name from the system spooler to generate a jobid.
619 ****************************************************************************/
621 static uint32 print_parse_jobid(char *fname)
623 int jobid;
625 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
626 return (uint32)-1;
627 fname += strlen(PRINT_SPOOL_PREFIX);
629 jobid = atoi(fname);
630 if (jobid <= 0)
631 return (uint32)-1;
633 return (uint32)jobid;
636 /****************************************************************************
637 List a unix job in the print database.
638 ****************************************************************************/
640 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
642 struct printjob pj, *old_pj;
644 if (jobid == (uint32)-1)
645 jobid = q->job + UNIX_JOB_START;
647 /* Preserve the timestamp on an existing unix print job */
649 old_pj = print_job_find(sharename, jobid);
651 ZERO_STRUCT(pj);
653 pj.pid = (pid_t)-1;
654 pj.sysjob = q->job;
655 pj.fd = -1;
656 pj.starttime = old_pj ? old_pj->starttime : q->time;
657 pj.status = q->status;
658 pj.size = q->size;
659 pj.spooled = True;
660 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
661 if (jobid < UNIX_JOB_START) {
662 pj.smbjob = True;
663 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
664 } else {
665 pj.smbjob = False;
666 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
668 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
669 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
671 pjob_store(sharename, jobid, &pj);
675 struct traverse_struct {
676 print_queue_struct *queue;
677 int qcount, snum, maxcount, total_jobs;
678 const char *sharename;
679 time_t lpq_time;
682 /****************************************************************************
683 Utility fn to delete any jobs that are no longer active.
684 ****************************************************************************/
686 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
688 struct traverse_struct *ts = (struct traverse_struct *)state;
689 struct printjob pjob;
690 uint32 jobid;
691 int i = 0;
693 if ( key.dsize != sizeof(jobid) )
694 return 0;
696 jobid = IVAL(key.dptr, 0);
697 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
698 return 0;
699 free_nt_devicemode( &pjob.nt_devmode );
702 if (!pjob.smbjob) {
703 /* remove a unix job if it isn't in the system queue any more */
705 for (i=0;i<ts->qcount;i++) {
706 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
707 if (jobid == u_jobid)
708 break;
710 if (i == ts->qcount) {
711 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
712 (unsigned int)jobid ));
713 pjob_delete(ts->sharename, jobid);
714 return 0;
717 /* need to continue the the bottom of the function to
718 save the correct attributes */
721 /* maybe it hasn't been spooled yet */
722 if (!pjob.spooled) {
723 /* if a job is not spooled and the process doesn't
724 exist then kill it. This cleans up after smbd
725 deaths */
726 if (!process_exists(pjob.pid)) {
727 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
728 (unsigned int)jobid, (unsigned int)pjob.pid ));
729 pjob_delete(ts->sharename, jobid);
730 } else
731 ts->total_jobs++;
732 return 0;
735 /* this check only makes sense for jobs submitted from Windows clients */
737 if ( pjob.smbjob ) {
738 for (i=0;i<ts->qcount;i++) {
739 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
740 if (jobid == curr_jobid)
741 break;
745 /* The job isn't in the system queue - we have to assume it has
746 completed, so delete the database entry. */
748 if (i == ts->qcount) {
750 /* A race can occur between the time a job is spooled and
751 when it appears in the lpq output. This happens when
752 the job is added to printing.tdb when another smbd
753 running print_queue_update() has completed a lpq and
754 is currently traversing the printing tdb and deleting jobs.
755 Don't delete the job if it was submitted after the lpq_time. */
757 if (pjob.starttime < ts->lpq_time) {
758 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
759 (unsigned int)jobid,
760 (unsigned int)pjob.starttime,
761 (unsigned int)ts->lpq_time ));
762 pjob_delete(ts->sharename, jobid);
763 } else
764 ts->total_jobs++;
765 return 0;
768 /* Save the pjob attributes we will store. */
769 /* FIXME!!! This is the only place where queue->job
770 represents the SMB jobid --jerry */
771 ts->queue[i].job = jobid;
772 ts->queue[i].size = pjob.size;
773 ts->queue[i].page_count = pjob.page_count;
774 ts->queue[i].status = pjob.status;
775 ts->queue[i].priority = 1;
776 ts->queue[i].time = pjob.starttime;
777 fstrcpy(ts->queue[i].fs_user, pjob.user);
778 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
780 ts->total_jobs++;
782 return 0;
785 /****************************************************************************
786 Check if the print queue has been updated recently enough.
787 ****************************************************************************/
789 static void print_cache_flush(int snum)
791 fstring key;
792 const char *sharename = lp_const_servicename(snum);
793 struct tdb_print_db *pdb = get_print_db_byname(sharename);
795 if (!pdb)
796 return;
797 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
798 tdb_store_int32(pdb->tdb, key, -1);
799 release_print_db(pdb);
802 /****************************************************************************
803 Check if someone already thinks they are doing the update.
804 ****************************************************************************/
806 static pid_t get_updating_pid(fstring sharename)
808 fstring keystr;
809 TDB_DATA data, key;
810 pid_t updating_pid;
811 struct tdb_print_db *pdb = get_print_db_byname(sharename);
813 if (!pdb)
814 return (pid_t)-1;
815 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
816 key.dptr = keystr;
817 key.dsize = strlen(keystr);
819 data = tdb_fetch(pdb->tdb, key);
820 release_print_db(pdb);
821 if (!data.dptr || data.dsize != sizeof(pid_t)) {
822 SAFE_FREE(data.dptr);
823 return (pid_t)-1;
826 updating_pid = IVAL(data.dptr, 0);
827 SAFE_FREE(data.dptr);
829 if (process_exists(updating_pid))
830 return updating_pid;
832 return (pid_t)-1;
835 /****************************************************************************
836 Set the fact that we're doing the update, or have finished doing the update
837 in the tdb.
838 ****************************************************************************/
840 static void set_updating_pid(const fstring sharename, BOOL delete)
842 fstring keystr;
843 TDB_DATA key;
844 TDB_DATA data;
845 pid_t updating_pid = sys_getpid();
846 uint8 buffer[4];
848 struct tdb_print_db *pdb = get_print_db_byname(sharename);
850 if (!pdb)
851 return;
853 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
854 key.dptr = keystr;
855 key.dsize = strlen(keystr);
857 if (delete) {
858 tdb_delete(pdb->tdb, key);
859 release_print_db(pdb);
860 return;
863 SIVAL( buffer, 0, updating_pid);
864 data.dptr = (void *)buffer;
865 data.dsize = 4; /* we always assume this is a 4 byte value */
867 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
868 release_print_db(pdb);
871 /****************************************************************************
872 Sort print jobs by submittal time.
873 ****************************************************************************/
875 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
877 /* Silly cases */
879 if (!j1 && !j2)
880 return 0;
881 if (!j1)
882 return -1;
883 if (!j2)
884 return 1;
886 /* Sort on job start time */
888 if (j1->time == j2->time)
889 return 0;
890 return (j1->time > j2->time) ? 1 : -1;
893 /****************************************************************************
894 Store the sorted queue representation for later portmon retrieval.
895 ****************************************************************************/
897 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
899 TDB_DATA data, key;
900 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
901 print_queue_struct *queue = pts->queue;
902 size_t len;
903 size_t i;
904 uint qcount;
906 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
907 pts->qcount = max_reported_jobs;
908 qcount = pts->qcount;
910 /* Work out the size. */
911 data.dsize = 0;
912 data.dsize += tdb_pack(NULL, 0, "d", qcount);
914 for (i = 0; i < pts->qcount; i++) {
915 data.dsize += tdb_pack(NULL, 0, "ddddddff",
916 (uint32)queue[i].job,
917 (uint32)queue[i].size,
918 (uint32)queue[i].page_count,
919 (uint32)queue[i].status,
920 (uint32)queue[i].priority,
921 (uint32)queue[i].time,
922 queue[i].fs_user,
923 queue[i].fs_file);
926 if ((data.dptr = malloc(data.dsize)) == NULL)
927 return;
929 len = 0;
930 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
931 for (i = 0; i < pts->qcount; i++) {
932 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
933 (uint32)queue[i].job,
934 (uint32)queue[i].size,
935 (uint32)queue[i].page_count,
936 (uint32)queue[i].status,
937 (uint32)queue[i].priority,
938 (uint32)queue[i].time,
939 queue[i].fs_user,
940 queue[i].fs_file);
943 key.dptr = "INFO/linear_queue_array";
944 key.dsize = strlen(key.dptr);
945 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
946 SAFE_FREE(data.dptr);
947 return;
950 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
952 TDB_DATA data, key;
954 key.dptr = "INFO/jobs_changed";
955 key.dsize = strlen(key.dptr);
956 ZERO_STRUCT(data);
958 data = tdb_fetch(pdb->tdb, key);
959 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
960 SAFE_FREE(data.dptr);
961 ZERO_STRUCT(data);
964 return data;
967 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
969 unsigned int i;
970 unsigned int job_count = data.dsize / 4;
972 for (i = 0; i < job_count; i++) {
973 uint32 ch_jobid;
975 ch_jobid = IVAL(data.dptr, i*4);
976 if (ch_jobid == jobid)
977 remove_from_jobs_changed(sharename, jobid);
981 struct print_queue_update_context {
982 fstring sharename;
983 enum printing_types printing_type;
984 pstring lpqcommand;
987 /****************************************************************************
988 main work for updating the lpq cahe for a printer queue
989 ****************************************************************************/
991 static void print_queue_update_internal( const char *sharename,
992 struct printif *current_printif,
993 char *lpq_command )
995 int i, qcount;
996 print_queue_struct *queue = NULL;
997 print_status_struct status;
998 print_status_struct old_status;
999 struct printjob *pjob;
1000 struct traverse_struct tstruct;
1001 TDB_DATA data, key;
1002 TDB_DATA jcdata;
1003 fstring keystr, cachestr;
1004 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1007 * Update the cache time FIRST ! Stops others even
1008 * attempting to get the lock and doing this
1009 * if the lpq takes a long time.
1012 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1013 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1015 /* get the current queue using the appropriate interface */
1016 ZERO_STRUCT(status);
1018 qcount = (*(current_printif->queue_get))(sharename,
1019 current_printif->type,
1020 lpq_command, &queue, &status);
1022 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1023 "s" : "", sharename));
1025 /* Sort the queue by submission time otherwise they are displayed
1026 in hash order. */
1028 qsort(queue, qcount, sizeof(print_queue_struct),
1029 QSORT_CAST(printjob_comp));
1032 any job in the internal database that is marked as spooled
1033 and doesn't exist in the system queue is considered finished
1034 and removed from the database
1036 any job in the system database but not in the internal database
1037 is added as a unix job
1039 fill in any system job numbers as we go
1042 jcdata = get_jobs_changed_data(pdb);
1044 for (i=0; i<qcount; i++) {
1045 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1047 if (jobid == (uint32)-1) {
1048 /* assume its a unix print job */
1049 print_unix_job(sharename, &queue[i], jobid);
1050 continue;
1053 /* we have an active SMB print job - update its status */
1054 pjob = print_job_find(sharename, jobid);
1055 if (!pjob) {
1056 /* err, somethings wrong. Probably smbd was restarted
1057 with jobs in the queue. All we can do is treat them
1058 like unix jobs. Pity. */
1059 print_unix_job(sharename, &queue[i], jobid);
1060 continue;
1063 pjob->sysjob = queue[i].job;
1064 pjob->status = queue[i].status;
1065 pjob_store(sharename, jobid, pjob);
1066 check_job_changed(sharename, jcdata, jobid);
1069 SAFE_FREE(jcdata.dptr);
1071 /* now delete any queued entries that don't appear in the
1072 system queue */
1073 tstruct.queue = queue;
1074 tstruct.qcount = qcount;
1075 tstruct.snum = -1;
1076 tstruct.total_jobs = 0;
1077 tstruct.lpq_time = time(NULL);
1078 tstruct.sharename = sharename;
1080 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1082 /* Store the linearised queue, max jobs only. */
1083 store_queue_struct(pdb, &tstruct);
1085 SAFE_FREE(tstruct.queue);
1087 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1088 sharename, tstruct.total_jobs ));
1090 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1092 get_queue_status(sharename, &old_status);
1093 if (old_status.qcount != qcount)
1094 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1095 old_status.qcount, qcount, sharename));
1097 /* store the new queue status structure */
1098 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1099 key.dptr = keystr;
1100 key.dsize = strlen(keystr);
1102 status.qcount = qcount;
1103 data.dptr = (void *)&status;
1104 data.dsize = sizeof(status);
1105 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1108 * Update the cache time again. We want to do this call
1109 * as little as possible...
1112 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1113 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1117 /****************************************************************************
1118 Update the internal database from the system print queue for a queue.
1119 obtain a lock on the print queue before proceeding (needed when mutiple
1120 smbd processes maytry to update the lpq cache concurrently).
1121 ****************************************************************************/
1123 static void print_queue_update_with_lock(int snum)
1125 fstring sharename, keystr;
1126 pstring lpq_command;
1127 struct tdb_print_db *pdb;
1128 struct printif *current_printif = get_printer_fns( snum );
1130 fstrcpy(sharename, lp_const_servicename(snum));
1131 pdb = get_print_db_byname(sharename);
1132 if (!pdb)
1133 return;
1136 * Check to see if someone else is doing this update.
1137 * This is essentially a mutex on the update.
1140 if (get_updating_pid(sharename) != -1) {
1141 release_print_db(pdb);
1142 return;
1145 /* Lock the queue for the database update */
1147 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1148 /* Only wait 10 seconds for this. */
1149 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1150 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", sharename));
1151 release_print_db(pdb);
1152 return;
1156 * Ensure that no one else got in here.
1157 * If the updating pid is still -1 then we are
1158 * the winner.
1161 if (get_updating_pid(sharename) != -1) {
1163 * Someone else is doing the update, exit.
1165 tdb_unlock_bystring(pdb->tdb, keystr);
1166 release_print_db(pdb);
1167 return;
1171 * We're going to do the update ourselves.
1174 /* Tell others we're doing the update. */
1175 set_updating_pid(sharename, False);
1178 * Allow others to enter and notice we're doing
1179 * the update.
1182 tdb_unlock_bystring(pdb->tdb, keystr);
1184 /* do the main work now */
1185 /* have to substitute any variables here since
1186 print_queue_get_internal() will not */
1188 pstrcpy( lpq_command, lp_lpqcommand(snum) );
1189 pstring_sub( lpq_command, "%p", PRINTERNAME(snum) );
1190 standard_sub_snum( snum, lpq_command, sizeof(lpq_command) );
1192 print_queue_update_internal( sharename, current_printif, lpq_command );
1194 /* Delete our pid from the db. */
1195 set_updating_pid(sharename, True);
1196 release_print_db(pdb);
1199 /****************************************************************************
1200 this is the receive function of the background lpq updater
1201 ****************************************************************************/
1202 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
1204 struct print_queue_update_context *ctx;
1206 if (len != sizeof(struct print_queue_update_context)) {
1207 DEBUG(1, ("Got invalid print queue update message\n"));
1208 return;
1211 ctx = (struct print_queue_update_context*)buf;
1212 print_queue_update_internal(ctx->sharename,
1213 get_printer_fns_from_type(ctx->printing_type),
1214 ctx->lpqcommand );
1217 static pid_t background_lpq_updater_pid = -1;
1219 /****************************************************************************
1220 main thread of the background lpq updater
1221 ****************************************************************************/
1222 void start_background_queue(void)
1224 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1225 background_lpq_updater_pid = sys_fork();
1227 if (background_lpq_updater_pid == -1) {
1228 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1229 exit(1);
1232 if(background_lpq_updater_pid == 0) {
1233 /* Child. */
1234 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1236 claim_connection( NULL, "smbd lpq backend", 0, False,
1237 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1239 if (!locking_init(0)) {
1240 exit(1);
1243 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1245 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1246 while (1) {
1247 pause();
1249 /* check for some essential signals first */
1251 if (got_sig_term) {
1252 exit_server("Caught TERM signal");
1255 if (reload_after_sighup) {
1256 change_to_root_user();
1257 DEBUG(1,("Reloading services after SIGHUP\n"));
1258 reload_services(False);
1259 reload_after_sighup = 0;
1262 /* now check for messages */
1264 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1265 message_dispatch();
1267 /* process any pending print change notify messages */
1269 print_notify_send_messages(0);
1274 /****************************************************************************
1275 update the internal database from the system print queue for a queue
1276 ****************************************************************************/
1277 static void print_queue_update(int snum)
1279 struct print_queue_update_context ctx;
1282 * Make sure that the background queue process exists.
1283 * Otherwise just do the update ourselves
1286 if ( background_lpq_updater_pid != -1 ) {
1287 fstrcpy(ctx.sharename, lp_const_servicename(snum));
1288 ctx.printing_type = lp_printing(snum);
1290 pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum));
1291 pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) );
1292 standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) );
1294 become_root();
1295 message_send_pid(background_lpq_updater_pid,
1296 MSG_PRINTER_UPDATE, &ctx, sizeof(ctx),
1297 False);
1298 unbecome_root();
1299 } else
1300 print_queue_update_with_lock( snum );
1303 /****************************************************************************
1304 Create/Update an entry in the print tdb that will allow us to send notify
1305 updates only to interested smbd's.
1306 ****************************************************************************/
1308 BOOL print_notify_register_pid(int snum)
1310 TDB_DATA data;
1311 struct tdb_print_db *pdb = NULL;
1312 TDB_CONTEXT *tdb = NULL;
1313 const char *printername;
1314 uint32 mypid = (uint32)sys_getpid();
1315 BOOL ret = False;
1316 size_t i;
1318 /* if (snum == -1), then the change notify request was
1319 on a print server handle and we need to register on
1320 all print queus */
1322 if (snum == -1)
1324 int num_services = lp_numservices();
1325 int idx;
1327 for ( idx=0; idx<num_services; idx++ ) {
1328 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1329 print_notify_register_pid(idx);
1332 return True;
1334 else /* register for a specific printer */
1336 printername = lp_const_servicename(snum);
1337 pdb = get_print_db_byname(printername);
1338 if (!pdb)
1339 return False;
1340 tdb = pdb->tdb;
1343 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1344 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1345 printername));
1346 if (pdb)
1347 release_print_db(pdb);
1348 return False;
1351 data = get_printer_notify_pid_list( tdb, printername, True );
1353 /* Add ourselves and increase the refcount. */
1355 for (i = 0; i < data.dsize; i += 8) {
1356 if (IVAL(data.dptr,i) == mypid) {
1357 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1358 SIVAL(data.dptr, i+4, new_refcount);
1359 break;
1363 if (i == data.dsize) {
1364 /* We weren't in the list. Realloc. */
1365 data.dptr = Realloc(data.dptr, data.dsize + 8);
1366 if (!data.dptr) {
1367 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1368 printername));
1369 goto done;
1371 data.dsize += 8;
1372 SIVAL(data.dptr,data.dsize - 8,mypid);
1373 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1376 /* Store back the record. */
1377 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1378 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1379 list for printer %s\n", printername));
1380 goto done;
1383 ret = True;
1385 done:
1387 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1388 if (pdb)
1389 release_print_db(pdb);
1390 SAFE_FREE(data.dptr);
1391 return ret;
1394 /****************************************************************************
1395 Update an entry in the print tdb that will allow us to send notify
1396 updates only to interested smbd's.
1397 ****************************************************************************/
1399 BOOL print_notify_deregister_pid(int snum)
1401 TDB_DATA data;
1402 struct tdb_print_db *pdb = NULL;
1403 TDB_CONTEXT *tdb = NULL;
1404 const char *printername;
1405 uint32 mypid = (uint32)sys_getpid();
1406 size_t i;
1407 BOOL ret = False;
1409 /* if ( snum == -1 ), we are deregister a print server handle
1410 which means to deregister on all print queues */
1412 if (snum == -1)
1414 int num_services = lp_numservices();
1415 int idx;
1417 for ( idx=0; idx<num_services; idx++ ) {
1418 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1419 print_notify_deregister_pid(idx);
1422 return True;
1424 else /* deregister a specific printer */
1426 printername = lp_const_servicename(snum);
1427 pdb = get_print_db_byname(printername);
1428 if (!pdb)
1429 return False;
1430 tdb = pdb->tdb;
1433 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1434 DEBUG(0,("print_notify_register_pid: Failed to lock \
1435 printer %s database\n", printername));
1436 if (pdb)
1437 release_print_db(pdb);
1438 return False;
1441 data = get_printer_notify_pid_list( tdb, printername, True );
1443 /* Reduce refcount. Remove ourselves if zero. */
1445 for (i = 0; i < data.dsize; ) {
1446 if (IVAL(data.dptr,i) == mypid) {
1447 uint32 refcount = IVAL(data.dptr, i+4);
1449 refcount--;
1451 if (refcount == 0) {
1452 if (data.dsize - i > 8)
1453 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1454 data.dsize -= 8;
1455 continue;
1457 SIVAL(data.dptr, i+4, refcount);
1460 i += 8;
1463 if (data.dsize == 0)
1464 SAFE_FREE(data.dptr);
1466 /* Store back the record. */
1467 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1468 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1469 list for printer %s\n", printername));
1470 goto done;
1473 ret = True;
1475 done:
1477 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1478 if (pdb)
1479 release_print_db(pdb);
1480 SAFE_FREE(data.dptr);
1481 return ret;
1484 /****************************************************************************
1485 Check if a jobid is valid. It is valid if it exists in the database.
1486 ****************************************************************************/
1488 BOOL print_job_exists(const char* sharename, uint32 jobid)
1490 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1491 BOOL ret;
1493 if (!pdb)
1494 return False;
1495 ret = tdb_exists(pdb->tdb, print_key(jobid));
1496 release_print_db(pdb);
1497 return ret;
1500 /****************************************************************************
1501 Give the fd used for a jobid.
1502 ****************************************************************************/
1504 int print_job_fd(const char* sharename, uint32 jobid)
1506 struct printjob *pjob = print_job_find(sharename, jobid);
1507 if (!pjob)
1508 return -1;
1509 /* don't allow another process to get this info - it is meaningless */
1510 if (pjob->pid != sys_getpid())
1511 return -1;
1512 return pjob->fd;
1515 /****************************************************************************
1516 Give the filename used for a jobid.
1517 Only valid for the process doing the spooling and when the job
1518 has not been spooled.
1519 ****************************************************************************/
1521 char *print_job_fname(const char* sharename, uint32 jobid)
1523 struct printjob *pjob = print_job_find(sharename, jobid);
1524 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1525 return NULL;
1526 return pjob->filename;
1530 /****************************************************************************
1531 Give the filename used for a jobid.
1532 Only valid for the process doing the spooling and when the job
1533 has not been spooled.
1534 ****************************************************************************/
1536 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1538 struct printjob *pjob = print_job_find(sharename, jobid);
1540 if ( !pjob )
1541 return NULL;
1543 return pjob->nt_devmode;
1546 /****************************************************************************
1547 Set the place in the queue for a job.
1548 ****************************************************************************/
1550 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1552 DEBUG(2,("print_job_set_place not implemented yet\n"));
1553 return False;
1556 /****************************************************************************
1557 Set the name of a job. Only possible for owner.
1558 ****************************************************************************/
1560 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1562 const char* sharename = lp_const_servicename(snum);
1563 struct printjob *pjob;
1565 pjob = print_job_find(sharename, jobid);
1566 if (!pjob || pjob->pid != sys_getpid())
1567 return False;
1569 fstrcpy(pjob->jobname, name);
1570 return pjob_store(sharename, jobid, pjob);
1573 /***************************************************************************
1574 Remove a jobid from the 'jobs changed' list.
1575 ***************************************************************************/
1577 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1579 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1580 TDB_DATA data, key;
1581 size_t job_count, i;
1582 BOOL ret = False;
1583 BOOL gotlock = False;
1585 key.dptr = "INFO/jobs_changed";
1586 key.dsize = strlen(key.dptr);
1587 ZERO_STRUCT(data);
1589 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1590 goto out;
1592 gotlock = True;
1594 data = tdb_fetch(pdb->tdb, key);
1596 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1597 goto out;
1599 job_count = data.dsize / 4;
1600 for (i = 0; i < job_count; i++) {
1601 uint32 ch_jobid;
1603 ch_jobid = IVAL(data.dptr, i*4);
1604 if (ch_jobid == jobid) {
1605 if (i < job_count -1 )
1606 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1607 data.dsize -= 4;
1608 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1609 goto out;
1610 break;
1614 ret = True;
1615 out:
1617 if (gotlock)
1618 tdb_chainunlock(pdb->tdb, key);
1619 SAFE_FREE(data.dptr);
1620 release_print_db(pdb);
1621 if (ret)
1622 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1623 else
1624 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1625 return ret;
1628 /****************************************************************************
1629 Delete a print job - don't update queue.
1630 ****************************************************************************/
1632 static BOOL print_job_delete1(int snum, uint32 jobid)
1634 const char* sharename = lp_const_servicename(snum);
1635 struct printjob *pjob = print_job_find(sharename, jobid);
1636 int result = 0;
1637 struct printif *current_printif = get_printer_fns( snum );
1639 pjob = print_job_find(sharename, jobid);
1641 if (!pjob)
1642 return False;
1645 * If already deleting just return.
1648 if (pjob->status == LPQ_DELETING)
1649 return True;
1651 /* Hrm - we need to be able to cope with deleting a job before it
1652 has reached the spooler. */
1654 if (pjob->sysjob == -1) {
1655 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1658 /* Set the tdb entry to be deleting. */
1660 pjob->status = LPQ_DELETING;
1661 pjob_store(sharename, jobid, pjob);
1663 if (pjob->spooled && pjob->sysjob != -1)
1664 result = (*(current_printif->job_delete))(snum, pjob);
1666 /* Delete the tdb entry if the delete succeeded or the job hasn't
1667 been spooled. */
1669 if (result == 0) {
1670 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1671 int njobs = 1;
1673 if (!pdb)
1674 return False;
1675 pjob_delete(sharename, jobid);
1676 /* Ensure we keep a rough count of the number of total jobs... */
1677 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1678 release_print_db(pdb);
1681 return (result == 0);
1684 /****************************************************************************
1685 Return true if the current user owns the print job.
1686 ****************************************************************************/
1688 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1690 struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
1691 user_struct *vuser;
1693 if (!pjob || !user)
1694 return False;
1696 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1697 return strequal(pjob->user, vuser->user.smb_name);
1698 } else {
1699 return strequal(pjob->user, uidtoname(user->uid));
1703 /****************************************************************************
1704 Delete a print job.
1705 ****************************************************************************/
1707 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1709 const char* sharename = lp_const_servicename( snum );
1710 BOOL owner, deleted;
1711 char *fname;
1713 *errcode = WERR_OK;
1715 owner = is_owner(user, snum, jobid);
1717 /* Check access against security descriptor or whether the user
1718 owns their job. */
1720 if (!owner &&
1721 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1722 DEBUG(3, ("delete denied by security descriptor\n"));
1723 *errcode = WERR_ACCESS_DENIED;
1725 /* BEGIN_ADMIN_LOG */
1726 sys_adminlog( LOG_ERR,
1727 "Permission denied-- user not allowed to delete, \
1728 pause, or resume print job. User name: %s. Printer name: %s.",
1729 uidtoname(user->uid), PRINTERNAME(snum) );
1730 /* END_ADMIN_LOG */
1732 return False;
1736 * get the spooled filename of the print job
1737 * if this works, then the file has not been spooled
1738 * to the underlying print system. Just delete the
1739 * spool file & return.
1742 if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1744 /* remove the spool file */
1745 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1746 if ( unlink( fname ) == -1 ) {
1747 *errcode = map_werror_from_unix(errno);
1748 return False;
1752 if (!print_job_delete1(snum, jobid)) {
1753 *errcode = WERR_ACCESS_DENIED;
1754 return False;
1757 /* force update the database and say the delete failed if the
1758 job still exists */
1760 print_queue_update(snum);
1762 deleted = !print_job_exists(sharename, jobid);
1763 if ( !deleted )
1764 *errcode = WERR_ACCESS_DENIED;
1766 return deleted;
1769 /****************************************************************************
1770 Pause a job.
1771 ****************************************************************************/
1773 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1775 const char* sharename = lp_const_servicename(snum);
1776 struct printjob *pjob;
1777 int ret = -1;
1778 struct printif *current_printif = get_printer_fns( snum );
1780 pjob = print_job_find(sharename, jobid);
1782 if (!pjob || !user)
1783 return False;
1785 if (!pjob->spooled || pjob->sysjob == -1)
1786 return False;
1788 if (!is_owner(user, snum, jobid) &&
1789 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1790 DEBUG(3, ("pause denied by security descriptor\n"));
1792 /* BEGIN_ADMIN_LOG */
1793 sys_adminlog( LOG_ERR,
1794 "Permission denied-- user not allowed to delete, \
1795 pause, or resume print job. User name: %s. Printer name: %s.",
1796 uidtoname(user->uid), PRINTERNAME(snum) );
1797 /* END_ADMIN_LOG */
1799 *errcode = WERR_ACCESS_DENIED;
1800 return False;
1803 /* need to pause the spooled entry */
1804 ret = (*(current_printif->job_pause))(snum, pjob);
1806 if (ret != 0) {
1807 *errcode = WERR_INVALID_PARAM;
1808 return False;
1811 /* force update the database */
1812 print_cache_flush(snum);
1814 /* Send a printer notify message */
1816 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
1818 /* how do we tell if this succeeded? */
1820 return True;
1823 /****************************************************************************
1824 Resume a job.
1825 ****************************************************************************/
1827 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1829 const char *sharename = lp_const_servicename(snum);
1830 struct printjob *pjob;
1831 int ret;
1832 struct printif *current_printif = get_printer_fns( snum );
1834 pjob = print_job_find(sharename, jobid);
1836 if (!pjob || !user)
1837 return False;
1839 if (!pjob->spooled || pjob->sysjob == -1)
1840 return False;
1842 if (!is_owner(user, snum, jobid) &&
1843 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1844 DEBUG(3, ("resume denied by security descriptor\n"));
1845 *errcode = WERR_ACCESS_DENIED;
1847 /* BEGIN_ADMIN_LOG */
1848 sys_adminlog( LOG_ERR,
1849 "Permission denied-- user not allowed to delete, \
1850 pause, or resume print job. User name: %s. Printer name: %s.",
1851 uidtoname(user->uid), PRINTERNAME(snum) );
1852 /* END_ADMIN_LOG */
1853 return False;
1856 ret = (*(current_printif->job_resume))(snum, pjob);
1858 if (ret != 0) {
1859 *errcode = WERR_INVALID_PARAM;
1860 return False;
1863 /* force update the database */
1864 print_cache_flush(snum);
1866 /* Send a printer notify message */
1868 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
1870 return True;
1873 /****************************************************************************
1874 Write to a print file.
1875 ****************************************************************************/
1877 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1879 const char* sharename = lp_const_servicename(snum);
1880 int return_code;
1881 struct printjob *pjob;
1883 pjob = print_job_find(sharename, jobid);
1885 if (!pjob)
1886 return -1;
1887 /* don't allow another process to get this info - it is meaningless */
1888 if (pjob->pid != sys_getpid())
1889 return -1;
1891 return_code = write(pjob->fd, buf, size);
1892 if (return_code>0) {
1893 pjob->size += size;
1894 pjob_store(sharename, jobid, pjob);
1896 return return_code;
1899 /****************************************************************************
1900 Check if the print queue has been updated recently enough.
1901 ****************************************************************************/
1903 static BOOL print_cache_expired(int snum)
1905 fstring key;
1906 time_t last_qscan_time, time_now = time(NULL);
1907 const char *printername = lp_const_servicename(snum);
1908 struct tdb_print_db *pdb = get_print_db_byname(printername);
1910 if (!pdb)
1911 return False;
1913 slprintf(key, sizeof(key), "CACHE/%s", printername);
1914 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1917 * Invalidate the queue for 3 reasons.
1918 * (1). last queue scan time == -1.
1919 * (2). Current time - last queue scan time > allowed cache time.
1920 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1921 * This last test picks up machines for which the clock has been moved
1922 * forward, an lpq scan done and then the clock moved back. Otherwise
1923 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1926 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1927 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1928 DEBUG(3, ("print cache expired for queue %s \
1929 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1930 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1931 release_print_db(pdb);
1932 return True;
1934 release_print_db(pdb);
1935 return False;
1938 /****************************************************************************
1939 Get the queue status - do not update if db is out of date.
1940 ****************************************************************************/
1942 static int get_queue_status(const char* sharename, print_status_struct *status)
1944 fstring keystr;
1945 TDB_DATA data, key;
1946 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1947 int len;
1949 if (!pdb)
1950 return 0;
1952 if (status) {
1953 ZERO_STRUCTP(status);
1954 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1955 key.dptr = keystr;
1956 key.dsize = strlen(keystr);
1957 data = tdb_fetch(pdb->tdb, key);
1958 if (data.dptr) {
1959 if (data.dsize == sizeof(print_status_struct))
1960 /* this memcpy is ok since the status struct was
1961 not packed before storing it in the tdb */
1962 memcpy(status, data.dptr, sizeof(print_status_struct));
1963 SAFE_FREE(data.dptr);
1966 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1967 release_print_db(pdb);
1968 return (len == -1 ? 0 : len);
1971 /****************************************************************************
1972 Determine the number of jobs in a queue.
1973 ****************************************************************************/
1975 int print_queue_length(int snum, print_status_struct *pstatus)
1977 const char* sharename = lp_const_servicename( snum );
1978 print_status_struct status;
1979 int len;
1981 /* make sure the database is up to date */
1982 if (print_cache_expired(snum))
1983 print_queue_update(snum);
1985 /* also fetch the queue status */
1986 memset(&status, 0, sizeof(status));
1987 len = get_queue_status(sharename, &status);
1989 if (pstatus)
1990 *pstatus = status;
1992 return len;
1995 /***************************************************************************
1996 Allocate a jobid. Hold the lock for as short a time as possible.
1997 ***************************************************************************/
1999 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2001 int i;
2002 uint32 jobid;
2004 *pjobid = (uint32)-1;
2006 for (i = 0; i < 3; i++) {
2007 /* Lock the database - only wait 20 seconds. */
2008 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
2009 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2010 return False;
2013 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2014 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2015 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2016 sharename));
2017 return False;
2019 jobid = 0;
2022 jobid = NEXT_JOBID(jobid);
2024 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2025 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2026 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2027 return False;
2030 /* We've finished with the INFO/nextjob lock. */
2031 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2033 if (!print_job_exists(sharename, jobid))
2034 break;
2037 if (i > 2) {
2038 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2039 sharename));
2040 /* Probably full... */
2041 errno = ENOSPC;
2042 return False;
2045 /* Store a dummy placeholder. */
2047 TDB_DATA dum;
2048 dum.dptr = NULL;
2049 dum.dsize = 0;
2050 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2051 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2052 jobid ));
2053 return False;
2057 *pjobid = jobid;
2058 return True;
2061 /***************************************************************************
2062 Append a jobid to the 'jobs changed' list.
2063 ***************************************************************************/
2065 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2067 TDB_DATA data, key;
2068 uint32 store_jobid;
2070 key.dptr = "INFO/jobs_changed";
2071 key.dsize = strlen(key.dptr);
2072 SIVAL(&store_jobid, 0, jobid);
2073 data.dptr = (char *)&store_jobid;
2074 data.dsize = 4;
2076 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2078 return (tdb_append(pdb->tdb, key, data) == 0);
2081 /***************************************************************************
2082 Start spooling a job - return the jobid.
2083 ***************************************************************************/
2085 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2087 uint32 jobid;
2088 char *path;
2089 struct printjob pjob;
2090 user_struct *vuser;
2091 const char *sharename = lp_const_servicename(snum);
2092 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2093 int njobs;
2095 errno = 0;
2097 if (!pdb)
2098 return (uint32)-1;
2100 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2101 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2102 release_print_db(pdb);
2103 return (uint32)-1;
2106 if (!print_time_access_check(snum)) {
2107 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2108 release_print_db(pdb);
2109 return (uint32)-1;
2112 path = lp_pathname(snum);
2114 /* see if we have sufficient disk space */
2115 if (lp_minprintspace(snum)) {
2116 SMB_BIG_UINT dspace, dsize;
2117 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2118 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2119 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2120 release_print_db(pdb);
2121 errno = ENOSPC;
2122 return (uint32)-1;
2126 /* for autoloaded printers, check that the printcap entry still exists */
2127 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
2128 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2129 release_print_db(pdb);
2130 errno = ENOENT;
2131 return (uint32)-1;
2134 /* Insure the maximum queue size is not violated */
2135 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2136 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2137 sharename, njobs, lp_maxprintjobs(snum) ));
2138 release_print_db(pdb);
2139 errno = ENOSPC;
2140 return (uint32)-1;
2143 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2144 sharename, njobs, lp_maxprintjobs(snum) ));
2146 if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2147 goto fail;
2149 /* create the database entry */
2151 ZERO_STRUCT(pjob);
2153 pjob.pid = sys_getpid();
2154 pjob.sysjob = -1;
2155 pjob.fd = -1;
2156 pjob.starttime = time(NULL);
2157 pjob.status = LPQ_SPOOLING;
2158 pjob.size = 0;
2159 pjob.spooled = False;
2160 pjob.smbjob = True;
2161 pjob.nt_devmode = nt_devmode;
2163 fstrcpy(pjob.jobname, jobname);
2165 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2166 fstrcpy(pjob.user, vuser->user.smb_name);
2167 } else {
2168 fstrcpy(pjob.user, uidtoname(user->uid));
2171 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2173 /* we have a job entry - now create the spool file */
2174 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2175 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2176 pjob.fd = smb_mkstemp(pjob.filename);
2178 if (pjob.fd == -1) {
2179 if (errno == EACCES) {
2180 /* Common setup error, force a report. */
2181 DEBUG(0, ("print_job_start: insufficient permissions \
2182 to open spool file %s.\n", pjob.filename));
2183 } else {
2184 /* Normal case, report at level 3 and above. */
2185 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2186 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2188 goto fail;
2191 pjob_store(sharename, jobid, &pjob);
2193 /* Update the 'jobs changed' entry used by print_queue_status. */
2194 add_to_jobs_changed(pdb, jobid);
2196 /* Ensure we keep a rough count of the number of total jobs... */
2197 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2199 release_print_db(pdb);
2201 return jobid;
2203 fail:
2204 if (jobid != -1)
2205 pjob_delete(sharename, jobid);
2207 release_print_db(pdb);
2209 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2210 return (uint32)-1;
2213 /****************************************************************************
2214 Update the number of pages spooled to jobid
2215 ****************************************************************************/
2217 void print_job_endpage(int snum, uint32 jobid)
2219 const char* sharename = lp_const_servicename(snum);
2220 struct printjob *pjob;
2222 pjob = print_job_find(sharename, jobid);
2223 if (!pjob)
2224 return;
2225 /* don't allow another process to get this info - it is meaningless */
2226 if (pjob->pid != sys_getpid())
2227 return;
2229 pjob->page_count++;
2230 pjob_store(sharename, jobid, pjob);
2233 /****************************************************************************
2234 Print a file - called on closing the file. This spools the job.
2235 If normal close is false then we're tearing down the jobs - treat as an
2236 error.
2237 ****************************************************************************/
2239 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2241 const char* sharename = lp_const_servicename(snum);
2242 struct printjob *pjob;
2243 int ret;
2244 SMB_STRUCT_STAT sbuf;
2245 struct printif *current_printif = get_printer_fns( snum );
2247 pjob = print_job_find(sharename, jobid);
2249 if (!pjob)
2250 return False;
2252 if (pjob->spooled || pjob->pid != sys_getpid())
2253 return False;
2255 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2256 pjob->size = sbuf.st_size;
2257 close(pjob->fd);
2258 pjob->fd = -1;
2259 } else {
2262 * Not a normal close or we couldn't stat the job file,
2263 * so something has gone wrong. Cleanup.
2265 close(pjob->fd);
2266 pjob->fd = -1;
2267 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2268 goto fail;
2271 /* Technically, this is not quite right. If the printer has a separator
2272 * page turned on, the NT spooler prints the separator page even if the
2273 * print job is 0 bytes. 010215 JRR */
2274 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2275 /* don't bother spooling empty files or something being deleted. */
2276 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2277 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2278 unlink(pjob->filename);
2279 pjob_delete(sharename, jobid);
2280 return True;
2283 pjob->smbjob = jobid;
2285 ret = (*(current_printif->job_submit))(snum, pjob);
2287 if (ret)
2288 goto fail;
2290 /* The print job has been sucessfully handed over to the back-end */
2292 pjob->spooled = True;
2293 pjob->status = LPQ_QUEUED;
2294 pjob_store(sharename, jobid, pjob);
2296 /* make sure the database is up to date */
2297 if (print_cache_expired(snum))
2298 print_queue_update(snum);
2300 return True;
2302 fail:
2304 /* The print job was not succesfully started. Cleanup */
2305 /* Still need to add proper error return propagation! 010122:JRR */
2306 unlink(pjob->filename);
2307 pjob_delete(sharename, jobid);
2308 return False;
2311 /****************************************************************************
2312 Get a snapshot of jobs in the system without traversing.
2313 ****************************************************************************/
2315 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2317 TDB_DATA data, key, cgdata;
2318 print_queue_struct *queue = NULL;
2319 uint32 qcount = 0;
2320 uint32 extra_count = 0;
2321 int total_count = 0;
2322 size_t len = 0;
2323 uint32 i;
2324 int max_reported_jobs = lp_max_reported_jobs(snum);
2325 BOOL ret = False;
2326 const char* sharename = lp_servicename(snum);
2328 /* make sure the database is up to date */
2329 if (print_cache_expired(snum))
2330 print_queue_update(snum);
2332 *pcount = 0;
2333 *ppqueue = NULL;
2335 ZERO_STRUCT(data);
2336 ZERO_STRUCT(cgdata);
2337 key.dptr = "INFO/linear_queue_array";
2338 key.dsize = strlen(key.dptr);
2340 /* Get the stored queue data. */
2341 data = tdb_fetch(pdb->tdb, key);
2343 if (data.dptr && data.dsize >= sizeof(qcount))
2344 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2346 /* Get the changed jobs list. */
2347 key.dptr = "INFO/jobs_changed";
2348 key.dsize = strlen(key.dptr);
2350 cgdata = tdb_fetch(pdb->tdb, key);
2351 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2352 extra_count = cgdata.dsize/4;
2354 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2356 /* Allocate the queue size. */
2357 if (qcount == 0 && extra_count == 0)
2358 goto out;
2360 if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2361 goto out;
2363 /* Retrieve the linearised queue data. */
2365 for( i = 0; i < qcount; i++) {
2366 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2367 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2368 &qjob,
2369 &qsize,
2370 &qpage_count,
2371 &qstatus,
2372 &qpriority,
2373 &qtime,
2374 queue[i].fs_user,
2375 queue[i].fs_file);
2376 queue[i].job = qjob;
2377 queue[i].size = qsize;
2378 queue[i].page_count = qpage_count;
2379 queue[i].status = qstatus;
2380 queue[i].priority = qpriority;
2381 queue[i].time = qtime;
2384 total_count = qcount;
2386 /* Add in the changed jobids. */
2387 for( i = 0; i < extra_count; i++) {
2388 uint32 jobid;
2389 struct printjob *pjob;
2391 jobid = IVAL(cgdata.dptr, i*4);
2392 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2393 pjob = print_job_find(lp_const_servicename(snum), jobid);
2394 if (!pjob) {
2395 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2396 remove_from_jobs_changed(sharename, jobid);
2397 continue;
2400 queue[total_count].job = jobid;
2401 queue[total_count].size = pjob->size;
2402 queue[total_count].page_count = pjob->page_count;
2403 queue[total_count].status = pjob->status;
2404 queue[total_count].priority = 1;
2405 queue[total_count].time = pjob->starttime;
2406 fstrcpy(queue[total_count].fs_user, pjob->user);
2407 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2408 total_count++;
2411 /* Sort the queue by submission time otherwise they are displayed
2412 in hash order. */
2414 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2416 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2418 if (max_reported_jobs && total_count > max_reported_jobs)
2419 total_count = max_reported_jobs;
2421 *ppqueue = queue;
2422 *pcount = total_count;
2424 ret = True;
2426 out:
2428 SAFE_FREE(data.dptr);
2429 SAFE_FREE(cgdata.dptr);
2430 return ret;
2433 /****************************************************************************
2434 Get a printer queue listing.
2435 set queue = NULL and status = NULL if you just want to update the cache
2436 ****************************************************************************/
2438 int print_queue_status(int snum,
2439 print_queue_struct **ppqueue,
2440 print_status_struct *status)
2442 fstring keystr;
2443 TDB_DATA data, key;
2444 const char *sharename;
2445 struct tdb_print_db *pdb;
2446 int count = 0;
2448 /* make sure the database is up to date */
2450 if (print_cache_expired(snum))
2451 print_queue_update(snum);
2453 /* return if we are done */
2454 if ( !ppqueue || !status )
2455 return 0;
2457 *ppqueue = NULL;
2458 sharename = lp_const_servicename(snum);
2459 pdb = get_print_db_byname(sharename);
2461 if (!pdb)
2462 return 0;
2465 * Fetch the queue status. We must do this first, as there may
2466 * be no jobs in the queue.
2469 ZERO_STRUCTP(status);
2470 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2471 key.dptr = keystr;
2472 key.dsize = strlen(keystr);
2473 data = tdb_fetch(pdb->tdb, key);
2474 if (data.dptr) {
2475 if (data.dsize == sizeof(*status)) {
2476 /* this memcpy is ok since the status struct was
2477 not packed before storing it in the tdb */
2478 memcpy(status, data.dptr, sizeof(*status));
2480 SAFE_FREE(data.dptr);
2484 * Now, fetch the print queue information. We first count the number
2485 * of entries, and then only retrieve the queue if necessary.
2488 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2489 release_print_db(pdb);
2490 return 0;
2493 release_print_db(pdb);
2494 return count;
2497 /****************************************************************************
2498 Pause a queue.
2499 ****************************************************************************/
2501 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2503 int ret;
2504 struct printif *current_printif = get_printer_fns( snum );
2506 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2507 *errcode = WERR_ACCESS_DENIED;
2508 return False;
2511 ret = (*(current_printif->queue_pause))(snum);
2513 if (ret != 0) {
2514 *errcode = WERR_INVALID_PARAM;
2515 return False;
2518 /* force update the database */
2519 print_cache_flush(snum);
2521 /* Send a printer notify message */
2523 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2525 return True;
2528 /****************************************************************************
2529 Resume a queue.
2530 ****************************************************************************/
2532 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2534 int ret;
2535 struct printif *current_printif = get_printer_fns( snum );
2537 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2538 *errcode = WERR_ACCESS_DENIED;
2539 return False;
2542 ret = (*(current_printif->queue_resume))(snum);
2544 if (ret != 0) {
2545 *errcode = WERR_INVALID_PARAM;
2546 return False;
2549 /* make sure the database is up to date */
2550 if (print_cache_expired(snum))
2551 print_queue_update(snum);
2553 /* Send a printer notify message */
2555 notify_printer_status(snum, PRINTER_STATUS_OK);
2557 return True;
2560 /****************************************************************************
2561 Purge a queue - implemented by deleting all jobs that we can delete.
2562 ****************************************************************************/
2564 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2566 print_queue_struct *queue;
2567 print_status_struct status;
2568 int njobs, i;
2569 BOOL can_job_admin;
2571 /* Force and update so the count is accurate (i.e. not a cached count) */
2572 print_queue_update(snum);
2574 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2575 njobs = print_queue_status(snum, &queue, &status);
2577 for (i=0;i<njobs;i++) {
2578 BOOL owner = is_owner(user, snum, queue[i].job);
2580 if (owner || can_job_admin) {
2581 print_job_delete1(snum, queue[i].job);
2585 SAFE_FREE(queue);
2587 return True;