r4904: sync up with 3.0 for 3.0.11pre2
[Samba.git] / source / printing / printing.c
blobb4d0f3a44b3708d8db0f9109ec17371be308eb02
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 struct print_queue_update_context {
47 char* sharename;
48 enum printing_types printing_type;
49 char* lpqcommand;
53 static TDB_CONTEXT *rap_tdb;
54 static uint16 next_rap_jobid;
55 struct rap_jobid_key {
56 fstring sharename;
57 uint32 jobid;
60 /***************************************************************************
61 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
62 bit RPC jobids.... JRA.
63 ***************************************************************************/
65 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
67 uint16 rap_jobid;
68 TDB_DATA data, key;
69 struct rap_jobid_key jinfo;
71 DEBUG(10,("pjobid_to_rap: called.\n"));
73 if (!rap_tdb) {
74 /* Create the in-memory tdb. */
75 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
76 if (!rap_tdb)
77 return 0;
80 ZERO_STRUCT( jinfo );
81 fstrcpy( jinfo.sharename, sharename );
82 jinfo.jobid = jobid;
83 key.dptr = (char*)&jinfo;
84 key.dsize = sizeof(jinfo);
86 data = tdb_fetch(rap_tdb, key);
87 if (data.dptr && data.dsize == sizeof(uint16)) {
88 rap_jobid = SVAL(data.dptr, 0);
89 SAFE_FREE(data.dptr);
90 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
91 (unsigned int)jobid, (unsigned int)rap_jobid));
92 return rap_jobid;
94 SAFE_FREE(data.dptr);
95 /* Not found - create and store mapping. */
96 rap_jobid = ++next_rap_jobid;
97 if (rap_jobid == 0)
98 rap_jobid = ++next_rap_jobid;
99 data.dptr = (char *)&rap_jobid;
100 data.dsize = sizeof(rap_jobid);
101 tdb_store(rap_tdb, key, data, TDB_REPLACE);
102 tdb_store(rap_tdb, data, key, TDB_REPLACE);
104 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
105 (unsigned int)jobid, (unsigned int)rap_jobid));
106 return rap_jobid;
109 BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
111 TDB_DATA data, key;
113 DEBUG(10,("rap_to_pjobid called.\n"));
115 if (!rap_tdb)
116 return False;
118 key.dptr = (char *)&rap_jobid;
119 key.dsize = sizeof(rap_jobid);
120 data = tdb_fetch(rap_tdb, key);
121 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
123 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
124 fstrcpy( sharename, jinfo->sharename );
125 *pjobid = jinfo->jobid;
126 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
127 (unsigned int)*pjobid, (unsigned int)rap_jobid));
128 SAFE_FREE(data.dptr);
129 return True;
132 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
133 (unsigned int)rap_jobid));
134 SAFE_FREE(data.dptr);
135 return False;
138 static void rap_jobid_delete(const char* sharename, uint32 jobid)
140 TDB_DATA key, data;
141 uint16 rap_jobid;
142 struct rap_jobid_key jinfo;
144 DEBUG(10,("rap_jobid_delete: called.\n"));
146 if (!rap_tdb)
147 return;
149 ZERO_STRUCT( jinfo );
150 fstrcpy( jinfo.sharename, sharename );
151 jinfo.jobid = jobid;
152 key.dptr = (char*)&jinfo;
153 key.dsize = sizeof(jinfo);
155 data = tdb_fetch(rap_tdb, key);
156 if (!data.dptr || (data.dsize != sizeof(uint16))) {
157 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
158 (unsigned int)jobid ));
159 SAFE_FREE(data.dptr);
160 return;
163 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
164 (unsigned int)jobid ));
166 rap_jobid = SVAL(data.dptr, 0);
167 SAFE_FREE(data.dptr);
168 data.dptr = (char *)&rap_jobid;
169 data.dsize = sizeof(rap_jobid);
170 tdb_delete(rap_tdb, key);
171 tdb_delete(rap_tdb, data);
174 static int get_queue_status(const char* sharename, print_status_struct *);
176 /****************************************************************************
177 Initialise the printing backend. Called once at startup before the fork().
178 ****************************************************************************/
180 BOOL print_backend_init(void)
182 const char *sversion = "INFO/version";
183 pstring printing_path;
184 int services = lp_numservices();
185 int snum;
187 unlink(lock_path("printing.tdb"));
188 pstrcpy(printing_path,lock_path("printing"));
189 mkdir(printing_path,0755);
191 /* handle a Samba upgrade */
193 for (snum = 0; snum < services; snum++) {
194 struct tdb_print_db *pdb;
195 if (!lp_print_ok(snum))
196 continue;
198 pdb = get_print_db_byname(lp_const_servicename(snum));
199 if (!pdb)
200 continue;
201 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
202 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
203 release_print_db(pdb);
204 return False;
206 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
207 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
208 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
210 tdb_unlock_bystring(pdb->tdb, sversion);
211 release_print_db(pdb);
214 close_all_print_db(); /* Don't leave any open. */
216 /* do NT print initialization... */
217 return nt_printing_init();
220 /****************************************************************************
221 Shut down printing backend. Called once at shutdown to close the tdb.
222 ****************************************************************************/
224 void printing_end(void)
226 close_all_print_db(); /* Don't leave any open. */
229 /****************************************************************************
230 Retrieve the set of printing functions for a given service. This allows
231 us to set the printer function table based on the value of the 'printing'
232 service parameter.
234 Use the generic interface as the default and only use cups interface only
235 when asked for (and only when supported)
236 ****************************************************************************/
238 static struct printif *get_printer_fns_from_type( enum printing_types type )
240 struct printif *printer_fns = &generic_printif;
242 #ifdef HAVE_CUPS
243 if ( type == PRINT_CUPS ) {
244 printer_fns = &cups_printif;
246 #endif /* HAVE_CUPS */
248 printer_fns->type = type;
250 return printer_fns;
253 static struct printif *get_printer_fns( int snum )
255 return get_printer_fns_from_type( lp_printing(snum) );
259 /****************************************************************************
260 Useful function to generate a tdb key.
261 ****************************************************************************/
263 static TDB_DATA print_key(uint32 jobid)
265 static uint32 j;
266 TDB_DATA ret;
268 SIVAL(&j, 0, jobid);
269 ret.dptr = (void *)&j;
270 ret.dsize = sizeof(j);
271 return ret;
274 /***********************************************************************
275 unpack a pjob from a tdb buffer
276 ***********************************************************************/
278 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
280 int len = 0;
281 int used;
282 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
283 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
285 if ( !buf || !pjob )
286 return -1;
288 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
289 &pjpid,
290 &pjsysjob,
291 &pjfd,
292 &pjstarttime,
293 &pjstatus,
294 &pjsize,
295 &pjpage_count,
296 &pjspooled,
297 &pjsmbjob,
298 pjob->filename,
299 pjob->jobname,
300 pjob->user,
301 pjob->queuename);
303 if ( len == -1 )
304 return -1;
306 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
307 return -1;
309 len += used;
311 pjob->pid = pjpid;
312 pjob->sysjob = pjsysjob;
313 pjob->fd = pjfd;
314 pjob->starttime = pjstarttime;
315 pjob->status = pjstatus;
316 pjob->size = pjsize;
317 pjob->page_count = pjpage_count;
318 pjob->spooled = pjspooled;
319 pjob->smbjob = pjsmbjob;
321 return len;
325 /****************************************************************************
326 Useful function to find a print job in the database.
327 ****************************************************************************/
329 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
331 static struct printjob pjob;
332 TDB_DATA ret;
333 struct tdb_print_db *pdb = get_print_db_byname(sharename);
336 if (!pdb)
337 return NULL;
339 ret = tdb_fetch(pdb->tdb, print_key(jobid));
340 release_print_db(pdb);
342 if (!ret.dptr)
343 return NULL;
345 if ( pjob.nt_devmode )
346 free_nt_devicemode( &pjob.nt_devmode );
348 ZERO_STRUCT( pjob );
350 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
351 SAFE_FREE(ret.dptr);
352 return NULL;
355 SAFE_FREE(ret.dptr);
356 return &pjob;
359 /* Convert a unix jobid to a smb jobid */
361 static uint32 sysjob_to_jobid_value;
363 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
364 TDB_DATA data, void *state)
366 struct printjob *pjob;
367 int *sysjob = (int *)state;
369 if (!data.dptr || data.dsize == 0)
370 return 0;
372 pjob = (struct printjob *)data.dptr;
373 if (key.dsize != sizeof(uint32))
374 return 0;
376 if (*sysjob == pjob->sysjob) {
377 uint32 jobid = IVAL(key.dptr,0);
379 sysjob_to_jobid_value = jobid;
380 return 1;
383 return 0;
386 /****************************************************************************
387 This is a *horribly expensive call as we have to iterate through all the
388 current printer tdb's. Don't do this often ! JRA.
389 ****************************************************************************/
391 uint32 sysjob_to_jobid(int unix_jobid)
393 int services = lp_numservices();
394 int snum;
396 sysjob_to_jobid_value = (uint32)-1;
398 for (snum = 0; snum < services; snum++) {
399 struct tdb_print_db *pdb;
400 if (!lp_print_ok(snum))
401 continue;
402 pdb = get_print_db_byname(lp_const_servicename(snum));
403 if (pdb)
404 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
405 release_print_db(pdb);
406 if (sysjob_to_jobid_value != (uint32)-1)
407 return sysjob_to_jobid_value;
409 return (uint32)-1;
412 /****************************************************************************
413 Send notifications based on what has changed after a pjob_store.
414 ****************************************************************************/
416 static struct {
417 uint32 lpq_status;
418 uint32 spoolss_status;
419 } lpq_to_spoolss_status_map[] = {
420 { LPQ_QUEUED, JOB_STATUS_QUEUED },
421 { LPQ_PAUSED, JOB_STATUS_PAUSED },
422 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
423 { LPQ_PRINTING, JOB_STATUS_PRINTING },
424 { LPQ_DELETING, JOB_STATUS_DELETING },
425 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
426 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
427 { LPQ_PRINTED, JOB_STATUS_PRINTED },
428 { LPQ_DELETED, JOB_STATUS_DELETED },
429 { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
430 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
431 { -1, 0 }
434 /* Convert a lpq status value stored in printing.tdb into the
435 appropriate win32 API constant. */
437 static uint32 map_to_spoolss_status(uint32 lpq_status)
439 int i = 0;
441 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
442 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
443 return lpq_to_spoolss_status_map[i].spoolss_status;
444 i++;
447 return 0;
450 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
451 struct printjob *new_data)
453 BOOL new_job = False;
455 if (!old_data)
456 new_job = True;
458 /* Job attributes that can't be changed. We only send
459 notification for these on a new job. */
461 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
462 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
463 time first or else we'll end up with potential alignment
464 errors. I don't think the systemtime should be spooled as
465 a string, but this gets us around that error.
466 --jerry (i'll feel dirty for this) */
468 if (new_job) {
469 notify_job_submitted(sharename, jobid, new_data->starttime);
470 notify_job_username(sharename, jobid, new_data->user);
473 if (new_job || !strequal(old_data->jobname, new_data->jobname))
474 notify_job_name(sharename, jobid, new_data->jobname);
476 /* Job attributes of a new job or attributes that can be
477 modified. */
479 if (new_job || !strequal(old_data->jobname, new_data->jobname))
480 notify_job_name(sharename, jobid, new_data->jobname);
482 if (new_job || old_data->status != new_data->status)
483 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
485 if (new_job || old_data->size != new_data->size)
486 notify_job_total_bytes(sharename, jobid, new_data->size);
488 if (new_job || old_data->page_count != new_data->page_count)
489 notify_job_total_pages(sharename, jobid, new_data->page_count);
492 /****************************************************************************
493 Store a job structure back to the database.
494 ****************************************************************************/
496 static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
498 TDB_DATA old_data, new_data;
499 BOOL ret = False;
500 struct tdb_print_db *pdb = get_print_db_byname(sharename);
501 char *buf = NULL;
502 int len, newlen, buflen;
505 if (!pdb)
506 return False;
508 /* Get old data */
510 old_data = tdb_fetch(pdb->tdb, print_key(jobid));
512 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
514 newlen = 0;
516 do {
517 len = 0;
518 buflen = newlen;
519 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
520 (uint32)pjob->pid,
521 (uint32)pjob->sysjob,
522 (uint32)pjob->fd,
523 (uint32)pjob->starttime,
524 (uint32)pjob->status,
525 (uint32)pjob->size,
526 (uint32)pjob->page_count,
527 (uint32)pjob->spooled,
528 (uint32)pjob->smbjob,
529 pjob->filename,
530 pjob->jobname,
531 pjob->user,
532 pjob->queuename);
534 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
536 if (buflen != len) {
537 char *tb;
539 tb = (char *)SMB_REALLOC(buf, len);
540 if (!tb) {
541 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
542 goto done;
544 else
545 buf = tb;
546 newlen = len;
548 } while ( buflen != len );
551 /* Store new data */
553 new_data.dptr = buf;
554 new_data.dsize = len;
555 ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
557 release_print_db(pdb);
559 /* Send notify updates for what has changed */
561 if ( ret ) {
562 struct printjob old_pjob;
564 if ( old_data.dsize )
566 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
568 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
569 free_nt_devicemode( &old_pjob.nt_devmode );
572 else {
573 /* new job */
574 pjob_store_notify( sharename, jobid, NULL, pjob );
578 done:
579 SAFE_FREE( old_data.dptr );
580 SAFE_FREE( buf );
582 return ret;
585 /****************************************************************************
586 Remove a job structure from the database.
587 ****************************************************************************/
589 void pjob_delete(const char* sharename, uint32 jobid)
591 struct printjob *pjob;
592 uint32 job_status = 0;
593 struct tdb_print_db *pdb;
595 pdb = get_print_db_byname( sharename );
597 if (!pdb)
598 return;
600 pjob = print_job_find( sharename, jobid );
602 if (!pjob) {
603 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
604 (unsigned int)jobid));
605 release_print_db(pdb);
606 return;
609 /* We must cycle through JOB_STATUS_DELETING and
610 JOB_STATUS_DELETED for the port monitor to delete the job
611 properly. */
613 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
614 notify_job_status(sharename, jobid, job_status);
616 /* Remove from printing.tdb */
618 tdb_delete(pdb->tdb, print_key(jobid));
619 remove_from_jobs_changed(sharename, jobid);
620 release_print_db( pdb );
621 rap_jobid_delete(sharename, jobid);
624 /****************************************************************************
625 Parse a file name from the system spooler to generate a jobid.
626 ****************************************************************************/
628 static uint32 print_parse_jobid(char *fname)
630 int jobid;
632 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
633 return (uint32)-1;
634 fname += strlen(PRINT_SPOOL_PREFIX);
636 jobid = atoi(fname);
637 if (jobid <= 0)
638 return (uint32)-1;
640 return (uint32)jobid;
643 /****************************************************************************
644 List a unix job in the print database.
645 ****************************************************************************/
647 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
649 struct printjob pj, *old_pj;
651 if (jobid == (uint32)-1)
652 jobid = q->job + UNIX_JOB_START;
654 /* Preserve the timestamp on an existing unix print job */
656 old_pj = print_job_find(sharename, jobid);
658 ZERO_STRUCT(pj);
660 pj.pid = (pid_t)-1;
661 pj.sysjob = q->job;
662 pj.fd = -1;
663 pj.starttime = old_pj ? old_pj->starttime : q->time;
664 pj.status = q->status;
665 pj.size = q->size;
666 pj.spooled = True;
667 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
668 if (jobid < UNIX_JOB_START) {
669 pj.smbjob = True;
670 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
671 } else {
672 pj.smbjob = False;
673 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
675 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
676 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
678 pjob_store(sharename, jobid, &pj);
682 struct traverse_struct {
683 print_queue_struct *queue;
684 int qcount, snum, maxcount, total_jobs;
685 const char *sharename;
686 time_t lpq_time;
689 /****************************************************************************
690 Utility fn to delete any jobs that are no longer active.
691 ****************************************************************************/
693 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
695 struct traverse_struct *ts = (struct traverse_struct *)state;
696 struct printjob pjob;
697 uint32 jobid;
698 int i = 0;
700 if ( key.dsize != sizeof(jobid) )
701 return 0;
703 jobid = IVAL(key.dptr, 0);
704 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
705 return 0;
706 free_nt_devicemode( &pjob.nt_devmode );
709 if (!pjob.smbjob) {
710 /* remove a unix job if it isn't in the system queue any more */
712 for (i=0;i<ts->qcount;i++) {
713 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
714 if (jobid == u_jobid)
715 break;
717 if (i == ts->qcount) {
718 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
719 (unsigned int)jobid ));
720 pjob_delete(ts->sharename, jobid);
721 return 0;
724 /* need to continue the the bottom of the function to
725 save the correct attributes */
728 /* maybe it hasn't been spooled yet */
729 if (!pjob.spooled) {
730 /* if a job is not spooled and the process doesn't
731 exist then kill it. This cleans up after smbd
732 deaths */
733 if (!process_exists(pjob.pid)) {
734 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
735 (unsigned int)jobid, (unsigned int)pjob.pid ));
736 pjob_delete(ts->sharename, jobid);
737 } else
738 ts->total_jobs++;
739 return 0;
742 /* this check only makes sense for jobs submitted from Windows clients */
744 if ( pjob.smbjob ) {
745 for (i=0;i<ts->qcount;i++) {
746 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
747 if (jobid == curr_jobid)
748 break;
752 /* The job isn't in the system queue - we have to assume it has
753 completed, so delete the database entry. */
755 if (i == ts->qcount) {
757 /* A race can occur between the time a job is spooled and
758 when it appears in the lpq output. This happens when
759 the job is added to printing.tdb when another smbd
760 running print_queue_update() has completed a lpq and
761 is currently traversing the printing tdb and deleting jobs.
762 Don't delete the job if it was submitted after the lpq_time. */
764 if (pjob.starttime < ts->lpq_time) {
765 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
766 (unsigned int)jobid,
767 (unsigned int)pjob.starttime,
768 (unsigned int)ts->lpq_time ));
769 pjob_delete(ts->sharename, jobid);
770 } else
771 ts->total_jobs++;
772 return 0;
775 /* Save the pjob attributes we will store. */
776 /* FIXME!!! This is the only place where queue->job
777 represents the SMB jobid --jerry */
778 ts->queue[i].job = jobid;
779 ts->queue[i].size = pjob.size;
780 ts->queue[i].page_count = pjob.page_count;
781 ts->queue[i].status = pjob.status;
782 ts->queue[i].priority = 1;
783 ts->queue[i].time = pjob.starttime;
784 fstrcpy(ts->queue[i].fs_user, pjob.user);
785 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
787 ts->total_jobs++;
789 return 0;
792 /****************************************************************************
793 Check if the print queue has been updated recently enough.
794 ****************************************************************************/
796 static void print_cache_flush(int snum)
798 fstring key;
799 const char *sharename = lp_const_servicename(snum);
800 struct tdb_print_db *pdb = get_print_db_byname(sharename);
802 if (!pdb)
803 return;
804 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
805 tdb_store_int32(pdb->tdb, key, -1);
806 release_print_db(pdb);
809 /****************************************************************************
810 Check if someone already thinks they are doing the update.
811 ****************************************************************************/
813 static pid_t get_updating_pid(fstring sharename)
815 fstring keystr;
816 TDB_DATA data, key;
817 pid_t updating_pid;
818 struct tdb_print_db *pdb = get_print_db_byname(sharename);
820 if (!pdb)
821 return (pid_t)-1;
822 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
823 key.dptr = keystr;
824 key.dsize = strlen(keystr);
826 data = tdb_fetch(pdb->tdb, key);
827 release_print_db(pdb);
828 if (!data.dptr || data.dsize != sizeof(pid_t)) {
829 SAFE_FREE(data.dptr);
830 return (pid_t)-1;
833 updating_pid = IVAL(data.dptr, 0);
834 SAFE_FREE(data.dptr);
836 if (process_exists(updating_pid))
837 return updating_pid;
839 return (pid_t)-1;
842 /****************************************************************************
843 Set the fact that we're doing the update, or have finished doing the update
844 in the tdb.
845 ****************************************************************************/
847 static void set_updating_pid(const fstring sharename, BOOL updating)
849 fstring keystr;
850 TDB_DATA key;
851 TDB_DATA data;
852 pid_t updating_pid = sys_getpid();
853 uint8 buffer[4];
855 struct tdb_print_db *pdb = get_print_db_byname(sharename);
857 if (!pdb)
858 return;
860 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
861 key.dptr = keystr;
862 key.dsize = strlen(keystr);
864 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
865 updating ? "" : "not ",
866 sharename ));
868 if ( !updating ) {
869 tdb_delete(pdb->tdb, key);
870 release_print_db(pdb);
871 return;
874 SIVAL( buffer, 0, updating_pid);
875 data.dptr = (void *)buffer;
876 data.dsize = 4; /* we always assume this is a 4 byte value */
878 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
879 release_print_db(pdb);
882 /****************************************************************************
883 Sort print jobs by submittal time.
884 ****************************************************************************/
886 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
888 /* Silly cases */
890 if (!j1 && !j2)
891 return 0;
892 if (!j1)
893 return -1;
894 if (!j2)
895 return 1;
897 /* Sort on job start time */
899 if (j1->time == j2->time)
900 return 0;
901 return (j1->time > j2->time) ? 1 : -1;
904 /****************************************************************************
905 Store the sorted queue representation for later portmon retrieval.
906 ****************************************************************************/
908 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
910 TDB_DATA data, key;
911 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
912 print_queue_struct *queue = pts->queue;
913 size_t len;
914 size_t i;
915 uint qcount;
917 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
918 pts->qcount = max_reported_jobs;
919 qcount = pts->qcount;
921 /* Work out the size. */
922 data.dsize = 0;
923 data.dsize += tdb_pack(NULL, 0, "d", qcount);
925 for (i = 0; i < pts->qcount; i++) {
926 data.dsize += tdb_pack(NULL, 0, "ddddddff",
927 (uint32)queue[i].job,
928 (uint32)queue[i].size,
929 (uint32)queue[i].page_count,
930 (uint32)queue[i].status,
931 (uint32)queue[i].priority,
932 (uint32)queue[i].time,
933 queue[i].fs_user,
934 queue[i].fs_file);
937 if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL)
938 return;
940 len = 0;
941 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
942 for (i = 0; i < pts->qcount; i++) {
943 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
944 (uint32)queue[i].job,
945 (uint32)queue[i].size,
946 (uint32)queue[i].page_count,
947 (uint32)queue[i].status,
948 (uint32)queue[i].priority,
949 (uint32)queue[i].time,
950 queue[i].fs_user,
951 queue[i].fs_file);
954 key.dptr = "INFO/linear_queue_array";
955 key.dsize = strlen(key.dptr);
956 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
957 SAFE_FREE(data.dptr);
958 return;
961 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
963 TDB_DATA data, key;
965 key.dptr = "INFO/jobs_changed";
966 key.dsize = strlen(key.dptr);
967 ZERO_STRUCT(data);
969 data = tdb_fetch(pdb->tdb, key);
970 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
971 SAFE_FREE(data.dptr);
972 ZERO_STRUCT(data);
975 return data;
978 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
980 unsigned int i;
981 unsigned int job_count = data.dsize / 4;
983 for (i = 0; i < job_count; i++) {
984 uint32 ch_jobid;
986 ch_jobid = IVAL(data.dptr, i*4);
987 if (ch_jobid == jobid)
988 remove_from_jobs_changed(sharename, jobid);
992 /****************************************************************************
993 Check if the print queue has been updated recently enough.
994 ****************************************************************************/
996 static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
998 fstring key;
999 time_t last_qscan_time, time_now = time(NULL);
1000 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1001 BOOL result = False;
1003 if (!pdb)
1004 return False;
1006 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1007 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1010 * Invalidate the queue for 3 reasons.
1011 * (1). last queue scan time == -1.
1012 * (2). Current time - last queue scan time > allowed cache time.
1013 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1014 * This last test picks up machines for which the clock has been moved
1015 * forward, an lpq scan done and then the clock moved back. Otherwise
1016 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1019 if (last_qscan_time == ((time_t)-1)
1020 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1021 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1023 time_t msg_pending_time;
1025 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1026 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1027 sharename, (int)last_qscan_time, (int)time_now,
1028 (int)lp_lpqcachetime() ));
1030 /* check if another smbd has already sent a message to update the
1031 queue. Give the pending message one minute to clear and
1032 then send another message anyways. Make sure to check for
1033 clocks that have been run forward and then back again. */
1035 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1037 if ( check_pending
1038 && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time )
1039 && msg_pending_time > 0
1040 && msg_pending_time <= time_now
1041 && (time_now - msg_pending_time) < 60 )
1043 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1044 sharename));
1045 goto done;
1048 result = True;
1051 done:
1052 release_print_db(pdb);
1053 return result;
1056 /****************************************************************************
1057 main work for updating the lpq cahe for a printer queue
1058 ****************************************************************************/
1060 static void print_queue_update_internal( const char *sharename,
1061 struct printif *current_printif,
1062 char *lpq_command )
1064 int i, qcount;
1065 print_queue_struct *queue = NULL;
1066 print_status_struct status;
1067 print_status_struct old_status;
1068 struct printjob *pjob;
1069 struct traverse_struct tstruct;
1070 TDB_DATA data, key;
1071 TDB_DATA jcdata;
1072 fstring keystr, cachestr;
1073 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1075 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1076 sharename, current_printif->type, lpq_command));
1078 if ( !print_cache_expired(sharename, False) ) {
1079 DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename));
1080 release_print_db(pdb);
1081 return;
1085 * Update the cache time FIRST ! Stops others even
1086 * attempting to get the lock and doing this
1087 * if the lpq takes a long time.
1090 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1091 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1093 /* get the current queue using the appropriate interface */
1094 ZERO_STRUCT(status);
1096 qcount = (*(current_printif->queue_get))(sharename,
1097 current_printif->type,
1098 lpq_command, &queue, &status);
1100 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1101 qcount, (qcount != 1) ? "s" : "", sharename));
1103 /* Sort the queue by submission time otherwise they are displayed
1104 in hash order. */
1106 qsort(queue, qcount, sizeof(print_queue_struct),
1107 QSORT_CAST(printjob_comp));
1110 any job in the internal database that is marked as spooled
1111 and doesn't exist in the system queue is considered finished
1112 and removed from the database
1114 any job in the system database but not in the internal database
1115 is added as a unix job
1117 fill in any system job numbers as we go
1120 jcdata = get_jobs_changed_data(pdb);
1122 for (i=0; i<qcount; i++) {
1123 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1125 if (jobid == (uint32)-1) {
1126 /* assume its a unix print job */
1127 print_unix_job(sharename, &queue[i], jobid);
1128 continue;
1131 /* we have an active SMB print job - update its status */
1132 pjob = print_job_find(sharename, jobid);
1133 if (!pjob) {
1134 /* err, somethings wrong. Probably smbd was restarted
1135 with jobs in the queue. All we can do is treat them
1136 like unix jobs. Pity. */
1137 print_unix_job(sharename, &queue[i], jobid);
1138 continue;
1141 pjob->sysjob = queue[i].job;
1142 pjob->status = queue[i].status;
1143 pjob_store(sharename, jobid, pjob);
1144 check_job_changed(sharename, jcdata, jobid);
1147 SAFE_FREE(jcdata.dptr);
1149 /* now delete any queued entries that don't appear in the
1150 system queue */
1151 tstruct.queue = queue;
1152 tstruct.qcount = qcount;
1153 tstruct.snum = -1;
1154 tstruct.total_jobs = 0;
1155 tstruct.lpq_time = time(NULL);
1156 tstruct.sharename = sharename;
1158 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1160 /* Store the linearised queue, max jobs only. */
1161 store_queue_struct(pdb, &tstruct);
1163 SAFE_FREE(tstruct.queue);
1165 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1166 sharename, tstruct.total_jobs ));
1168 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1170 get_queue_status(sharename, &old_status);
1171 if (old_status.qcount != qcount)
1172 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1173 old_status.qcount, qcount, sharename));
1175 /* store the new queue status structure */
1176 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1177 key.dptr = keystr;
1178 key.dsize = strlen(keystr);
1180 status.qcount = qcount;
1181 data.dptr = (void *)&status;
1182 data.dsize = sizeof(status);
1183 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1186 * Update the cache time again. We want to do this call
1187 * as little as possible...
1190 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1191 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1193 /* clear the msg pending record for this queue */
1195 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1197 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1198 /* log a message but continue on */
1200 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1201 sharename));
1204 release_print_db( pdb );
1206 return;
1209 /****************************************************************************
1210 Update the internal database from the system print queue for a queue.
1211 obtain a lock on the print queue before proceeding (needed when mutiple
1212 smbd processes maytry to update the lpq cache concurrently).
1213 ****************************************************************************/
1215 static void print_queue_update_with_lock(int snum)
1217 fstring sharename, keystr;
1218 pstring lpq_command;
1219 struct tdb_print_db *pdb;
1220 struct printif *current_printif = get_printer_fns( snum );
1222 fstrcpy(sharename, lp_const_servicename(snum));
1224 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1225 pdb = get_print_db_byname(sharename);
1226 if (!pdb)
1227 return;
1230 * Check to see if someone else is doing this update.
1231 * This is essentially a mutex on the update.
1234 if (get_updating_pid(sharename) != -1) {
1235 release_print_db(pdb);
1236 return;
1239 /* Lock the queue for the database update */
1241 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1242 /* Only wait 10 seconds for this. */
1243 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1244 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1245 release_print_db(pdb);
1246 return;
1250 * Ensure that no one else got in here.
1251 * If the updating pid is still -1 then we are
1252 * the winner.
1255 if (get_updating_pid(sharename) != -1) {
1257 * Someone else is doing the update, exit.
1259 tdb_unlock_bystring(pdb->tdb, keystr);
1260 release_print_db(pdb);
1261 return;
1265 * We're going to do the update ourselves.
1268 /* Tell others we're doing the update. */
1269 set_updating_pid(sharename, True);
1272 * Allow others to enter and notice we're doing
1273 * the update.
1276 tdb_unlock_bystring(pdb->tdb, keystr);
1278 /* do the main work now */
1279 /* have to substitute any variables here since
1280 print_queue_get_internal() will not */
1282 pstrcpy( lpq_command, lp_lpqcommand(snum) );
1283 pstring_sub( lpq_command, "%p", PRINTERNAME(snum) );
1284 standard_sub_snum( snum, lpq_command, sizeof(lpq_command) );
1286 print_queue_update_internal( sharename, current_printif, lpq_command );
1288 /* Delete our pid from the db. */
1289 set_updating_pid(sharename, False);
1290 release_print_db(pdb);
1293 /****************************************************************************
1294 this is the receive function of the background lpq updater
1295 ****************************************************************************/
1296 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
1298 struct print_queue_update_context ctx;
1299 fstring sharename;
1300 pstring lpqcommand;
1301 size_t len;
1303 len = tdb_unpack( buf, msglen, "fdP",
1304 sharename,
1305 &ctx.printing_type,
1306 lpqcommand );
1308 if ( len == -1 ) {
1309 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1310 return;
1313 ctx.sharename = sharename;
1314 ctx.lpqcommand = lpqcommand;
1316 print_queue_update_internal(ctx.sharename,
1317 get_printer_fns_from_type(ctx.printing_type),
1318 ctx.lpqcommand );
1320 return;
1323 static pid_t background_lpq_updater_pid = -1;
1325 /****************************************************************************
1326 main thread of the background lpq updater
1327 ****************************************************************************/
1328 void start_background_queue(void)
1330 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1331 background_lpq_updater_pid = sys_fork();
1333 if (background_lpq_updater_pid == -1) {
1334 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1335 exit(1);
1338 if(background_lpq_updater_pid == 0) {
1339 /* Child. */
1340 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1342 claim_connection( NULL, "smbd lpq backend", 0, False,
1343 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1345 if (!locking_init(0)) {
1346 exit(1);
1349 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1351 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1352 while (1) {
1353 pause();
1355 /* check for some essential signals first */
1357 if (got_sig_term) {
1358 exit_server("Caught TERM signal");
1361 if (reload_after_sighup) {
1362 change_to_root_user();
1363 DEBUG(1,("Reloading services after SIGHUP\n"));
1364 reload_services(False);
1365 reload_after_sighup = 0;
1368 /* now check for messages */
1370 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1371 message_dispatch();
1373 /* process any pending print change notify messages */
1375 print_notify_send_messages(0);
1380 /****************************************************************************
1381 update the internal database from the system print queue for a queue
1382 ****************************************************************************/
1383 static void print_queue_update(int snum)
1385 struct print_queue_update_context ctx;
1386 fstring key;
1387 fstring sharename;
1388 pstring lpqcommand;
1389 char *buffer = NULL;
1390 size_t len = 0;
1391 size_t newlen;
1392 struct tdb_print_db *pdb;
1395 * Make sure that the background queue process exists.
1396 * Otherwise just do the update ourselves
1399 if ( background_lpq_updater_pid == -1 ) {
1400 print_queue_update_with_lock( snum );
1401 return;
1404 fstrcpy( sharename, lp_const_servicename(snum));
1406 ctx.printing_type = lp_printing(snum);
1408 pstrcpy( lpqcommand, lp_lpqcommand(snum));
1409 pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
1410 standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
1412 ctx.sharename = SMB_STRDUP( sharename );
1413 ctx.lpqcommand = SMB_STRDUP( lpqcommand );
1415 /* get the length */
1417 len = tdb_pack( buffer, len, "fdP",
1418 ctx.sharename,
1419 ctx.printing_type,
1420 ctx.lpqcommand );
1422 buffer = SMB_XMALLOC_ARRAY( char, len );
1424 /* now pack the buffer */
1425 newlen = tdb_pack( buffer, len, "fdP",
1426 ctx.sharename,
1427 ctx.printing_type,
1428 ctx.lpqcommand );
1430 SMB_ASSERT( newlen == len );
1432 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1433 "type = %d, lpq command = [%s]\n",
1434 ctx.sharename, ctx.printing_type, ctx.lpqcommand ));
1436 /* here we set a msg pending record for other smbd processes
1437 to throttle the number of duplicate print_queue_update msgs
1438 sent. */
1440 pdb = get_print_db_byname(sharename);
1441 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1443 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1444 /* log a message but continue on */
1446 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1447 sharename));
1450 release_print_db( pdb );
1452 /* finally send the message */
1454 become_root();
1455 message_send_pid(background_lpq_updater_pid,
1456 MSG_PRINTER_UPDATE, buffer, len, False);
1457 unbecome_root();
1459 SAFE_FREE( ctx.sharename );
1460 SAFE_FREE( ctx.lpqcommand );
1461 SAFE_FREE( buffer );
1463 return;
1466 /****************************************************************************
1467 Create/Update an entry in the print tdb that will allow us to send notify
1468 updates only to interested smbd's.
1469 ****************************************************************************/
1471 BOOL print_notify_register_pid(int snum)
1473 TDB_DATA data;
1474 struct tdb_print_db *pdb = NULL;
1475 TDB_CONTEXT *tdb = NULL;
1476 const char *printername;
1477 uint32 mypid = (uint32)sys_getpid();
1478 BOOL ret = False;
1479 size_t i;
1481 /* if (snum == -1), then the change notify request was
1482 on a print server handle and we need to register on
1483 all print queus */
1485 if (snum == -1)
1487 int num_services = lp_numservices();
1488 int idx;
1490 for ( idx=0; idx<num_services; idx++ ) {
1491 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1492 print_notify_register_pid(idx);
1495 return True;
1497 else /* register for a specific printer */
1499 printername = lp_const_servicename(snum);
1500 pdb = get_print_db_byname(printername);
1501 if (!pdb)
1502 return False;
1503 tdb = pdb->tdb;
1506 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1507 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1508 printername));
1509 if (pdb)
1510 release_print_db(pdb);
1511 return False;
1514 data = get_printer_notify_pid_list( tdb, printername, True );
1516 /* Add ourselves and increase the refcount. */
1518 for (i = 0; i < data.dsize; i += 8) {
1519 if (IVAL(data.dptr,i) == mypid) {
1520 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1521 SIVAL(data.dptr, i+4, new_refcount);
1522 break;
1526 if (i == data.dsize) {
1527 /* We weren't in the list. Realloc. */
1528 data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
1529 if (!data.dptr) {
1530 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1531 printername));
1532 goto done;
1534 data.dsize += 8;
1535 SIVAL(data.dptr,data.dsize - 8,mypid);
1536 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1539 /* Store back the record. */
1540 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1541 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1542 list for printer %s\n", printername));
1543 goto done;
1546 ret = True;
1548 done:
1550 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1551 if (pdb)
1552 release_print_db(pdb);
1553 SAFE_FREE(data.dptr);
1554 return ret;
1557 /****************************************************************************
1558 Update an entry in the print tdb that will allow us to send notify
1559 updates only to interested smbd's.
1560 ****************************************************************************/
1562 BOOL print_notify_deregister_pid(int snum)
1564 TDB_DATA data;
1565 struct tdb_print_db *pdb = NULL;
1566 TDB_CONTEXT *tdb = NULL;
1567 const char *printername;
1568 uint32 mypid = (uint32)sys_getpid();
1569 size_t i;
1570 BOOL ret = False;
1572 /* if ( snum == -1 ), we are deregister a print server handle
1573 which means to deregister on all print queues */
1575 if (snum == -1)
1577 int num_services = lp_numservices();
1578 int idx;
1580 for ( idx=0; idx<num_services; idx++ ) {
1581 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1582 print_notify_deregister_pid(idx);
1585 return True;
1587 else /* deregister a specific printer */
1589 printername = lp_const_servicename(snum);
1590 pdb = get_print_db_byname(printername);
1591 if (!pdb)
1592 return False;
1593 tdb = pdb->tdb;
1596 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1597 DEBUG(0,("print_notify_register_pid: Failed to lock \
1598 printer %s database\n", printername));
1599 if (pdb)
1600 release_print_db(pdb);
1601 return False;
1604 data = get_printer_notify_pid_list( tdb, printername, True );
1606 /* Reduce refcount. Remove ourselves if zero. */
1608 for (i = 0; i < data.dsize; ) {
1609 if (IVAL(data.dptr,i) == mypid) {
1610 uint32 refcount = IVAL(data.dptr, i+4);
1612 refcount--;
1614 if (refcount == 0) {
1615 if (data.dsize - i > 8)
1616 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1617 data.dsize -= 8;
1618 continue;
1620 SIVAL(data.dptr, i+4, refcount);
1623 i += 8;
1626 if (data.dsize == 0)
1627 SAFE_FREE(data.dptr);
1629 /* Store back the record. */
1630 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1631 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1632 list for printer %s\n", printername));
1633 goto done;
1636 ret = True;
1638 done:
1640 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1641 if (pdb)
1642 release_print_db(pdb);
1643 SAFE_FREE(data.dptr);
1644 return ret;
1647 /****************************************************************************
1648 Check if a jobid is valid. It is valid if it exists in the database.
1649 ****************************************************************************/
1651 BOOL print_job_exists(const char* sharename, uint32 jobid)
1653 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1654 BOOL ret;
1656 if (!pdb)
1657 return False;
1658 ret = tdb_exists(pdb->tdb, print_key(jobid));
1659 release_print_db(pdb);
1660 return ret;
1663 /****************************************************************************
1664 Give the fd used for a jobid.
1665 ****************************************************************************/
1667 int print_job_fd(const char* sharename, uint32 jobid)
1669 struct printjob *pjob = print_job_find(sharename, jobid);
1670 if (!pjob)
1671 return -1;
1672 /* don't allow another process to get this info - it is meaningless */
1673 if (pjob->pid != sys_getpid())
1674 return -1;
1675 return pjob->fd;
1678 /****************************************************************************
1679 Give the filename used for a jobid.
1680 Only valid for the process doing the spooling and when the job
1681 has not been spooled.
1682 ****************************************************************************/
1684 char *print_job_fname(const char* sharename, uint32 jobid)
1686 struct printjob *pjob = print_job_find(sharename, jobid);
1687 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1688 return NULL;
1689 return pjob->filename;
1693 /****************************************************************************
1694 Give the filename used for a jobid.
1695 Only valid for the process doing the spooling and when the job
1696 has not been spooled.
1697 ****************************************************************************/
1699 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1701 struct printjob *pjob = print_job_find(sharename, jobid);
1703 if ( !pjob )
1704 return NULL;
1706 return pjob->nt_devmode;
1709 /****************************************************************************
1710 Set the place in the queue for a job.
1711 ****************************************************************************/
1713 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1715 DEBUG(2,("print_job_set_place not implemented yet\n"));
1716 return False;
1719 /****************************************************************************
1720 Set the name of a job. Only possible for owner.
1721 ****************************************************************************/
1723 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1725 const char* sharename = lp_const_servicename(snum);
1726 struct printjob *pjob;
1728 pjob = print_job_find(sharename, jobid);
1729 if (!pjob || pjob->pid != sys_getpid())
1730 return False;
1732 fstrcpy(pjob->jobname, name);
1733 return pjob_store(sharename, jobid, pjob);
1736 /***************************************************************************
1737 Remove a jobid from the 'jobs changed' list.
1738 ***************************************************************************/
1740 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1742 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1743 TDB_DATA data, key;
1744 size_t job_count, i;
1745 BOOL ret = False;
1746 BOOL gotlock = False;
1748 key.dptr = "INFO/jobs_changed";
1749 key.dsize = strlen(key.dptr);
1750 ZERO_STRUCT(data);
1752 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1753 goto out;
1755 gotlock = True;
1757 data = tdb_fetch(pdb->tdb, key);
1759 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1760 goto out;
1762 job_count = data.dsize / 4;
1763 for (i = 0; i < job_count; i++) {
1764 uint32 ch_jobid;
1766 ch_jobid = IVAL(data.dptr, i*4);
1767 if (ch_jobid == jobid) {
1768 if (i < job_count -1 )
1769 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1770 data.dsize -= 4;
1771 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1772 goto out;
1773 break;
1777 ret = True;
1778 out:
1780 if (gotlock)
1781 tdb_chainunlock(pdb->tdb, key);
1782 SAFE_FREE(data.dptr);
1783 release_print_db(pdb);
1784 if (ret)
1785 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1786 else
1787 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1788 return ret;
1791 /****************************************************************************
1792 Delete a print job - don't update queue.
1793 ****************************************************************************/
1795 static BOOL print_job_delete1(int snum, uint32 jobid)
1797 const char* sharename = lp_const_servicename(snum);
1798 struct printjob *pjob = print_job_find(sharename, jobid);
1799 int result = 0;
1800 struct printif *current_printif = get_printer_fns( snum );
1802 pjob = print_job_find(sharename, jobid);
1804 if (!pjob)
1805 return False;
1808 * If already deleting just return.
1811 if (pjob->status == LPQ_DELETING)
1812 return True;
1814 /* Hrm - we need to be able to cope with deleting a job before it
1815 has reached the spooler. */
1817 if (pjob->sysjob == -1) {
1818 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1821 /* Set the tdb entry to be deleting. */
1823 pjob->status = LPQ_DELETING;
1824 pjob_store(sharename, jobid, pjob);
1826 if (pjob->spooled && pjob->sysjob != -1)
1827 result = (*(current_printif->job_delete))(snum, pjob);
1829 /* Delete the tdb entry if the delete succeeded or the job hasn't
1830 been spooled. */
1832 if (result == 0) {
1833 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1834 int njobs = 1;
1836 if (!pdb)
1837 return False;
1838 pjob_delete(sharename, jobid);
1839 /* Ensure we keep a rough count of the number of total jobs... */
1840 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1841 release_print_db(pdb);
1844 return (result == 0);
1847 /****************************************************************************
1848 Return true if the current user owns the print job.
1849 ****************************************************************************/
1851 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1853 struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
1854 user_struct *vuser;
1856 if (!pjob || !user)
1857 return False;
1859 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1860 return strequal(pjob->user, vuser->user.smb_name);
1861 } else {
1862 return strequal(pjob->user, uidtoname(user->uid));
1866 /****************************************************************************
1867 Delete a print job.
1868 ****************************************************************************/
1870 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1872 const char* sharename = lp_const_servicename( snum );
1873 BOOL owner, deleted;
1874 char *fname;
1876 *errcode = WERR_OK;
1878 owner = is_owner(user, snum, jobid);
1880 /* Check access against security descriptor or whether the user
1881 owns their job. */
1883 if (!owner &&
1884 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1885 DEBUG(3, ("delete denied by security descriptor\n"));
1886 *errcode = WERR_ACCESS_DENIED;
1888 /* BEGIN_ADMIN_LOG */
1889 sys_adminlog( LOG_ERR,
1890 "Permission denied-- user not allowed to delete, \
1891 pause, or resume print job. User name: %s. Printer name: %s.",
1892 uidtoname(user->uid), PRINTERNAME(snum) );
1893 /* END_ADMIN_LOG */
1895 return False;
1899 * get the spooled filename of the print job
1900 * if this works, then the file has not been spooled
1901 * to the underlying print system. Just delete the
1902 * spool file & return.
1905 if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1907 /* remove the spool file */
1908 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1909 if ( unlink( fname ) == -1 ) {
1910 *errcode = map_werror_from_unix(errno);
1911 return False;
1915 if (!print_job_delete1(snum, jobid)) {
1916 *errcode = WERR_ACCESS_DENIED;
1917 return False;
1920 /* force update the database and say the delete failed if the
1921 job still exists */
1923 print_queue_update(snum);
1925 deleted = !print_job_exists(sharename, jobid);
1926 if ( !deleted )
1927 *errcode = WERR_ACCESS_DENIED;
1929 return deleted;
1932 /****************************************************************************
1933 Pause a job.
1934 ****************************************************************************/
1936 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1938 const char* sharename = lp_const_servicename(snum);
1939 struct printjob *pjob;
1940 int ret = -1;
1941 struct printif *current_printif = get_printer_fns( snum );
1943 pjob = print_job_find(sharename, jobid);
1945 if (!pjob || !user)
1946 return False;
1948 if (!pjob->spooled || pjob->sysjob == -1)
1949 return False;
1951 if (!is_owner(user, snum, jobid) &&
1952 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1953 DEBUG(3, ("pause denied by security descriptor\n"));
1955 /* BEGIN_ADMIN_LOG */
1956 sys_adminlog( LOG_ERR,
1957 "Permission denied-- user not allowed to delete, \
1958 pause, or resume print job. User name: %s. Printer name: %s.",
1959 uidtoname(user->uid), PRINTERNAME(snum) );
1960 /* END_ADMIN_LOG */
1962 *errcode = WERR_ACCESS_DENIED;
1963 return False;
1966 /* need to pause the spooled entry */
1967 ret = (*(current_printif->job_pause))(snum, pjob);
1969 if (ret != 0) {
1970 *errcode = WERR_INVALID_PARAM;
1971 return False;
1974 /* force update the database */
1975 print_cache_flush(snum);
1977 /* Send a printer notify message */
1979 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
1981 /* how do we tell if this succeeded? */
1983 return True;
1986 /****************************************************************************
1987 Resume a job.
1988 ****************************************************************************/
1990 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1992 const char *sharename = lp_const_servicename(snum);
1993 struct printjob *pjob;
1994 int ret;
1995 struct printif *current_printif = get_printer_fns( snum );
1997 pjob = print_job_find(sharename, jobid);
1999 if (!pjob || !user)
2000 return False;
2002 if (!pjob->spooled || pjob->sysjob == -1)
2003 return False;
2005 if (!is_owner(user, snum, jobid) &&
2006 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2007 DEBUG(3, ("resume denied by security descriptor\n"));
2008 *errcode = WERR_ACCESS_DENIED;
2010 /* BEGIN_ADMIN_LOG */
2011 sys_adminlog( LOG_ERR,
2012 "Permission denied-- user not allowed to delete, \
2013 pause, or resume print job. User name: %s. Printer name: %s.",
2014 uidtoname(user->uid), PRINTERNAME(snum) );
2015 /* END_ADMIN_LOG */
2016 return False;
2019 ret = (*(current_printif->job_resume))(snum, pjob);
2021 if (ret != 0) {
2022 *errcode = WERR_INVALID_PARAM;
2023 return False;
2026 /* force update the database */
2027 print_cache_flush(snum);
2029 /* Send a printer notify message */
2031 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2033 return True;
2036 /****************************************************************************
2037 Write to a print file.
2038 ****************************************************************************/
2040 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
2042 const char* sharename = lp_const_servicename(snum);
2043 int return_code;
2044 struct printjob *pjob;
2046 pjob = print_job_find(sharename, jobid);
2048 if (!pjob)
2049 return -1;
2050 /* don't allow another process to get this info - it is meaningless */
2051 if (pjob->pid != sys_getpid())
2052 return -1;
2054 return_code = write(pjob->fd, buf, size);
2055 if (return_code>0) {
2056 pjob->size += size;
2057 pjob_store(sharename, jobid, pjob);
2059 return return_code;
2062 /****************************************************************************
2063 Get the queue status - do not update if db is out of date.
2064 ****************************************************************************/
2066 static int get_queue_status(const char* sharename, print_status_struct *status)
2068 fstring keystr;
2069 TDB_DATA data, key;
2070 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2071 int len;
2073 if (!pdb)
2074 return 0;
2076 if (status) {
2077 ZERO_STRUCTP(status);
2078 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2079 key.dptr = keystr;
2080 key.dsize = strlen(keystr);
2081 data = tdb_fetch(pdb->tdb, key);
2082 if (data.dptr) {
2083 if (data.dsize == sizeof(print_status_struct))
2084 /* this memcpy is ok since the status struct was
2085 not packed before storing it in the tdb */
2086 memcpy(status, data.dptr, sizeof(print_status_struct));
2087 SAFE_FREE(data.dptr);
2090 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2091 release_print_db(pdb);
2092 return (len == -1 ? 0 : len);
2095 /****************************************************************************
2096 Determine the number of jobs in a queue.
2097 ****************************************************************************/
2099 int print_queue_length(int snum, print_status_struct *pstatus)
2101 const char* sharename = lp_const_servicename( snum );
2102 print_status_struct status;
2103 int len;
2105 /* make sure the database is up to date */
2106 if (print_cache_expired(lp_const_servicename(snum), True))
2107 print_queue_update(snum);
2109 /* also fetch the queue status */
2110 memset(&status, 0, sizeof(status));
2111 len = get_queue_status(sharename, &status);
2113 if (pstatus)
2114 *pstatus = status;
2116 return len;
2119 /***************************************************************************
2120 Allocate a jobid. Hold the lock for as short a time as possible.
2121 ***************************************************************************/
2123 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2125 int i;
2126 uint32 jobid;
2128 *pjobid = (uint32)-1;
2130 for (i = 0; i < 3; i++) {
2131 /* Lock the database - only wait 20 seconds. */
2132 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
2133 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2134 return False;
2137 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2138 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2139 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2140 sharename));
2141 return False;
2143 jobid = 0;
2146 jobid = NEXT_JOBID(jobid);
2148 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2149 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2150 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2151 return False;
2154 /* We've finished with the INFO/nextjob lock. */
2155 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2157 if (!print_job_exists(sharename, jobid))
2158 break;
2161 if (i > 2) {
2162 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2163 sharename));
2164 /* Probably full... */
2165 errno = ENOSPC;
2166 return False;
2169 /* Store a dummy placeholder. */
2171 TDB_DATA dum;
2172 dum.dptr = NULL;
2173 dum.dsize = 0;
2174 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2175 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2176 jobid ));
2177 return False;
2181 *pjobid = jobid;
2182 return True;
2185 /***************************************************************************
2186 Append a jobid to the 'jobs changed' list.
2187 ***************************************************************************/
2189 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2191 TDB_DATA data, key;
2192 uint32 store_jobid;
2194 key.dptr = "INFO/jobs_changed";
2195 key.dsize = strlen(key.dptr);
2196 SIVAL(&store_jobid, 0, jobid);
2197 data.dptr = (char *)&store_jobid;
2198 data.dsize = 4;
2200 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2202 return (tdb_append(pdb->tdb, key, data) == 0);
2205 /***************************************************************************
2206 Start spooling a job - return the jobid.
2207 ***************************************************************************/
2209 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2211 uint32 jobid;
2212 char *path;
2213 struct printjob pjob;
2214 user_struct *vuser;
2215 const char *sharename = lp_const_servicename(snum);
2216 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2217 int njobs;
2219 errno = 0;
2221 if (!pdb)
2222 return (uint32)-1;
2224 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2225 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2226 release_print_db(pdb);
2227 return (uint32)-1;
2230 if (!print_time_access_check(snum)) {
2231 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2232 release_print_db(pdb);
2233 return (uint32)-1;
2236 path = lp_pathname(snum);
2238 /* see if we have sufficient disk space */
2239 if (lp_minprintspace(snum)) {
2240 SMB_BIG_UINT dspace, dsize;
2241 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2242 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2243 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2244 release_print_db(pdb);
2245 errno = ENOSPC;
2246 return (uint32)-1;
2250 /* for autoloaded printers, check that the printcap entry still exists */
2251 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2252 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2253 release_print_db(pdb);
2254 errno = ENOENT;
2255 return (uint32)-1;
2258 /* Insure the maximum queue size is not violated */
2259 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2260 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2261 sharename, njobs, lp_maxprintjobs(snum) ));
2262 release_print_db(pdb);
2263 errno = ENOSPC;
2264 return (uint32)-1;
2267 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2268 sharename, njobs, lp_maxprintjobs(snum) ));
2270 if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2271 goto fail;
2273 /* create the database entry */
2275 ZERO_STRUCT(pjob);
2277 pjob.pid = sys_getpid();
2278 pjob.sysjob = -1;
2279 pjob.fd = -1;
2280 pjob.starttime = time(NULL);
2281 pjob.status = LPQ_SPOOLING;
2282 pjob.size = 0;
2283 pjob.spooled = False;
2284 pjob.smbjob = True;
2285 pjob.nt_devmode = nt_devmode;
2287 fstrcpy(pjob.jobname, jobname);
2289 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2290 fstrcpy(pjob.user, vuser->user.smb_name);
2291 } else {
2292 fstrcpy(pjob.user, uidtoname(user->uid));
2295 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2297 /* we have a job entry - now create the spool file */
2298 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2299 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2300 pjob.fd = smb_mkstemp(pjob.filename);
2302 if (pjob.fd == -1) {
2303 if (errno == EACCES) {
2304 /* Common setup error, force a report. */
2305 DEBUG(0, ("print_job_start: insufficient permissions \
2306 to open spool file %s.\n", pjob.filename));
2307 } else {
2308 /* Normal case, report at level 3 and above. */
2309 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2310 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2312 goto fail;
2315 pjob_store(sharename, jobid, &pjob);
2317 /* Update the 'jobs changed' entry used by print_queue_status. */
2318 add_to_jobs_changed(pdb, jobid);
2320 /* Ensure we keep a rough count of the number of total jobs... */
2321 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2323 release_print_db(pdb);
2325 return jobid;
2327 fail:
2328 if (jobid != -1)
2329 pjob_delete(sharename, jobid);
2331 release_print_db(pdb);
2333 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2334 return (uint32)-1;
2337 /****************************************************************************
2338 Update the number of pages spooled to jobid
2339 ****************************************************************************/
2341 void print_job_endpage(int snum, uint32 jobid)
2343 const char* sharename = lp_const_servicename(snum);
2344 struct printjob *pjob;
2346 pjob = print_job_find(sharename, jobid);
2347 if (!pjob)
2348 return;
2349 /* don't allow another process to get this info - it is meaningless */
2350 if (pjob->pid != sys_getpid())
2351 return;
2353 pjob->page_count++;
2354 pjob_store(sharename, jobid, pjob);
2357 /****************************************************************************
2358 Print a file - called on closing the file. This spools the job.
2359 If normal close is false then we're tearing down the jobs - treat as an
2360 error.
2361 ****************************************************************************/
2363 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2365 const char* sharename = lp_const_servicename(snum);
2366 struct printjob *pjob;
2367 int ret;
2368 SMB_STRUCT_STAT sbuf;
2369 struct printif *current_printif = get_printer_fns( snum );
2371 pjob = print_job_find(sharename, jobid);
2373 if (!pjob)
2374 return False;
2376 if (pjob->spooled || pjob->pid != sys_getpid())
2377 return False;
2379 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2380 pjob->size = sbuf.st_size;
2381 close(pjob->fd);
2382 pjob->fd = -1;
2383 } else {
2386 * Not a normal close or we couldn't stat the job file,
2387 * so something has gone wrong. Cleanup.
2389 close(pjob->fd);
2390 pjob->fd = -1;
2391 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2392 goto fail;
2395 /* Technically, this is not quite right. If the printer has a separator
2396 * page turned on, the NT spooler prints the separator page even if the
2397 * print job is 0 bytes. 010215 JRR */
2398 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2399 /* don't bother spooling empty files or something being deleted. */
2400 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2401 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2402 unlink(pjob->filename);
2403 pjob_delete(sharename, jobid);
2404 return True;
2407 pjob->smbjob = jobid;
2409 ret = (*(current_printif->job_submit))(snum, pjob);
2411 if (ret)
2412 goto fail;
2414 /* The print job has been sucessfully handed over to the back-end */
2416 pjob->spooled = True;
2417 pjob->status = LPQ_QUEUED;
2418 pjob_store(sharename, jobid, pjob);
2420 /* make sure the database is up to date */
2421 if (print_cache_expired(lp_const_servicename(snum), True))
2422 print_queue_update(snum);
2424 return True;
2426 fail:
2428 /* The print job was not succesfully started. Cleanup */
2429 /* Still need to add proper error return propagation! 010122:JRR */
2430 unlink(pjob->filename);
2431 pjob_delete(sharename, jobid);
2432 return False;
2435 /****************************************************************************
2436 Get a snapshot of jobs in the system without traversing.
2437 ****************************************************************************/
2439 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2441 TDB_DATA data, key, cgdata;
2442 print_queue_struct *queue = NULL;
2443 uint32 qcount = 0;
2444 uint32 extra_count = 0;
2445 int total_count = 0;
2446 size_t len = 0;
2447 uint32 i;
2448 int max_reported_jobs = lp_max_reported_jobs(snum);
2449 BOOL ret = False;
2450 const char* sharename = lp_servicename(snum);
2452 /* make sure the database is up to date */
2453 if (print_cache_expired(lp_const_servicename(snum), True))
2454 print_queue_update(snum);
2456 *pcount = 0;
2457 *ppqueue = NULL;
2459 ZERO_STRUCT(data);
2460 ZERO_STRUCT(cgdata);
2461 key.dptr = "INFO/linear_queue_array";
2462 key.dsize = strlen(key.dptr);
2464 /* Get the stored queue data. */
2465 data = tdb_fetch(pdb->tdb, key);
2467 if (data.dptr && data.dsize >= sizeof(qcount))
2468 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2470 /* Get the changed jobs list. */
2471 key.dptr = "INFO/jobs_changed";
2472 key.dsize = strlen(key.dptr);
2474 cgdata = tdb_fetch(pdb->tdb, key);
2475 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2476 extra_count = cgdata.dsize/4;
2478 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2480 /* Allocate the queue size. */
2481 if (qcount == 0 && extra_count == 0)
2482 goto out;
2484 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2485 goto out;
2487 /* Retrieve the linearised queue data. */
2489 for( i = 0; i < qcount; i++) {
2490 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2491 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2492 &qjob,
2493 &qsize,
2494 &qpage_count,
2495 &qstatus,
2496 &qpriority,
2497 &qtime,
2498 queue[i].fs_user,
2499 queue[i].fs_file);
2500 queue[i].job = qjob;
2501 queue[i].size = qsize;
2502 queue[i].page_count = qpage_count;
2503 queue[i].status = qstatus;
2504 queue[i].priority = qpriority;
2505 queue[i].time = qtime;
2508 total_count = qcount;
2510 /* Add in the changed jobids. */
2511 for( i = 0; i < extra_count; i++) {
2512 uint32 jobid;
2513 struct printjob *pjob;
2515 jobid = IVAL(cgdata.dptr, i*4);
2516 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2517 pjob = print_job_find(lp_const_servicename(snum), jobid);
2518 if (!pjob) {
2519 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2520 remove_from_jobs_changed(sharename, jobid);
2521 continue;
2524 queue[total_count].job = jobid;
2525 queue[total_count].size = pjob->size;
2526 queue[total_count].page_count = pjob->page_count;
2527 queue[total_count].status = pjob->status;
2528 queue[total_count].priority = 1;
2529 queue[total_count].time = pjob->starttime;
2530 fstrcpy(queue[total_count].fs_user, pjob->user);
2531 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2532 total_count++;
2535 /* Sort the queue by submission time otherwise they are displayed
2536 in hash order. */
2538 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2540 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2542 if (max_reported_jobs && total_count > max_reported_jobs)
2543 total_count = max_reported_jobs;
2545 *ppqueue = queue;
2546 *pcount = total_count;
2548 ret = True;
2550 out:
2552 SAFE_FREE(data.dptr);
2553 SAFE_FREE(cgdata.dptr);
2554 return ret;
2557 /****************************************************************************
2558 Get a printer queue listing.
2559 set queue = NULL and status = NULL if you just want to update the cache
2560 ****************************************************************************/
2562 int print_queue_status(int snum,
2563 print_queue_struct **ppqueue,
2564 print_status_struct *status)
2566 fstring keystr;
2567 TDB_DATA data, key;
2568 const char *sharename;
2569 struct tdb_print_db *pdb;
2570 int count = 0;
2572 /* make sure the database is up to date */
2574 if (print_cache_expired(lp_const_servicename(snum), True))
2575 print_queue_update(snum);
2577 /* return if we are done */
2578 if ( !ppqueue || !status )
2579 return 0;
2581 *ppqueue = NULL;
2582 sharename = lp_const_servicename(snum);
2583 pdb = get_print_db_byname(sharename);
2585 if (!pdb)
2586 return 0;
2589 * Fetch the queue status. We must do this first, as there may
2590 * be no jobs in the queue.
2593 ZERO_STRUCTP(status);
2594 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2595 key.dptr = keystr;
2596 key.dsize = strlen(keystr);
2597 data = tdb_fetch(pdb->tdb, key);
2598 if (data.dptr) {
2599 if (data.dsize == sizeof(*status)) {
2600 /* this memcpy is ok since the status struct was
2601 not packed before storing it in the tdb */
2602 memcpy(status, data.dptr, sizeof(*status));
2604 SAFE_FREE(data.dptr);
2608 * Now, fetch the print queue information. We first count the number
2609 * of entries, and then only retrieve the queue if necessary.
2612 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2613 release_print_db(pdb);
2614 return 0;
2617 release_print_db(pdb);
2618 return count;
2621 /****************************************************************************
2622 Pause a queue.
2623 ****************************************************************************/
2625 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2627 int ret;
2628 struct printif *current_printif = get_printer_fns( snum );
2630 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2631 *errcode = WERR_ACCESS_DENIED;
2632 return False;
2635 ret = (*(current_printif->queue_pause))(snum);
2637 if (ret != 0) {
2638 *errcode = WERR_INVALID_PARAM;
2639 return False;
2642 /* force update the database */
2643 print_cache_flush(snum);
2645 /* Send a printer notify message */
2647 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2649 return True;
2652 /****************************************************************************
2653 Resume a queue.
2654 ****************************************************************************/
2656 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2658 int ret;
2659 struct printif *current_printif = get_printer_fns( snum );
2661 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2662 *errcode = WERR_ACCESS_DENIED;
2663 return False;
2666 ret = (*(current_printif->queue_resume))(snum);
2668 if (ret != 0) {
2669 *errcode = WERR_INVALID_PARAM;
2670 return False;
2673 /* make sure the database is up to date */
2674 if (print_cache_expired(lp_const_servicename(snum), True))
2675 print_queue_update(snum);
2677 /* Send a printer notify message */
2679 notify_printer_status(snum, PRINTER_STATUS_OK);
2681 return True;
2684 /****************************************************************************
2685 Purge a queue - implemented by deleting all jobs that we can delete.
2686 ****************************************************************************/
2688 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2690 print_queue_struct *queue;
2691 print_status_struct status;
2692 int njobs, i;
2693 BOOL can_job_admin;
2695 /* Force and update so the count is accurate (i.e. not a cached count) */
2696 print_queue_update(snum);
2698 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2699 njobs = print_queue_status(snum, &queue, &status);
2701 for (i=0;i<njobs;i++) {
2702 BOOL owner = is_owner(user, snum, queue[i].job);
2704 if (owner || can_job_admin) {
2705 print_job_delete1(snum, queue[i].job);
2709 SAFE_FREE(queue);
2711 return True;