r6369: update release notes
[Samba.git] / source / printing / printing.c
blob572ecb373a8c75c9885cd1051b41dd320bee53e5
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 int 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( int 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(const char *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;
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 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
955 TDB_REPLACE);
956 SAFE_FREE(data.dptr);
957 return;
960 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
962 TDB_DATA data;
964 ZERO_STRUCT(data);
966 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
967 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
968 SAFE_FREE(data.dptr);
969 ZERO_STRUCT(data);
972 return data;
975 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
977 unsigned int i;
978 unsigned int job_count = data.dsize / 4;
980 for (i = 0; i < job_count; i++) {
981 uint32 ch_jobid;
983 ch_jobid = IVAL(data.dptr, i*4);
984 if (ch_jobid == jobid)
985 remove_from_jobs_changed(sharename, jobid);
989 /****************************************************************************
990 Check if the print queue has been updated recently enough.
991 ****************************************************************************/
993 static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
995 fstring key;
996 time_t last_qscan_time, time_now = time(NULL);
997 struct tdb_print_db *pdb = get_print_db_byname(sharename);
998 BOOL result = False;
1000 if (!pdb)
1001 return False;
1003 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1004 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1007 * Invalidate the queue for 3 reasons.
1008 * (1). last queue scan time == -1.
1009 * (2). Current time - last queue scan time > allowed cache time.
1010 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1011 * This last test picks up machines for which the clock has been moved
1012 * forward, an lpq scan done and then the clock moved back. Otherwise
1013 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1016 if (last_qscan_time == ((time_t)-1)
1017 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1018 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1020 time_t msg_pending_time;
1022 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1023 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1024 sharename, (int)last_qscan_time, (int)time_now,
1025 (int)lp_lpqcachetime() ));
1027 /* check if another smbd has already sent a message to update the
1028 queue. Give the pending message one minute to clear and
1029 then send another message anyways. Make sure to check for
1030 clocks that have been run forward and then back again. */
1032 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1034 if ( check_pending
1035 && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time )
1036 && msg_pending_time > 0
1037 && msg_pending_time <= time_now
1038 && (time_now - msg_pending_time) < 60 )
1040 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1041 sharename));
1042 goto done;
1045 result = True;
1048 done:
1049 release_print_db(pdb);
1050 return result;
1053 /****************************************************************************
1054 main work for updating the lpq cahe for a printer queue
1055 ****************************************************************************/
1057 static void print_queue_update_internal( const char *sharename,
1058 struct printif *current_printif,
1059 char *lpq_command )
1061 int i, qcount;
1062 print_queue_struct *queue = NULL;
1063 print_status_struct status;
1064 print_status_struct old_status;
1065 struct printjob *pjob;
1066 struct traverse_struct tstruct;
1067 TDB_DATA data, key;
1068 TDB_DATA jcdata;
1069 fstring keystr, cachestr;
1070 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1072 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1073 sharename, current_printif->type, lpq_command));
1076 * Update the cache time FIRST ! Stops others even
1077 * attempting to get the lock and doing this
1078 * if the lpq takes a long time.
1081 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1082 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1084 /* get the current queue using the appropriate interface */
1085 ZERO_STRUCT(status);
1087 qcount = (*(current_printif->queue_get))(sharename,
1088 current_printif->type,
1089 lpq_command, &queue, &status);
1091 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1092 qcount, (qcount != 1) ? "s" : "", sharename));
1094 /* Sort the queue by submission time otherwise they are displayed
1095 in hash order. */
1097 qsort(queue, qcount, sizeof(print_queue_struct),
1098 QSORT_CAST(printjob_comp));
1101 any job in the internal database that is marked as spooled
1102 and doesn't exist in the system queue is considered finished
1103 and removed from the database
1105 any job in the system database but not in the internal database
1106 is added as a unix job
1108 fill in any system job numbers as we go
1111 jcdata = get_jobs_changed_data(pdb);
1113 for (i=0; i<qcount; i++) {
1114 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1116 if (jobid == (uint32)-1) {
1117 /* assume its a unix print job */
1118 print_unix_job(sharename, &queue[i], jobid);
1119 continue;
1122 /* we have an active SMB print job - update its status */
1123 pjob = print_job_find(sharename, jobid);
1124 if (!pjob) {
1125 /* err, somethings wrong. Probably smbd was restarted
1126 with jobs in the queue. All we can do is treat them
1127 like unix jobs. Pity. */
1128 print_unix_job(sharename, &queue[i], jobid);
1129 continue;
1132 pjob->sysjob = queue[i].job;
1133 pjob->status = queue[i].status;
1134 pjob_store(sharename, jobid, pjob);
1135 check_job_changed(sharename, jcdata, jobid);
1138 SAFE_FREE(jcdata.dptr);
1140 /* now delete any queued entries that don't appear in the
1141 system queue */
1142 tstruct.queue = queue;
1143 tstruct.qcount = qcount;
1144 tstruct.snum = -1;
1145 tstruct.total_jobs = 0;
1146 tstruct.lpq_time = time(NULL);
1147 tstruct.sharename = sharename;
1149 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1151 /* Store the linearised queue, max jobs only. */
1152 store_queue_struct(pdb, &tstruct);
1154 SAFE_FREE(tstruct.queue);
1156 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1157 sharename, tstruct.total_jobs ));
1159 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1161 get_queue_status(sharename, &old_status);
1162 if (old_status.qcount != qcount)
1163 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1164 old_status.qcount, qcount, sharename));
1166 /* store the new queue status structure */
1167 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1168 key.dptr = keystr;
1169 key.dsize = strlen(keystr);
1171 status.qcount = qcount;
1172 data.dptr = (void *)&status;
1173 data.dsize = sizeof(status);
1174 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1177 * Update the cache time again. We want to do this call
1178 * as little as possible...
1181 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1182 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1184 /* clear the msg pending record for this queue */
1186 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1188 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1189 /* log a message but continue on */
1191 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1192 sharename));
1195 release_print_db( pdb );
1197 return;
1200 /****************************************************************************
1201 Update the internal database from the system print queue for a queue.
1202 obtain a lock on the print queue before proceeding (needed when mutiple
1203 smbd processes maytry to update the lpq cache concurrently).
1204 ****************************************************************************/
1206 static void print_queue_update_with_lock( const char *sharename,
1207 struct printif *current_printif,
1208 char *lpq_command )
1210 fstring keystr;
1211 struct tdb_print_db *pdb;
1213 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1214 pdb = get_print_db_byname(sharename);
1215 if (!pdb)
1216 return;
1218 if ( !print_cache_expired(sharename, False) ) {
1219 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1220 release_print_db(pdb);
1221 return;
1225 * Check to see if someone else is doing this update.
1226 * This is essentially a mutex on the update.
1229 if (get_updating_pid(sharename) != -1) {
1230 release_print_db(pdb);
1231 return;
1234 /* Lock the queue for the database update */
1236 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1237 /* Only wait 10 seconds for this. */
1238 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1239 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1240 release_print_db(pdb);
1241 return;
1245 * Ensure that no one else got in here.
1246 * If the updating pid is still -1 then we are
1247 * the winner.
1250 if (get_updating_pid(sharename) != -1) {
1252 * Someone else is doing the update, exit.
1254 tdb_unlock_bystring(pdb->tdb, keystr);
1255 release_print_db(pdb);
1256 return;
1260 * We're going to do the update ourselves.
1263 /* Tell others we're doing the update. */
1264 set_updating_pid(sharename, True);
1267 * Allow others to enter and notice we're doing
1268 * the update.
1271 tdb_unlock_bystring(pdb->tdb, keystr);
1273 /* do the main work now */
1275 print_queue_update_internal( sharename, current_printif, lpq_command );
1277 /* Delete our pid from the db. */
1278 set_updating_pid(sharename, False);
1279 release_print_db(pdb);
1282 /****************************************************************************
1283 this is the receive function of the background lpq updater
1284 ****************************************************************************/
1285 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
1287 struct print_queue_update_context ctx;
1288 fstring sharename;
1289 pstring lpqcommand;
1290 size_t len;
1292 len = tdb_unpack( buf, msglen, "fdP",
1293 sharename,
1294 &ctx.printing_type,
1295 lpqcommand );
1297 if ( len == -1 ) {
1298 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1299 return;
1302 ctx.sharename = sharename;
1303 ctx.lpqcommand = lpqcommand;
1305 print_queue_update_with_lock(ctx.sharename,
1306 get_printer_fns_from_type(ctx.printing_type),
1307 ctx.lpqcommand );
1309 return;
1312 static pid_t background_lpq_updater_pid = -1;
1314 /****************************************************************************
1315 main thread of the background lpq updater
1316 ****************************************************************************/
1317 void start_background_queue(void)
1319 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1320 background_lpq_updater_pid = sys_fork();
1322 if (background_lpq_updater_pid == -1) {
1323 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1324 exit(1);
1327 if(background_lpq_updater_pid == 0) {
1328 /* Child. */
1329 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1331 claim_connection( NULL, "smbd lpq backend", 0, False,
1332 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1334 if (!locking_init(0)) {
1335 exit(1);
1338 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1340 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1341 while (1) {
1342 pause();
1344 /* check for some essential signals first */
1346 if (got_sig_term) {
1347 exit_server("Caught TERM signal");
1350 if (reload_after_sighup) {
1351 change_to_root_user();
1352 DEBUG(1,("Reloading services after SIGHUP\n"));
1353 reload_services(False);
1354 reload_after_sighup = 0;
1357 /* now check for messages */
1359 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1360 message_dispatch();
1362 /* process any pending print change notify messages */
1364 print_notify_send_messages(0);
1369 /****************************************************************************
1370 update the internal database from the system print queue for a queue
1371 ****************************************************************************/
1373 static void print_queue_update(int snum, BOOL force)
1375 fstring key;
1376 fstring sharename;
1377 pstring lpqcommand;
1378 char *buffer = NULL;
1379 size_t len = 0;
1380 size_t newlen;
1381 struct tdb_print_db *pdb;
1382 int type;
1383 struct printif *current_printif;
1385 fstrcpy( sharename, lp_const_servicename(snum));
1387 pstrcpy( lpqcommand, lp_lpqcommand(snum));
1388 pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
1389 standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
1392 * Make sure that the background queue process exists.
1393 * Otherwise just do the update ourselves
1396 if ( force || background_lpq_updater_pid == -1 ) {
1397 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1398 current_printif = get_printer_fns( snum );
1399 print_queue_update_with_lock( sharename, current_printif, lpqcommand );
1401 return;
1404 type = lp_printing(snum);
1406 /* get the length */
1408 len = tdb_pack( buffer, len, "fdP",
1409 sharename,
1410 type,
1411 lpqcommand );
1413 buffer = SMB_XMALLOC_ARRAY( char, len );
1415 /* now pack the buffer */
1416 newlen = tdb_pack( buffer, len, "fdP",
1417 sharename,
1418 type,
1419 lpqcommand );
1421 SMB_ASSERT( newlen == len );
1423 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1424 "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand ));
1426 /* here we set a msg pending record for other smbd processes
1427 to throttle the number of duplicate print_queue_update msgs
1428 sent. */
1430 pdb = get_print_db_byname(sharename);
1431 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1433 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1434 /* log a message but continue on */
1436 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1437 sharename));
1440 release_print_db( pdb );
1442 /* finally send the message */
1444 become_root();
1445 message_send_pid(background_lpq_updater_pid,
1446 MSG_PRINTER_UPDATE, buffer, len, False);
1447 unbecome_root();
1449 SAFE_FREE( buffer );
1451 return;
1454 /****************************************************************************
1455 Create/Update an entry in the print tdb that will allow us to send notify
1456 updates only to interested smbd's.
1457 ****************************************************************************/
1459 BOOL print_notify_register_pid(int snum)
1461 TDB_DATA data;
1462 struct tdb_print_db *pdb = NULL;
1463 TDB_CONTEXT *tdb = NULL;
1464 const char *printername;
1465 uint32 mypid = (uint32)sys_getpid();
1466 BOOL ret = False;
1467 size_t i;
1469 /* if (snum == -1), then the change notify request was
1470 on a print server handle and we need to register on
1471 all print queus */
1473 if (snum == -1)
1475 int num_services = lp_numservices();
1476 int idx;
1478 for ( idx=0; idx<num_services; idx++ ) {
1479 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1480 print_notify_register_pid(idx);
1483 return True;
1485 else /* register for a specific printer */
1487 printername = lp_const_servicename(snum);
1488 pdb = get_print_db_byname(printername);
1489 if (!pdb)
1490 return False;
1491 tdb = pdb->tdb;
1494 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1495 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1496 printername));
1497 if (pdb)
1498 release_print_db(pdb);
1499 return False;
1502 data = get_printer_notify_pid_list( tdb, printername, True );
1504 /* Add ourselves and increase the refcount. */
1506 for (i = 0; i < data.dsize; i += 8) {
1507 if (IVAL(data.dptr,i) == mypid) {
1508 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1509 SIVAL(data.dptr, i+4, new_refcount);
1510 break;
1514 if (i == data.dsize) {
1515 /* We weren't in the list. Realloc. */
1516 data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
1517 if (!data.dptr) {
1518 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1519 printername));
1520 goto done;
1522 data.dsize += 8;
1523 SIVAL(data.dptr,data.dsize - 8,mypid);
1524 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1527 /* Store back the record. */
1528 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1529 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1530 list for printer %s\n", printername));
1531 goto done;
1534 ret = True;
1536 done:
1538 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1539 if (pdb)
1540 release_print_db(pdb);
1541 SAFE_FREE(data.dptr);
1542 return ret;
1545 /****************************************************************************
1546 Update an entry in the print tdb that will allow us to send notify
1547 updates only to interested smbd's.
1548 ****************************************************************************/
1550 BOOL print_notify_deregister_pid(int snum)
1552 TDB_DATA data;
1553 struct tdb_print_db *pdb = NULL;
1554 TDB_CONTEXT *tdb = NULL;
1555 const char *printername;
1556 uint32 mypid = (uint32)sys_getpid();
1557 size_t i;
1558 BOOL ret = False;
1560 /* if ( snum == -1 ), we are deregister a print server handle
1561 which means to deregister on all print queues */
1563 if (snum == -1)
1565 int num_services = lp_numservices();
1566 int idx;
1568 for ( idx=0; idx<num_services; idx++ ) {
1569 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1570 print_notify_deregister_pid(idx);
1573 return True;
1575 else /* deregister a specific printer */
1577 printername = lp_const_servicename(snum);
1578 pdb = get_print_db_byname(printername);
1579 if (!pdb)
1580 return False;
1581 tdb = pdb->tdb;
1584 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1585 DEBUG(0,("print_notify_register_pid: Failed to lock \
1586 printer %s database\n", printername));
1587 if (pdb)
1588 release_print_db(pdb);
1589 return False;
1592 data = get_printer_notify_pid_list( tdb, printername, True );
1594 /* Reduce refcount. Remove ourselves if zero. */
1596 for (i = 0; i < data.dsize; ) {
1597 if (IVAL(data.dptr,i) == mypid) {
1598 uint32 refcount = IVAL(data.dptr, i+4);
1600 refcount--;
1602 if (refcount == 0) {
1603 if (data.dsize - i > 8)
1604 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1605 data.dsize -= 8;
1606 continue;
1608 SIVAL(data.dptr, i+4, refcount);
1611 i += 8;
1614 if (data.dsize == 0)
1615 SAFE_FREE(data.dptr);
1617 /* Store back the record. */
1618 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1619 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1620 list for printer %s\n", printername));
1621 goto done;
1624 ret = True;
1626 done:
1628 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1629 if (pdb)
1630 release_print_db(pdb);
1631 SAFE_FREE(data.dptr);
1632 return ret;
1635 /****************************************************************************
1636 Check if a jobid is valid. It is valid if it exists in the database.
1637 ****************************************************************************/
1639 BOOL print_job_exists(const char* sharename, uint32 jobid)
1641 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1642 BOOL ret;
1644 if (!pdb)
1645 return False;
1646 ret = tdb_exists(pdb->tdb, print_key(jobid));
1647 release_print_db(pdb);
1648 return ret;
1651 /****************************************************************************
1652 Give the fd used for a jobid.
1653 ****************************************************************************/
1655 int print_job_fd(const char* sharename, uint32 jobid)
1657 struct printjob *pjob = print_job_find(sharename, jobid);
1658 if (!pjob)
1659 return -1;
1660 /* don't allow another process to get this info - it is meaningless */
1661 if (pjob->pid != sys_getpid())
1662 return -1;
1663 return pjob->fd;
1666 /****************************************************************************
1667 Give the filename used for a jobid.
1668 Only valid for the process doing the spooling and when the job
1669 has not been spooled.
1670 ****************************************************************************/
1672 char *print_job_fname(const char* sharename, uint32 jobid)
1674 struct printjob *pjob = print_job_find(sharename, jobid);
1675 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1676 return NULL;
1677 return pjob->filename;
1681 /****************************************************************************
1682 Give the filename used for a jobid.
1683 Only valid for the process doing the spooling and when the job
1684 has not been spooled.
1685 ****************************************************************************/
1687 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1689 struct printjob *pjob = print_job_find(sharename, jobid);
1691 if ( !pjob )
1692 return NULL;
1694 return pjob->nt_devmode;
1697 /****************************************************************************
1698 Set the place in the queue for a job.
1699 ****************************************************************************/
1701 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1703 DEBUG(2,("print_job_set_place not implemented yet\n"));
1704 return False;
1707 /****************************************************************************
1708 Set the name of a job. Only possible for owner.
1709 ****************************************************************************/
1711 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1713 const char* sharename = lp_const_servicename(snum);
1714 struct printjob *pjob;
1716 pjob = print_job_find(sharename, jobid);
1717 if (!pjob || pjob->pid != sys_getpid())
1718 return False;
1720 fstrcpy(pjob->jobname, name);
1721 return pjob_store(sharename, jobid, pjob);
1724 /***************************************************************************
1725 Remove a jobid from the 'jobs changed' list.
1726 ***************************************************************************/
1728 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1730 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1731 TDB_DATA data, key;
1732 size_t job_count, i;
1733 BOOL ret = False;
1734 BOOL gotlock = False;
1736 ZERO_STRUCT(data);
1738 key = string_tdb_data("INFO/jobs_changed");
1740 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1741 goto out;
1743 gotlock = True;
1745 data = tdb_fetch(pdb->tdb, key);
1747 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1748 goto out;
1750 job_count = data.dsize / 4;
1751 for (i = 0; i < job_count; i++) {
1752 uint32 ch_jobid;
1754 ch_jobid = IVAL(data.dptr, i*4);
1755 if (ch_jobid == jobid) {
1756 if (i < job_count -1 )
1757 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1758 data.dsize -= 4;
1759 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1760 goto out;
1761 break;
1765 ret = True;
1766 out:
1768 if (gotlock)
1769 tdb_chainunlock(pdb->tdb, key);
1770 SAFE_FREE(data.dptr);
1771 release_print_db(pdb);
1772 if (ret)
1773 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1774 else
1775 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1776 return ret;
1779 /****************************************************************************
1780 Delete a print job - don't update queue.
1781 ****************************************************************************/
1783 static BOOL print_job_delete1(int snum, uint32 jobid)
1785 const char* sharename = lp_const_servicename(snum);
1786 struct printjob *pjob = print_job_find(sharename, jobid);
1787 int result = 0;
1788 struct printif *current_printif = get_printer_fns( snum );
1790 pjob = print_job_find(sharename, jobid);
1792 if (!pjob)
1793 return False;
1796 * If already deleting just return.
1799 if (pjob->status == LPQ_DELETING)
1800 return True;
1802 /* Hrm - we need to be able to cope with deleting a job before it
1803 has reached the spooler. */
1805 if (pjob->sysjob == -1) {
1806 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1809 /* Set the tdb entry to be deleting. */
1811 pjob->status = LPQ_DELETING;
1812 pjob_store(sharename, jobid, pjob);
1814 if (pjob->spooled && pjob->sysjob != -1)
1815 result = (*(current_printif->job_delete))(snum, pjob);
1817 /* Delete the tdb entry if the delete succeeded or the job hasn't
1818 been spooled. */
1820 if (result == 0) {
1821 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1822 int njobs = 1;
1824 if (!pdb)
1825 return False;
1826 pjob_delete(sharename, jobid);
1827 /* Ensure we keep a rough count of the number of total jobs... */
1828 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1829 release_print_db(pdb);
1832 return (result == 0);
1835 /****************************************************************************
1836 Return true if the current user owns the print job.
1837 ****************************************************************************/
1839 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1841 struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
1842 user_struct *vuser;
1844 if (!pjob || !user)
1845 return False;
1847 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1848 return strequal(pjob->user, vuser->user.smb_name);
1849 } else {
1850 return strequal(pjob->user, uidtoname(user->uid));
1854 /****************************************************************************
1855 Delete a print job.
1856 ****************************************************************************/
1858 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1860 const char* sharename = lp_const_servicename( snum );
1861 BOOL owner, deleted;
1862 char *fname;
1864 *errcode = WERR_OK;
1866 owner = is_owner(user, snum, jobid);
1868 /* Check access against security descriptor or whether the user
1869 owns their job. */
1871 if (!owner &&
1872 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1873 DEBUG(3, ("delete denied by security descriptor\n"));
1874 *errcode = WERR_ACCESS_DENIED;
1876 /* BEGIN_ADMIN_LOG */
1877 sys_adminlog( LOG_ERR,
1878 "Permission denied-- user not allowed to delete, \
1879 pause, or resume print job. User name: %s. Printer name: %s.",
1880 uidtoname(user->uid), PRINTERNAME(snum) );
1881 /* END_ADMIN_LOG */
1883 return False;
1887 * get the spooled filename of the print job
1888 * if this works, then the file has not been spooled
1889 * to the underlying print system. Just delete the
1890 * spool file & return.
1893 if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1895 /* remove the spool file */
1896 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1897 if ( unlink( fname ) == -1 ) {
1898 *errcode = map_werror_from_unix(errno);
1899 return False;
1903 if (!print_job_delete1(snum, jobid)) {
1904 *errcode = WERR_ACCESS_DENIED;
1905 return False;
1908 /* force update the database and say the delete failed if the
1909 job still exists */
1911 print_queue_update(snum, True);
1913 deleted = !print_job_exists(sharename, jobid);
1914 if ( !deleted )
1915 *errcode = WERR_ACCESS_DENIED;
1917 return deleted;
1920 /****************************************************************************
1921 Pause a job.
1922 ****************************************************************************/
1924 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1926 const char* sharename = lp_const_servicename(snum);
1927 struct printjob *pjob;
1928 int ret = -1;
1929 struct printif *current_printif = get_printer_fns( snum );
1931 pjob = print_job_find(sharename, jobid);
1933 if (!pjob || !user)
1934 return False;
1936 if (!pjob->spooled || pjob->sysjob == -1)
1937 return False;
1939 if (!is_owner(user, snum, jobid) &&
1940 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1941 DEBUG(3, ("pause denied by security descriptor\n"));
1943 /* BEGIN_ADMIN_LOG */
1944 sys_adminlog( LOG_ERR,
1945 "Permission denied-- user not allowed to delete, \
1946 pause, or resume print job. User name: %s. Printer name: %s.",
1947 uidtoname(user->uid), PRINTERNAME(snum) );
1948 /* END_ADMIN_LOG */
1950 *errcode = WERR_ACCESS_DENIED;
1951 return False;
1954 /* need to pause the spooled entry */
1955 ret = (*(current_printif->job_pause))(snum, pjob);
1957 if (ret != 0) {
1958 *errcode = WERR_INVALID_PARAM;
1959 return False;
1962 /* force update the database */
1963 print_cache_flush(snum);
1965 /* Send a printer notify message */
1967 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
1969 /* how do we tell if this succeeded? */
1971 return True;
1974 /****************************************************************************
1975 Resume a job.
1976 ****************************************************************************/
1978 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1980 const char *sharename = lp_const_servicename(snum);
1981 struct printjob *pjob;
1982 int ret;
1983 struct printif *current_printif = get_printer_fns( snum );
1985 pjob = print_job_find(sharename, jobid);
1987 if (!pjob || !user)
1988 return False;
1990 if (!pjob->spooled || pjob->sysjob == -1)
1991 return False;
1993 if (!is_owner(user, snum, jobid) &&
1994 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1995 DEBUG(3, ("resume denied by security descriptor\n"));
1996 *errcode = WERR_ACCESS_DENIED;
1998 /* BEGIN_ADMIN_LOG */
1999 sys_adminlog( LOG_ERR,
2000 "Permission denied-- user not allowed to delete, \
2001 pause, or resume print job. User name: %s. Printer name: %s.",
2002 uidtoname(user->uid), PRINTERNAME(snum) );
2003 /* END_ADMIN_LOG */
2004 return False;
2007 ret = (*(current_printif->job_resume))(snum, pjob);
2009 if (ret != 0) {
2010 *errcode = WERR_INVALID_PARAM;
2011 return False;
2014 /* force update the database */
2015 print_cache_flush(snum);
2017 /* Send a printer notify message */
2019 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2021 return True;
2024 /****************************************************************************
2025 Write to a print file.
2026 ****************************************************************************/
2028 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
2030 const char* sharename = lp_const_servicename(snum);
2031 int return_code;
2032 struct printjob *pjob;
2034 pjob = print_job_find(sharename, jobid);
2036 if (!pjob)
2037 return -1;
2038 /* don't allow another process to get this info - it is meaningless */
2039 if (pjob->pid != sys_getpid())
2040 return -1;
2042 return_code = write(pjob->fd, buf, size);
2043 if (return_code>0) {
2044 pjob->size += size;
2045 pjob_store(sharename, jobid, pjob);
2047 return return_code;
2050 /****************************************************************************
2051 Get the queue status - do not update if db is out of date.
2052 ****************************************************************************/
2054 static int get_queue_status(const char* sharename, print_status_struct *status)
2056 fstring keystr;
2057 TDB_DATA data;
2058 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2059 int len;
2061 if (!pdb)
2062 return 0;
2064 if (status) {
2065 ZERO_STRUCTP(status);
2066 fstr_sprintf(keystr, "STATUS/%s", sharename);
2067 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2068 if (data.dptr) {
2069 if (data.dsize == sizeof(print_status_struct))
2070 /* this memcpy is ok since the status struct was
2071 not packed before storing it in the tdb */
2072 memcpy(status, data.dptr, sizeof(print_status_struct));
2073 SAFE_FREE(data.dptr);
2076 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2077 release_print_db(pdb);
2078 return (len == -1 ? 0 : len);
2081 /****************************************************************************
2082 Determine the number of jobs in a queue.
2083 ****************************************************************************/
2085 int print_queue_length(int snum, print_status_struct *pstatus)
2087 const char* sharename = lp_const_servicename( snum );
2088 print_status_struct status;
2089 int len;
2091 /* make sure the database is up to date */
2092 if (print_cache_expired(lp_const_servicename(snum), True))
2093 print_queue_update(snum, False);
2095 /* also fetch the queue status */
2096 memset(&status, 0, sizeof(status));
2097 len = get_queue_status(sharename, &status);
2099 if (pstatus)
2100 *pstatus = status;
2102 return len;
2105 /***************************************************************************
2106 Allocate a jobid. Hold the lock for as short a time as possible.
2107 ***************************************************************************/
2109 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2111 int i;
2112 uint32 jobid;
2114 *pjobid = (uint32)-1;
2116 for (i = 0; i < 3; i++) {
2117 /* Lock the database - only wait 20 seconds. */
2118 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
2119 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2120 return False;
2123 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2124 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2125 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2126 sharename));
2127 return False;
2129 jobid = 0;
2132 jobid = NEXT_JOBID(jobid);
2134 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2135 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2136 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2137 return False;
2140 /* We've finished with the INFO/nextjob lock. */
2141 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2143 if (!print_job_exists(sharename, jobid))
2144 break;
2147 if (i > 2) {
2148 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2149 sharename));
2150 /* Probably full... */
2151 errno = ENOSPC;
2152 return False;
2155 /* Store a dummy placeholder. */
2157 TDB_DATA dum;
2158 dum.dptr = NULL;
2159 dum.dsize = 0;
2160 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2161 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2162 jobid ));
2163 return False;
2167 *pjobid = jobid;
2168 return True;
2171 /***************************************************************************
2172 Append a jobid to the 'jobs changed' list.
2173 ***************************************************************************/
2175 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2177 TDB_DATA data;
2178 uint32 store_jobid;
2180 SIVAL(&store_jobid, 0, jobid);
2181 data.dptr = (char *)&store_jobid;
2182 data.dsize = 4;
2184 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2186 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2187 data) == 0);
2190 /***************************************************************************
2191 Start spooling a job - return the jobid.
2192 ***************************************************************************/
2194 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2196 uint32 jobid;
2197 char *path;
2198 struct printjob pjob;
2199 user_struct *vuser;
2200 const char *sharename = lp_const_servicename(snum);
2201 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2202 int njobs;
2204 errno = 0;
2206 if (!pdb)
2207 return (uint32)-1;
2209 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2210 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2211 release_print_db(pdb);
2212 return (uint32)-1;
2215 if (!print_time_access_check(snum)) {
2216 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2217 release_print_db(pdb);
2218 return (uint32)-1;
2221 path = lp_pathname(snum);
2223 /* see if we have sufficient disk space */
2224 if (lp_minprintspace(snum)) {
2225 SMB_BIG_UINT dspace, dsize;
2226 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2227 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2228 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2229 release_print_db(pdb);
2230 errno = ENOSPC;
2231 return (uint32)-1;
2235 /* for autoloaded printers, check that the printcap entry still exists */
2236 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2237 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2238 release_print_db(pdb);
2239 errno = ENOENT;
2240 return (uint32)-1;
2243 /* Insure the maximum queue size is not violated */
2244 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2245 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2246 sharename, njobs, lp_maxprintjobs(snum) ));
2247 release_print_db(pdb);
2248 errno = ENOSPC;
2249 return (uint32)-1;
2252 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2253 sharename, njobs, lp_maxprintjobs(snum) ));
2255 if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2256 goto fail;
2258 /* create the database entry */
2260 ZERO_STRUCT(pjob);
2262 pjob.pid = sys_getpid();
2263 pjob.sysjob = -1;
2264 pjob.fd = -1;
2265 pjob.starttime = time(NULL);
2266 pjob.status = LPQ_SPOOLING;
2267 pjob.size = 0;
2268 pjob.spooled = False;
2269 pjob.smbjob = True;
2270 pjob.nt_devmode = nt_devmode;
2272 fstrcpy(pjob.jobname, jobname);
2274 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2275 fstrcpy(pjob.user, vuser->user.smb_name);
2276 } else {
2277 fstrcpy(pjob.user, uidtoname(user->uid));
2280 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2282 /* we have a job entry - now create the spool file */
2283 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2284 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2285 pjob.fd = smb_mkstemp(pjob.filename);
2287 if (pjob.fd == -1) {
2288 if (errno == EACCES) {
2289 /* Common setup error, force a report. */
2290 DEBUG(0, ("print_job_start: insufficient permissions \
2291 to open spool file %s.\n", pjob.filename));
2292 } else {
2293 /* Normal case, report at level 3 and above. */
2294 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2295 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2297 goto fail;
2300 pjob_store(sharename, jobid, &pjob);
2302 /* Update the 'jobs changed' entry used by print_queue_status. */
2303 add_to_jobs_changed(pdb, jobid);
2305 /* Ensure we keep a rough count of the number of total jobs... */
2306 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2308 release_print_db(pdb);
2310 return jobid;
2312 fail:
2313 if (jobid != -1)
2314 pjob_delete(sharename, jobid);
2316 release_print_db(pdb);
2318 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2319 return (uint32)-1;
2322 /****************************************************************************
2323 Update the number of pages spooled to jobid
2324 ****************************************************************************/
2326 void print_job_endpage(int snum, uint32 jobid)
2328 const char* sharename = lp_const_servicename(snum);
2329 struct printjob *pjob;
2331 pjob = print_job_find(sharename, jobid);
2332 if (!pjob)
2333 return;
2334 /* don't allow another process to get this info - it is meaningless */
2335 if (pjob->pid != sys_getpid())
2336 return;
2338 pjob->page_count++;
2339 pjob_store(sharename, jobid, pjob);
2342 /****************************************************************************
2343 Print a file - called on closing the file. This spools the job.
2344 If normal close is false then we're tearing down the jobs - treat as an
2345 error.
2346 ****************************************************************************/
2348 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2350 const char* sharename = lp_const_servicename(snum);
2351 struct printjob *pjob;
2352 int ret;
2353 SMB_STRUCT_STAT sbuf;
2354 struct printif *current_printif = get_printer_fns( snum );
2356 pjob = print_job_find(sharename, jobid);
2358 if (!pjob)
2359 return False;
2361 if (pjob->spooled || pjob->pid != sys_getpid())
2362 return False;
2364 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2365 pjob->size = sbuf.st_size;
2366 close(pjob->fd);
2367 pjob->fd = -1;
2368 } else {
2371 * Not a normal close or we couldn't stat the job file,
2372 * so something has gone wrong. Cleanup.
2374 close(pjob->fd);
2375 pjob->fd = -1;
2376 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2377 goto fail;
2380 /* Technically, this is not quite right. If the printer has a separator
2381 * page turned on, the NT spooler prints the separator page even if the
2382 * print job is 0 bytes. 010215 JRR */
2383 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2384 /* don't bother spooling empty files or something being deleted. */
2385 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2386 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2387 unlink(pjob->filename);
2388 pjob_delete(sharename, jobid);
2389 return True;
2392 pjob->smbjob = jobid;
2394 ret = (*(current_printif->job_submit))(snum, pjob);
2396 if (ret)
2397 goto fail;
2399 /* The print job has been sucessfully handed over to the back-end */
2401 pjob->spooled = True;
2402 pjob->status = LPQ_QUEUED;
2403 pjob_store(sharename, jobid, pjob);
2405 /* make sure the database is up to date */
2406 if (print_cache_expired(lp_const_servicename(snum), True))
2407 print_queue_update(snum, False);
2409 return True;
2411 fail:
2413 /* The print job was not succesfully started. Cleanup */
2414 /* Still need to add proper error return propagation! 010122:JRR */
2415 unlink(pjob->filename);
2416 pjob_delete(sharename, jobid);
2417 return False;
2420 /****************************************************************************
2421 Get a snapshot of jobs in the system without traversing.
2422 ****************************************************************************/
2424 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2426 TDB_DATA data, cgdata;
2427 print_queue_struct *queue = NULL;
2428 uint32 qcount = 0;
2429 uint32 extra_count = 0;
2430 int total_count = 0;
2431 size_t len = 0;
2432 uint32 i;
2433 int max_reported_jobs = lp_max_reported_jobs(snum);
2434 BOOL ret = False;
2435 const char* sharename = lp_servicename(snum);
2437 /* make sure the database is up to date */
2438 if (print_cache_expired(lp_const_servicename(snum), True))
2439 print_queue_update(snum, False);
2441 *pcount = 0;
2442 *ppqueue = NULL;
2444 ZERO_STRUCT(data);
2445 ZERO_STRUCT(cgdata);
2447 /* Get the stored queue data. */
2448 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2450 if (data.dptr && data.dsize >= sizeof(qcount))
2451 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2453 /* Get the changed jobs list. */
2454 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2455 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2456 extra_count = cgdata.dsize/4;
2458 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2460 /* Allocate the queue size. */
2461 if (qcount == 0 && extra_count == 0)
2462 goto out;
2464 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2465 goto out;
2467 /* Retrieve the linearised queue data. */
2469 for( i = 0; i < qcount; i++) {
2470 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2471 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2472 &qjob,
2473 &qsize,
2474 &qpage_count,
2475 &qstatus,
2476 &qpriority,
2477 &qtime,
2478 queue[i].fs_user,
2479 queue[i].fs_file);
2480 queue[i].job = qjob;
2481 queue[i].size = qsize;
2482 queue[i].page_count = qpage_count;
2483 queue[i].status = qstatus;
2484 queue[i].priority = qpriority;
2485 queue[i].time = qtime;
2488 total_count = qcount;
2490 /* Add in the changed jobids. */
2491 for( i = 0; i < extra_count; i++) {
2492 uint32 jobid;
2493 struct printjob *pjob;
2495 jobid = IVAL(cgdata.dptr, i*4);
2496 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2497 pjob = print_job_find(lp_const_servicename(snum), jobid);
2498 if (!pjob) {
2499 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2500 remove_from_jobs_changed(sharename, jobid);
2501 continue;
2504 queue[total_count].job = jobid;
2505 queue[total_count].size = pjob->size;
2506 queue[total_count].page_count = pjob->page_count;
2507 queue[total_count].status = pjob->status;
2508 queue[total_count].priority = 1;
2509 queue[total_count].time = pjob->starttime;
2510 fstrcpy(queue[total_count].fs_user, pjob->user);
2511 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2512 total_count++;
2515 /* Sort the queue by submission time otherwise they are displayed
2516 in hash order. */
2518 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2520 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2522 if (max_reported_jobs && total_count > max_reported_jobs)
2523 total_count = max_reported_jobs;
2525 *ppqueue = queue;
2526 *pcount = total_count;
2528 ret = True;
2530 out:
2532 SAFE_FREE(data.dptr);
2533 SAFE_FREE(cgdata.dptr);
2534 return ret;
2537 /****************************************************************************
2538 Get a printer queue listing.
2539 set queue = NULL and status = NULL if you just want to update the cache
2540 ****************************************************************************/
2542 int print_queue_status(int snum,
2543 print_queue_struct **ppqueue,
2544 print_status_struct *status)
2546 fstring keystr;
2547 TDB_DATA data, key;
2548 const char *sharename;
2549 struct tdb_print_db *pdb;
2550 int count = 0;
2552 /* make sure the database is up to date */
2554 if (print_cache_expired(lp_const_servicename(snum), True))
2555 print_queue_update(snum, False);
2557 /* return if we are done */
2558 if ( !ppqueue || !status )
2559 return 0;
2561 *ppqueue = NULL;
2562 sharename = lp_const_servicename(snum);
2563 pdb = get_print_db_byname(sharename);
2565 if (!pdb)
2566 return 0;
2569 * Fetch the queue status. We must do this first, as there may
2570 * be no jobs in the queue.
2573 ZERO_STRUCTP(status);
2574 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2575 key.dptr = keystr;
2576 key.dsize = strlen(keystr);
2577 data = tdb_fetch(pdb->tdb, key);
2578 if (data.dptr) {
2579 if (data.dsize == sizeof(*status)) {
2580 /* this memcpy is ok since the status struct was
2581 not packed before storing it in the tdb */
2582 memcpy(status, data.dptr, sizeof(*status));
2584 SAFE_FREE(data.dptr);
2588 * Now, fetch the print queue information. We first count the number
2589 * of entries, and then only retrieve the queue if necessary.
2592 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2593 release_print_db(pdb);
2594 return 0;
2597 release_print_db(pdb);
2598 return count;
2601 /****************************************************************************
2602 Pause a queue.
2603 ****************************************************************************/
2605 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2607 int ret;
2608 struct printif *current_printif = get_printer_fns( snum );
2610 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2611 *errcode = WERR_ACCESS_DENIED;
2612 return False;
2616 become_root();
2618 ret = (*(current_printif->queue_pause))(snum);
2620 unbecome_root();
2622 if (ret != 0) {
2623 *errcode = WERR_INVALID_PARAM;
2624 return False;
2627 /* force update the database */
2628 print_cache_flush(snum);
2630 /* Send a printer notify message */
2632 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2634 return True;
2637 /****************************************************************************
2638 Resume a queue.
2639 ****************************************************************************/
2641 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2643 int ret;
2644 struct printif *current_printif = get_printer_fns( snum );
2646 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2647 *errcode = WERR_ACCESS_DENIED;
2648 return False;
2651 become_root();
2653 ret = (*(current_printif->queue_resume))(snum);
2655 unbecome_root();
2657 if (ret != 0) {
2658 *errcode = WERR_INVALID_PARAM;
2659 return False;
2662 /* make sure the database is up to date */
2663 if (print_cache_expired(lp_const_servicename(snum), True))
2664 print_queue_update(snum, True);
2666 /* Send a printer notify message */
2668 notify_printer_status(snum, PRINTER_STATUS_OK);
2670 return True;
2673 /****************************************************************************
2674 Purge a queue - implemented by deleting all jobs that we can delete.
2675 ****************************************************************************/
2677 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2679 print_queue_struct *queue;
2680 print_status_struct status;
2681 int njobs, i;
2682 BOOL can_job_admin;
2684 /* Force and update so the count is accurate (i.e. not a cached count) */
2685 print_queue_update(snum, True);
2687 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2688 njobs = print_queue_status(snum, &queue, &status);
2690 if ( can_job_admin )
2691 become_root();
2693 for (i=0;i<njobs;i++) {
2694 BOOL owner = is_owner(user, snum, queue[i].job);
2696 if (owner || can_job_admin) {
2697 print_job_delete1(snum, queue[i].job);
2701 if ( can_job_admin )
2702 unbecome_root();
2704 /* update the cache */
2705 print_queue_update( snum, True );
2707 SAFE_FREE(queue);
2709 return True;