r4348: syncing up for 3.0.11pre1
[Samba.git] / source / printing / printing.c
blobb5785440aeb7020ac118847d4cc0f73d1eceec92
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 return;
1084 * Update the cache time FIRST ! Stops others even
1085 * attempting to get the lock and doing this
1086 * if the lpq takes a long time.
1089 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1090 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1092 /* get the current queue using the appropriate interface */
1093 ZERO_STRUCT(status);
1095 qcount = (*(current_printif->queue_get))(sharename,
1096 current_printif->type,
1097 lpq_command, &queue, &status);
1099 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1100 qcount, (qcount != 1) ? "s" : "", sharename));
1102 /* Sort the queue by submission time otherwise they are displayed
1103 in hash order. */
1105 qsort(queue, qcount, sizeof(print_queue_struct),
1106 QSORT_CAST(printjob_comp));
1109 any job in the internal database that is marked as spooled
1110 and doesn't exist in the system queue is considered finished
1111 and removed from the database
1113 any job in the system database but not in the internal database
1114 is added as a unix job
1116 fill in any system job numbers as we go
1119 jcdata = get_jobs_changed_data(pdb);
1121 for (i=0; i<qcount; i++) {
1122 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1124 if (jobid == (uint32)-1) {
1125 /* assume its a unix print job */
1126 print_unix_job(sharename, &queue[i], jobid);
1127 continue;
1130 /* we have an active SMB print job - update its status */
1131 pjob = print_job_find(sharename, jobid);
1132 if (!pjob) {
1133 /* err, somethings wrong. Probably smbd was restarted
1134 with jobs in the queue. All we can do is treat them
1135 like unix jobs. Pity. */
1136 print_unix_job(sharename, &queue[i], jobid);
1137 continue;
1140 pjob->sysjob = queue[i].job;
1141 pjob->status = queue[i].status;
1142 pjob_store(sharename, jobid, pjob);
1143 check_job_changed(sharename, jcdata, jobid);
1146 SAFE_FREE(jcdata.dptr);
1148 /* now delete any queued entries that don't appear in the
1149 system queue */
1150 tstruct.queue = queue;
1151 tstruct.qcount = qcount;
1152 tstruct.snum = -1;
1153 tstruct.total_jobs = 0;
1154 tstruct.lpq_time = time(NULL);
1155 tstruct.sharename = sharename;
1157 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1159 /* Store the linearised queue, max jobs only. */
1160 store_queue_struct(pdb, &tstruct);
1162 SAFE_FREE(tstruct.queue);
1164 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1165 sharename, tstruct.total_jobs ));
1167 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1169 get_queue_status(sharename, &old_status);
1170 if (old_status.qcount != qcount)
1171 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1172 old_status.qcount, qcount, sharename));
1174 /* store the new queue status structure */
1175 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1176 key.dptr = keystr;
1177 key.dsize = strlen(keystr);
1179 status.qcount = qcount;
1180 data.dptr = (void *)&status;
1181 data.dsize = sizeof(status);
1182 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1185 * Update the cache time again. We want to do this call
1186 * as little as possible...
1189 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1190 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1192 /* clear the msg pending record for this queue */
1194 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1196 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1197 /* log a message but continue on */
1199 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1200 sharename));
1203 release_print_db( pdb );
1205 return;
1208 /****************************************************************************
1209 Update the internal database from the system print queue for a queue.
1210 obtain a lock on the print queue before proceeding (needed when mutiple
1211 smbd processes maytry to update the lpq cache concurrently).
1212 ****************************************************************************/
1214 static void print_queue_update_with_lock(int snum)
1216 fstring sharename, keystr;
1217 pstring lpq_command;
1218 struct tdb_print_db *pdb;
1219 struct printif *current_printif = get_printer_fns( snum );
1221 fstrcpy(sharename, lp_const_servicename(snum));
1223 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1224 pdb = get_print_db_byname(sharename);
1225 if (!pdb)
1226 return;
1229 * Check to see if someone else is doing this update.
1230 * This is essentially a mutex on the update.
1233 if (get_updating_pid(sharename) != -1) {
1234 release_print_db(pdb);
1235 return;
1238 /* Lock the queue for the database update */
1240 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1241 /* Only wait 10 seconds for this. */
1242 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1243 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1244 release_print_db(pdb);
1245 return;
1249 * Ensure that no one else got in here.
1250 * If the updating pid is still -1 then we are
1251 * the winner.
1254 if (get_updating_pid(sharename) != -1) {
1256 * Someone else is doing the update, exit.
1258 tdb_unlock_bystring(pdb->tdb, keystr);
1259 release_print_db(pdb);
1260 return;
1264 * We're going to do the update ourselves.
1267 /* Tell others we're doing the update. */
1268 set_updating_pid(sharename, True);
1271 * Allow others to enter and notice we're doing
1272 * the update.
1275 tdb_unlock_bystring(pdb->tdb, keystr);
1277 /* do the main work now */
1278 /* have to substitute any variables here since
1279 print_queue_get_internal() will not */
1281 pstrcpy( lpq_command, lp_lpqcommand(snum) );
1282 pstring_sub( lpq_command, "%p", PRINTERNAME(snum) );
1283 standard_sub_snum( snum, lpq_command, sizeof(lpq_command) );
1285 print_queue_update_internal( sharename, current_printif, lpq_command );
1287 /* Delete our pid from the db. */
1288 set_updating_pid(sharename, False);
1289 release_print_db(pdb);
1292 /****************************************************************************
1293 this is the receive function of the background lpq updater
1294 ****************************************************************************/
1295 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
1297 struct print_queue_update_context ctx;
1298 fstring sharename;
1299 pstring lpqcommand;
1300 size_t len;
1302 len = tdb_unpack( buf, msglen, "fdP",
1303 sharename,
1304 &ctx.printing_type,
1305 lpqcommand );
1307 if ( len == -1 ) {
1308 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1309 return;
1312 ctx.sharename = sharename;
1313 ctx.lpqcommand = lpqcommand;
1315 print_queue_update_internal(ctx.sharename,
1316 get_printer_fns_from_type(ctx.printing_type),
1317 ctx.lpqcommand );
1319 return;
1322 static pid_t background_lpq_updater_pid = -1;
1324 /****************************************************************************
1325 main thread of the background lpq updater
1326 ****************************************************************************/
1327 void start_background_queue(void)
1329 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1330 background_lpq_updater_pid = sys_fork();
1332 if (background_lpq_updater_pid == -1) {
1333 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1334 exit(1);
1337 if(background_lpq_updater_pid == 0) {
1338 /* Child. */
1339 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1341 claim_connection( NULL, "smbd lpq backend", 0, False,
1342 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1344 if (!locking_init(0)) {
1345 exit(1);
1348 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1350 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1351 while (1) {
1352 pause();
1354 /* check for some essential signals first */
1356 if (got_sig_term) {
1357 exit_server("Caught TERM signal");
1360 if (reload_after_sighup) {
1361 change_to_root_user();
1362 DEBUG(1,("Reloading services after SIGHUP\n"));
1363 reload_services(False);
1364 reload_after_sighup = 0;
1367 /* now check for messages */
1369 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1370 message_dispatch();
1372 /* process any pending print change notify messages */
1374 print_notify_send_messages(0);
1379 /****************************************************************************
1380 update the internal database from the system print queue for a queue
1381 ****************************************************************************/
1382 static void print_queue_update(int snum)
1384 struct print_queue_update_context ctx;
1385 fstring key;
1386 fstring sharename;
1387 pstring lpqcommand;
1388 char *buffer = NULL;
1389 size_t len = 0;
1390 size_t newlen;
1391 struct tdb_print_db *pdb;
1394 * Make sure that the background queue process exists.
1395 * Otherwise just do the update ourselves
1398 if ( background_lpq_updater_pid == -1 ) {
1399 print_queue_update_with_lock( snum );
1400 return;
1403 fstrcpy( sharename, lp_const_servicename(snum));
1405 ctx.printing_type = lp_printing(snum);
1407 pstrcpy( lpqcommand, lp_lpqcommand(snum));
1408 pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
1409 standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
1411 ctx.sharename = SMB_STRDUP( sharename );
1412 ctx.lpqcommand = SMB_STRDUP( lpqcommand );
1414 /* get the length */
1416 len = tdb_pack( buffer, len, "fdP",
1417 ctx.sharename,
1418 ctx.printing_type,
1419 ctx.lpqcommand );
1421 buffer = SMB_XMALLOC_ARRAY( char, len );
1423 /* now pack the buffer */
1424 newlen = tdb_pack( buffer, len, "fdP",
1425 ctx.sharename,
1426 ctx.printing_type,
1427 ctx.lpqcommand );
1429 SMB_ASSERT( newlen == len );
1431 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1432 "type = %d, lpq command = [%s]\n",
1433 ctx.sharename, ctx.printing_type, ctx.lpqcommand ));
1435 /* here we set a msg pending record for other smbd processes
1436 to throttle the number of duplicate print_queue_update msgs
1437 sent. */
1439 pdb = get_print_db_byname(sharename);
1440 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1442 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1443 /* log a message but continue on */
1445 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1446 sharename));
1449 release_print_db( pdb );
1451 /* finally send the message */
1453 become_root();
1454 message_send_pid(background_lpq_updater_pid,
1455 MSG_PRINTER_UPDATE, buffer, len, False);
1456 unbecome_root();
1458 SAFE_FREE( ctx.sharename );
1459 SAFE_FREE( ctx.lpqcommand );
1460 SAFE_FREE( buffer );
1462 return;
1465 /****************************************************************************
1466 Create/Update an entry in the print tdb that will allow us to send notify
1467 updates only to interested smbd's.
1468 ****************************************************************************/
1470 BOOL print_notify_register_pid(int snum)
1472 TDB_DATA data;
1473 struct tdb_print_db *pdb = NULL;
1474 TDB_CONTEXT *tdb = NULL;
1475 const char *printername;
1476 uint32 mypid = (uint32)sys_getpid();
1477 BOOL ret = False;
1478 size_t i;
1480 /* if (snum == -1), then the change notify request was
1481 on a print server handle and we need to register on
1482 all print queus */
1484 if (snum == -1)
1486 int num_services = lp_numservices();
1487 int idx;
1489 for ( idx=0; idx<num_services; idx++ ) {
1490 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1491 print_notify_register_pid(idx);
1494 return True;
1496 else /* register for a specific printer */
1498 printername = lp_const_servicename(snum);
1499 pdb = get_print_db_byname(printername);
1500 if (!pdb)
1501 return False;
1502 tdb = pdb->tdb;
1505 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1506 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1507 printername));
1508 if (pdb)
1509 release_print_db(pdb);
1510 return False;
1513 data = get_printer_notify_pid_list( tdb, printername, True );
1515 /* Add ourselves and increase the refcount. */
1517 for (i = 0; i < data.dsize; i += 8) {
1518 if (IVAL(data.dptr,i) == mypid) {
1519 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1520 SIVAL(data.dptr, i+4, new_refcount);
1521 break;
1525 if (i == data.dsize) {
1526 /* We weren't in the list. Realloc. */
1527 data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
1528 if (!data.dptr) {
1529 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1530 printername));
1531 goto done;
1533 data.dsize += 8;
1534 SIVAL(data.dptr,data.dsize - 8,mypid);
1535 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1538 /* Store back the record. */
1539 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1540 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1541 list for printer %s\n", printername));
1542 goto done;
1545 ret = True;
1547 done:
1549 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1550 if (pdb)
1551 release_print_db(pdb);
1552 SAFE_FREE(data.dptr);
1553 return ret;
1556 /****************************************************************************
1557 Update an entry in the print tdb that will allow us to send notify
1558 updates only to interested smbd's.
1559 ****************************************************************************/
1561 BOOL print_notify_deregister_pid(int snum)
1563 TDB_DATA data;
1564 struct tdb_print_db *pdb = NULL;
1565 TDB_CONTEXT *tdb = NULL;
1566 const char *printername;
1567 uint32 mypid = (uint32)sys_getpid();
1568 size_t i;
1569 BOOL ret = False;
1571 /* if ( snum == -1 ), we are deregister a print server handle
1572 which means to deregister on all print queues */
1574 if (snum == -1)
1576 int num_services = lp_numservices();
1577 int idx;
1579 for ( idx=0; idx<num_services; idx++ ) {
1580 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1581 print_notify_deregister_pid(idx);
1584 return True;
1586 else /* deregister a specific printer */
1588 printername = lp_const_servicename(snum);
1589 pdb = get_print_db_byname(printername);
1590 if (!pdb)
1591 return False;
1592 tdb = pdb->tdb;
1595 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1596 DEBUG(0,("print_notify_register_pid: Failed to lock \
1597 printer %s database\n", printername));
1598 if (pdb)
1599 release_print_db(pdb);
1600 return False;
1603 data = get_printer_notify_pid_list( tdb, printername, True );
1605 /* Reduce refcount. Remove ourselves if zero. */
1607 for (i = 0; i < data.dsize; ) {
1608 if (IVAL(data.dptr,i) == mypid) {
1609 uint32 refcount = IVAL(data.dptr, i+4);
1611 refcount--;
1613 if (refcount == 0) {
1614 if (data.dsize - i > 8)
1615 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1616 data.dsize -= 8;
1617 continue;
1619 SIVAL(data.dptr, i+4, refcount);
1622 i += 8;
1625 if (data.dsize == 0)
1626 SAFE_FREE(data.dptr);
1628 /* Store back the record. */
1629 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1630 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1631 list for printer %s\n", printername));
1632 goto done;
1635 ret = True;
1637 done:
1639 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1640 if (pdb)
1641 release_print_db(pdb);
1642 SAFE_FREE(data.dptr);
1643 return ret;
1646 /****************************************************************************
1647 Check if a jobid is valid. It is valid if it exists in the database.
1648 ****************************************************************************/
1650 BOOL print_job_exists(const char* sharename, uint32 jobid)
1652 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1653 BOOL ret;
1655 if (!pdb)
1656 return False;
1657 ret = tdb_exists(pdb->tdb, print_key(jobid));
1658 release_print_db(pdb);
1659 return ret;
1662 /****************************************************************************
1663 Give the fd used for a jobid.
1664 ****************************************************************************/
1666 int print_job_fd(const char* sharename, uint32 jobid)
1668 struct printjob *pjob = print_job_find(sharename, jobid);
1669 if (!pjob)
1670 return -1;
1671 /* don't allow another process to get this info - it is meaningless */
1672 if (pjob->pid != sys_getpid())
1673 return -1;
1674 return pjob->fd;
1677 /****************************************************************************
1678 Give the filename used for a jobid.
1679 Only valid for the process doing the spooling and when the job
1680 has not been spooled.
1681 ****************************************************************************/
1683 char *print_job_fname(const char* sharename, uint32 jobid)
1685 struct printjob *pjob = print_job_find(sharename, jobid);
1686 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1687 return NULL;
1688 return pjob->filename;
1692 /****************************************************************************
1693 Give the filename used for a jobid.
1694 Only valid for the process doing the spooling and when the job
1695 has not been spooled.
1696 ****************************************************************************/
1698 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1700 struct printjob *pjob = print_job_find(sharename, jobid);
1702 if ( !pjob )
1703 return NULL;
1705 return pjob->nt_devmode;
1708 /****************************************************************************
1709 Set the place in the queue for a job.
1710 ****************************************************************************/
1712 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1714 DEBUG(2,("print_job_set_place not implemented yet\n"));
1715 return False;
1718 /****************************************************************************
1719 Set the name of a job. Only possible for owner.
1720 ****************************************************************************/
1722 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1724 const char* sharename = lp_const_servicename(snum);
1725 struct printjob *pjob;
1727 pjob = print_job_find(sharename, jobid);
1728 if (!pjob || pjob->pid != sys_getpid())
1729 return False;
1731 fstrcpy(pjob->jobname, name);
1732 return pjob_store(sharename, jobid, pjob);
1735 /***************************************************************************
1736 Remove a jobid from the 'jobs changed' list.
1737 ***************************************************************************/
1739 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1741 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1742 TDB_DATA data, key;
1743 size_t job_count, i;
1744 BOOL ret = False;
1745 BOOL gotlock = False;
1747 key.dptr = "INFO/jobs_changed";
1748 key.dsize = strlen(key.dptr);
1749 ZERO_STRUCT(data);
1751 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1752 goto out;
1754 gotlock = True;
1756 data = tdb_fetch(pdb->tdb, key);
1758 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1759 goto out;
1761 job_count = data.dsize / 4;
1762 for (i = 0; i < job_count; i++) {
1763 uint32 ch_jobid;
1765 ch_jobid = IVAL(data.dptr, i*4);
1766 if (ch_jobid == jobid) {
1767 if (i < job_count -1 )
1768 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1769 data.dsize -= 4;
1770 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1771 goto out;
1772 break;
1776 ret = True;
1777 out:
1779 if (gotlock)
1780 tdb_chainunlock(pdb->tdb, key);
1781 SAFE_FREE(data.dptr);
1782 release_print_db(pdb);
1783 if (ret)
1784 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1785 else
1786 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1787 return ret;
1790 /****************************************************************************
1791 Delete a print job - don't update queue.
1792 ****************************************************************************/
1794 static BOOL print_job_delete1(int snum, uint32 jobid)
1796 const char* sharename = lp_const_servicename(snum);
1797 struct printjob *pjob = print_job_find(sharename, jobid);
1798 int result = 0;
1799 struct printif *current_printif = get_printer_fns( snum );
1801 pjob = print_job_find(sharename, jobid);
1803 if (!pjob)
1804 return False;
1807 * If already deleting just return.
1810 if (pjob->status == LPQ_DELETING)
1811 return True;
1813 /* Hrm - we need to be able to cope with deleting a job before it
1814 has reached the spooler. */
1816 if (pjob->sysjob == -1) {
1817 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1820 /* Set the tdb entry to be deleting. */
1822 pjob->status = LPQ_DELETING;
1823 pjob_store(sharename, jobid, pjob);
1825 if (pjob->spooled && pjob->sysjob != -1)
1826 result = (*(current_printif->job_delete))(snum, pjob);
1828 /* Delete the tdb entry if the delete succeeded or the job hasn't
1829 been spooled. */
1831 if (result == 0) {
1832 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1833 int njobs = 1;
1835 if (!pdb)
1836 return False;
1837 pjob_delete(sharename, jobid);
1838 /* Ensure we keep a rough count of the number of total jobs... */
1839 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1840 release_print_db(pdb);
1843 return (result == 0);
1846 /****************************************************************************
1847 Return true if the current user owns the print job.
1848 ****************************************************************************/
1850 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1852 struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
1853 user_struct *vuser;
1855 if (!pjob || !user)
1856 return False;
1858 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1859 return strequal(pjob->user, vuser->user.smb_name);
1860 } else {
1861 return strequal(pjob->user, uidtoname(user->uid));
1865 /****************************************************************************
1866 Delete a print job.
1867 ****************************************************************************/
1869 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1871 const char* sharename = lp_const_servicename( snum );
1872 BOOL owner, deleted;
1873 char *fname;
1875 *errcode = WERR_OK;
1877 owner = is_owner(user, snum, jobid);
1879 /* Check access against security descriptor or whether the user
1880 owns their job. */
1882 if (!owner &&
1883 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1884 DEBUG(3, ("delete denied by security descriptor\n"));
1885 *errcode = WERR_ACCESS_DENIED;
1887 /* BEGIN_ADMIN_LOG */
1888 sys_adminlog( LOG_ERR,
1889 "Permission denied-- user not allowed to delete, \
1890 pause, or resume print job. User name: %s. Printer name: %s.",
1891 uidtoname(user->uid), PRINTERNAME(snum) );
1892 /* END_ADMIN_LOG */
1894 return False;
1898 * get the spooled filename of the print job
1899 * if this works, then the file has not been spooled
1900 * to the underlying print system. Just delete the
1901 * spool file & return.
1904 if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1906 /* remove the spool file */
1907 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1908 if ( unlink( fname ) == -1 ) {
1909 *errcode = map_werror_from_unix(errno);
1910 return False;
1914 if (!print_job_delete1(snum, jobid)) {
1915 *errcode = WERR_ACCESS_DENIED;
1916 return False;
1919 /* force update the database and say the delete failed if the
1920 job still exists */
1922 print_queue_update(snum);
1924 deleted = !print_job_exists(sharename, jobid);
1925 if ( !deleted )
1926 *errcode = WERR_ACCESS_DENIED;
1928 return deleted;
1931 /****************************************************************************
1932 Pause a job.
1933 ****************************************************************************/
1935 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1937 const char* sharename = lp_const_servicename(snum);
1938 struct printjob *pjob;
1939 int ret = -1;
1940 struct printif *current_printif = get_printer_fns( snum );
1942 pjob = print_job_find(sharename, jobid);
1944 if (!pjob || !user)
1945 return False;
1947 if (!pjob->spooled || pjob->sysjob == -1)
1948 return False;
1950 if (!is_owner(user, snum, jobid) &&
1951 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1952 DEBUG(3, ("pause denied by security descriptor\n"));
1954 /* BEGIN_ADMIN_LOG */
1955 sys_adminlog( LOG_ERR,
1956 "Permission denied-- user not allowed to delete, \
1957 pause, or resume print job. User name: %s. Printer name: %s.",
1958 uidtoname(user->uid), PRINTERNAME(snum) );
1959 /* END_ADMIN_LOG */
1961 *errcode = WERR_ACCESS_DENIED;
1962 return False;
1965 /* need to pause the spooled entry */
1966 ret = (*(current_printif->job_pause))(snum, pjob);
1968 if (ret != 0) {
1969 *errcode = WERR_INVALID_PARAM;
1970 return False;
1973 /* force update the database */
1974 print_cache_flush(snum);
1976 /* Send a printer notify message */
1978 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
1980 /* how do we tell if this succeeded? */
1982 return True;
1985 /****************************************************************************
1986 Resume a job.
1987 ****************************************************************************/
1989 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1991 const char *sharename = lp_const_servicename(snum);
1992 struct printjob *pjob;
1993 int ret;
1994 struct printif *current_printif = get_printer_fns( snum );
1996 pjob = print_job_find(sharename, jobid);
1998 if (!pjob || !user)
1999 return False;
2001 if (!pjob->spooled || pjob->sysjob == -1)
2002 return False;
2004 if (!is_owner(user, snum, jobid) &&
2005 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2006 DEBUG(3, ("resume denied by security descriptor\n"));
2007 *errcode = WERR_ACCESS_DENIED;
2009 /* BEGIN_ADMIN_LOG */
2010 sys_adminlog( LOG_ERR,
2011 "Permission denied-- user not allowed to delete, \
2012 pause, or resume print job. User name: %s. Printer name: %s.",
2013 uidtoname(user->uid), PRINTERNAME(snum) );
2014 /* END_ADMIN_LOG */
2015 return False;
2018 ret = (*(current_printif->job_resume))(snum, pjob);
2020 if (ret != 0) {
2021 *errcode = WERR_INVALID_PARAM;
2022 return False;
2025 /* force update the database */
2026 print_cache_flush(snum);
2028 /* Send a printer notify message */
2030 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2032 return True;
2035 /****************************************************************************
2036 Write to a print file.
2037 ****************************************************************************/
2039 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
2041 const char* sharename = lp_const_servicename(snum);
2042 int return_code;
2043 struct printjob *pjob;
2045 pjob = print_job_find(sharename, jobid);
2047 if (!pjob)
2048 return -1;
2049 /* don't allow another process to get this info - it is meaningless */
2050 if (pjob->pid != sys_getpid())
2051 return -1;
2053 return_code = write(pjob->fd, buf, size);
2054 if (return_code>0) {
2055 pjob->size += size;
2056 pjob_store(sharename, jobid, pjob);
2058 return return_code;
2061 /****************************************************************************
2062 Get the queue status - do not update if db is out of date.
2063 ****************************************************************************/
2065 static int get_queue_status(const char* sharename, print_status_struct *status)
2067 fstring keystr;
2068 TDB_DATA data, key;
2069 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2070 int len;
2072 if (!pdb)
2073 return 0;
2075 if (status) {
2076 ZERO_STRUCTP(status);
2077 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2078 key.dptr = keystr;
2079 key.dsize = strlen(keystr);
2080 data = tdb_fetch(pdb->tdb, key);
2081 if (data.dptr) {
2082 if (data.dsize == sizeof(print_status_struct))
2083 /* this memcpy is ok since the status struct was
2084 not packed before storing it in the tdb */
2085 memcpy(status, data.dptr, sizeof(print_status_struct));
2086 SAFE_FREE(data.dptr);
2089 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2090 release_print_db(pdb);
2091 return (len == -1 ? 0 : len);
2094 /****************************************************************************
2095 Determine the number of jobs in a queue.
2096 ****************************************************************************/
2098 int print_queue_length(int snum, print_status_struct *pstatus)
2100 const char* sharename = lp_const_servicename( snum );
2101 print_status_struct status;
2102 int len;
2104 /* make sure the database is up to date */
2105 if (print_cache_expired(lp_const_servicename(snum), True))
2106 print_queue_update(snum);
2108 /* also fetch the queue status */
2109 memset(&status, 0, sizeof(status));
2110 len = get_queue_status(sharename, &status);
2112 if (pstatus)
2113 *pstatus = status;
2115 return len;
2118 /***************************************************************************
2119 Allocate a jobid. Hold the lock for as short a time as possible.
2120 ***************************************************************************/
2122 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2124 int i;
2125 uint32 jobid;
2127 *pjobid = (uint32)-1;
2129 for (i = 0; i < 3; i++) {
2130 /* Lock the database - only wait 20 seconds. */
2131 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
2132 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2133 return False;
2136 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2137 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2138 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2139 sharename));
2140 return False;
2142 jobid = 0;
2145 jobid = NEXT_JOBID(jobid);
2147 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2148 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2149 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2150 return False;
2153 /* We've finished with the INFO/nextjob lock. */
2154 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2156 if (!print_job_exists(sharename, jobid))
2157 break;
2160 if (i > 2) {
2161 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2162 sharename));
2163 /* Probably full... */
2164 errno = ENOSPC;
2165 return False;
2168 /* Store a dummy placeholder. */
2170 TDB_DATA dum;
2171 dum.dptr = NULL;
2172 dum.dsize = 0;
2173 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2174 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2175 jobid ));
2176 return False;
2180 *pjobid = jobid;
2181 return True;
2184 /***************************************************************************
2185 Append a jobid to the 'jobs changed' list.
2186 ***************************************************************************/
2188 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2190 TDB_DATA data, key;
2191 uint32 store_jobid;
2193 key.dptr = "INFO/jobs_changed";
2194 key.dsize = strlen(key.dptr);
2195 SIVAL(&store_jobid, 0, jobid);
2196 data.dptr = (char *)&store_jobid;
2197 data.dsize = 4;
2199 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2201 return (tdb_append(pdb->tdb, key, data) == 0);
2204 /***************************************************************************
2205 Start spooling a job - return the jobid.
2206 ***************************************************************************/
2208 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2210 uint32 jobid;
2211 char *path;
2212 struct printjob pjob;
2213 user_struct *vuser;
2214 const char *sharename = lp_const_servicename(snum);
2215 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2216 int njobs;
2218 errno = 0;
2220 if (!pdb)
2221 return (uint32)-1;
2223 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2224 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2225 release_print_db(pdb);
2226 return (uint32)-1;
2229 if (!print_time_access_check(snum)) {
2230 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2231 release_print_db(pdb);
2232 return (uint32)-1;
2235 path = lp_pathname(snum);
2237 /* see if we have sufficient disk space */
2238 if (lp_minprintspace(snum)) {
2239 SMB_BIG_UINT dspace, dsize;
2240 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2241 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2242 DEBUG(3, ("print_job_start: disk space check failed.\n"));
2243 release_print_db(pdb);
2244 errno = ENOSPC;
2245 return (uint32)-1;
2249 /* for autoloaded printers, check that the printcap entry still exists */
2250 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
2251 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2252 release_print_db(pdb);
2253 errno = ENOENT;
2254 return (uint32)-1;
2257 /* Insure the maximum queue size is not violated */
2258 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2259 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2260 sharename, njobs, lp_maxprintjobs(snum) ));
2261 release_print_db(pdb);
2262 errno = ENOSPC;
2263 return (uint32)-1;
2266 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2267 sharename, njobs, lp_maxprintjobs(snum) ));
2269 if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2270 goto fail;
2272 /* create the database entry */
2274 ZERO_STRUCT(pjob);
2276 pjob.pid = sys_getpid();
2277 pjob.sysjob = -1;
2278 pjob.fd = -1;
2279 pjob.starttime = time(NULL);
2280 pjob.status = LPQ_SPOOLING;
2281 pjob.size = 0;
2282 pjob.spooled = False;
2283 pjob.smbjob = True;
2284 pjob.nt_devmode = nt_devmode;
2286 fstrcpy(pjob.jobname, jobname);
2288 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2289 fstrcpy(pjob.user, vuser->user.smb_name);
2290 } else {
2291 fstrcpy(pjob.user, uidtoname(user->uid));
2294 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2296 /* we have a job entry - now create the spool file */
2297 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2298 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2299 pjob.fd = smb_mkstemp(pjob.filename);
2301 if (pjob.fd == -1) {
2302 if (errno == EACCES) {
2303 /* Common setup error, force a report. */
2304 DEBUG(0, ("print_job_start: insufficient permissions \
2305 to open spool file %s.\n", pjob.filename));
2306 } else {
2307 /* Normal case, report at level 3 and above. */
2308 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2309 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2311 goto fail;
2314 pjob_store(sharename, jobid, &pjob);
2316 /* Update the 'jobs changed' entry used by print_queue_status. */
2317 add_to_jobs_changed(pdb, jobid);
2319 /* Ensure we keep a rough count of the number of total jobs... */
2320 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2322 release_print_db(pdb);
2324 return jobid;
2326 fail:
2327 if (jobid != -1)
2328 pjob_delete(sharename, jobid);
2330 release_print_db(pdb);
2332 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2333 return (uint32)-1;
2336 /****************************************************************************
2337 Update the number of pages spooled to jobid
2338 ****************************************************************************/
2340 void print_job_endpage(int snum, uint32 jobid)
2342 const char* sharename = lp_const_servicename(snum);
2343 struct printjob *pjob;
2345 pjob = print_job_find(sharename, jobid);
2346 if (!pjob)
2347 return;
2348 /* don't allow another process to get this info - it is meaningless */
2349 if (pjob->pid != sys_getpid())
2350 return;
2352 pjob->page_count++;
2353 pjob_store(sharename, jobid, pjob);
2356 /****************************************************************************
2357 Print a file - called on closing the file. This spools the job.
2358 If normal close is false then we're tearing down the jobs - treat as an
2359 error.
2360 ****************************************************************************/
2362 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2364 const char* sharename = lp_const_servicename(snum);
2365 struct printjob *pjob;
2366 int ret;
2367 SMB_STRUCT_STAT sbuf;
2368 struct printif *current_printif = get_printer_fns( snum );
2370 pjob = print_job_find(sharename, jobid);
2372 if (!pjob)
2373 return False;
2375 if (pjob->spooled || pjob->pid != sys_getpid())
2376 return False;
2378 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2379 pjob->size = sbuf.st_size;
2380 close(pjob->fd);
2381 pjob->fd = -1;
2382 } else {
2385 * Not a normal close or we couldn't stat the job file,
2386 * so something has gone wrong. Cleanup.
2388 close(pjob->fd);
2389 pjob->fd = -1;
2390 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2391 goto fail;
2394 /* Technically, this is not quite right. If the printer has a separator
2395 * page turned on, the NT spooler prints the separator page even if the
2396 * print job is 0 bytes. 010215 JRR */
2397 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2398 /* don't bother spooling empty files or something being deleted. */
2399 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2400 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2401 unlink(pjob->filename);
2402 pjob_delete(sharename, jobid);
2403 return True;
2406 pjob->smbjob = jobid;
2408 ret = (*(current_printif->job_submit))(snum, pjob);
2410 if (ret)
2411 goto fail;
2413 /* The print job has been sucessfully handed over to the back-end */
2415 pjob->spooled = True;
2416 pjob->status = LPQ_QUEUED;
2417 pjob_store(sharename, jobid, pjob);
2419 /* make sure the database is up to date */
2420 if (print_cache_expired(lp_const_servicename(snum), True))
2421 print_queue_update(snum);
2423 return True;
2425 fail:
2427 /* The print job was not succesfully started. Cleanup */
2428 /* Still need to add proper error return propagation! 010122:JRR */
2429 unlink(pjob->filename);
2430 pjob_delete(sharename, jobid);
2431 return False;
2434 /****************************************************************************
2435 Get a snapshot of jobs in the system without traversing.
2436 ****************************************************************************/
2438 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2440 TDB_DATA data, key, cgdata;
2441 print_queue_struct *queue = NULL;
2442 uint32 qcount = 0;
2443 uint32 extra_count = 0;
2444 int total_count = 0;
2445 size_t len = 0;
2446 uint32 i;
2447 int max_reported_jobs = lp_max_reported_jobs(snum);
2448 BOOL ret = False;
2449 const char* sharename = lp_servicename(snum);
2451 /* make sure the database is up to date */
2452 if (print_cache_expired(lp_const_servicename(snum), True))
2453 print_queue_update(snum);
2455 *pcount = 0;
2456 *ppqueue = NULL;
2458 ZERO_STRUCT(data);
2459 ZERO_STRUCT(cgdata);
2460 key.dptr = "INFO/linear_queue_array";
2461 key.dsize = strlen(key.dptr);
2463 /* Get the stored queue data. */
2464 data = tdb_fetch(pdb->tdb, key);
2466 if (data.dptr && data.dsize >= sizeof(qcount))
2467 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2469 /* Get the changed jobs list. */
2470 key.dptr = "INFO/jobs_changed";
2471 key.dsize = strlen(key.dptr);
2473 cgdata = tdb_fetch(pdb->tdb, key);
2474 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2475 extra_count = cgdata.dsize/4;
2477 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2479 /* Allocate the queue size. */
2480 if (qcount == 0 && extra_count == 0)
2481 goto out;
2483 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2484 goto out;
2486 /* Retrieve the linearised queue data. */
2488 for( i = 0; i < qcount; i++) {
2489 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2490 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2491 &qjob,
2492 &qsize,
2493 &qpage_count,
2494 &qstatus,
2495 &qpriority,
2496 &qtime,
2497 queue[i].fs_user,
2498 queue[i].fs_file);
2499 queue[i].job = qjob;
2500 queue[i].size = qsize;
2501 queue[i].page_count = qpage_count;
2502 queue[i].status = qstatus;
2503 queue[i].priority = qpriority;
2504 queue[i].time = qtime;
2507 total_count = qcount;
2509 /* Add in the changed jobids. */
2510 for( i = 0; i < extra_count; i++) {
2511 uint32 jobid;
2512 struct printjob *pjob;
2514 jobid = IVAL(cgdata.dptr, i*4);
2515 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2516 pjob = print_job_find(lp_const_servicename(snum), jobid);
2517 if (!pjob) {
2518 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2519 remove_from_jobs_changed(sharename, jobid);
2520 continue;
2523 queue[total_count].job = jobid;
2524 queue[total_count].size = pjob->size;
2525 queue[total_count].page_count = pjob->page_count;
2526 queue[total_count].status = pjob->status;
2527 queue[total_count].priority = 1;
2528 queue[total_count].time = pjob->starttime;
2529 fstrcpy(queue[total_count].fs_user, pjob->user);
2530 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2531 total_count++;
2534 /* Sort the queue by submission time otherwise they are displayed
2535 in hash order. */
2537 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2539 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2541 if (max_reported_jobs && total_count > max_reported_jobs)
2542 total_count = max_reported_jobs;
2544 *ppqueue = queue;
2545 *pcount = total_count;
2547 ret = True;
2549 out:
2551 SAFE_FREE(data.dptr);
2552 SAFE_FREE(cgdata.dptr);
2553 return ret;
2556 /****************************************************************************
2557 Get a printer queue listing.
2558 set queue = NULL and status = NULL if you just want to update the cache
2559 ****************************************************************************/
2561 int print_queue_status(int snum,
2562 print_queue_struct **ppqueue,
2563 print_status_struct *status)
2565 fstring keystr;
2566 TDB_DATA data, key;
2567 const char *sharename;
2568 struct tdb_print_db *pdb;
2569 int count = 0;
2571 /* make sure the database is up to date */
2573 if (print_cache_expired(lp_const_servicename(snum), True))
2574 print_queue_update(snum);
2576 /* return if we are done */
2577 if ( !ppqueue || !status )
2578 return 0;
2580 *ppqueue = NULL;
2581 sharename = lp_const_servicename(snum);
2582 pdb = get_print_db_byname(sharename);
2584 if (!pdb)
2585 return 0;
2588 * Fetch the queue status. We must do this first, as there may
2589 * be no jobs in the queue.
2592 ZERO_STRUCTP(status);
2593 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2594 key.dptr = keystr;
2595 key.dsize = strlen(keystr);
2596 data = tdb_fetch(pdb->tdb, key);
2597 if (data.dptr) {
2598 if (data.dsize == sizeof(*status)) {
2599 /* this memcpy is ok since the status struct was
2600 not packed before storing it in the tdb */
2601 memcpy(status, data.dptr, sizeof(*status));
2603 SAFE_FREE(data.dptr);
2607 * Now, fetch the print queue information. We first count the number
2608 * of entries, and then only retrieve the queue if necessary.
2611 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2612 release_print_db(pdb);
2613 return 0;
2616 release_print_db(pdb);
2617 return count;
2620 /****************************************************************************
2621 Pause a queue.
2622 ****************************************************************************/
2624 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2626 int ret;
2627 struct printif *current_printif = get_printer_fns( snum );
2629 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2630 *errcode = WERR_ACCESS_DENIED;
2631 return False;
2634 ret = (*(current_printif->queue_pause))(snum);
2636 if (ret != 0) {
2637 *errcode = WERR_INVALID_PARAM;
2638 return False;
2641 /* force update the database */
2642 print_cache_flush(snum);
2644 /* Send a printer notify message */
2646 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2648 return True;
2651 /****************************************************************************
2652 Resume a queue.
2653 ****************************************************************************/
2655 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2657 int ret;
2658 struct printif *current_printif = get_printer_fns( snum );
2660 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2661 *errcode = WERR_ACCESS_DENIED;
2662 return False;
2665 ret = (*(current_printif->queue_resume))(snum);
2667 if (ret != 0) {
2668 *errcode = WERR_INVALID_PARAM;
2669 return False;
2672 /* make sure the database is up to date */
2673 if (print_cache_expired(lp_const_servicename(snum), True))
2674 print_queue_update(snum);
2676 /* Send a printer notify message */
2678 notify_printer_status(snum, PRINTER_STATUS_OK);
2680 return True;
2683 /****************************************************************************
2684 Purge a queue - implemented by deleting all jobs that we can delete.
2685 ****************************************************************************/
2687 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2689 print_queue_struct *queue;
2690 print_status_struct status;
2691 int njobs, i;
2692 BOOL can_job_admin;
2694 /* Force and update so the count is accurate (i.e. not a cached count) */
2695 print_queue_update(snum);
2697 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2698 njobs = print_queue_status(snum, &queue, &status);
2700 for (i=0;i<njobs;i++) {
2701 BOOL owner = is_owner(user, snum, queue[i].job);
2703 if (owner || can_job_admin) {
2704 print_job_delete1(snum, queue[i].job);
2708 SAFE_FREE(queue);
2710 return True;